В базовом комплекте MaxSite CMS список похожих страниц для блока "Еще записи по теме" формируется на основе их принадлежности к категориям. Более достоверный список похожих страниц можно получить, используя в качестве меры похожести число общих меток.
Этим и займется наш плагин similar_post_tag.
Способ определения похожести.
Все страницы сравниваются с текущей страницей и для каждой страницы формируется мера похожести на текущую - сколько у страниц общих меток и категорий.
foreach ($all_pages as $cur_page) // сравниваем все страницы с текущей
{
if ($cur_page['page_id'] == $page['page_id']) continue;
// похожесть страниц - это сколько у них одинаковых меток и категорий
$tag_similarity = count(array_intersect($cur_page['page_tags'] , $page['page_tags']));
$cat_similarity = count(array_intersect($cur_page['page_categories'] , $page['page_categories']));
$k = 1; // коэффициент
$similarity = $tag_similarity*$k + $cat_similarity;
if ($similarity) // похожесть > 0 - есть общие метки и категории
{
$cur_page['similarity'] = $similarity;
$bl_pages[] = $cur_page;
}
}
Отсортированный по мере похожести массив номеров и используется в дальнейшем для получения похожих страниц.
Способ вывода.
В предыдущей версии плагина использовался вывод похожих страниц по хуку content_end.
В последних версиях MaxSite CMS есть стандартный блок вывода похожих страниц "Еще записи по теме", который можно использовать.
При формировании страниц в блоке "Еще записи по теме" есть возможность добавить в вызов mso_get_pages свои строчки SQL-запроса.
Вот как выглядит функция mso_page_other_pages в фале common\page.php:
# блок "Еще записи этой рубрики"
function mso_page_other_pages($page_id = 0, $page_categories = array())
{
if ($bl_title = mso_get_option('page_other_pages', 'templates', tf('Еще записи по теме')))
{
// алгоритм получения записей
$algoritm = mso_get_option('page_other_pages_algoritm', 'templates', 'all');
$type_page = mso_get_option('page_other_pages_type_page', 'templates', '');
if (!$type_page) $type_page = false;
$custom_type = 'category';
if ($algoritm == 'lowlewel') // только из подрубрик
{
$all_cat = mso_cat_array_single(); // все рубрики
$bl_page_categories = array(); // обработаный массив id-level
foreach ($page_categories as $cat_id)
{
$bl_page_categories[$cat_id] = $all_cat[$cat_id]['level'];
}
arsort($bl_page_categories); // сортируем в обратном порядке
$bl_page_categories = array_keys($bl_page_categories); // оставляем только ключи (id)
// если что-то есть, то оставляем только первую рубрику, иначе $page_categories
if (isset($bl_page_categories[0]))
$bl_page_categories = array($bl_page_categories[0]);
else $bl_page_categories = $page_categories;
}
elseif ($algoritm == 'no-cat') // не учитывать рубрики
{
$bl_page_categories = array();
$custom_type = 'home';
}
else
{
// обычный вывод по всем рубрикам
$bl_page_categories = $page_categories;
}
// своя функция sql-запроса для function_add_custom_sql
// задается через mso_set_val()
$fasc = mso_get_val('page_other_pages_function_add_custom_sql', false);
$bl_pages = mso_get_pages(
array( 'type'=> $type_page,
'content'=> false,
'pagination'=>false,
'custom_type'=> $custom_type,
'categories'=>$bl_page_categories,
'exclude_page_id'=>array($page_id),
'limit'=> mso_get_option('page_other_pages_limit', 'templates', 7),
'order'=>mso_get_option('page_other_pages_order', 'templates', 'page_date_publish'),
'order_asc'=>mso_get_option('page_other_pages_order_asc', 'templates', 'random'),
'function_add_custom_sql' => $fasc,
),
$_temp);
if ($bl_pages)
{
if ($f = mso_page_foreach('page-other-pages-out')) // свой вывод
{
require($f);
}
else
{
echo '<div class="mso-page-other-pages">' . mso_get_val('page_other_pages_start', '<h4>') . $bl_title . mso_get_val('page_other_pages_end', '</h4>') . '<ul>';
foreach ($bl_pages as $bl_page)
{
mso_page_title($bl_page['page_slug'], $bl_page['page_title'], '<li>', '</li>', true);
}
echo '</ul></div>';
}
}
}
}Необходимо только добавив в запрос получения записей для этого блока всего одну строчку:
$CI->db->where_in('page.page_id', $array_id);
Для этого нам необходимо определить функцию, добавляющую эту строчку, при построении запроса получения записей по теме.
// функция - добавка, получаемая в mso_get_val('page_other_pages_function_add_custom_sql', false);
// добавляем условие получения только похожих страниц
function sql_add_similar_posts_tags()
{
global $page;
// не страница
if (!isset($page['page_id']) or !$page['page_id']) return array();
$CI = & get_instance();
// добавим в запрос id похожих страниц
$field_of_numbers = 'similar_post_tags_id'; // метаполе, где находится список похожих страниц
// на всякий случай проверка, хотя поле должно быть обязательно
if ( isset($page['page_meta'][$field_of_numbers][0]) and $page['page_meta'][$field_of_numbers][0])
{
$array_id = mso_explode($page['page_meta'][$field_of_numbers][0]);
if ($array_id) $CI->db->where_in('page.page_id', $array_id);
}
}
Имя этой функции занесем в специальную переменную при помощи mso_set_val.
Кроме того, нам нужно между моментом, когда текущая запись уже получена, и моментом получения записей для блока "Еще записи по теме" получить массив номеров записей, похожих на текущую запись и записать этот массив в искусственное метаполе. Это удобно сделать по хуку content_end.
Искусственность метаполя состоит в том, что оно не хранится в базе данных и используется только для передачи массива из функции в функцию.
# функция автоподключения плагина
function similar_posts_tags_autoload($args = array())
{
if ( is_type('page') )
{
// зададим функцию - добавку к запросу получения страниц
mso_set_val('page_other_pages_function_add_custom_sql', 'sql_add_similar_posts_tags');
// определим функцию - добавку к запросу получения страниц
require(getinfo('plugins_dir').'similar_posts_tags/functions.php');
// после получения страницы нам нужно в результат добавить метаполе с похожими страницами
mso_hook_add('content_end', 'similar_posts_tags_get_id');
}
}
Скачать плагин похожих статей для MaxSite CMS.
Ноябрь 2019.
Версия 2.1.
Добавлена возможность указать коэффициент для категорий и меток.
Целочисленное число, позволяющее придать приоритет вычислениях.
Например:
Вес категорий=0 => категории не учитываются.
Вес меток=2 => метки в два раза важнее категорий.
Алгоритм очень простой.
foreach ($all_pages as $cur_page) // сравниваем все страницы с текущей
{
if ($cur_page['page_id'] == $page['page_id']) continue;
// похожесть страниц - это сколько у них одинаковых меток и категорий
$tag_similarity = count(array_intersect($cur_page['page_tags'] , $page['page_tags']));
$cat_similarity = count(array_intersect($cur_page['page_categories'] , $page['page_categories']));
$similarity = $tag_similarity*$k_tag + $cat_similarity*$k_cat;
if ($similarity) // если похожесть больше 0, тоесть есть общие метки и категории
{
$cur_page['similarity'] = $similarity;
$bl_pages[] = $cur_page;
}
}









