Skip to content

Instantly share code, notes, and snippets.

@pafnuty
Created July 27, 2014 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pafnuty/3cbca6637585e6132671 to your computer and use it in GitHub Desktop.
Save pafnuty/3cbca6637585e6132671 to your computer and use it in GitHub Desktop.
Модуль для вывода новостей на новом "ядре"
<?php
if (!defined('DATALIFEENGINE')) die("Go fuck yourself!");
if($showstat) {
$start = microtime(true);
$dbStat = '';
}
// Конфиг модуля
$cfg = array(
'moderate' => !empty($moderate)?$moderate: false, // Показывать только новости на модерации
'template' => !empty($template)?$template:'blockpro/blockpro', // Название шаблона (без расширения)
'cachePrefix' => !empty($cachePrefix) ? $cachePrefix : 'news', // Префикс кеша
'cacheSuffixOff' => !empty($cacheSuffixOff) ? true : false, // Отключить суффикс кеша (будет создаваться один кеш-файл для всех пользователей). По умолчанию включен, т.е. для каждой группы пользователей будет создаваться свой кеш (на случай разного отображения контента разным юзерам).
'cacheNameAddon' => '', // Назначаем дополнение к имени кеша, если имеются переменные со значениями this, они будут дописаны в имя кеша, иначе для разных мест будет создаваться один и тот же файл кеша
'nocache' => !empty($nocache)?$nocache:false, // Не использовать кеш
'cacheLive' => (!empty($cacheLive) && !$mcache)?$cacheLive:false, // Время жизни кеша в минутах
'startFrom' => !empty($startFrom)?$startFrom:'0', // C какой новости начать вывод
'limit' => !empty($limit)?$limit:'10', // Количество новостей в блоке
'fixed' => !empty($fixed)?$fixed:'yes', // Обработка фиксированных новостей (yes/only/witout показ всех/только фиксированных/только обычных новостей)
'postId' => !empty($postId)?$postId:'', // ID новостей для вывода в блоке (через запятую)
'notPostId' => !empty($notPostId)?$notPostId:'', // ID игнорируемых новостей (через запятую)
'author' => !empty($author)?$author:'', // Логины авторов, для показа их новостей в блоке (через запятую)
'notAuthor' => !empty($notAuthor)?$notAuthor:'', // Логины игнорируемых авторов (через запятую)
'xfilter' => !empty($xfilter)?$xfilter:'', // Имена дополнительных полей для фильтрации по ним новостей (через запятую)
'notXfilter' => !empty($notXfilter)?$notXfilter:'', // Имена дополнительных полей для игнорирования показа (через запятую)
'xfSearch' => !empty($xfSearch) ? $xfSearch : false, // синтаксис передачи данных: &xfSearch=имя_поля|значение||имя_поля|значение
'notXfSearch' => !empty($notXfSearch) ? $notXfSearch : false, // синтаксис передачи данных: &notXfSearch=имя_поля|значение||имя_поля|значение
'xfSearchLogic' => !empty($xfSearchLogic) ? $xfSearchLogic : 'OR', // Принимает OR или AND (по умолчанию OR)
'catId' => !empty($catId)?$catId:'', // Категории для показа (через запятую)
'notCatId' => !empty($notCatId)?$notCatId:'', // Игнорируемые категории (через запятую)
'tags' => !empty($tags)?$tags:'', // Теги для показа (через запятую)
'notTags' => !empty($notTags)?$notTags:'', // Игнорируемые теги (через запятую)
'noicon' => !empty($noicon)?$noicon:'noicon.png', // Заглушка для иконок категорий
'day' => !empty($day)?$day:false, // Временной период для отбора новостей
'dayCount' => !empty($dayCount)?$dayCount:false, // Интервал для отбора (т.е. к примеру выбираем новости за прошлую недею так: &day=14&dayCount=7 )
'sort' => !empty($sort)?$sort:'top', // Сортировка (top, date, comms, rating, views, title)
'order' => !empty($order)?$order:'new', // Направление сортировки
'avatar' => !empty($avatar)?$avatar:false, // Вывод аватарки пользователя (+1 запрос на новость).
'showstat' => !empty($showstat)?$showstat:false, // Показывать время стату по блоку
'related' => !empty($related)?$related:'', // Включить режим вывода похожих новостей (по умолчанию нет)
);
// Если имеются переменные со значениями this, изменяем значение переменной cacheNameAddon
if ($cfg['catId'] == 'this') $cfg['cacheNameAddon'] .= $category_id.'cId_';
if ($cfg['notCatId'] == 'this') $cfg['cacheNameAddon'] .= $category_id.'nCId_';
if ($cfg['postId'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["newsid"].'pId_';
if ($cfg['notPostId'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["newsid"].'nPId_';
if ($cfg['author'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["user"].'a_';
if ($cfg['notAuthor'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["user"].'nA_';
if ($cfg['tags'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["tag"].'t_';
if ($cfg['notTags'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["tag"].'nT_';
if ($cfg['related'] == 'this') $cfg['cacheNameAddon'] .= $_REQUEST["newsid"].'r_';
if($cfg['cacheLive']) {
// Меняем префикс кеша для того, чтобы он не чистился автоматически, если указано время жизни кеша.
$cfg['cachePrefix'] = 'base';
}
// Формируем имя кеша
$cacheName = implode('_', $cfg) . $config['skin'];
// Определяем необходимость создания кеша для разных групп
$cacheSuffix = ($cfg['cacheSuffixOff']) ? false : true ;
// Если установлено время жизни кеша
if ($cfg['cacheLive']) {
// Формируем имя кеш-файла в соответствии с правилами формирования тагового стандартными средствами DLE, для последующей проверки на существование этого файла.
$_end_file = (!$cfg['cacheSuffixOff']) ? ($is_logged) ? '_' . $member_id['user_group'] : '_0' : false;
$filedate = ENGINE_DIR.'/cache/' . $cfg['cachePrefix'] . '_'. md5($cacheName) . $_end_file . '.tmp';
if(@file_exists($filedate)) {
$cache_time = time() - @filemtime($filedate);
} else {
$cache_time = $cfg['cacheLive']*60;
}
if ($cache_time >= $cfg['cacheLive']*60) {
$clear_time_cache = true;
}
}
$output = false;
// Если nocache не установлен - пытаемся вывести данные из кеша.
if(!$cfg['nocache']) {
$output = dle_cache($cfg['cachePrefix'], $cacheName, $cacheSuffix);
}
// Сбрасываем данные, если истекло время жизни кеша
if ($clear_time_cache) {
$output = false;
}
if (!$output) {
// Подключаем всё необходимое
include_once ('core/base.php');
// Вызываем основной класс
$base = new base();
// Подрубаем конфиг DLE
$base->dle_config = $config;
// Подрубаем конфиг модуля
$base->cfg = $cfg;
// Массив с условиями запроса
$wheres = array();
// Условие для отображения только постов, прошедших модерацию или находящихся на модерации
$wheres[] = ($base->cfg['moderate']) ? 'approve = 0' : 'approve';
// Определяем в какую сторону направлена сортировка
$ordering = ($base->cfg['order'] == 'new') ? 'DESC' : 'ASC' ;
// Если без сортировки - сбрасываем направление
if ($base->cfg['sort'] == 'none') {
$ordering = false;
}
// Массив, куда будем записывать сортировки
$orderArr = array();
// Учёт фиксированных новостей
switch ($base->cfg['fixed']) {
case 'only':
$wheres[] = 'fixed = 1';
break;
case 'without':
$wheres[] = 'fixed = 0';
break;
default:
if ($base->cfg['sort'] != 'random' && $base->cfg['sort'] != 'none') {
$orderArr[] = 'fixed ' . $ordering;
}
break;
}
// Определяем тип сортировки
switch ($base->cfg['sort']) {
case 'none': // Не сортировать (можно использовать для вывода похожих новостей, аналогично стандарту DLE)
// $orderArr[] = false;
break;
case 'date': // Дата
$orderArr[] = 'p.date ' . $ordering;
break;
case 'rating': // Рейтинг
$orderArr[] = 'e.rating ' . $ordering;
break;
case 'comms': // Комментарии
$orderArr[] = 'p.comm_num ' . $ordering;
break;
case 'views': // Просмотры
$orderArr[] = 'e.news_read ' . $ordering;
break;
case 'random': // Случайные
$orderArr[] = 'RAND()';
break;
case 'title': // По алфавиту
$orderArr[] = 'p.title ' . $ordering;
break;
case 'hit': // Правильный топ
$orderArr[] = '(e.rating*100+p.comm_num*10+e.news_read) ' . $ordering;
break;
default: // Топ как в DLE (сортировка по умолчанию)
$orderArr[] = 'e.rating ' . $ordering . ', p.comm_num ' . $ordering . ', e.news_read ' . $ordering;
break;
}
// Фильтрация по значению допполей
if ($base->cfg['xfSearch'] || $base->cfg['notXfSearch']) {
// Массив для составления подзапроса
$xfWheres = array();
// Защита логики построения запроса от кривых рук (если прописать неправильно - будет логика OR)
$_xfSearchLogic = (strtolower($base->cfg['xfSearchLogic']) == 'and' ) ? ' AND ' : ' OR ' ;
// Определяем масивы с данными по фильтрации
$xfSearchArray = ($base->cfg['xfSearch']) ? explode('||', $base->cfg['xfSearch']) : array();
$notXfSearchArray = ($base->cfg['notXfSearch']) ? explode('||', $base->cfg['notXfSearch']) : array();
// Пробегаем по сформированным массивам
foreach ($xfSearchArray as $xf) {
$xfWheres[] = $base->db->parse('xfields LIKE ?s', '%'.$xf.'%');
}
foreach ($notXfSearchArray as $xf) {
$xfWheres[] = $base->db->parse('xfields NOT LIKE LIKE ?s', '%'.$xf.'%');
}
// Добавляем полученные данные (и логику) в основной массив, формирующий запрос
$wheres[] = implode($_xfSearchLogic, $xfWheres);
}
// Складываем условия
$where = (count($wheres)) ? ' WHERE ' . implode(' AND ', $wheres) : '';
// Поля, выбираемые из БД
$selectRows = 'p.id, p.autor, p.date, p.short_story, p.full_story, p.xfields, p.title, p.category, p.alt_name, p.allow_comm, p.comm_num, p.fixed, p.tags, e.news_read, e.allow_rate, e.rating, e.vote_num, e.votes, e.view_edit, e.editdate, e.editor, e.reason';
// Определяем необходимость и данные для сортировки
$orderBy = (count($orderArr)) ? 'ORDER BY ' . implode(', ', $orderArr) : '';
// Запрос в БД (данные фильтруются в классе для работы с БД, так что можно не переживать), главное правильно сконструировать запрос.
$query = 'SELECT ?p FROM ?n p LEFT JOIN ?n e ON (p.id=e.news_id) ?p ' . $orderBy . ' LIMIT ?i, ?i';
// Получаем новости
$list = $base->db->getAll($query, $selectRows, PREFIX.'_post', PREFIX . '_post_extras', $where, $base->cfg['startFrom'], $base->cfg['limit']);
// Разбираемся с допполями.
foreach ($list as $key => $value) {
$list[$key]['xfields'] = xfieldsdataload($value['xfields']);
}
// Полученный массив с данными для обработки в шаблоне
$tplArr['list'] = $list;
// Результат обработки шаблона
try {
$output = $base->tpl->fetch($base->cfg['template'] . '.tpl', $tplArr);
} catch (Exception $e) {
$output = '<div style="color: red;">' . $e->getMessage() . '</div>';
$base->cfg['nocache'] = true;
}
// Формируем данные о запросах для статистики, если требуется
if ($base->cfg['showstat'] && $user_group[$member_id['user_group']]['allow_all_edit']) {
$stat = $base->db->getStats();
$dbStat = 'Запрос: ' . $stat[0]['query'] . '<br>Время выполнения: <b>' . $stat[0]['timer'] . '</b><br>';
}
// Создаём кеш, если требуется
if(!$base->cfg['nocache']) {
create_cache($base->cfg['cachePrefix'], $output, $cacheName, $cacheSuffix);
}
}
// Результат работы модуля
echo $output;
// Показываем стстаистику выполнения скрипта, если требуется
if ($cfg['showstat'] && $user_group[$member_id['user_group']]['allow_all_edit']) {
// Информация об оперативке
$mem_usg = (function_exists("memory_get_peak_usage")) ? '<br>Расход памяти: <b>' . round(memory_get_peak_usage()/(1024*1024),2).'Мб </b>' : '';
// Вывод статистикик
echo '<div style="border: solid 1px red; padding: 5px; margin: 5pxx 0;">' . $dbStat . 'Время выполнения скрипта: <b>'. round((microtime(true) - $start), 6). '</b> c.' . $mem_usg . '</div>';
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment