<?php

/*
 * @name        JMY CMS
 * @link        https://jmy.su/
 * @copyright   Copyright (C) 2012-2025 JMY LTD
 * @license     LICENSE.txt (see attached file)
 * @version     VERSION.txt (see attached file)
 * @author      Komarov Ivan
 * @edited      Orlov Alexsey
 */

if (!defined('ACCESS')) {
    header('Location: /');
    exit;
}

class template
{
    var $ext = '.tpl';
    var $sep = '%';
    var $sources = false;
    var $vars = array();
    var $vars_block = array();
    var $vars_tpl = array();
    var $file_dir = '';
    var $file = false;
    var $tplDir = false;
    var $filesTpl = false;
    var $cahceTpl = array();
    var $open_file = 'table';
    var $headerIncludes = array();
    var $bodyIncludes = '';
    var $keywords = false;
    var $title = false;
    var $admin_title = false;
    var $feed_link = '';
    var $uniqTag = array();
    var $fullAjaxBody = '';
    var $adminTheme = false;
    var $time_compile = false;
    var $startCompile = false;
    var $starWidth = 19;
    var $blocks = array();
    var $modules = array();
    var $moduleArray = '';
    var $adminBar = '';
    var $endJs = '';
    var $players = '';

    function __construct()
    {
        global $core, $db, $config, $url;
        if (isset($url[0]) && $url[0] == ADMIN) {
            $this->adminTheme = true;
            $this->file_dir = 'usr/tpl/admin/';
            $this->sep = '';
        }
        if (!isset($_COOKIE['smartphone'])) setcookie('smartphone', 1);
        if (empty($this->file_dir)) {
            $file_dir = ($config['smartphone'] == '1') && $this->check_phone() && (($_COOKIE['smartphone'] == 1) || (!isset($_COOKIE['smartphone']))) ? 'usr/tpl/smartphone/' : 'usr/tpl/' . $config['tpl'] . '/';
            $this->file_dir = $file_dir;
        }
        $this->filesTpl = getcache('tplFiles');
        if (empty($this->filesTpl) || $this->filesTpl['theme'] != $this->file_dir || ($config['tpl_change'] == '0' && 'usr/tpl/' . $config['tpl'] . '/' != $this->file_dir)) {
            $this->filesTpl = listFiles($this->file_dir, $this->ext);
            $this->filesTpl['theme'] = $this->file_dir;
            setcache('tplFiles', $this->filesTpl);
        }
        $modArr = getcache('plugins');
        if (empty($modArr)) {
            $query = $core->select_data('plugins', '`active` = 1', 'priority ASC');
            while ($result = $db->getRow($query)) {
                if ($result['service'] == 'blocks') {
                    $this->blocks[$result['id']] = $result;
                } else {
                    $this->modules[$result['title']] = $result;
                }
            }
            setcache('plugins', array($this->blocks, $this->modules));
        } else {
            $this->blocks = $modArr[0];
            $this->modules = $modArr[1];
        }
    }

    function check_phone(): bool
    {
        $agent_now = strtolower($_SERVER['HTTP_USER_AGENT']);
        $agent_array = array('opera mini', 'ipad', 'android', 'pocket', 'palm', 'windows ce', 'windowsce', 'cellphone', 'opera mobi', 'ipod', 'small', 'sharp', 'sonyericsson', 'symbian', 'iphone', 'nokia', 'htc_', 'samsung', 'motorola', 'smartphone', 'blackberry', 'playstation portable', 'tablet browser');
        foreach ($agent_array as $agent) {
            if (str_contains($agent_now, $agent)) return true;
        }
        return false;
    }

    #[NoReturn] function __destruct()
    {
        die();
    }

    public function loadFileADM($file, $check = false): void
    {
        global $lang;
        $loadDefault = 'usr/tpl/admin/' . $file . $this->ext;
        $loadUrl = $loadDefault;
        if (!isset($this->cacheTpl[$loadUrl])) {
            if (is_file(ROOT . $loadUrl)) {
                $this->cacheTpl[$loadUrl] = file_get_contents(ROOT . $loadUrl);
            } elseif (is_file(ROOT . $loadDefault)) {
                $this->cacheTpl[$loadDefault] = file_get_contents(ROOT . $loadDefault);
                $loadUrl = $loadDefault;
            } else {
                if (!$check) {
                    delcache('tplFiles');
                    $this->filesTpl = listFiles($this->file_dir, $this->ext);
                    $this->loadFile($file, true);
                } else {
                    fatal_error($lang['error'], str_replace('[file]', $file . $this->ext, $lang['file_not_found']));
                }
            }
        }
        $this->file = $loadUrl;
        $lo = explode('/', $loadUrl);
        $this->tplDir = $lo[2];
        $this->startCompile = microtime(1);
        $this->sources = $this->cacheTpl[$loadUrl];
    }

    public function loadFile($file, $check = false): void
    {
        global $config, $lang;
        $loadDefault = 'usr/tpl/default/' . $file . $this->ext;
        if (!$this->adminTheme) {
            $loadUrl = $this->getThemeFile($file);
        } else if ($config['tpl_change'] == '0') {
            $loadUrl = 'usr/tpl/' . $config['tpl'] . '/' . $file . $this->ext;
        } else {
            $loadUrl = $this->file_dir . $file . $this->ext;
            if (isset($this->cacheTpl[$loadDefault])) $loadUrl = $loadDefault;
        }
        if (!isset($this->cacheTpl[$loadUrl])) {
            if (is_file(ROOT . $loadUrl)) {
                $this->cacheTpl[$loadUrl] = file_get_contents(ROOT . $loadUrl);
            } elseif (is_file(ROOT . $loadDefault)) {
                $this->cacheTpl[$loadDefault] = file_get_contents(ROOT . $loadDefault);
                $loadUrl = $loadDefault;
            } else {
                if (!$check) {
                    delcache('tplFiles');
                    $this->filesTpl = listFiles($this->file_dir, $this->ext);
                    $this->loadFile($file, true);
                } else {
                    fatal_error($lang['error'], str_replace('[file]', $file . $this->ext, $lang['file_not_found']));
                }
            }
        }
        include(ROOT . 'boot/vars.class.php');
        $this->file = $loadUrl;
        $lo = explode('/', $loadUrl);
        $this->tplDir = $lo[2] ?? false;
        $this->startCompile = microtime(1);
        if (isset($loadUrl)) $this->sources = $this->cacheTpl[$loadUrl];
    }

    private function getThemeFile($file): string
    {
        global $url;
        $file = isset($file) ? $this->file_dir . $file : '';
        $loadFile = '';
        if (!empty($this->uniqTag)) {
            if (!is_array($this->uniqTag)) $this->uniqTag = array($this->uniqTag);
            if (INDEX) $this->uniqTag[] = 'index';
            foreach ($this->uniqTag as $uniq) {
                if (in_array($file . '-' . $url[0] . '-' . $uniq . $this->ext, $this->filesTpl)) {
                    $loadFile = $file . '-' . $url[0] . '-' . $uniq . $this->ext;
                    break;
                } elseif (in_array($file . '_' . $uniq . $this->ext, $this->filesTpl)) {
                    $loadFile = $file . '_' . $uniq . $this->ext;
                    break;
                } elseif (in_array($file . '--' . $uniq . $this->ext, $this->filesTpl)) {
                    $loadFile = $file . '--' . $uniq . $this->ext;
                    break;
                }
            }
        }
        if (empty($loadFile)) {
            if (in_array($file . '-' . $url[0] . $this->ext, $this->filesTpl)) {
                $loadFile = $file . '-' . $url[0] . $this->ext;
            } elseif (in_array($file . $this->ext, $this->filesTpl)) {
                $loadFile = $file . $this->ext;
            }
        }
        return $loadFile;
    }

    public function setVarTPL($k, $v): void
    {
        $this->vars_tpl[$k] = $v;
    }

    function check_lang($matches = array())
    {
        global $config;
        return $config['lang'] == $matches[2] ? $matches[3] : false;
    }

    function lang_include($matches = array())
    {
        global $lang;
        return $lang ? ($lang[$matches[1]] ?? '') : false;
    }

    function preOpen($matches = array())
    {
        $this->open();
        echo stripslashes($matches[1]);
        return $this->close(true);
    }

    public function open($file = null): void
    {
        if ($file) $this->uniqTag[] = $file;
        ob_start();
    }

    public function close($return = false)
    {
        $content = ob_get_contents();
        ob_end_clean();
        $this->loadFile('table');
        $this->setVar('CONTENT', $content);
        if (!$return) {
            $this->end();
        } else {
            return $this->return_end();
        }
    }

    public function setVar($k, $v): void
    {
        $this->vars[$k] = $v;
    }

    public function end(): void
    {
        global $core;
        if (DEBUG) $this->listTemplates[($this->file ?: 'main')] = MicroTime(1) - $this->startCompile;
        $tpl_now = str_replace("usr/tpl/", '', $this->file_dir);
        $tpl_now = substr($tpl_now, 0, -1);
        if (file_exists(ROOT . 'langs/' . $core->lang . '/tpl/' . $core->lang . '.' . $tpl_now . '.lng')) include(ROOT . 'langs/' . $core->lang . '/tpl/' . $core->lang . '.' . $tpl_now . '.lng');
        $this->time_compile += microtime(1) - $this->startCompile;
        $this->parse();
        $this->compile();
        $this->clear();
    }

    public function parse(): void
    {
        global $url;
        if ($url[0] != ADMIN) {
            ////////////////////////////////////BANNERS//////////////////////////
            if (file_exists(ROOT . 'usr/modules/banners/banners.php')) include(ROOT . 'usr/modules/banners/banners.php');
            //////////////////////////////END_BANNERS//////////////////////////
            ////////////////////////////////////TAGCODE//////////////////////////
            if (file_exists(ROOT . 'usr/modules/tagcode/tagcode.php')) include(ROOT . 'usr/modules/tagcode/tagcode.php');
            //////////////////////////////END_TAGCODE//////////////////////////
            ////////////////////////////////////FEED//////////////////////////
            if (file_exists(ROOT . 'usr/modules/feed/feed.php')) include(ROOT . 'usr/modules/feed/feed.php');
            //////////////////////////////END_FEED//////////////////////////
            ////////////////////////////////////INCLUD_CHART//////////////////////////
            if (file_exists(ROOT . 'usr/modules/includ_chart/counter.php')) include(ROOT . 'usr/modules/includ_chart/counter.php');
            //////////////////////////////END_INCLUD_CHART//////////////////////////
            $tpl_now = str_replace("usr/tpl/", '', $this->file_dir);
            $tpl_now = substr($tpl_now, 0, -1);
            $this->sources = preg_replace_callback("#\\[lang_tpl:(.+?)\\]#is", array(&$this, 'lang_include'), $this->sources);
            $this->sources = preg_replace_callback("#\\[lang:(.+?)\\]#i", array(&$this, 'lang_include'), $this->sources);
            $this->sources = preg_replace_callback("#\\{%nowdate:(.*?)%\\}#is", function ($matches) {
                return strtoupper(date($matches[1], time()));
            }, $this->sources);
            $this->sources = preg_replace_callback("#\\[group=(.+?)](.*?)\\[/group]#is", "Group", $this->sources);
            $this->sources = preg_replace_callback("#\\[nogroup=(.+?)](.*?)\\[/nogroup]#is", "noGroup", $this->sources);
            $this->sources = preg_replace_callback("#\\[index:(.+?)\\](.*?)\\[/index\\]#is", "indexShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[modules:(.+?):(.+?)](.*?)\\[/modules]#is", "modulesShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[category:(.+?):(.+?)](.*?)\\[/category]#is", "categoryShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[news:(.+?):(.+?)](.*?)\\[/news]#is", "newsShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[addnews:(.+?)\\](.*?)\\[/addnews\\]#is", "addnewsShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[full:(.+?)\\](.*?)\\[/full\\]#is", "fullnewsShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[content:(.+?):(.+?)](.*?)\\[/content]#is", "contentShow", $this->sources);
            $this->sources = preg_replace_callback("#\\[guest](.*?)\\[/guest]#is", "checkGuest", $this->sources);
            $this->sources = preg_replace_callback("#\\[user](.*?)\\[/user]#is", "checkUser", $this->sources);
            $this->sources = preg_replace_callback("#\\[uprof](.*?)\\[/uprof]#is", "checkUprof", $this->sources);
            $this->sources = preg_replace_callback("#\\[unprof](.*?)\\[/unprof]#is", "checkUnprof", $this->sources);
            $this->sources = preg_replace_callback("#\\[outpro](.*?)\\[/outpro]#is", "checkOutpro", $this->sources);
            $this->sources = preg_replace_callback("#\\[inpro](.*?)\\[/inpro]#is", "checkInpro", $this->sources);
            $this->sources = preg_replace_callback("#\\[admin](.*?)\\[/admin]#is", "checkAdmin", $this->sources);
            $this->sources = preg_replace_callback("#\\[social](.*?)\\[/social]#is", "checkSocial", $this->sources);
            $this->sources = preg_replace_callback("#\\[captcha](.*?)\\[/captcha]#is", "checkCaptcha", $this->sources);
            ///////////////////////////////////////////////////////BLOK//////////////////////////////////////////////////////////////////////////////////////
            $count_folder = 0;
            foreach (glob(ROOT . 'usr/blocks/*.block.php') as $inFile) {
                $name = explode('usr/blocks/', $inFile);
                $name = $name[1];
                $subDir = explode(',', $name);
                $inDirs[$subDir[0]][] = $inFile;
            }
            if (isset($inDirs)) {
                foreach ($inDirs as $bloks => $files) {
                    $count_folder++;
                    $abs = str_replace(array('.', 'block', 'php'), array('', '', ''), $bloks);
                    $_names[$bloks] = $abs ?: '';
                    $string = ucfirst($_names[$bloks]);
                    $this->sources = preg_replace_callback("#\\[$_names[$bloks]_bloks](.*?)\\[/$_names[$bloks]_bloks]#is", "check$string", $this->sources);
                }
            }
            //////////////////////////////////////////////////////END BLOK///////////////////////////////////////////////////////////////////////////////////////
            $this->sources = preg_replace_callback("#\<?php(.*?)\?>#is", function ($matches) {
                return stripslashes(eval($matches[1]));
            }, $this->sources);
            $this->sources = preg_replace_callback("#\\[recaptcha:(.+?)\\](.*?)\\[/recaptcha]#is", "checkReCaptcha", $this->sources);
            $this->sources = preg_replace_callback("#\\[title:(.*?)]#is", array(&$this, 'preTitle'), $this->sources);
            $this->sources = preg_replace_callback("#\\[open](.*?)\\[/open]#is", array(&$this, 'preOpen'), $this->sources);
            $this->sources = preg_replace_callback("#\\[userinfo:(.*?)]#is", array(&$this, 'ustinf'), $this->sources);
            $this->sources = preg_replace_callback("#\\[custom category=\"(.*?)\" template=\"(.*?)\" aviable=\"(.*?)\" limit=\"(.*?)\" module=\"(.*?)\" order=\"(.*?)\" short=\"(.*?)\" notin=\"(.*?)\"]#is", "buildCustom", $this->sources);
            $this->sources = preg_replace_callback("#\\[custom category=\"(.*?)\" template=\"(.*?)\" aviable=\"(.*?)\" limit=\"(.*?)\" module=\"(.*?)\" order=\"(.*?)\" short=\"(.*?)\"]#is", "buildCustom", $this->sources);
            if (file_exists(ROOT . 'usr/other/other.replace.php')) include(ROOT . 'usr/other/other.replace.php');
            if (file_exists(ROOT . 'usr/tpl/' . $tpl_now . '/function.php')) include(ROOT . 'usr/tpl/' . $tpl_now . '/function.php');
        } else {
            $this->sources = preg_replace_callback("#\\[(lang)=(.+?)\\](.*?)\\[/lang\\]#is", array(&$this, 'check_lang'), $this->sources);
            $this->sources = preg_replace_callback("#\\[alang:(.+?)\\]#i", array(&$this, 'lang_include'), $this->sources);
        }
        foreach ($this->vars as $k => $v) $in['#{' . $this->sep . $k . $this->sep . '}#i'] = $v;
        if (!empty($in)) $this->sources = preg_replace(array_keys($in), array_values($in), $this->sources);
        if ($url[0] != ADMIN) {
            $this->sources = preg_replace_callback("#\\{" . $this->sep . "BLOCKS:(.*?):(.*?)" . $this->sep . "\\}#is", array(&$this, 'blockParse'), $this->sources);
            $this->sources = preg_replace_callback("#\\{" . $this->sep . "TPL:(.*?)" . $this->sep . "\\}#is", array(&$this, 'loadTPL'), $this->sources);
        }
    }

    private function compile(): void
    {
        echo $this->sources;
    }

    private function clear(): void
    {
        $this->sources = false;
        $this->vars = array();
        $this->file = false;
        $this->startCompile = false;
    }

    public function return_end()
    {
        global $core;
        $tpl_now = str_replace("usr/tpl/", '', $this->file_dir);
        $tpl_now = substr($tpl_now, 0, -1);
        if (file_exists(ROOT . 'langs/' . $core->lang . '/tpl/' . $core->lang . '.' . $tpl_now . '.lng')) include(ROOT . 'langs/' . $core->lang . '/tpl/' . $core->lang . '.' . $tpl_now . '.lng');
        $this->time_compile += microtime(1) - $this->startCompile;
        $this->parse();
        return $this->sources;
        $this->clear();
    }

    function preTitle($matches = array())
    {
        return $this->title(stripslashes($matches[1]), true);
    }

    public function title($text, $return = false)
    {
        $this->loadFile('title');
        $this->setVar('TITLE', $text);
        if (!$return) {
            $this->end();
        } else {
            return $this->return_end();
        }
    }

    function enUrl($urlGo, $lang): string
    {
        global $config, $lang;
        if (!eregStrt('http', $urlGo) && !eregStrt('css', $urlGo) && !eregStrt('ico', $urlGo) && !eregStrt('javascript', $urlGo) && !eregStrt($lang . '/', $urlGo) && !empty($urlGo) && $urlGo != '/' && $lang != $config['lang']) $urlGo = $lang . '/' . $urlGo;
        return $config['mod_rewrite'] == 1 ? 'href="' . $urlGo . '"' : 'href="index.php?url=' . $urlGo . '"';
    }

    function initTags($module): void
    {
        global $core, $db;
        $query = $core->select_data($module, false, 'id ASC');
        if ($db->numRows($query) > 0) {
            while ($rows = $db->getRow($query)) {
                $tags = $rows['tag'] ?? $rows['tags'];
                $this->sources = preg_replace_callback("#\\[" . $tags . "](.*?)\\[/" . $tags . "]#is", array(&$this, 'preOpen'), $this->sources);
                if (!$tags || $rows['active'] != 1) $this->setVar($tags, '');
            }
        }
    }

    function ustinf($matches = array())
    {
        global $core;
        if (isset($core->auth->user_info[$matches[1]])) return stripslashes($core->auth->user_info[$matches[1]]);
    }

    public function head(): void
    {
        ob_start();
    }

    public function foot($subContent = false, $disable_index = false): void
    {
        global $core, $config, $lang;
        LoadLang(true);
        $content = ob_get_contents();
        ob_end_clean();
        $cat_keyword = (isset($this->keywords) ? ', ' . $this->keywords : false);
        $desc = (isset($this->description) ? ', ' . $this->description : $config['description']);
        $title_now = html_entity_decode((!empty($this->title) && !empty($_REQUEST['url']) ? $this->title . $config['name'] : $config['name'] . $config['divider'] . $config['slogan']), ENT_QUOTES);
        $meta = "<title>" . $title_now . "</title>" . "\n";
        $core->InitLang();
        $meta .= "<meta http-equiv=\"content-type\" content=\"text/html; charset=\"utf8\" />" . "\n";
        $meta .= "<meta name=\"keywords\" content=\"" . $config['keywords'] . $cat_keyword . "\" />" . "\n";
        $meta .= "<meta name=\"description\" content=\"" . $desc . $cat_keyword . "\" />" . "\n";
        $meta .= "<meta name=\"author\" content=\"" . $lang['jmy_cms'] . "\" />" . "\n";
        $meta .= "<base href=\"" . $config['url'] . "/\" />" . "\n";
        $meta .= $disable_index ? "<meta name=\"robots\" content=\"noindex,nofollow\" />" . "\n" : "<meta name=\"robots\" content=\"index, follow\" />" . "\n";
        $meta .= "<meta name=\"robots\" content=\"index, follow\" />" . "\n";
        $meta .= "<meta name=\"generator\" content=\"" . $lang['jmy_cms'] . "\" />" . "\n";
        $meta .= "<link rel=\"alternate\" href=\"" . $config['url'] . "/feed/rss/" . $this->feed_link . "\" type=\"application/rss+xml\" title=\"" . $lang['ver_rrs'] . "\" />" . "\n";
        $meta .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" href=\"" . $config['url'] . "/feed/opensearch/\"	title=\"" . $config['name'] . "\" />" . "\n";
        $meta .= "<script src=\"usr/plugins/js/JMY_Ajax.min.js\" type=\"text/javascript\"></script>" . "\n";
        $meta .= "<script src=\"usr/plugins/js/engine.min.js\" type=\"text/javascript\"></script>" . "\n";
        $meta .= "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"></script>" . "\n";
        if (!empty($this->players)) $meta .= $this->players;
        array_unique($this->headerIncludes);
        foreach ($this->headerIncludes as $metas) {
            if ($metas) $meta .= $metas;
        }
        $this->loadFile('index');
        if (str_contains($this->sources, "<body")) {
            $this->sources = preg_replace('#<body(.*)[^>]#i', '<body\\1<div id="loading" class="loading" style="display:none;top:0;"><img src="media/showloading.gif" alt="Загрузка..." /><br />Загрузка...</div>' . $this->bodyIncludes, $this->sources);
        } else {
            $meta .= '<div id="loading" class="loading" style="display:none;top:0;"><img src="media/showloading.gif" alt="' . $lang['meta_load'] . '" /><br />' . $lang['meta_load'] . '</div>' . "\n";
        }
        if (!empty($this->endJs)) $this->sources = preg_replace('#</body(.*)[^>]#i', $this->endJs . '</body\\1', $this->sources);
        if (str_contains($this->sources, "{%FULL_AJAX:") && $config['fullajax']) {
            if (preg_match("#({%FULL_AJAX:start%}(.+){%FULL_AJAX:end%})#si", $this->sources, $fullAjax) && $subContent) $this->sources = $fullAjax[1];
        }
        $this->setVar('META', $meta);
        $this->setVar('MODULE', $content);
        $this->end();
        unset($this->cacheTpl);
    }

    public function loadTPL($matches = array())
    {
        $this->loadFile($matches[1]);
        include(ROOT . 'boot/vars.class.php');
        return $this->return_end();
    }

    public function info($text, $type = 'info', $redicret = null, $title = null, $url_text = null, $url = null, $url_type = 'url', $help_confirm = null, $help_title = null, $help_text = null, $help_descr = null, $url_link = null, $return = false)
    {
        global $core;
        $url_help = '';
        $GLOBALS["urll"] = $url;
        $GLOBALS["urllh"] = $url_link;
        switch ($url_type) {
            case 'url':
                $url = "location.href = '" . $url . "'";
                break;
            case 'modal':
                $url = 'modal_o(\'#modal-form-' . $url . '\')';
                break;
            default:
                break;
        }
        $url_help .= $core->fullURL() . '#" onclick="modal_o(\'#modal-form-help\')".';
        if ($url_link) $url_help .= modal_form_text('help', $help_confirm, 'fa-info', $help_title, $help_text, $help_descr);
        if ($type == 'info') {
            $type = 'success';
        } elseif ($type == 'empty') {
            $type = 'info';
        } elseif ($type == 'warning') {
            $type = 'warning';
        } elseif ($type == 'error') {
            $type = 'danger';
        } else {
            $type = $type ? 'default' : '';
        }
        $this->loadFile('info');
        $this->setVar('TEXT', $text);
        $this->setVar('TYPE', $type);
        $this->setVar('TITLE', $title);
        $this->setVar('HELP_TEXT', $help_confirm);
        $this->setVar('URL', $url);
        $this->setVar('URL_HELP', $url_help);
        $this->setVar('URL_TEXT', $url_text);
        $this->sources = preg_replace_callback("#\\[URL](.*?)\\[/URL]#is", function ($matches) {
            if (!empty($GLOBALS["urll"])) return $matches[1];
        }, $this->sources);
        $this->sources = preg_replace_callback("#\\[URL_HELP](.*?)\\[/URL_HELP]#is", function ($matches) {
            if (!empty($GLOBALS["urllh"])) return $matches[1];
        }, $this->sources);
        if ($return) {
            return $this->return_end();
        } else {
            $this->end();
        }
    }

    public function alert($type = 'info', $title = null, $text = null, $url = null, $stime = false): void
    {
        global $admin_conf, $urll;
        $GLOBALS["urll"] = $url;
        $time = !$stime ? ($type ? $admin_conf['alert_' . $type] : false) : $stime;
        $ttime = $time == 0 ? (86400 * 1000) : ($time * 1000);
        $this->loadFile('alert');
        $this->setVar('TEXT', $text);
        $this->setVar('TYPE', $type);
        $this->setVar('TITLE', $title);
        $this->setVar('URL', $urll);
        $this->setVar('TIME', $ttime);
        $this->end();
    }

    public function redicret($message, $url = 'news'): void
    {
        global $config;
        $full_url = $url;
        if ($config['redicret']) {
            include(ROOT . 'usr/tpl/redirect.tpl');
        } else {
            location($full_url);
        }
    }

    public function blockParse($matches = array())
    {
        global $core, $url, $lang;
        $type = mb_strtolower($matches[1]);
        $file = $matches[2];
        switch ($type) {
            case 'file':
                $block_path = ROOT . "usr/blocks/$file.block.php";
                if (!empty($file) && file_exists($block_path)) {
                    ob_start();
                    include_once($block_path);
                    $contetn_block = ob_get_contents();
                    ob_end_clean();
                    return $contetn_block;
                } else {
                    return $lang['block_empty'];
                }
            case 'type':
                if (empty($file)) return false;
                $block_content = null;
                $sideDe = !empty($this->modules[$url[0]]) ? explode(',', $this->modules[$url[0]]['unshow']) : '';
                $sideDe = !empty($this->modules[$url[0]]) ? explode(',', $this->modules[$url[0]]['unshow']) : '';
                foreach ($this->blocks as $array) {
                    if ($this->blockShow($array['showin'], $array['unshow'], $array['groups'])) {
                        if ($array['type'] == $file && (empty($sideDe) || !in_array($file, $sideDe))) {
                            $block_path = ROOT . "usr/blocks/" . $array['file'];
                            if (!empty($array['file']) && file_exists($block_path)) {
                                ob_start();
                                require($block_path);
                                $contetn_block = ob_get_contents();
                                ob_end_clean();
                                $this->uniqTag = array($array['id'], $array['file'], $array['type']);
                            } elseif (empty($array['file']) && !empty($array['content'])) {
                                $contetn_block = $core->bbDecode($array['content']);
                                $this->uniqTag = array($array['id'], $array['type']);
                            } else $contetn_block = '<div style="text-align: center;"><b>' . $lang['empty_content'] . '</b></div>';
                            ob_start();
                            $this->loadFile('block');
                            $this->setVar('TITLE', $array['title']);
                            if (!empty($edit)) $this->setVar('EDIT', $edit);
                            $this->setVar('CONTENT', $contetn_block);
                            $this->end();
                            $block_content .= ob_get_contents();
                            ob_end_clean();
                            unset($contetn_block);
                        }
                    }
                }
                return $block_content;
            case 'id':
                if (empty($file)) return false;
                $block_content = null;
                if (isset($this->blocks[$file])) {
                    $array = $this->blocks[$file];
                    $block_path = ROOT . "usr/blocks/" . $array['file'];
                    if (!empty($array['file']) && empty($array['content']) && file_exists($block_path)) {
                        ob_start();
                        require($block_path);
                        $contetn_block = ob_get_contents();
                        ob_end_clean();
                    } elseif (empty($array['file']) && !empty($array['content'])) {
                        $contetn_block = $core->bbDecode($array['content']);
                    } else $contetn_block = '<div style="text-align: center;"><b>Нет содержания!</b></div>';
                    return $contetn_block;
                    unset($contetn_block);
                }
                break;
            default:
                break;
        }
    }

    private function blockShow($mods, $unmods, $groups, $free = false)
    {
        global $url, $core;
        if (eregStrt('_free', $mods) && !$free) return false;
        $modNow = $url[0];
        $modsArr = explode(',', $mods);
        $unModsArr = explode(',', $unmods);
        $groupsArr = explode(',', $groups);
        $groupAccess = false;
        if ((is_null($groupsArr) && is_array($groupsArr) && in_array($core->auth->user_info['group'], $groupsArr)) or $groups == '' or $core->auth->isAdmin) $groupAccess = true;
        if (is_array($unModsArr) && in_array($modNow, $unModsArr)) {
            return false;
        } elseif ((is_array($modsArr) && in_array($modNow, $modsArr)) && !INDEX) {
            return $groupAccess;
        } elseif (eregStrt('_index', $mods)) {
            if (INDEX) {
                return $groupAccess;
            } else {
                return false;
            }
        } elseif (eregStrt('_all', $mods)) {
            return $groupAccess;
        }
    }

    public function pages($page, $num, $all, $link, $onClick = false, $return = false)
    {
        global $nums, $lang;
        if (!eregStrt('{page}', $link)) $link = $link . '/{page}';
        $numpages = ceil($all / $num);
        $predel = 4;
        $nextpage = $page + 1;
        $prevpage = $page - 1;
        for ($var = 1; $var < $numpages + 1; $var++) {
            if ($var == $page) {
                $nums .= '<span class="pages">' . $var . '</span>';
            } else {
                if ((($var > ($page - $predel)) && ($var < ($page + $predel))) or ($var == $numpages) || ($var == 1)) $nums .= ' <a href="' . str_replace('{page}', 'page/' . $var, $link) . '" ' . ($onClick ? str_replace('{num}', $var, $onClick) : '') . '><b>' . $var . '</b></a> ';
                if ($var < $numpages) {
                    if (($var > ($page - $predel - 2)) && ($var < ($page + $predel))) $nums .= " ";
                    if (($page > $predel + 2) && ($var == 1)) $nums .= "";
                    if (($page < ($numpages - $predel)) && ($var == ($numpages - 2))) $nums .= "";
                }
            }
        }
        if ($numpages != 1 && $numpages != 0) {
            $this->loadFile('pages');
            $this->setVar('NUM', $nums);
            $this->setVar('NUM', $nums);
            $this->sources = preg_replace_callback("#\\{" . $this->sep . "NEXT" . $this->sep . "\\}(.*?)\\{/" . $this->sep . "NEXT" . $this->sep . "\\}#is",
                function ($matches) use ($link, $nextpage, $onClick, $page, $var, $lang) {
                    if ($page < $var - 1) return pageLink($link, $matches[1], $nextpage, ($onClick ? str_replace("'", "\'", $onClick) : ''), $lang['forward']);

                }, $this->sources);
            $this->sources = preg_replace_callback("#\\{" . $this->sep . "PREV" . $this->sep . "\\}(.*?)\\{/" . $this->sep . "PREV" . $this->sep . "\\}#is",
                function ($matches) use ($link, $prevpage, $onClick, $page, $var, $lang) {
                    if ($page != 1) return pageLink($link, $matches[1], $prevpage, ($onClick ? str_replace("'", "\'", $onClick) : ''), $lang['back']);

                }, $this->sources);
            if ($return) {
                return $this->return_end();
            } else {
                $this->end();
            }
            $nums = '';
        }
    }
}