Skip to content

Commit

Permalink
#3, #13206. Добавлена возможность удаления кеша с помощью вспомогател…
Browse files Browse the repository at this point in the history
…ьного класса.

Произведен рефакторинг внутренних модулей системы
  • Loading branch information
mmjurov committed May 29, 2016
1 parent d721864 commit 63c5027
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 96 deletions.
16 changes: 13 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ vendor:component_name[:template[:specific_template_file]]
//Кодировка соответствует кодировке продукта
'charset' => SITE_CHARSET,

//кеш хранится в уникальной директории
//кеш хранится в уникальной директории. Должен быть полный абсолютный путь
'cache' => $_SERVER['DOCUMENT_ROOT'] . '/bitrix/cache/maximaster/tools.twig',

//Автообновление включается только в момент очистки кеша
Expand All @@ -59,13 +59,15 @@ vendor:component_name[:template[:specific_template_file]]
## Расширение

С версии 0.5 появилась возможность добавления собственных расширений. Реализуется это с помощью обработчика события **onAfterTwigTemplateEngineInited**. Событие не привязано ни к одному из модулей, поэтому при регистрации события в качестве идентификатора модуля нужно указать пустую строку.
В событие передается объект \Twig_Environment, с которым можно сделать определенные манипуляции.
В событие передается объект `\Twig_Environment`, с которым можно сделать определенные манипуляции.
Пример обработчика события, который зарегистрирует свое расширение:

```php

use Bitrix\Main\EventResult;

AddEventHandler('', 'onAfterTwigTemplateEngineInited', array('onAfterTwigTemplateEngineInited', 'addTwigExtension'));

class onAfterTwigTemplateEngineCreated
{
public static function addTwigExtension(\Twig_Environment $engine)
Expand All @@ -76,7 +78,7 @@ class onAfterTwigTemplateEngineCreated
}
```

Здесь класс MySuperDuperExtension должен быть наследником класса \Twig_Extension или имплементацией интерфейса \Twig_ExtensionInterface.
Здесь класс MySuperDuperExtension должен быть наследником класса `\Twig_Extension` или имплементацией интерфейса `\Twig_ExtensionInterface`.

## Дополнительные функции

Expand All @@ -91,3 +93,11 @@ class onAfterTwigTemplateEngineCreated
```

Порядок словоформ запомнить достаточно просто: 0 билетов, 1 билет, 2 билета. Для большинства слов такой порядок будет работать корректно.

## Работа с кешем

С версии 0.8 появилась возможность программно управлять очисткой кеша. Сделать это можно с помощью класса `\Maximaster\Tools\Twig\TwigCacheCleaner`. Данный класс можно использовать только в том случае, если кеш Twig хранится на диске.
Класс имеет 2 метода очистки:
* `clearByName($name)` - очищает кеш шаблона по его имени
* `clearAll()` - очищает весь кеш
Каждый их методов вернет количество удаленных файлов кеша
155 changes: 103 additions & 52 deletions src/Maximaster/Tools/Twig/BitrixLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,102 +8,153 @@
*/
class BitrixLoader extends \Twig_Loader_Filesystem implements \Twig_LoaderInterface
{
/** @var array Статическое хранилище для уже отрезолвленных путей для ускорения */
private static $resolved = array();
/** @var array Статическое хранилище нормализованных имен шаблонов для ускорения */
private static $normalized = array();

/**
* {@inheritdoc}
*
* Принимает на вход имя компонента и шаблона в виде<br>
* <b>vendor:componentname[:template[:specifictemplatefile]]</b><br>
* Например bitrix:news.list:.default, или bitrix:sale.order:show:step1
*
* @inheritdoc
* @param string $name
*/
function getSource($name)
public function getSource($name)
{
return file_get_contents($this->getSourcePath($name));
return file_get_contents($this->getSourcePath($this->normalizeName($name)));
}

function getSourcePath($name)
{
/*if ($name == SITE_TEMPLATE_ID)
{
return $this->siteTemplate();
}*/

$realFileName = $_SERVER[ 'DOCUMENT_ROOT' ] . $name;
if (file_exists($realFileName))
return $realFileName;

return $this->getComponentTemplatePath($name);
}

function getCacheKey($name)
/** {@inheritdoc} */
public function getCacheKey($name)
{
return $name;
return $this->normalizeName($name);
}

/**
* {@inheritdoc}
* Не использовать в продакшене!!
* Метод используется только в режиме разработки или при использовании опции auto_reload = true
* @param string $name Путь к шаблону
* @param int $time Время изменения закешированного шаблона
* @return bool Актуален ли закешированный шаблон
* @param string $name Путь к шаблону
* @param int $time Время изменения закешированного шаблона
* @return bool Актуален ли закешированный шаблон
*/
function isFresh($name, $time)
public function isFresh($name, $time)
{
return filemtime($this->getSourcePath($name)) <= $time;
return filemtime($this->getSource($name)) <= $time;
}

/**
* По Битрикс-имени шаблона возвращает путь к его файлу
*
* @param string $name
* @return string
* @throws \Twig_Error_Loader
*/
private function getComponentTemplatePath($name)
/**
* Получает путь до файла с шаблоном по его имени
*
* @param string $name
* @return string
* @throws \Twig_Error_Loader
*/
public function getSourcePath($name)
{
list($namespace, $component, $template, $file) = explode(':', $name);

if (strlen($template) === 0)
{
$template = '';
if (isset(static::$resolved[ $name ])) {
return static::$resolved[ $name ];
}

if (strlen($file) === 0)
{
$file = '';
$resolved = '';
$realFileName = $_SERVER['DOCUMENT_ROOT'] . $name;
if (file_exists($realFileName)) {
$resolved = $realFileName;
} else {
$resolved = $this->getComponentTemplatePath($name);
}

static::$resolved[ $name ] = $resolved;

return $resolved;

}


/**
* По Битрикс-имени шаблона возвращает путь к его файлу
*
* @param string $name
* @return string
* @throws \Twig_Error_Loader
*/
private function getComponentTemplatePath($name)
{
$name = $this->normalizeName($name);

list($namespace, $component, $template, $file) = explode(':', $name);

$componentName = "{$namespace}:{$component}";

$component = new \CBitrixComponent();
$component->InitComponent($componentName, $template);
$component->__templatePage = $file;
$component->__templatePage = $file;

$obTemplate = new \CBitrixComponentTemplate();
$obTemplate->Init($component);
$templatePath = $_SERVER['DOCUMENT_ROOT'] . $obTemplate->GetFile();

if (!file_exists($templatePath))
{
if (!file_exists($templatePath)) {
throw new \Twig_Error_Loader("Не удалось найти шаблон '{$name}'");
}

return $templatePath;
}

/*
private function siteTemplate()
/**
* На основании шаблона компонента создает полное имя для Twig
*
* @param \CBitrixComponentTemplate $template
* @return string
*/
public function makeComponentTemplateName(\CBitrixComponentTemplate $template)
{
$headerFile = $_SERVER['DOCUMENT_ROOT'] . SITE_TEMPLATE_PATH . '/header.twig';
$footerFile = $_SERVER['DOCUMENT_ROOT'] . SITE_TEMPLATE_PATH . '/footer.twig';
if ($template->__fileAlt) {
return $template->__fileAlt;
}

$templatePage = $template->__page;
$templateName = $template->__name;
$componentName = $template->getComponent()->getName();

return "{$componentName}:{$templateName}:{$templatePage}";
}

/**
* Преобразует имя в максимально-полное начертание
*
* @param string $name
* @return string
*/
public function normalizeName($name)
{
if (strpos($name, '/') !== false) {
return parent::normalizeName($name);
}

if (isset(static::$normalized[ $name ])) {
return static::$normalized[ $name ];
}

//Убираем все повторяющиеся двоеточия
$name = preg_replace('#/{2,}#', ':', (string)$name);

list( $namespace, $component, $template, $file ) = explode(':', $name);

if (strlen($template) === 0) {
$template = '.default';
}

if (!file_exists($headerFile) || !file_exists($footerFile))
{
throw new \Twig_Error_Loader("Не удалось найти шаблон '" . SITE_TEMPLATE_ID . "'");
if (strlen($file) === 0) {
$file = 'template';
}

return file_get_contents($headerFile) . '{% block workarea %}{% endblock %}' . file_get_contents($footerFile);
$normalizedName = "{$namespace}:{$component}:{$template}:{$file}";
static::$normalized[ $name ] = $normalizedName;
return $normalizedName;

}
*/
}
Loading

0 comments on commit 63c5027

Please sign in to comment.