Файл: system/classes/Template.php
Строк: 108
<?php
class Template
{
    /**
     * Имя макета.
     *
     * @var string
     */
    private $layoutName;
    /**
     * Переменные макета.
     *
     * @var array
     */
    private $layoutData = [];
    /**
     * Переменные шаблонов.
     *
     * @var array
     */
    private $data = [];
    /**
     * Массив содержания секций.
     *
     * @var array
     */
    private $sections = [];
    /**
     * Директория шаблонов.
     *
     * @var string
     */
    private $directory;
    /**
     * Расширение шаблонов.
     *
     * @var string
     */
    private $extension;
    /**
     * Инициализации шаблонизатора. (Задаёт директорию и расширение шаблонов)
     *
     * @param string $directory
     * @param string $extension
     */
    public function __construct($directory = null, $extension = '.tpl')
    {
        $this->directory = $directory;
        $this->extension = $extension;
    }
    /**
     * Расширяет текущий шаблон (макет).
     *
     * @param string $name
     * @param array  $data
     * @return null
     */
    private function layout($name, array $data = [])
    {
        $this->layoutName = $name;
        $this->layoutData = $data;
    }
    /**
     * Начинает новую секцию.
     *
     * @param string $name
     * @return null
     */
    private function start($name)
    {
        if ($name === 'content') {
            trigger_error('Данное название "content" зарезервировано.', E_USER_ERROR);
        }
        $this->sections[$name] = null;
        ob_start();
    }
    /**
     * Остановка текущей сецкии.
     *
     * @return null
     */
    private function stop()
    {
        if (empty($this->sections)) {
            trigger_error('Вы должны создать секцию, прежде чем вы можете её остановить.', E_USER_ERROR);
        }
        end($this->sections);
        $this->sections[key($this->sections)] = ob_get_clean();
    }
    /**
     * Возвращает содержимое секции.
     *
     * @param string $name
     * @return string
     */
    private function section($name)
    {
        return $this->sections[$name];
    }
    /**
     * Экранирует строку.
     *
     * @param string $string
     * @return string
     */
    private function escape($string)
    {
        return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
    /**
     * Создаёт ключ и его значение.
     *
     * @param string $key
     * @param mixed $value
     */
    public function set($key, $value) {
        $this->data[$key] = $value;
    }
    /**
     * Рендерит шаблон и его макет.
     *
     * @param string $name
     * @param array  $data
     * @return string
     */
    public function render($name, array $data = [])
    {
        if (is_array($data)) {
            $this->data = array_merge($this->data, $data);
        }
        extract($this->data);
        ob_start();
        $file = $this->directory . '/' . str_replace('.', '/', $name) . $this->extension;
        if (is_file($file)) {
            require $file;
        } else {
            trigger_error('Не найден файл <strong>' . $file . '</strong>', E_USER_ERROR);
        }
        $content = ob_get_clean();
        if (isset($this->layoutName)) {
            $layout = new $this($this->directory, $this->extension);
            $layout->sections = array_merge($this->sections, [
                'content' => $content
            ]);
            $this->layoutData = array_merge($this->layoutData, $this->data);
            $content = $layout->render($this->layoutName, $this->layoutData);
        }
        return $content;
    }
}