Files
ave-cms-alt/functions/func.parserequest.php

939 lines
38 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Класс для обработки тегов шаблона.
*
* @package AVE.cms
* @filesource
*/
class TagProcessor
{
private int $item_num;
private bool $is_last;
private object $row;
private int $rubric_id;
private int $items_count;
/**
* Конструктор класса.
*
* @param int $item_num Текущий номер элемента во всем списке (начиная с 1).
* @param bool $is_last Флаг, указывающий, является ли элемент последним.
* @param object $row Объект с данными документа.
* @param int $rubric_id ID рубрики.
* @param int $items_count Количество элементов на текущей странице.
*/
public function __construct(int $item_num, bool $is_last, object $row, int $rubric_id, int $items_count)
{
$this->item_num = $item_num;
$this->is_last = $is_last;
$this->row = $row;
$this->rubric_id = $rubric_id;
$this->items_count = $items_count;
}
/**
* Основной метод для обработки всех условных тегов в строке.
*
* @param string $content Строка с тегами, например, '[tag:if_first]...[/tag:if]'
* @return string Обработанная строка
*/
public function process(string $content): string
{
// Сначала обрабатываем теги if_notempty и if_empty
$processed_content = preg_replace_callback(
'/\\[tag:(if_notempty|if_empty):rfld:([a-zA-Z0-9-_]+)]\\[(more|esc|img|strip|[0-9-]+)](.*?)\\[tag:\\/if]/s',
function ($matches) {
$tag_type = $matches[1];
$field_name = $matches[2];
$format = $matches[3];
$inner_content = $matches[4];
$parts = explode('[tag:if_else]', $inner_content);
$true_content = $parts[0];
$false_content = $parts[1] ?? '';
$field_value = '';
if (defined('USE_GET_FIELDS') && USE_GET_FIELDS) {
$field_value = htmlspecialchars(get_field($field_name, (int)$this->row->Id), ENT_QUOTES);
} else {
$field_value = htmlspecialchars(request_get_document_field($field_name, (int)$this->row->Id, $format, $this->rubric_id), ENT_QUOTES);
}
$condition = ($tag_type === 'if_notempty' && $field_value !== '') || ($tag_type === 'if_empty' && $field_value === '');
return $condition ? $true_content : $false_content;
},
$content
);
// Затем обрабатываем остальные условные теги
$processed_content = preg_replace_callback(
'/\\[tag:(if_first|if_not_first|if_last|if_not_last|if_every:([0-9-]+)|if_not_every:([0-9-]+))](.*?)\\[tag:\\/if]/s',
function ($matches) {
$tag = $matches[1];
$inner_content = $matches[4];
$parts = explode('[tag:if_else]', $inner_content);
$true_content = $parts[0];
$false_content = $parts[1] ?? '';
$condition = false;
if ($tag === 'if_first') {
$condition = ($this->item_num === 1);
} elseif ($tag === 'if_not_first') {
$condition = ($this->item_num !== 1);
} elseif ($tag === 'if_last') {
$condition = $this->is_last;
} elseif (strpos($tag, 'if_not_last') === 0) {
$condition = !$this->is_last;
} elseif (strpos($tag, 'if_every') === 0) {
$mod = (int)($matches[2] ?? 0);
$condition = ($this->item_num > 0 && $mod > 0 && ($this->item_num % $mod) === 0);
} elseif (strpos($tag, 'if_not_every') === 0) {
$mod = (int)($matches[3] ?? 0);
$condition = ($this->item_num > 0 && $mod > 0 && ($this->item_num % $mod) !== 0);
}
return $condition ? $true_content : $false_content;
},
$processed_content
);
return $processed_content;
}
}
/**
* Функция для обработки тегов с использованием TagProcessor.
*
* @param string $items Строка с тегами.
* @param int $item_num Текущий номер элемента.
* @param bool $is_last Флаг, указывающий, является ли элемент последним.
* @param object $row Объект с данными документа.
* @param int $items_count Общее количество элементов на текущей странице.
* @return string Обработанная строка.
*/
function request_process_tags($items, $item_num, $is_last, $row, $items_count)
{
// Создаем экземпляр обработчика, передавая общее количество
$processor = new TagProcessor($item_num, $is_last, $row, (int)$row->rubric_id, $items_count);
// Обрабатываем содержимое и возвращаем результат
return $processor->process($items);
}
/**
* Достаем настройки запроса
*
* @param string|int $id Идентификатор или псевдоним запроса
* @return object|string Объект с настройками запроса или пустая строка в случае ошибки
*/
function request_get_settings ($id)
{
global $AVE_DB;
// Получаем информацию о запросе
$sql = "
SELECT
#REQUEST SETTINGS = " . $id . "
*
FROM
" . PREFIX . "_request
WHERE
" . (is_numeric($id) ? 'Id' : 'request_alias') . " = '" . $id . "'
";
// Выполняем запрос с учетом кеширования
$reqest_settings = $AVE_DB->Query($sql, -1, 'rqs_' . $id, true, '.settings')->FetchRow();
// Выходим, если нет запроса
if (! is_object($reqest_settings))
return '';
else
return $reqest_settings;
}
/**
* Обработка условий запроса.
* Возвращает строку условий в SQL-формате.
*
* @param int|string $id ID или алиас запроса.
*
* @return string Возвращает строку SQL-условия.
*/
function request_get_condition_sql_string($id)
{
global $AVE_DB, $AVE_Core;
// Используем request_get_settings() для получения ID и настроек запроса.
$request_settings = request_get_settings($id);
// Выходим, если запрос не найден.
if (!is_object($request_settings)) {
return '';
}
$from = [];
$where = [];
$retval = '';
$i = 0;
if (!defined('ACP'))
{
$doc = 'doc_' . $AVE_Core->curentdoc->Id;
if (isset($_POST['req_' . $id]))
{
$_SESSION[$doc]['req_' . $id] = $_POST['req_' . $id];
}
elseif (isset($_SESSION[$doc]['req_' . $id]))
{
$_POST['req_' . $id] = $_SESSION[$doc]['req_' . $id];
}
}
// Теперь мы можем безопасно запросить условия, используя гарантированный ID.
$sql_ak = $AVE_DB->Query(
"
SELECT
condition_field_id,
condition_value,
condition_compare,
condition_join
FROM " . PREFIX . "_request_conditions
WHERE
request_id = '" . $request_settings->Id . "'
AND condition_status = '1'
ORDER BY
condition_position ASC;
",
-1,
'rqc_' . $request_settings->Id,
true,
'.conditions'
);
if (!empty($_POST['req_' . $id]) && is_array($_POST['req_' . $id]))
{
foreach ($_POST['req_' . $id] as $fid => $val)
{
if (!($val != '' && isset($_SESSION['val_' . $fid]) && in_array($val, $_SESSION['val_' . $fid]))) continue;
if ($i) $from[] = "JOIN " . PREFIX . "_document_fields AS t$i ON t$i.document_id = t0.document_id";
$where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value = '" . $AVE_DB->Escape($val) . "'";
++$i;
}
}
while ($row_ak = $sql_ak->FetchRow())
{
$fid = $row_ak->condition_field_id;
if (isset($_POST['req_' . $id]) && isset($_POST['req_' . $id][$fid])) continue;
if ($i) $from[] = "JOIN " . PREFIX . "_document_fields AS t$i ON t$i.document_id = t0.document_id";
$val = $row_ak->condition_value;
switch ($row_ak->condition_compare)
{
case ' <': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value < '" . $AVE_DB->Escape($val) . "'"; break;
case ' >': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value > '" . $AVE_DB->Escape($val) . "'"; break;
case '<=': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value <= '" . $AVE_DB->Escape($val) . "'"; break;
case '>=': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value >= '" . $AVE_DB->Escape($val) . "'"; break;
case '==': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value = '" . $AVE_DB->Escape($val) . "'"; break;
case '!=': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value != '" . $AVE_DB->Escape($val) . "'"; break;
case '%%': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value LIKE '%" . $AVE_DB->Escape($val) . "%'"; break;
case '%': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value LIKE '" . $AVE_DB->Escape($val) . "%'"; break;
case '--': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value NOT LIKE '%" . $AVE_DB->Escape($val) . "%'"; break;
case '!-': $where[] = "t$i.rubric_field_id = " . $fid . " AND t$i.field_value NOT LIKE '" . $AVE_DB->Escape($val) . "%'"; break;
}
if ($i || $row_ak->condition_join == 'AND') ++$i;
}
if (!empty($where))
{
$from = ' FROM ' . PREFIX . '_document_fields AS t0 ' . implode(' ', $from);
$where = ' WHERE ' . (($i) ? implode(' AND ', $where) : '(' . implode(') OR(', $where) . ')');
$retval = 'AND a.Id = ANY(SELECT t0.document_id' . $from . $where . ')';
}
if (defined('ACP'))
{
$AVE_DB->Query("
UPDATE " . PREFIX . "_request
SET request_where_cond = '" . addslashes($retval) . "'
WHERE Id = '" . $request_settings->Id . "'
");
}
return $retval;
}
/**
* Функция обработки тэгов полей с использованием шаблонов
* в соответствии с типом поля
*
* @param int $rubric_id идентификатор рубрики
* @param int $document_id идентификатор документа
* @param int $maxlength максимальное количество символов обрабатываемого поля
* @return string
*/
function request_get_document_field ($field_id, $document_id, $maxlength = null, $rubric_id = 0)
{
if (! is_numeric($document_id) || $document_id < 1)
return '';
$_maxlength = $maxlength;
$document_fields = get_document_fields($document_id);
// ToDo
if (! is_array($document_fields[$field_id]))
$field_id = intval($document_fields[$field_id]);
if (empty($document_fields[$field_id]))
return '';
$field_value = trim($document_fields[$field_id]['field_value']);
if ($field_value == '' && $document_fields[$field_id]['tpl_req_empty'])
return '';
$func = 'get_field_' . $document_fields[$field_id]['rubric_field_type'];
if (! is_callable($func))
$func = 'get_field_default';
$field_value = $func($field_value, 'req', $field_id, $document_fields[$field_id]['rubric_field_template_request'], $document_fields[$field_id]['tpl_req_empty'], $_maxlength, $document_fields, $rubric_id, $document_fields[$field_id]['rubric_field_default']);
if ($maxlength != '')
{
if ($maxlength == 'more' || $maxlength == 'esc'|| $maxlength == 'img' || $maxlength == 'strip')
{
if ($maxlength == 'more')
{
// ToDo - Вывести в настройки или в настройки самого запроса
$teaser = explode('<a name="more"></a>', $field_value);
$field_value = $teaser[0];
}
elseif ($maxlength == 'esc')
{
$field_value = addslashes($field_value);
}
elseif ($maxlength == 'img')
{
$field_value = getImgSrc($field_value);
}
elseif ($maxlength == 'strip')
{
$field_value = str_replace(array("\r\n","\n","\r"), " ", $field_value);
$field_value = strip_tags($field_value, REQUEST_STRIP_TAGS);
$field_value = preg_replace('/ +/', ' ', $field_value);
$field_value = trim($field_value);
}
}
elseif (is_numeric($maxlength))
{
if ($maxlength < 0)
{
$field_value = str_replace(array("\r\n","\n","\r"), " ", $field_value);
$field_value = strip_tags($field_value, REQUEST_STRIP_TAGS);
$field_value = preg_replace('/ +/', ' ', $field_value);
$field_value = trim($field_value);
$maxlength = abs($maxlength);
}
// ToDo - сделать настройки окончаний = Уже есть в Доп настройках
if ($maxlength != 0)
{
$field_value = truncate($field_value, $maxlength, REQUEST_ETC, REQUEST_BREAK_WORDS);
}
}
else
return false;
}
return $field_value;
}
function showteaser ($id, $tparams = '')
{
$item = showrequestelement($id, '', $tparams);
$item = str_replace('[tag:path]', ABS_PATH, $item);
$item = str_replace('[tag:mediapath]', ABS_PATH . 'templates/' . ((defined('THEME_FOLDER') === false) ? DEFAULT_THEME_FOLDER : THEME_FOLDER) . '/', $item);
return $item;
}
// Функция получения уникальных параметров для каждого тизера
function f_params_of_teaser ($id_param_array,$num)
{
global $params_of_teaser;
return $params_of_teaser[$id_param_array][$num];
}
// Функция получения элемента запроса
function showrequestelement ($mixed, $template = '', $tparams = '', $req_item_num = null, $items_count = null, $is_last = null)
{
global
$AVE_DB,
$params_of_teaser,
$use_cache,
$request_id,
$request_changed,
$request_changed_elements;
if (is_array($mixed)) {
$row = intval($mixed[1]);
} else if (is_numeric($mixed)) {
$row = intval($mixed);
}
$row = (is_object($mixed) ? $mixed : getDocument($row));
unset ($mixed);
if (! $row) {
return '';
}
$tparams_id = '';
if ($tparams != '') {
$tparams_id = $row->Id . md5($tparams);
$params_of_teaser[$tparams_id] = [];
$tparams = trim($tparams,'[]:');
$params_of_teaser[$tparams_id] = explode('|',$tparams);
}
$sql = "
SELECT
rubric_teaser_template
FROM
" . PREFIX . "_rubrics
WHERE
Id = '" . intval($row->rubric_id) . "'
";
$template = ($template > ''
? $template
: $AVE_DB->Query($sql)->GetCell());
$hash = 'g-' . UGROUP;
$hash .= 'r-' . $request_id;
$hash .= 't-' . $row->Id;
if ($req_item_num !== null && $items_count !== null) {
$hash .= 'num-' . $req_item_num;
$hash .= 'total-' . $items_count;
}
$hash = md5($hash);
$cache_id = 'requests/elements/' . (floor($row->Id / 1000)) . '/' . $row->Id;
$cachefile_docid = BASE_DIR . '/tmp/cache/sql/' . $cache_id . '/' . $hash . '.element';
if (file_exists($cachefile_docid) && isset($use_cache) && $use_cache == 1) {
$check_file = $request_changed_elements;
if ($check_file > filemtime($cachefile_docid)) {
unlink ($cachefile_docid);
}
} else {
if (file_exists($cachefile_docid)) {
unlink ($cachefile_docid);
}
}
if (defined('DEV_MODE') AND DEV_MODE) {
$cachefile_docid = null;
}
if (! file_exists($cachefile_docid)) {
$link = rewrite_link('index.php?id=' . $row->Id . '&amp;doc=' . (empty($row->document_alias) ? prepare_url($row->document_title) : $row->document_alias));
$item = $template;
// Обработка всех условных тегов через TagProcessor
if ($req_item_num !== null && $items_count !== null) {
$tagProcessor = new TagProcessor($req_item_num, $is_last, $row, (int)$row->rubric_id, $items_count);
$item = $tagProcessor->process($item);
}
// Парсим теги визуальных блоков
$item = preg_replace_callback('/\[tag:block:([A-Za-z0-9-_]{1,20}+)\]/', 'parse_block', $item);
// Парсим теги системных блоков
$item = preg_replace_callback('/\[tag:sysblock:([A-Za-z0-9-_]{1,20}+)(|:\{(.*?)\})\]/',
function ($m) {
return parse_sysblock($m[1], $m[2]);
},
$item);
// Парсим элементы полей
$item = preg_replace_callback('/\[tag:rfld:([a-zA-Z0-9-_]+)\]\[([0-9]+)]\[([0-9]+)]/',
function ($m) use ($row) {
return get_field_element($m[1], $m[2], $m[3], (int)$row->Id);
},
$item);
// Парсим теги полей
$item = preg_replace_callback('/\[tag:rfld:([a-zA-Z0-9-_]+)\]\[(more|esc|img|strip|[0-9-]+)]/',
function ($match) use ($row) {
return request_get_document_field($match[1], (int)$row->Id, $match[2], (int)$row->rubric_id);
},
$item);
// Повторно парсим теги полей
$item = preg_replace_callback('/\[tag:rfld:([a-zA-Z0-9-_]+)\]\[(more|esc|img|strip|[0-9-]+)]/',
function ($m) use ($row) {
return request_get_document_field($m[1], (int)$row->Id, $m[2], (int)$row->rubric_id);
},
$item);
// Возвращаем поле документа из БД (document_***)
$item = preg_replace_callback('/\[tag:doc:([a-zA-Z0-9-_]+)\]/u',
function ($m) use ($row) {
return isset($row->{$m[1]}) ? $row->{$m[1]} : null;
},
$item
);
// Если пришел вызов на активацию языковых файлов
$item = preg_replace_callback(
'/\[tag:langfile:([a-zA-Z0-9-_]+)\]/u',
function ($m) {
global $AVE_Template;
return $AVE_Template->get_config_vars($m[1]);
},
$item
);
// Абсолютный путь
$item = str_replace('[tag:path]', ABS_PATH, $item);
// Путь к папке шаблона
$item = str_replace('[tag:mediapath]', ABS_PATH . 'templates/' . ((defined('THEME_FOLDER') === false) ? DEFAULT_THEME_FOLDER : THEME_FOLDER) . '/', $item);
// Watermarks
$item = preg_replace_callback('/\[tag:watermark:(.+?):([a-zA-Z]+):([0-9]+)\]/',
function ($m) {
watermarks($m[1], $m[2], $m[3]);
},
$item);
// Удаляем ошибочные теги полей документа и языковые, в шаблоне рубрики
$item = preg_replace('/\[tag:doc:\d*\]/', '', $item);
$item = preg_replace('/\[tag:langfile:\d*\]/', '', $item);
// Делаем линки на миниатюры
$item = preg_replace_callback('/\[tag:([r|c|f|t|s]\d+x\d+r*):(.+?)]/', 'callback_make_thumbnail', $item);
// Если был вызов тизера, ищем параметры
if ($tparams != '') {
$item = preg_replace_callback('/\[tparam:([0-9]+)\]/',
function ($m) use ($tparams_id) {
return f_params_of_teaser($tparams_id, $m[1]);
},
$item);
} else {
$item = preg_replace('/\[tparam:([0-9]+)\]/', '', $item);
}
$item = str_replace('[tag:domain]', getSiteUrl(), $item);
$item = str_replace('[tag:link]', $link, $item);
$item = str_replace('[tag:docid]', $row->Id, $item);
$item = str_replace('[tag:itemid]', $row->Id, $item);
$item = str_replace('[tag:docitemnum]', $req_item_num, $item);
$item = str_replace('[tag:adminlink]', 'index.php?do=docs&action=edit&rubric_id=' . $row->rubric_id . '&Id=' . $row->Id . '&cp=' . session_id() . '', $item);
$item = str_replace('[tag:doctitle]', stripslashes(htmlspecialchars_decode($row->document_title)), $item);
$item = str_replace('[tag:docparent]', $row->document_parent, $item);
$item = str_replace('[tag:doclang]', $row->document_lang, $item);
$item = str_replace('[tag:docdate]', translate_date(strftime(DATE_FORMAT, $row->document_published)), $item);
$item = str_replace('[tag:doctime]', translate_date(strftime(TIME_FORMAT, $row->document_published)), $item);
$item = str_replace('[tag:humandate]', human_date($row->document_published), $item);
$item = preg_replace_callback('/\[tag:date:([a-zA-Z0-9-. \/]+)\]/',
function ($m) use ($row) {
return translate_date(date($m[1], $row->document_published));
},
$item);
if (preg_match('/\[tag:docauthor]/u', $item)) {
$item = str_replace('[tag:docauthor]', get_username_by_id($row->document_author_id), $item);
}
$item = str_replace('[tag:docauthorid]', $row->document_author_id, $item);
$item = preg_replace_callback('/\[tag:docauthoravatar:(\d+)\]/',
function ($m) use ($row) {
return getAvatar(intval($row->document_author_id), $m[1]);
},
$item);
if (isset($use_cache) && $use_cache == 1) {
if (! file_exists(dirname($cachefile_docid))) {
@mkdir(dirname($cachefile_docid), 0777, true);
}
file_put_contents($cachefile_docid, $item);
}
} else {
$item = file_get_contents($cachefile_docid);
}
// Кол-во просмотров
$item = str_replace('[tag:docviews]', $row->document_count_view, $item);
Registry::remove('documents', $row->Id);
Registry::remove('fields', $row->Id);
Registry::remove('fields_param', $row->Id);
unset($row, $template);
return $item;
}
/**
* Парсинг запроса
*
* @param int|string $id Идентификатор или псевдоним запроса
* @return string
*/
function request_parse($id)
{
global $AVE_Core, $AVE_DB, $request_documents;
// Начальная проверка ID
if (is_array($id)) {
$id = $id[1];
}
// Получаем информацию о запросе. Эта функция должна создать .settings файл
$request = request_get_settings($id);
// Выходим, если запрос не найден
if (!is_object($request)) {
return '';
}
// Фиксируем время начала генерации запроса
Debug::startTime('request_' . $id);
// Инициализация переменных из настроек запроса
$limit = ($request->request_items_per_page < 1) ? 1 : $request->request_items_per_page;
$main_template = $request->request_template_main;
$item_template = $request->request_template_item;
$request_order_by = $request->request_order_by;
$request_order_by_nat = intval($request->request_order_by_nat);
$request_asc_desc = $request->request_asc_desc;
// Генерируем строку условий
$where_cond = request_get_condition_sql_string($request->Id);
$where_cond = str_replace('%%PREFIX%%', PREFIX, $where_cond);
// Динамическое формирование WHERE-части запросов
$where_common = "
a.Id != '1'
AND a.Id != '" . PAGE_NOT_FOUND_ID . "'
AND a.rubric_id = '" . (int)$request->rubric_id . "'
AND a.document_deleted != '1'
AND a.document_status != '0'
" . $hide_current_condition . "
" . $owner_condition . "
" . $lang_condition . "
" . $where_cond . "
" . $doctime . "
";
// Определение частей запроса в зависимости от наличия модуля комментариев и нативной сортировки
$join_comment = !empty($AVE_Core->install_modules['comment']->Status)
? "LEFT JOIN " . PREFIX . "_modul_comment_info AS b ON b.document_id = a.Id"
: "";
$select_comment_count = !empty($AVE_Core->install_modules['comment']->Status)
? ", COUNT(b.document_id) AS nums"
: "";
$group_by_doc_id = !empty($AVE_Core->install_modules['comment']->Status)
? "GROUP BY a.Id"
: "";
if ($request_order_by_nat != 0) {
$join_fields = "LEFT JOIN " . PREFIX . "_document_fields AS d ON a.Id = d.document_id";
$where_fields = "AND d.rubric_field_id = " . intval($request_order_by_nat);
$select_fields = ", d.field_value, d.rubric_field_id";
$order_by = "ORDER BY d.field_value " . ($request_asc_desc === 'DESC' ? 'DESC' : 'ASC');
} else {
$join_fields = "";
$where_fields = "";
$select_fields = "";
$order_by = "ORDER BY " . $request_order_by . " " . $request_asc_desc;
}
$num_items = 0;
$num_pages = 0;
$start = 0;
// Условное выполнение запроса для подсчета общего количества элементов
if ($request->request_show_pagination == 1 || $request->request_count_items == 1) {
// Формируем запрос для подсчета количества элементов
$count_sql = "
SELECT COUNT(*)
FROM " . PREFIX . "_documents AS a
" . $join_fields . "
WHERE
" . $where_common . "
" . $where_fields . "
";
// Получаем общее количество элементов, используя кеширование
$num_items = $AVE_DB->Query($count_sql, (int)$request->request_cache_lifetime, 'rqs_' . $id, true, '.count')->GetCell();
}
// Если пагинация включена, вычисляем количество страниц и начальную позицию
if ($request->request_show_pagination == 1) {
$num_pages = ceil($num_items / $limit);
$start = get_current_page('page') * $limit - $limit;
}
// Формируем финальный запрос для выборки данных
$main_sql_query = "
SELECT
a.Id,
a.document_title,
a.document_alias,
a.document_parent,
a.document_author_id,
a.document_count_view,
a.document_published,
a.document_lang
" . $select_comment_count . "
" . $select_fields . "
FROM
" . PREFIX . "_documents AS a
" . $join_comment . "
" . $join_fields . "
WHERE
" . $where_common . "
" . $where_fields . "
" . $group_by_doc_id . "
" . $order_by . "
LIMIT " . $start . "," . $limit . "
";
// Отладочный вывод SQL-запроса, если это необходимо
if ($request->request_show_sql == 1) {
$return = Debug::_print($main_sql_query);
return $return;
}
// Выполняем запрос с кешированием, создавая файл .request
Debug::startTime('SQL');
$q = $AVE_DB->Query($main_sql_query, (int)$request->request_cache_lifetime, 'rqs_' . $id, true, '.request');
$GLOBALS['block_generate']['REQUESTS'][$id]['SQL'] = Debug::endTime('SQL');
$rows = array();
$request_documents = array();
while ($row = $q->FetchRow()) {
array_push($request_documents, $row->Id);
array_push($rows, $row);
}
// Условное отображение контента
if ($q->NumRows() > 0) {
$main_template = preg_replace('/\[tag:if_empty](.*?)\[\/tag:if_empty]/si', '', $main_template);
$main_template = str_replace(array('[tag:if_notempty]','[/tag:if_notempty]'), '', $main_template);
} else {
$main_template = preg_replace('/\[tag:if_notempty](.*?)\[\/tag:if_notempty]/si', '', $main_template);
$main_template = str_replace(array('[tag:if_empty]','[/tag:if_empty]'), '', $main_template);
}
// Формирование пагинации
$pagination = '';
if ($request->request_show_pagination == 1 && $num_pages > 1) {
@$GLOBALS['page_id'][$_REQUEST['id']]['page'] = (isset($GLOBALS['page_id'][$_REQUEST['id']]['page']) && $GLOBALS['page_id'][$_REQUEST['id']]['page'] > $num_pages) ? @$GLOBALS['page_id'][$_REQUEST['id']]['page'] : $num_pages;
$queries = ($request->request_use_query == 1 || (isset($params['ADD_GET']) && $params['ADD_GET'] == 1)) ? ((isset($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : '') : '';
$pagination_base = 'index.php?id=' . $AVE_Core->curentdoc->Id . '&amp;doc=' . (empty($AVE_Core->curentdoc->document_alias) ? prepare_url($AVE_Core->curentdoc->document_title) : $AVE_Core->curentdoc->document_alias) . '&amp;page={s}';
$pagination_params = ((isset($_REQUEST['artpage']) && is_numeric($_REQUEST['artpage'])) ? '&amp;artpage=' . $_REQUEST['artpage'] : '') . ((isset($_REQUEST['apage']) && is_numeric($_REQUEST['apage'])) ? '&amp;apage=' . $_REQUEST['apage'] : '');
$pagination_full = $pagination_base . $pagination_params . clean_php($queries);
$pagination_id = (isset($params['PAGINATION']) && $params['PAGINATION'] > 0) ? $params['PAGINATION'] : $request->request_pagination;
$pagination = AVE_Paginations::getPagination($num_pages, 'page', $pagination_full, $pagination_id);
// Костыли для главной страницы
$pagination = str_ireplace('"//"', '"/"', str_ireplace('///', '/', rewrite_link($pagination)));
$pagination = str_ireplace('"//' . URL_SUFF . '"', '"/"', $pagination);
if ($request->request_use_query == 1 || (isset($params['ADD_GET']) && $params['ADD_GET'] == 1)) {
$pagination = preg_replace('/(?<!:)\/\//', '/', $pagination);
}
}
// Обработка шаблонов элементов
$items = '';
$x = 0;
$items_count = count($rows);
global $req_item_num, $use_cache, $request_id, $request_changed, $request_changed_elements;
$use_cache = $request->request_cache_elements;
$request_id = $request->Id;
$request_changed = $request->request_changed;
$request_changed_elements = $request->request_changed_elements;
Debug::startTime('ELEMENTS_ALL');
foreach ($rows as $row) {
$x++;
$last_item = ($x == $items_count);
$req_item_num = $x;
// Передаем элемент для обработки и кэширования в showrequestelement.
$items .= showrequestelement($row, $item_template, '', $req_item_num, $items_count, $last_item);
}
$GLOBALS['block_generate']['REQUESTS'][$id]['ELEMENTS']['ALL'] = Debug::endTime('ELEMENTS_ALL');
// Обработка основного шаблона
$main_template = str_replace('[tag:pages]', $pagination, $main_template);
$main_template = str_replace('[tag:docid]', $AVE_Core->curentdoc->Id, $main_template);
$main_template = str_replace('[tag:pagetitle]', stripslashes(htmlspecialchars_decode($AVE_Core->curentdoc->document_title)), $main_template);
$main_template = str_replace('[tag:pages:curent]', get_current_page('page'), $main_template);
$main_template = str_replace('[tag:pages:total]', $num_pages, $main_template);
$main_template = str_replace('[tag:doctotal]', $num_items, $main_template);
$main_template = str_replace('[tag:doconpage]', $x, $main_template);
$main_template = str_replace('[tag:docdate]', pretty_date(strftime(DATE_FORMAT, $AVE_Core->curentdoc->document_published)), $main_template);
$main_template = str_replace('[tag:doctime]', pretty_date(strftime(TIME_FORMAT, $AVE_Core->curentdoc->document_published)), $main_template);
$main_template = str_replace('[tag:docauthor]', get_username_by_id($AVE_Core->curentdoc->document_author_id), $main_template);
$main_template = preg_replace_callback('/\[tag:dropdown:([,0-9]+)\]/', function($m) use ($request) {
return request_get_dropdown($m[1], (int)$request->rubric_id, (int)$request->Id);
}, $main_template);
$main_template = preg_replace_callback('/\[tag:date:([a-zA-Z0-9-. \/]+)\]/', function ($match) use ($AVE_Core) {
return translate_date(date($match[1], $AVE_Core->curentdoc->document_published));
}, $main_template);
$main_template = preg_replace_callback('/\[tag:langfile:([a-zA-Z0-9-_]+)\]/u', function ($match) {
global $AVE_Template;
return $AVE_Template->get_config_vars($match[1]);
}, $main_template);
$main_template = preg_replace_callback('/\[tag:sysblock:([A-Za-z0-9-_]{1,20}+)\]/', 'parse_sysblock', $main_template);
$main_template = preg_replace_callback('/\[tag:block:([A-Za-z0-9-_]{1,20}+)\]/', 'parse_block', $main_template);
$return = str_replace('[tag:content]', $items, $main_template);
$return = str_replace('[tag:path]', ABS_PATH, $return);
$return = str_replace('[tag:mediapath]', ABS_PATH . 'templates/' . ((defined('THEME_FOLDER') === false) ? DEFAULT_THEME_FOLDER : THEME_FOLDER) . '/', $return);
$return = $AVE_Core->coreModuleTagParse($return);
// Фиксируем время генерации запроса
$GLOBALS['block_generate']['REQUESTS'][$id]['TIME'] = Debug::endTime('request_' . $id);
if ($request->request_show_statistic) {
$return .= "<div class=\"request_statistic\"><br>Найдено: $num_items<br>Показано: $items_count<br>Время генерации: " . Debug::endTime('request_' . $id) . " сек<br>Пиковое значение: " . number_format(memory_get_peak_usage() / 1024, 0, ',', ' ') . ' Kb</div>';
}
return $return;
}
/**
* Функция получения содержимого поля для обработки в шаблоне запроса
* <pre>
* Пример использования в шаблоне:
* <li>
* <?php
* $r = request_get_document_field_value(12, [tag:docid]);
* echo $r . ' (' . strlen($r) . ')';
* ?>
* </li>
* </pre>
*
* @param int $rubric_id идентификатор поля, для [tag:rfld:12][150] $rubric_id = 12
* @param int $document_id идентификатор документа к которому принадлежит поле.
* @param int $maxlength необязательный параметр, количество возвращаемых символов.
* Если данный параметр указать со знаком минус
* содержимое поля будет очищено от HTML-тэгов.
* @return string
*/
function request_get_document_field_value($rubric_id, $document_id, $maxlength = 0)
{
if (!is_numeric($rubric_id) || $rubric_id < 1 || !is_numeric($document_id) || $document_id < 1) return '';
$document_fields = get_document_fields($document_id);
$field_value = isset($document_fields[$rubric_id]) ? $document_fields[$rubric_id]['field_value'] : '';
if (!empty($field_value))
{
$field_value = strip_tags($field_value, '<br /><strong><em><p><i>');
$field_value = str_replace('[tag:mediapath]', ABS_PATH . 'templates/' . THEME_FOLDER . '/', $field_value);
}
if (is_numeric($maxlength) && $maxlength != 0)
{
if ($maxlength < 0)
{
$field_value = str_replace(array("\r\n", "\n", "\r"), ' ', $field_value);
$field_value = strip_tags($field_value);
$field_value = preg_replace('/ +/', ' ', $field_value);
$maxlength = abs($maxlength);
}
$field_value = substr($field_value, 0, $maxlength) . (strlen($field_value) > $maxlength ? '... ' : '');
}
return $field_value;
}
/**
* Функция формирования выпадающих списков
* для управления условиями запроса в публичной части
*
* @param string $dropdown_ids идентификаторы полей
* типа выпадающий список указанные через запятую
* @param int $rubric_id идентификатор рубрики
* @param int $request_id идентификатор запроса
* @return string
*/
function request_get_dropdown($dropdown_ids, $rubric_id, $request_id)
{
global $AVE_Core, $AVE_DB, $AVE_Template;
// Получаем настройки запроса
$request_settings = request_get_settings($request_id);
if (!is_object($request_settings)) {
return '';
}
$dropdown_ids = explode(',', preg_replace('/[^,\\d]/', '', $dropdown_ids));
$dropdown_ids[] = 0;
$dropdown_ids = implode(',', $dropdown_ids);
$doc = 'doc_' . $AVE_Core->curentdoc->Id;
$control = array();
// Для кеширования, используем $request_id в качестве уникального идентификатора.
$sql = $AVE_DB->Query(
"
SELECT
Id,
rubric_field_title,
rubric_field_default
FROM " . PREFIX . "_rubric_fields
WHERE Id IN(" . $dropdown_ids . ")
AND rubric_id = '" . $rubric_id . "'
AND rubric_field_type = 'drop_down'
", -1, 'rqs_' . $request_id, true, '.dropdown');
while ($row = $sql->FetchRow())
{
$dropdown['titel'] = $row->rubric_field_title;
$dropdown['selected'] = isset($_SESSION[$doc]['req_' . $request_id][$row->Id]) ? $_SESSION[$doc]['req_' . $request_id][$row->Id] : '';
$dropdown['options'] = $_SESSION['val_' . $row->Id] = explode(',', $row->rubric_field_default);
$control[$row->Id] = $dropdown;
}
$AVE_Template->assign('request_id', $request_id);
$AVE_Template->assign('ctrlrequest', $control);
return $AVE_Template->fetch(BASE_DIR . '/templates/' . THEME_FOLDER . '/tpl/request/public.tpl');
}
?>