Система управления «Сайт PRO»
Версия 20240107

Класс App

Объект $App: Cms\Root\App

Глобальный объект для инициализации системы управления

Содержит необходимые инструменты для подключения классов системы управления, создания объектов, обработки HTTP-запроса к странице.

Исходный код
class App { … }

Свойства

$root

$App->root = '.';

Корневая папка сайта

Определяется при инициализации системы управления.

Исходный код
    public $root = '.';

$version

$App->version = '20240107';

Версия системы управления

Исходный код
    public $version = '20240107';

$rootPrefix

$App->rootPrefix = '\\Cms\\Root\\';

Префикс классов системы управления

Исходный код
    public $rootPrefix = '\\Cms\\Root\\';

$sitePrefix

$App->sitePrefix = '\\Cms\\Site\\';

Префикс классов системы управления, переопределяемых разработчиком сайта

Исходный код
    public $sitePrefix = '\\Cms\\Site\\';

$Conf

$App->Conf

Объект $Conf

Исходный код
    var $Conf;

$Data

$App->Data

Объект $Data

Исходный код
    var $Data;

$Auth

$App->Auth

Объект $Auth

Исходный код
    var $Auth;

$Main

$App->Main

Объект $Main

Исходный код
    var $Main;

$Form

$App->Form

Объект $Form

Исходный код
    var $Form;

$objects

$App->objects = array();

Список объектов системы управления

Исходный код
    protected $objects = array();

$route

$App->route = array();

Порядок обработки HTTP-запроса к странице

Исходный код
    protected $route = array();

Методы

__construct()

new App($root=null);

Конструктор

Параметры:

ИмяОписание
$root

null; string корневая папка сайта

Эта функция не должна вызываться напрямую. Вместо этого необходимо использовать вызов статического метода App::getInstance()

Исходный код
    protected function __construct($root = null) {
        if (isset($root)) $this->root = strval($root);
        else $this->root = __DIR__ . '/../..';
    }

getInstance()

App::getInstance($root=null);

Статический метод для получения экземпляра класса

Параметры:

ИмяОписание
$root

null; string корневая папка сайта

Возвращает: Cms\Root\App

Исходный код
    public static function getInstance($root = null) {
        static $instance;
        if (!isset($instance)) {
            if (is_callable('get_called_class')) $class = get_called_class();
            elseif (class_exists($class = 'Cms\\Site\\App')) $class = $class;
            elseif (class_exists($class = 'Cms\\Root\\App')) $class = $class;
            else $class = __CLASS__;
            $instance = new $class($root);
            if (!isset($GLOBALS['App']) || !is_object($GLOBALS['App'])) $GLOBALS['App'] = $instance;
        }
        return $instance;
    }

root()

$App->root();

Корневая папка сайта

Возвращает: string

Исходный код
    public final function root() {
        return $this->root;
    }

Conf()

$App->Conf();

Объект $Conf

Возвращает: Cms\Root\Conf

Исходный код
    public final function Conf() {
        if (isset($this->Conf)) return $this->Conf;
        return $this->get('conf');
    }

Data()

$App->Data();

Объект $Data

Возвращает: Cms\Root\Data\Base

Исходный код
    public final function Data() {
        if (isset($this->Data)) return $this->Data;
        return $this->get('data');
    }

Auth()

$App->Auth();

Объект $Auth

Возвращает: Cms\Root\Auth

Исходный код
    public final function Auth() {
        if (isset($this->Auth)) return $this->Auth;
        return $this->get('auth');
    }

Main()

$App->Main();

Объект $Main

Возвращает: Cms\Root\Main

Исходный код
    public final function Main() {
        if (isset($this->Main)) return $this->Main;
        return $this->get('main');
    }

Form()

$App->Form();

Объект $Form

Возвращает: Cms\Root\Form

Исходный код
    public final function Form() {
        if (isset($this->Form)) return $this->Form;
        return $this->get('form');
    }

version()

$App->version();

Версия системы управления

Возвращает: string

Исходный код
    public final function version() {
        return $this->version;
    }

open()

$App->open();

Инициализация системы управления

Смотрите описание $App->init()

Исходный код
    function open() {
        return $this->init();
    }

nodb()

$App->nodb();

Инициализация системы управления без подключения к базе данных

Исходный код
    function nodb() {
        return $this->init(false);
    }

init()

$App->init($open=true);

Инициализация системы управления

Параметры:

ИмяОписание
$open

boolean открыть подключение к базе данных

Исходный код
    function init($open = true) {
        static $init;
        if (!isset($init)) {
            $this->initSettings();
            $this->initAutoload();
            $this->initObjects();
            $init = false;
        }
        if ($open) {
            if (!$init) {
                $this->Data()->init();
                $this->Auth()->init();
                $this->Main()->init();
                $init = true;
            }
        }
    }

initSettings()

$App->initSettings();

Инициализация настроек PHP.

Возвращает: true – настройки выполнены; null – настройки уже были выполнены ранее

LC_ALL = C – для корректной работы strval(doubleval()) и т.п.

LC_CTYPE = ru_RU.UTF-8 – для корректной работы basename(), dirname() и т.п.

LC_COLLATE = ru_RU.UTF-8 – для корректной работы sort(), asort(), ksort() и т.п.

mbstring.internal_encoding = UTF-8 – для корректной работы mbstring

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT – для корректного отображения ошибок

display_errors = 1 – для корректного отображения ошибок

html_errors = 0 – для корректного отображения ошибок

include_path – для корректной работы autoload

Исходный код
    function initSettings() {
        static $init;
        if (isset($init)) return;
        /**
         * `LC_ALL = C` – для корректной работы `strval(doubleval())` и т.п.
         */
        setlocale(LC_ALL, "C");
        /**
         * `LC_CTYPE = ru_RU.UTF-8` – для корректной работы `basename()`, `dirname()` и т.п.
         */
        setlocale(LC_CTYPE, "ru_RU.UTF-8");
        /**
         * `LC_COLLATE = ru_RU.UTF-8` – для корректной работы `sort()`, `asort()`, `ksort()` и т.п.
         */
        setlocale(LC_COLLATE, "ru_RU.UTF-8");
        /**
         * `mbstring.internal_encoding = UTF-8` – для корректной работы `mbstring`
         */
        mb_internal_encoding("UTF-8");
        /**
         * `error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT` – для корректного отображения ошибок
         */
        if (doubleval(phpversion()) >= 5.4) error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT ^ E_DEPRECATED);
        else error_reporting(E_ALL ^ E_NOTICE);
        /**
         * `display_errors = 1` – для корректного отображения ошибок
         */
        ini_set("display_errors", true);
        /**
         * `html_errors = 0` – для корректного отображения ошибок
         */
        ini_set("html_errors", false);
        /**
         * `include_path` – для корректной работы `autoload`
         */
        set_include_path($this->root . PATH_SEPARATOR . get_include_path());
        foreach (explode(PATH_SEPARATOR, get_include_path()) as $folder) {
            if (@is_dir($folder = "$folder/cms/root-{$this->version}")) set_include_path(get_include_path() . PATH_SEPARATOR . $folder);
        }
        set_error_handler(function($code, $message, $file, $line) {
            $error_reporting = error_reporting();
            if (!$error_reporting || $error_reporting === 4437) return;
            if ($message === 'Trying to access array offset on value of type null') return;
            $message18 = substr($message, 0, 18);
            if ($message18 === 'Undefined variable') return;
            if ($message18 === 'Undefined property') return;
            $message19 = substr($message, 0, 19);
            if ($message19 === 'Undefined array key') return;
            print "\n" . 'Warning: ' . $message . ' in ' . $file . ' on line ' . $line . "\n";
        }, E_WARNING);
        @chdir($this->root);
        return $init = true;
    }

initAutoload()

$App->initAutoload();

Инициализация автоматической загрузки классов

Возвращает: true|false|null

Исходный код
    function initAutoload() {
        static $init;
        if (isset($init)) return;
        else return $init = spl_autoload_register(array($this, 'autoload'), false);
    }

autoload()

$App->autoload($class);

Функция для автоматической загрузки классов

Параметры:

ИмяОписание
$class

string класс

Исходный код
    function autoload($class) {
        # if (!$_SERVER['REMOTE_ADDR']) print 'autoload ' . $class . "<br>\n";
        if ($class[0] === '\\') $class = ltrim($class, '\\');
        if (($lastSeparatorIndex = strrpos($class, '\\')) !== false) {
            if (is_string($classpath = $this->resolveClassPath($class))) {
                # if (!$_SERVER['REMOTE_ADDR']) print 'require ' . $classpath . "<br>\n";
                require_once($classpath);
                if (!class_exists($class)) {
                    $underscoreClass = str_replace('__', '_', strtr($class, '\\', '_'));
                    if (class_exists($underscoreClass)) {
                        $namespace = substr($class, 0, $lastSeparatorIndex);
                        $classname = substr($class, $lastSeparatorIndex + 1);
                        # if (!$_SERVER['REMOTE_ADDR']) print 'declare ' . $namespace . '\\' . $classname . ' (' . $underscoreClass . ')' . "<br>\n";
                        eval("namespace $namespace { class $classname extends \\$underscoreClass { } }");
                    }
                }
            } elseif (substr($class, 0, 9) === 'Cms\\Site\\') {
                $rootClass = 'Cms\\Root\\' . substr($class, 9);
                if (is_string($classpath = $this->resolveClassPath($rootClass))) {
                    require_once($classpath);
                    if (!class_exists($rootClass)) {
                        $underscoreRootClass = str_replace('__', '_', strtr($rootClass, '\\', '_'));
                        if (class_exists($underscoreRootClass)) {
                            $namespace = substr($rootClass, 0, $lastSeparatorIndex);
                            $classname = substr($rootClass, $lastSeparatorIndex + 1);
                            # if (!$_SERVER['REMOTE_ADDR']) print 'declare ' . $namespace . '\\' . $classname . ' (' . $underscoreRootClass . ')' . "<br>\n";
                            eval("namespace $namespace { class $classname extends \\$underscoreRootClass { } }");
                        }
                    }
                    $namespace = substr($class, 0, $lastSeparatorIndex);
                    $classname = substr($class, $lastSeparatorIndex + 1);
                    # if (!$_SERVER['REMOTE_ADDR']) print 'declare ' . $namespace . '\\' . $classname . ' (\\' . $rootClass . ')' . "<br>\n";
                    eval("namespace $namespace { class $classname extends \\$rootClass { } }");
                }
            }
        } else {
            $namespaceClass = str_replace('\\\\', '\\_', strtr($class, '_', '\\'));
            # if (!$_SERVER['REMOTE_ADDR']) print 'declare ' . $class . ' (\\' . $namespaceClass . ')' . "<br>\n";
            if (class_exists("\\$namespaceClass")) {
                eval("namespace { class $class extends \\$namespaceClass { } }");
            }
        }
    }

resolveClassPath()

$App->resolveClassPath($class);

Получение абсолютного пути к файлу с определением класса

Параметры:

ИмяОписание
$class

string класс

Возвращает: string

Исходный код
    function resolveClassPath($class) {
        if ($class[0] === '\\') $class = ltrim($class, '\\');
        $parts = explode('\\', strtolower(strtr($class, '_', '\\')));
        if ($parts[1] === 'root') $parts[1] .= '-' . $this->version;
        $path = implode(DIRECTORY_SEPARATOR, $parts) . '.php';
        if (is_string($path = $this->resolvePath($path))) return $path;
    }

getAutoload()

$App->getAutoload($class);

Получение абсолютного пути к файлу с определением класса

Параметры:

ИмяОписание
$class

string класс

Возвращает: string

Смотрите описание $App->resolveClassPath()

Исходный код
    function getAutoload($class) {
        return $this->resolveClassPath($class);
    }

resolvePath()

$App->resolvePath($filename);

Получение абсолютного пути к файлу из include_path

Параметры:

ИмяОписание
$filename

string относительный путь к файлу

Возвращает: string

Исходный код
    function resolvePath($filename) {
        $root = $this->root();
        if (@file_exists($include = $root . DIRECTORY_SEPARATOR . $filename)) return $include;
        static $indexData;
        if (!isset($indexData)) $indexData = include(__DIR__ . '/index.data.php');
        $filepath = $filename;
        if (DIRECTORY_SEPARATOR !== '/') $filepath = strtr($filepath, DIRECTORY_SEPARATOR, '/');
        if (strpos($filepath, '//') !== false) $filepath = preg_replace('~//+~', '/', $filepath);
        if ($filepath[0] === '/') $filepath = ltrim($filepath, '/');
        if (substr($filepath, 0, 9) === 'cms/root-' && substr($filepath, 9, strlen($this->version) + 1) === $this->version . '/') {
            $filepath = substr($filepath, 10 + strlen($this->version));
            if (in_array($filepath, $indexData)) return __DIR__ . DIRECTORY_SEPARATOR . $filepath;
        } else {
            if (in_array($filepath, $indexData)) return __DIR__ . DIRECTORY_SEPARATOR . $filename;
        }
    }

getAbsolutePath()

$App->getAbsolutePath($filename);

Получение абсолютного пути к файлу из include_path

Параметры:

ИмяОписание
$filename

string относительный путь к файлу

Возвращает: string

Смотрите описание $App->resolvePath()

Исходный код
    function getAbsolutePath($filename) {
        return $this->resolvePath($filename);
    }

initObjects()

$App->initObjects();

Инициализация глобальных переменных $root, $Conf, $Data, $Auth, $Main, $Form

Исходный код
    function initObjects() {
        $GLOBALS['root'] = $this->root;
        $GLOBALS['Conf'] = $this->Conf = $this->Conf();
        $GLOBALS['Data'] = $this->Data = $this->Data();
        $GLOBALS['Auth'] = $this->Auth = $this->Auth();
        $GLOBALS['Main'] = $this->Main = $this->Main();
        $GLOBALS['Form'] = $this->Form = $this->Form();
    }

getClass()

$App->getClass($type);

Имя класса для типа объекта

Параметры:

ИмяОписание
$type

string тип объекта

Возвращает: string имя класса

Определяет класс для типа и возвращает имя этого класса.

Исходный код
    function getClass($type) {
        static $keywords = array(
            'abstract', 'and', 'array', 'as',
            'break', 'callable', 'case', 'catch', 'class',
            'clone', 'const', 'continue', 'declare', 'default',
            'die', 'do', 'echo', 'else', 'elseif',
            'empty', 'enddeclare', 'endfor', 'endforeach', 'endif',
            'endswitch', 'endwhile', 'eval', 'exit', 'extends',
            'final', 'finally', 'fn', 'for', 'foreach',
            'function', 'global', 'goto', 'if', 'implements',
            'include', 'include_once', 'instanceof', 'insteadof', 'interface',
            'isset', 'list', 'match', 'namespace', 'new',
            'or', 'print', 'private', 'protected', 'public',
            'readonly', 'require', 'require_once', 'return', 'static',
            'switch', 'throw', 'trait', 'try', 'unset',
            'use', 'var', 'while', 'xor', 'yield', 'from',
        );
        $r = rtrim($this->sitePrefix, '\\');
        foreach (explode('\\', strtolower(strtr($type, '-_', '\\\\'))) as $name) {
            $r .= '\\' . (intval($name) || in_array($name, $keywords) ? '_' : '') . ucfirst($name);
        }
        return $r;
    }

get()

$App->get($type);

Получение объекта системы управления

Параметры:

ИмяОписание
$type

string тип объекта

Возвращает: Cms\Root\Base

Автоматически определяет класс для типа, создает и возвращает объект этого класса. Для каждого типа создается не более одного объекта.

Исходный код
    function get($type) {
        if (isset($this->objects[$type])) {
            $object = $this->objects[$type];
        } else {
            $class = $this->getClass($type);
            $object = $this->objects[$type] = new $class(null);
        }
        return $object;
    }

getObject()

$App->getObject($type);

Получение объекта системы управления

Параметры:

ИмяОписание
$type

string тип объекта

Возвращает: Cms\Root\Base

Автоматически определяет класс для типа, создает и возвращает объект этого класса. Для каждого типа создается не более одного объекта. Смотрите описание $App->get()

Исходный код
    function getObject($type) {
        return $this->get($type);
    }

getPageObject()

$App->getPageObject($type);

Получение объекта страницы

Параметры:

ИмяОписание
$type

string тип страницы

Возвращает: Cms\Root\Page

Автоматически определяет класс для типа страницы, создает и возвращает объект этого класса. Для каждого типа страницы создается не более одного объекта.

Исходный код
    function getPageObject($type) {
        $object = $this->objects[$type];
        if (!isset($object)) {
            $class = $this->getClass($type);
            if (!class_exists($class)) {
                if (($lastSeparatorIndex = strrpos($class, '\\')) !== false) {
                    $namespace = ltrim(substr($class, 0, $lastSeparatorIndex), '\\');
                    $classname = substr($class, $lastSeparatorIndex + 1);
                    eval("namespace $namespace { class $classname extends \\Cms\\Site\\Page { } }");
                } else {
                    eval("namespace { class $class extends \\Cms\\Site\\Page { } }");
                }
            }
            $object = $this->objects[$type] = new $class(null);
        }
        return $object;
    }

getObjects()

$App->getObjects();

Получение списка объектов системы управления

Возвращает: array

Возвращает список всех объектов, созданных с помощью $App->get() и $App->getPageObject()

Исходный код
    function getObjects() {
        return $this->objects;
    }

initRoute()

$App->initRoute();

Инициализация обработчиков HTTP-запроса

Исходный код
    function initRoute() {
        $this->addRoute(array($this->get('api'), 'route'));
        $this->addRoute(array($this->get('file'), 'route'));
        $this->addRoute(array($this->get('thumb'), 'route'));
        $this->addRoute(array($this->get('page'), 'route'));
        if ($this->Conf()->get('redis'))
        $this->addRoute(array($this->get('redis'), 'route'));
        $this->addRoute(array($this->get('main'), 'route'));
    }

getRoute()

$App->getRoute();

Получение списка обработчиков HTTP-запроса

Возвращает: array

Исходный код
    function getRoute() {
        return $this->route;
    }

addRoute()

$App->addRoute($callback, $prepend=false);

Добавление обработчика HTTP-запроса

Параметры:

ИмяОписание
$callback

callable функция или метод-обработчик

$prepend

boolean добавить обработчик в начало списка

Исходный код
    function addRoute($callback, $prepend = false) {
        if ($prepend) array_unshift($this->route, $callback);
        else array_push($this->route, $callback);
    }

delRoute()

$App->delRoute($callback);

Удаление обработчика HTTP-запроса

Параметры:

ИмяОписание
$callback

callable функция или метод-обработчик

Исходный код
    function delRoute($callback) {
        $index = array_search($callback, $this->route, true);
        if (is_int($index)) unset($this->route[$index]);
        elseif (is_array($index)) foreach ($index as $index) unset($this->route[$index]);
        $this->route = array_values($this->route);
    }

route()

$App->route();

Обработка HTTP-запроса к странице

Последовательно вызывает обработчики HTTP-запроса, пока один из них не вернет true или false . После этого отправляет ответ в браузер.

Исходный код
    function route() {
        $Request = $this->get('main_request');
        $Request->init();
        foreach ($this->route as $callback) if (is_callable($callback)) {
            $r = call_user_func($callback, $Request);
            if (!isset($r)) continue;
            else break;
        }
        return $Request->send($r);
    }

largeMemoryLimit()

$App->largeMemoryLimit();

Увеличение лимита памяти до 1ГБ

Исходный код
    function largeMemoryLimit() {
        @ini_set('memory_limit', '1G');
    }

__main()

$App->__main();

Инициализация системы управления, обработка HTTP-запроса к странице

Исходный код
    function __main() {
        if (php_sapi_name() === 'cli-server') {
            if ($pathInfo = pathinfo($_SERVER['SCRIPT_FILENAME'])) {
                if ($pathInfo['extension'] && $pathInfo['extension'] !== 'php') {
                    return false;
                }
            }
        }
        $this->initSettings();
        $this->initAutoload();
        $this->initRoute();
        $this->route();
    }