Forums / National / Russian / Модули и плагины / [Plugin] Comlist / Pagecom

Плагин вывода комментариев через функцию по условиям (аргументам)

Kort
#1 2023-08-17 17:30

[Plugin] Comlist / Pagecom

Плагин вывода комментариев через функцию по условиям (аргументам):

  • $tpl – имя шаблона
  • $items – количество выводимых элементов (при непустом $pagination – на страницу)
  • $order – сортировка в формате SQL (по умолчанию com_id DESC)
  • $extra – дополнительный SQL-запрос
  • $group – значение 1 группирует комментарии по страницам (одна страница -- один комментарий)
  • $offset -- сдвиг записей от начала (минус $offset комментариев)
  • $pagination – код паджинации
  • $ajax_block – id блока при использовании аякса (включение аякса в конфиге плагина)
  • $cache_name – имя записи кэша
  • $cache_ttl – срок действия кэша

Для работы плагина необходимо установить или просто загрузить плагин Pagelist.

Примеры использования

// Вывести 5 последних комментариев
{PHP|cot_comlist(‘comlist’, 5}

// Вывести 5 последних комментариев, сгруппированных по страницам
{PHP|cot_comlist(‘comlist’, 5, ‘’, ‘’, 1}

// Вывести последние комментарии, сгруппированные по страницам 
// и с паджинацией по 5 записей на страницу
{PHP|cot_comlist(‘comlist’, 5, ‘’, ‘’, 1, ‘compage’}

// Вывести последние комментарии, сгруппированные по страницам 
// и с ajax-паджинацией по 5 записей на страницу
{PHP|cot_comlist(‘comlist’, 5, ‘’, ‘’, 1, ‘compage’, ‘com2list’}

// Вывести 5 последних комментариев к опросам
{PHP|cot_comlist(‘comlist’, 5, '', 'com_area = "polls"'}

// Вывести 5 последних комментариев к разделу docs
{PHP|cot_comlist(‘comlist’, 5, '', 'com_area = "page" and com_code = "docs"'}


// Вывести 5 последних комментариев с сортировкой по дате и закэшировать на 1 день
{PHP|cot_comlist(‘comlist’, 5, 'com_date DESC', '', 1, '', '', 'comments_global', 86400}

Почему удалены аргументы black / white lists

Функционал белого и черного списка нечасто используется, поэтому он реализоватн в виде дополнения. Пример использования в шаблоне:

{PHP|cot_comlist('comlist', '5', 'com_date DESC', '-1docs;system', 1)}

В аргументе $extra можно указать режим и опции белого и черно списка:

  • первый символ (+ или -) отвечает за режим белого или черного списка соответственно,
  • второй символ (0 или 1) отвечает за включение или не включение вложенных подкаталогов,
  • все остальное - это коды разделов, указанные через точку с запятой.

Если в аргументе $extra присутствует точка с запятой, функция "расшифрует" и обработает указанные настройки. Работает только при включенной опции "Генерировать page tags".

Если необходимости в использовании белых и черных списков нет, части comlist.first.black_white.php и comlist.query.black_white.php можно отключить (поставить на паузу).

Страница загрузкиРепозиторий на Github

SED.by - создание сайтов, разработка плагинов и тем для Котонти
This post was edited by Kort (2023-09-15 17:06, 7 months ago)
Kabak
#2 2023-08-28 15:11

В рандом плагин начинает показывать комментарии страниц которые не должны показываться определённым читателям. Нарушается приватность.  Чёрный список из прежней версии плагина мне нравится больше. 
 

Аякс использован только для кэша ? ( может ерунду спрашиваю )

Kort
#3 2023-08-28 19:47

С какими аргументами вызывается функция? Плагин обновлен из репозитория?

SED.by - создание сайтов, разработка плагинов и тем для Котонти
Kabak
#4 2023-08-29 06:21

Я про Pagecom , если не использовать чёрный список. 

 

В Comlist при рандомной генерации списка комментариев учитывается уровень читателя и не используются комментарии из закрытых для пользователя разделов ?

Kort
#5 2023-08-29 06:43

А как вообще надо? Черно-белые списки нужны принципиально или только для исключения показа комментариев в недоступных пользователю разделах?

SED.by - создание сайтов, разработка плагинов и тем для Котонти
This post was edited by Kort (2023-08-29 06:51, 8 months ago)
Kabak
#6 2023-08-29 07:05

Нужно, чтобы плагин делвл выборку комментариев только из тех разделов которые может читать конкретный пользователь в соответствии с его уровнем на сайте.  Чёрным списком я могу исключить коментарии как минимум не зарегистрированным пользователям на сайте.  Для меня чёрный список удобен. 

 

Если плагин без чёрного списка сам выбирает из базы коментарии которые видны конкретному пользователю в соответствии с его уровнем, то чёрный список не нужен.

 

Чёрный и белый списки добавляют гибкости.  Мне нравится, что я могу управлятьтем,  что показывать не зарегистрированным пользователям и наоборот - не показывать, если появилась необходимость.

Добавлено 8 минут спустя:

Удобно было бы все эти настройки размещать в админке, а не править TPL.  Например, что в белом или чёрных листах, количество символов и количество строк которое необходимо оставлять, тип сортировки и т.д.

Добавлено 45 секунд спустя:

Мне не понятна прелесть кэша. Я , вероятно, не понимаю как он работает в Cotonti

This post was edited by Kabak (2023-08-29 07:17, 8 months ago)
Kort
#7 2023-08-29 07:30

1. Удобство настроек состоит именно в том, что они указываются при конкретном вызове функции. Зачем в админке их задавать глобально? В каждом конкретном случае нужно свое количество записей, порядок сортировки, паджинация, кэш и прочее.

2. Количество символов и строк -- это вообще из области допфункций и CSS. Как оставлять их нужное количество уже пояснял.

3. Прелесть кэша в том, что при наличии закэшированного вывода, он и отдается сразу в шаблон, без отработки функции и не нагружая сервер. При добавлении, удалении и редактировании комментария весь кэш плагина удаляется и при следующем вызове функции создается заново. И так по кругу. Время загрузки страницы можешь сравнить.

4. Кэш и аякс вместе не работают. Плюс необходимости в этом нет.

5. Права доступа к разделам (и, соответственно, страницам) и черно-белые списки -- это о разном. Отдельно сделать можно и то и другое.

SED.by - создание сайтов, разработка плагинов и тем для Котонти
Kabak
#8 2023-08-29 07:52

Я переделал под мои нужны Pagecom/ Из-за наличия чёрного и белых списков он мне нравится больше.  Но это здорово, что есть выбор для пользователей Cotonti.

Kort
#9 2023-08-29 08:33

Реализация белого и черного списка:

  1. включить опцию "Создавать теги для модуля Page",
  2. в аргументе $extra указать +/- (белый / черный), 1/0 (добавлять / не добавлять вложенные подразделы) и указать разделы белого списка через ';' -- все без пробелов,
  3. установить плагин Pagelist последней версии

Вызов такой:

{PHP|cot_comlist('comlist', '0', '', '+0cat1;cat2')}

P.S. Но сделать под свои нужды тоже дело!

SED.by - создание сайтов, разработка плагинов и тем для Котонти
This post was edited by Kort (2023-08-31 08:02, 8 months ago)
Kabak
#10 2023-09-18 14:30
function pagecom_string_truncate($text, $allowed_symbols_in_str = 100, $considerhtml = true, $exact = false, $Output_Ending = '', $str_amount_required = 3 )
{
    $looking_for = ['<br>', '<br />', '<br/>' ];
    $looking_for2 = [ '<a href=' ];
    $looking_for3 = [ '<p>' ];
    $looking_for4 = [ '<h1>', '<h2>', '<h3>', '</h1>', '</h2>', '</h3>' ];

    $str_amount_required < 1 ? $str_amount_required = 1 : $str_amount_required;
 
    $No_BR = 0;
    
    $total_symbols_amount = $str_amount_required * $allowed_symbols_in_str;
    
    $Output = '';
    $No_Output_Ending = false;
    $Required_output_ending = false;
    $str_amount_ready = 0;  // how many strings ready for output strings
    $str_symbols_ready = 0; // how many symbols were pushed to the next output struing


    $link_replaced = false;

    $visible_length = mb_strlen(preg_replace('/<.*?>/', '', $text));
    
    $Output_Ending_size = strlen( $Output_Ending ) + 1;

    $truncate = '';
    $truncate_required = false;
    $add_one_BR = false;
    $truncated_by_space = false;
    $plain_mode = false;
    $open_tags = [];
    $total_length = 0;
    $plain_tag = false;
    $long_str_found = false;


    $text = str_replace($looking_for4, '', $text );

    for ( $index = count ( $looking_for ) - 1; $index >= 0; --$index )
    {
        $No_BR += substr_count ($text, $looking_for[$index] );
    }

	if (empty($text)) {
		$truncate .= $Output_Ending;
        $truncate .= "<br><br>";
		goto Inject_New_Lines;
    }

	if (!$considerhtml) 
	{
		if (mb_strlen($text) <= $total_symbols_amount) 
		{
                $truncate = $text;
                goto Inject_New_Lines;
		}
		else 
			$truncate = mb_substr($text, 0, $total_symbols_amount);
	}
	else
	{
		// if the plain text is shorter than the maximum length, return the whole text
		$temp = mb_strlen(preg_replace('/<.*?>/', '', $text));
		if ( !preg_match('/<\s*(pre|plaintext)/', $text ) && $temp <= $total_symbols_amount ) 
		{
            if ( $No_BR > 0 )
            {
                // do nothing
            }
            else
            {
                if ( $visible_length < $allowed_symbols_in_str )
                {

// Check for <p> tag
                    $offset = 0;
                    $offset1 = '';
                    $offset1 = strpos($text, $looking_for3[0], $offset );

                    if ( $offset1 == '' )
                    {
                        $truncate = $text;
                        goto Inject_New_Lines;
                    }
// Check for <p> tag


                }
            }
		}
		// splits all html-tags to scanable lines
		preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);

		foreach ($lines as $line_matchings) {
			// if there is any html-tag in this line, handle it and add it (uncounted) to the output
			if (!empty($line_matchings[1])) {
				// if it's an "empty element" with or without xhtml-conform closing slash (f.e. <br/>)
				if (
                    preg_match(
                        '/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is',
                        $line_matchings[1]
                    )
                ) {
					// do nothing
 //                   ++$str_amount_ready;
                    $str_symbols_ready = 0;
				} elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
                    // if tag is a closing tag (f.e. </b>)
					$tag = false;
					if (strtolower($tag_matchings[1]) == $plain_mode) {
						$plain_mode = false;
					} else {
						// delete tag from $open_tags list
						$pos = array_search($tag_matchings[1], $open_tags);
						if ($pos !== false) {
							unset($open_tags[$pos]);
						}
					}
				} elseif (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
                    // if tag is an opening tag (f.e. <b>)
					$tag = strtolower($tag_matchings[1]);
					$plain_tag = in_array($tag, array('pre','plaintext')) ? $tag : false;
					// add tag to the beginning of $open_tags list
					if (!$plain_mode && !$plain_tag) {
                        array_unshift($open_tags, mb_strtolower($tag));
                    }
				}
				// add html-tag to $truncate'd text
				if (!$plain_mode) 
                {
                    if ( $str_amount_ready > $str_amount_required )
                        break;
                        
                    // Found <li> tag
                    if ( $line_matchings[1] == '</li>' )
                    {
                        if ( $str_amount_ready < $str_amount_required )
                        {
                            ++$str_amount_ready;
                            $str_symbols_ready = 0;
                        } 
                        else 
                        {
                            break;
                        }
                    }

                    if ( $line_matchings[1] == '</p>' )
                    {
                        if ( $str_amount_ready < $str_amount_required )
                        {
                            ++$str_amount_ready;
                            $str_symbols_ready = 0;
                            $long_str_found == true ? $long_str_found = false : $long_str_found;
                        } 
                        else 
                        {
                            break;
                        }
                    }

                    // Last <li> should not be closed
                    if ( $line_matchings[1] == '</li>' && $str_amount_ready >= $str_amount_required )
                    {
                        $No_Output_Ending = true;
                        $truncate .= $Output_Ending;
                        $truncate .= $line_matchings[1];
                        break;
                    } 

                    if ( $line_matchings[1] == '<p>' && $str_amount_ready >= $str_amount_required )
                    {
                        break;
                    }
                    else
                    {
                        $truncate .= $line_matchings[1];
                    }

                    if ( $line_matchings[1] == '<p>' && $str_symbols_ready > 0 && $long_str_found )
                    {
                        ++$str_amount_ready;
                        $str_symbols_ready = 0;
                        $long_str_found = false;
                    }

                    if ( $line_matchings[1] == '</p>' && $str_amount_ready == $str_amount_required )
                    {
                        break;
                    }
                    
                    if ( $line_matchings[1] == '<br>' || $line_matchings[1] == '<br />' || $line_matchings[1] == '<br/>' )
                    {
                        if ( $str_amount_ready >= $str_amount_required )
                        {
                            break;
                        }
                        else
                        {
                            ++$str_amount_ready;
                            $str_symbols_ready = 0;   
                            
                            if ( $str_amount_ready >= $str_amount_required )
                            {                            
                                $No_Output_Ending = true;
                                $truncate .= $Output_Ending; 
                                break;
                            }
                        }
                    }
                }
			}

			// the number of characters which are left
			$left = $total_symbols_amount - $total_length;
			if ($plain_mode || ($plain_tag && $tag)) {
				// treats text as plain in <pre>, <plaintext> tags
				$content = $plain_mode ? $line_matchings[0] : $line_matchings[2];
				if (mb_strlen($content) <= $left) {
					$truncate .= $content;
					$total_length += mb_strlen($content);

				} else {
					$truncate .= mb_substr($content, 0, $left);
					$total_length += $left;
				}
				if ($plain_tag && !$plain_mode) {
                    $plain_mode = $plain_tag;
                }

			} else {
				// calculate the length of the plain text part of the line; handle entities as one character
				$content_length = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};|[\r\n\s]{2,}/i', ' ', $line_matchings[2]));
                // Checking for <a> href block
                $offset1 = strpos($line_matchings[1], $looking_for2[0], 0 );

				if ($total_length + $content_length > $total_symbols_amount && $offset1 =='' ) {
					$entities_length = 0;

                    // One big string
                    $Big_str = (int)($content_length / $allowed_symbols_in_str);
                    
                    $New_str_sym_amount = $content_length - $allowed_symbols_in_str;
                    if ( $New_str_sym_amount < 0 )
                    {
                        $New_str_sym_amount = 0;
                    }

                    $str_amount_ready += $Big_str;
                    if ( $str_amount_ready >= $str_amount_required )
                    {
// LINK REPLACE     
                        $offset1 = strpos($line_matchings[1], $looking_for2[0], 0 );

                        if ( $offset1 != '' )
                        {
                            $truncate .= '...';
                        }
                        else
                        {
                            $truncate_required = true;

                            if ( $left < $allowed_symbols_in_str )
                            {
                                $truncate .= mb_substr($line_matchings[2], 0, $left ); 
                            }

                            if ( $New_str_sym_amount < $allowed_symbols_in_str )
                            {
                                $truncate .= mb_substr($line_matchings[2], 0, $allowed_symbols_in_str );
                                $Required_output_ending = true;
                            }

                            if ( $New_str_sym_amount > $allowed_symbols_in_str &&
                                 $left > $allowed_symbols_in_str )
                                 {
                                    $truncate .= mb_substr($line_matchings[2], 0, $left - $Output_Ending_size * 3 ); 
                                 }
                            
                        }
// LINK REPLACE 
// One big string  no <p> tag
                        $offset1 = strpos($truncate, $looking_for3[0], 0 );

                        if ( $offset1 == '' )
                        {
                            $add_one_BR = true;
                        }
                        else
                        {
                            $add_one_BR = false;
                        }
// One big string  no <p> tag
                    }
                    
                    
					// search for html entities and spaces
					if (
                        preg_match_all(
                            '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};|[\r\n\s]{2,}/i',
                            $line_matchings[2],
                            $entities,
                            PREG_OFFSET_CAPTURE
                        )
                    ) {
						// calculate the real length of all entities in the legal range
						foreach ($entities[0] as $entity) {
							if ($entity[1]+1-$entities_length <= $left) {
								$left--;
								$entities_length += mb_strlen($entity[0]);
							} else {
								// no more characters left
								break;
							}
						}
					}

                    // maximum lenght is reached, so get off the loop
					$truncated_by_space = preg_match('/[\r\n\s]/', mb_substr($line_matchings[2], $left+$entities_length, 1));
					break;
				} else 
                {
                    $offset1 = strpos($line_matchings[1], $looking_for2[0], 0 );

                    if ( $offset1 != '' )
                    {
                            $truncate .= '...';
                            $No_Output_Ending = true;
                            $total_length += $content_length;
                            $link_replaced = true;
                    }
                    else
                    {
                        $truncate .= $line_matchings[2]; 
                        $total_length += $content_length;
                    }
					
/* Injection */
                    if ( $link_replaced )
                    {
                        $link_replaced = false;
                        $str_symbols_ready += 3;
                    }
                    else
                    {
                        $str_symbols_ready += $content_length;
                    }
                
                    if ( $str_symbols_ready >= $allowed_symbols_in_str && $str_amount_ready < $str_amount_required )
                    {
                        $long_str_found = true;
                        do 
                        {
                            ++$str_amount_ready;

                            if ( $str_amount_ready > $str_amount_required )
                                break;

                            if ( $str_amount_ready == $str_amount_required && 
                                $str_symbols_ready > $allowed_symbols_in_str )
                                {
                                    $truncate = mb_substr($truncate, 0, -($str_symbols_ready - $allowed_symbols_in_str + $Output_Ending_size) );
                                    break;
                                }

                            $str_symbols_ready = $str_symbols_ready - $allowed_symbols_in_str;
                        }
                        while ( $str_symbols_ready >= $allowed_symbols_in_str );
                    }

/* Injection */                    
				}
			}

			// if the maximum length is reached, get off the loop
			if ($total_length >= $total_symbols_amount || $str_symbols_ready >= $allowed_symbols_in_str  ) {
				break;
			}
		}
        // No Output_Ending required
        if ( (( $total_length + $Output_Ending_size ) < $total_symbols_amount) && (( $content_length + $Output_Ending_size ) < $total_symbols_amount ) && 
             ( $str_symbols_ready + $Output_Ending_size ) < $allowed_symbols_in_str )
        {
            $No_Output_Ending = true;
        }

        if ( $Required_output_ending )
        {
            $No_Output_Ending = false;
        }

    }

	if ( $truncate_required || ( !$exact && !$truncated_by_space && !$plain_mode 
                && ( ($str_symbols_ready >= $allowed_symbols_in_str) || ($content_length >= $total_symbols_amount)) )
    ) {
		// ...search the last occurence of a space...
		if (mb_strrpos($truncate, ' ') > 0) {
			$pos1 = mb_strrpos($truncate, ' ');
			$pos2 = mb_strrpos($truncate, '>');
			$spos = ($pos2 < $pos1) ? $pos1 : ($pos2+1);
			if (isset($spos)) {
				// ...and cut the text in this position
				$truncate = mb_substr($truncate, 0, $spos );
			}
		}
	}

    if ( !$No_Output_Ending )
    {
        $truncate .= $Output_Ending;
    }

	if ($considerhtml) {
		// close all unclosed html-tags
		if ($plain_mode) {
            $truncate .= '</' . $plain_mode . '>';
        }
		foreach ($open_tags as $tag) {
			$truncate .= '</' . $tag . '>';
            if ( $tag == 'p' )
             ++$str_amount_ready;
		}
	}

Inject_New_Lines:
    
    if ( $add_one_BR )
    {
        $truncate .= "<br>";
    }


    for ($count = $str_amount_ready; $count < $str_amount_required ; ++$count )
    {
        $truncate .= "<br>";
    }
 
	 return $truncate;
 }

 

		$t->assign(cot_generate_usertags($row, 'PAGECOM_ROW_AUTHOR_'));
/* +++++   My code    ==== */
	//	$cutstring = cot_string_truncate($row['com_text'], $cfg['plugin']['pagecom']['message_cut_amount'] * $cfg['plugin']['pagecom']['message_strings_amount'], $considerhtml = true, $exact = false, $cuttext = $cfg['plugin']['pagecom']['end_string']);
		$cutstring = pagecom_string_truncate($row['com_text'], $cfg['plugin']['pagecom']['message_cut_amount'], $considerhtml = true, $exact = false, $cuttext = $cfg['plugin']['pagecom']['end_string'] , $cfg['plugin']['pagecom']['message_strings_amount'] );
/* +++++   My code    ==== */
		$com_text = cot_parse($row['com_text'], $cfg['plugin']['comments']['markup']);

		$t->assign(array(
			'PAGECOM_ROW_NUM' => $jj,
			'PAGECOM_ROW_ODDEVEN' => cot_build_oddeven($jj),
			'PAGECOM_ROW_ID' => $row['com_id'],
			'PAGECOM_ROW_URL' => cot_url('page', $link_params, '#c'.$row['com_id']),
			'PAGECOM_ROW_AUTHOR' => cot_build_user($row['com_authorid'], htmlspecialchars($row['com_author'])),
			'PAGECOM_ROW_AUTHORNAME' => htmlspecialchars($row['com_author']),
			'PAGECOM_ROW_AUTHORID' => $row['com_authorid'],
			'PAGECOM_ROW_TEXT' => $com_text,
			/* +++++   My code    ==== */
			'PAGECOM_ROW_CUTED_TEXT' => $cutstring,
			/* +++++   My code    ==== */			
			'PAGECOM_ROW_TEXT_PLAIN' => strip_tags($com_text),
			'PAGECOM_ROW_DATE' => cot_date('datetime_medium', $row['com_date']),
			'PAGECOM_ROW_DATE_STAMP' => $row['com_date'],
			'PAGECOM_ROW_CATTITLE' => htmlspecialchars($structure['page'][$row['page_cat']]['title'])
		));