<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* MaxSite CMS
* (c) https://max-3000.com/
*
*/
/**
* Вывод юнитов
*
* $text_units содержит полный текст с юнитами
* пример использования см. shared/type/home/home.php
* через $PAGES и $PAGINATION можно передать в юнит заранее подготовленные записи
*
* спецкод @fromfile файл — позволяет подключать любой файл в виде текста.
* файл относительно шаблона. Не зависит от вложенности в [unit]
* @fromfile blocks/home/lastp-1.php
*
* спецкод @module модуль — позволяет подключать файл в виде текста из каталога шаблона modules.
* @module ads/ad1 -> подключит файл modules/ads/ad1/index.php как и @fromfile
*
* В @module можно использовать дополнительные параметры, которые добавляются в виде значения юнита {args}
* @module berry/block || block = ca/ca1.php ^ color = t-red
* В модуле berry/block вставка {args} бужет заменена на указанные параметры
*/
function mso_units_out($text_units, $PAGES = [], $PAGINATION = [], $path_file = 'type/home/units/')
{
$text_units .= "\n";
// подключаем файл как текст @fromfile и @module
$text_units = preg_replace_callback('!@fromfile (.*?)\n!is', '_mso_units_out_fromfile', $text_units);
// каталог для модулей можно переопределить через mso_set_val('mso_units_out_modulesDir', 'каталог/');
$modulesDir = mso_get_val('mso_units_out_modulesDir', 'modules/');
$text_units = preg_replace_callback('!@module (.*?)\n!is', '_mso_units_out_module', $text_units);
// еще раз @fromfile, поскольку он может быть в подключенном @module
$text_units = preg_replace_callback('!@fromfile (.*?)\n!is', '_mso_units_out_fromfile', $text_units);
// если в тексте юнита есть вхождение @USE_PHP@
// то разрешим в файле исполнять PHP, включая php-шаблонизатор
if (strpos($text_units, '@USE_PHP@')) {
$text_units = mso_tmpl_prepare($text_units, false);
ob_start();
eval($text_units);
$text_units = ob_get_contents();
ob_end_clean();
}
// замены по всему тексту юнитов
$text_units = str_replace('[siteurl]', getinfo('siteurl'), $text_units);
$text_units = str_replace('[site_url]', getinfo('siteurl'), $text_units);
$text_units = str_replace('[templateurl]', getinfo('template_url'), $text_units);
$text_units = str_replace('[template_url]', getinfo('template_url'), $text_units);
// ищем вхождение [unit] ... [/unit]
$units = mso_section_to_array($text_units, '!\[unit\](.*?)\[\/unit\]!is', ['file' => '']);
// pr($units[0], 1);
// подключаем каждый указанный unit
// _rules — php-условие, при котором юнит выводится
// параметр file где указывается файл юнита в каталоге $path_file (type/home/units/) или относительно шаблона
// если file нет, то проверяются другие параметры если есть:
// html — выводится как есть текстом/ Можно использовать php-шаблонизатор {{ }} и {% %}
// require — подключается файл в шаблоне (путь относительно каталога шаблона)
// у require также можно указать
// парсер parser = autotag_simple — функция, которая через которую прогонится файл
// php-шаблонизатор: tmpl = 1
// каталог модуля в module = ads/ad1 — поиск файла будет относительно каталога модуля
// ushka — ушка
// component — компонент шаблона
// option_key и option_type и option_default — опция
if ($units) {
$UNIT_NUM = 0; // порядковый номер юнита (можно использовать для кэширования)
foreach ($units as $UNIT) {
$UNIT_NUM++;
// уникальный id-хэш юнита — можно использовать при кэшировании
// с учтом адреса страницы
$UNIT_UID = abs(crc32(json_encode($UNIT) . $UNIT_NUM . mso_current_url()));
// в юните в произвольном поле может быть вхождение [var@ПЕРЕМЕННАЯ]
// нужно их обработать и заменить
$UNIT1 = [];
foreach ($UNIT as $k => $v) {
if (strpos($v, '[var@') !== false) {
preg_match_all('!(\[var@)(.*?)(\])!is', $v, $matches, PREG_SET_ORDER);
if ($matches) {
foreach ($matches as $m) {
if (isset($UNIT['var@' . $m[2]])) {
$v = str_replace('[var@' . $m[2] . ']', trim($UNIT['var@' . $m[2]]), $v);
}
}
}
}
$UNIT1[$k] = $v;
}
$UNIT = $UNIT1;
// храним текущий юнит в глобальном доступе
mso_set_val('current_unit', $UNIT);
// _rules — устаревший, вместо него нужно использовать rules
if (isset($UNIT['_rules']) and trim($UNIT['_rules'])) {
$rules = 'return ( ' . trim($UNIT['_rules']) . ' ) ? 1 : 0;';
$rules_result = eval($rules); // выполяем
if ($rules_result === false) $rules_result = 1; // возможно произошла ошибка
if ($rules_result !== 1) continue;
}
// rules тоже самое что и _rules — код для обратной совместимости
if (isset($UNIT['rules']) and trim($UNIT['rules'])) {
$rules = 'return ( ' . trim($UNIT['rules']) . ' ) ? 1 : 0;';
$rules_result = eval($rules); // выполяем
if ($rules_result === false) $rules_result = 1; // возможно произошла ошибка
if ($rules_result !== 1) continue;
}
if (trim($UNIT['file'])) {
$file = trim($UNIT['file']);
$module = (isset($UNIT['module']) and trim($UNIT['module'])) ? trim($UNIT['module']) : false;
if ($module) $file = $modulesDir . $module . '/' . $file;
// в подключаемом файле доступна переменная $UNIT — массив параметров
if ($fn = mso_find_ts_file($path_file . $file)) {
require $fn;
} else {
// аналогично, только файл относительно каталога шаблона
if ($fn = mso_fe($file)) require $fn;
}
} elseif (isset($UNIT['html']) and trim($UNIT['html'])) {
eval(mso_tmpl_prepare(trim($UNIT['html']), false));
} elseif (isset($UNIT['require']) and trim($UNIT['require'])) {
$parser = (isset($UNIT['parser']) and trim($UNIT['parser'])) ? trim($UNIT['parser']) : false;
$tmpl = (isset($UNIT['tmpl']) and trim($UNIT['tmpl'])) ? trim($UNIT['tmpl']) : false;
$file = trim($UNIT['require']);
// если указан модуль, то файл указан относительно каталога модуля
$module = (isset($UNIT['module']) and trim($UNIT['module'])) ? trim($UNIT['module']) : false;
if ($module) $file = $modulesDir . $module . '/' . $file;
// pr($UNIT);
mso_parse_file($file, $parser, $tmpl, true);
} elseif (isset($UNIT['ushka']) and trim($UNIT['ushka']) and function_exists('ushka')) {
echo ushka(trim($UNIT['ushka']));
} elseif (isset($UNIT['component']) and trim($UNIT['component'])) {
if ($_fn = mso_fe('components/' . trim($UNIT['component']) . '/index.php'))
require $_fn;
elseif ($_fn = mso_fe('components/' . trim($UNIT['component']) . '/' . trim($UNIT['component']) . '.php'))
require $_fn;
} elseif (isset($UNIT['option_key']) and trim($UNIT['option_key'])) {
// если option_type не указан, то это текущий шаблон
if (!isset($UNIT['option_type']))
$ot = getinfo('template');
else
$ot = trim($UNIT['option_type']);
// если option_type = %TEMPLATE% — меняем на текущий шаблон
if ($ot === '%TEMPLATE%') $ot = getinfo('template');
$od = isset($UNIT['option_default']) ? trim($UNIT['option_default']) : '';
echo mso_get_option(trim($UNIT['option_key']), $ot, $od);
} elseif (isset($UNIT['sidebar']) and trim($UNIT['sidebar'])) {
mso_show_sidebar($UNIT['sidebar']);
}
mso_unset_val('current_unit'); // удалим текущий юнит, чтобы он больше не влиял
}
}
}
// callback к mso_units_out()
function _mso_units_out_fromfile($matches)
{
$fn = trim(str_replace('=', '', $matches[1]));
if ($fn = mso_fe($fn)) {
$data = file_get_contents($fn);
// pr($data, 1);
return $data;
} else {
return '';
}
}
// callback к mso_units_out()
function _mso_units_out_module($matches)
{
$modulesDir = mso_get_val('mso_units_out_modulesDir', 'modules/');
// параметры модуля
$par = explode('||', $matches[1]);
$f = trim($par[0]);
$args = $par[1] ?? '';
if ($args) {
// внутри может использовать перенос строки в виде символа ^
$args = explode("^", $args);
$args = array_map('trim', $args);
$args = implode("\n", $args);
}
$fn = $modulesDir . $f . '/index.php';
// $fn = $modulesDir . trim(str_replace('=', '', $matches[1])) . '/index.php'; // старый вариант
if ($fn = mso_fe($fn)) {
$data = file_get_contents($fn);
$data = str_replace('{args}', $args, $data);
// pr($data);
return $data;
} else {
return '';
}
}
# end of file