ModuleAsset
Package | framework.modules |
---|---|
Inheritance | class ModuleAsset » Module » LsObject |
Since | 2.0 |
Source Code | /framework/classes/modules/asset/Asset.class.php |
Модуль управления статическими файлами css стилей и js сриптов
Позволяет сжимать и объединять файлы для более быстрой загрузки
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
_aBehaviors | Список поведений в виде готовых объектов, формируется автоматически | LsObject | |
aAssets | array | Список файлов по типам | ModuleAsset |
aBehaviors | array | Список поведений | LsObject |
bIsInit | bool | Указывает на то, была ли проведенна инициализация модуля | Module |
hDescriptorMergeLock | null|resource | Дескриптор файла для проверки блокировки | ModuleAsset |
Public Methods
Method | Description | Defined By |
---|---|---|
AddBehaviorHook() | Добавляет хук поведения | LsObject |
AddCss() | Добавляет файл css стиля | ModuleAsset |
AddJs() | Добавляет файл js скрипта | ModuleAsset |
AttachBehavior() | Присоединяет поведение к объекту | LsObject |
BuildHeadItems() | Возвращает HTML код подключения файлов в HEAD'ер страницы | ModuleAsset |
CheckAssetType() | Проверяет корректность типа файла | ModuleAsset |
CreateObjectType() | Создает и возврашает объект типа | ModuleAsset |
DetachBehavior() | Отсоединяет поведение от объекта | LsObject |
GetBehavior() | Возвращает объект поведения по его имени | LsObject |
GetBehaviors() | Возвращает все объекты поведения | LsObject |
GetFileWeb() | Возвращает корректный WEB путь до файла | ModuleAsset |
GetRealpath() | ModuleAsset | |
Init() | Инициалищация модуля | ModuleAsset |
PrepareParams() | Производит предварительную обработку параметров | ModuleAsset |
Processing() | Производит обработку файлов | ModuleAsset |
RemoveBehaviorHook() | Удаляет хук поведения | LsObject |
RunBehaviorHook() | Запускает хук поведения на выполнение | LsObject |
SetInit() | Помечает модуль как инициализированный | Module |
Shutdown() | ModuleAsset | |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля | LsObject |
__clone() | Блокируем копирование/клонирование объекта | Module |
__construct() | Конструктор, запускается автоматически при создании объекта | LsObject |
__get() | Обработка доступа к объекты поведения | LsObject |
isInit() | Возвращает значение флага инициализации модуля | Module |
Protected Methods
Method | Description | Defined By |
---|---|---|
Add() | Добавляет новый файл | ModuleAsset |
InitAssets() | Задает начальную структуры для хранения списка файлов по типам | ModuleAsset |
IsLockMerge() | Проверяет на блокировку | ModuleAsset |
Merge() | Производит объединение и сжатие файлов | ModuleAsset |
NormalizeFilePath() | Приводит путь до файла к единому виду | ModuleAsset |
PrepareBehaviors() | Инициализация поведений | LsObject |
RemoveLockMerge() | Удаляет блокировку | ModuleAsset |
Property Details
aAssets
property
protected array $aAssets;
Список файлов по типам
See Also
hDescriptorMergeLock
property
protected null|resource $hDescriptorMergeLock;
Дескриптор файла для проверки блокировки
Method Details
Add()
method
protected bool Add(string $sFile, array $aParams, string $sType, bool $bPrepend=false, bool $bReplace=false)
| ||
$sFile | string | Полный путь до файла |
$aParams | array | Дополнительные параметры |
$sType | string | Тип файла |
$bPrepend | bool | Добавлять файл в начало общего списка или нет |
$bReplace | bool | Если такой файл уже добавлен, то заменяет его |
{return} | bool |
Source Code: /framework/classes/modules/asset/Asset.class.php#99 (show)
protected function Add($sFile, $aParams, $sType, $bPrepend = false, $bReplace = false)
{
if (!$this->CheckAssetType($sType)) {
return false;
}
$aParams['file'] = $sFile;
/**
* Подготавливаем параметры
*/
$aParams = $this->PrepareParams($aParams);
/**
* В качестве уникального ключа использется имя или путь до файла
*/
$sFileKey = $aParams['name'] ? $aParams['name'] : $aParams['file'];
/**
* Проверям на необходимость замены
*/
if (isset($this->aAssets[$sType]['prepend'][$sFileKey])) {
if ($bReplace) {
unset($this->aAssets[$sType]['prepend'][$sFileKey]);
} else {
return false;
}
}
if (isset($this->aAssets[$sType]['append'][$sFileKey])) {
if ($bReplace) {
unset($this->aAssets[$sType]['append'][$sFileKey]);
} else {
return false;
}
}
$this->aAssets[$sType][$bPrepend ? 'prepend' : 'append'][$sFileKey] = $aParams;
return true;
}
Добавляет новый файл
AddCss()
method
public bool AddCss(string $sFile, array $aParams, bool $bPrepend=false, bool $bReplace=false)
| ||
$sFile | string | Полный путь до файла |
$aParams | array | Дополнительные параметры |
$bPrepend | bool | Добавлять файл в начало общего списка или нет |
$bReplace | bool | Если такой файл уже добавлен, то заменяет его |
{return} | bool |
Source Code: /framework/classes/modules/asset/Asset.class.php#144 (show)
public function AddCss($sFile, $aParams, $bPrepend = false, $bReplace = false)
{
return $this->Add($sFile, $aParams, self::ASSET_TYPE_CSS, $bPrepend, $bReplace);
}
Добавляет файл css стиля
AddJs()
method
public bool AddJs(string $sFile, array $aParams, bool $bPrepend=false, bool $bReplace=false)
| ||
$sFile | string | Полный путь до файла |
$aParams | array | Дополнительные параметры |
$bPrepend | bool | Добавлять файл в начало общего списка или нет |
$bReplace | bool | Если такой файл уже добавлен, то заменяет его |
{return} | bool |
Source Code: /framework/classes/modules/asset/Asset.class.php#159 (show)
public function AddJs($sFile, $aParams, $bPrepend = false, $bReplace = false)
{
return $this->Add($sFile, $aParams, self::ASSET_TYPE_JS, $bPrepend, $bReplace);
}
Добавляет файл js скрипта
BuildHeadItems()
method
public array BuildHeadItems()
| ||
{return} | array | Список HTML оберток подключения файлов |
Source Code: /framework/classes/modules/asset/Asset.class.php#282 (show)
public function BuildHeadItems()
{
/**
* Запускаем обработку
*/
$aAssets = $this->Processing();
$aHeader = array_combine(array_keys($this->aAssets), array('', ''));
foreach ($aAssets as $sType => $aFile) {
if ($oType = $this->CreateObjectType($sType)) {
foreach ($aFile as $aParams) {
$aHeader[$sType] .= $oType->getHeadHtml($aParams['file'], $aParams) . PHP_EOL;
}
}
}
return $aHeader;
}
Возвращает HTML код подключения файлов в HEAD'ер страницы
CheckAssetType()
method
public bool CheckAssetType($sType $sType)
| ||
$sType | $sType | |
{return} | bool |
Source Code: /framework/classes/modules/asset/Asset.class.php#171 (show)
public function CheckAssetType($sType)
{
return in_array($sType, array(self::ASSET_TYPE_CSS, self::ASSET_TYPE_JS));
}
Проверяет корректность типа файла
CreateObjectType()
method
public bool|ModuleAsset_EntityType CreateObjectType(string $sType)
| ||
$sType | string | |
{return} | bool|ModuleAsset_EntityType |
Source Code: /framework/classes/modules/asset/Asset.class.php#498 (show)
public function CreateObjectType($sType)
{
/**
* Формируем имя класса для типа
*/
$sClass = "ModuleAsset_EntityType" . func_camelize($sType);
if (class_exists(Engine::GetEntityClass($sClass))) {
return Engine::GetEntity($sClass);
}
return false;
}
Создает и возврашает объект типа
GetFileWeb()
method
public string GetFileWeb(string $sFile, array $aParams=array (
))
| ||
$sFile | string | Исходный путь до файла, обычно он задается в конфиге при подключении css/js, либо через методы Asset_Add* |
$aParams | array | |
{return} | string |
Source Code: /framework/classes/modules/asset/Asset.class.php#208 (show)
public function GetFileWeb($sFile, $aParams = array())
{
return $this->NormalizeFilePath($sFile, $aParams);
}
Возвращает корректный WEB путь до файла
GetRealpath()
method
public void GetRealpath($sPath)
| ||
$sPath |
Source Code: /framework/classes/modules/asset/Asset.class.php#510 (show)
public function GetRealpath($sPath)
{
if (preg_match("@^(http|https):@", $sPath)) {
$aUrl = parse_url($sPath);
$sPath = $aUrl['path'];
$aParts = array();
$sPath = preg_replace('~/\./~', '/', $sPath);
foreach (explode('/', preg_replace('~/+~', '/', $sPath)) as $sPart) {
if ($sPart === "..") {
array_pop($aParts);
} elseif ($sPart != "") {
$aParts[] = $sPart;
}
}
return ((array_key_exists('scheme',
$aUrl)) ? $aUrl['scheme'] . '://' . $aUrl['host'] : "") . "/" . implode("/", $aParts);
} else {
return realpath($sPath);
}
}
Init()
method
public void Init()
|
Source Code: /framework/classes/modules/asset/Asset.class.php#56 (show)
public function Init()
{
/**
* Задаем начальную структуру для хранения списка файлов по типам
*/
$this->InitAssets();
}
Инициалищация модуля
InitAssets()
method
protected void InitAssets()
|
Source Code: /framework/classes/modules/asset/Asset.class.php#67 (show)
protected function InitAssets()
{
$this->aAssets = array(
self::ASSET_TYPE_CSS => array(
/**
* Список файлов для добавления в конец списка
* В качестве ключей используется путь до файла либо уникальное имя, в качестве значений - дополнительные параметры
*/
'append' => array(),
/**
* Список файлов для добавления в начало списка
*/
'prepend' => array(),
),
self::ASSET_TYPE_JS => array(
'append' => array(),
'prepend' => array(),
),
);
}
Задает начальную структуры для хранения списка файлов по типам
IsLockMerge()
method
protected bool IsLockMerge()
| ||
{return} | bool |
Source Code: /framework/classes/modules/asset/Asset.class.php#404 (show)
protected function IsLockMerge()
{
$sFile = Config::Get('path.tmp.server') . '/asset.merge.lock';
$this->hDescriptorMergeLock = @fopen($sFile, 'a');
return $this->Fs_IsLock($this->hDescriptorMergeLock);
}
Проверяет на блокировку Если нет блокировки, то создает ее
Merge()
method
protected string Merge($aAssetItems $aAssetItems, $sType $sType, bool $bCompress=false)
| ||
$aAssetItems | $aAssetItems | |
$sType | $sType | |
$bCompress | bool | |
{return} | string | Web путь до нового файла |
Source Code: /framework/classes/modules/asset/Asset.class.php#431 (show)
protected function Merge($aAssetItems, $sType, $bCompress = false)
{
$sCacheDir = Config::Get('path.cache_assets.server') . "/" . Config::Get('view.skin');
$sCacheFile = $sCacheDir . "/" . md5(serialize(array_keys($aAssetItems)) . '_head') . '.' . $sType;
/**
* Если файла еще нет, то создаем его
* Но только в том случае, если еще другой процесс не начал его создавать - проверка на блокировку
*/
if (!file_exists($sCacheFile) and !$this->IsLockMerge()) {
/**
* Создаем директорию для кеша текущего скина,
* если таковая отсутствует
*/
if (!is_dir($sCacheDir)) {
@mkdir($sCacheDir, 0777, true);
}
$sContent = '';
foreach ($aAssetItems as $sFile => $aParams) {
if (strpos($sFile, '//') === 0) {
/**
* Добавляем текущий протокол
*/
$sFile = (Router::GetIsSecureConnection() ? 'https' : 'http') . ':' . $sFile;
}
$sFile = $this->Fs_GetPathServerFromWeb($sFile);
/**
* Считываем содержимое файла
*/
if ($sFileContent = @file_get_contents($sFile)) {
/**
* Создаем объект
*/
if ($oType = $this->CreateObjectType($sType)) {
$oType->setContent($sFileContent);
$oType->setFile($sFile);
unset($sFileContent);
$oType->prepare();
if ($bCompress and (!isset($aParams['compress']) or $aParams['compress'])) {
$oType->compress();
}
$sContent .= $oType->getContent();
unset($oType);
} else {
$sContent .= $sFileContent;
}
}
}
/**
* Создаем файл и сливаем туда содержимое
*/
@file_put_contents($sCacheFile, $sContent);
@chmod($sCacheFile, 0766);
/**
* Удаляем блокировку
*/
$this->RemoveLockMerge();
}
return $this->Fs_GetPathWebFromServer($sCacheFile);
}
Производит объединение и сжатие файлов
NormalizeFilePath()
method
protected string NormalizeFilePath($sFile $sFile, array $aParams=array (
))
| ||
$sFile | $sFile | |
$aParams | array | |
{return} | string |
Source Code: /framework/classes/modules/asset/Asset.class.php#221 (show)
protected function NormalizeFilePath($sFile, $aParams = array())
{
/**
* По дефолту считаем, что это локальный абсолютный путь до файла: /var/www/site.com или c:\server\root\site.com
*/
$sProtocol = '';
$sPath = $sFile;
$sSeparate = DIRECTORY_SEPARATOR;
/**
* Проверяем на URL https://site.com или http://site.com
*/
if (preg_match('#^(https?://)(.*)#i', $sFile, $aMatch)) {
$sProtocol = $aMatch[1];
$sPath = $aMatch[2];
$sSeparate = '/';
/**
* Если необходимо, то меняем протокол на https
*/
if (Router::GetIsSecureConnection() and strtolower($sProtocol) == 'http://' and Config::Get('module.asset.force_https')) {
$sProtocol = 'https://';
}
/**
* Проверяем на //site.com
*/
} elseif (strpos($sFile, '//') === 0) {
$sProtocol = '//';
$sPath = substr($sFile, 2);
$sSeparate = '/';
/**
* Проверяем на относительный путь без протокола и без первого слеша
*/
} elseif (preg_match('#^[a-z0-9\_]#i', $sFile)) {
/**
* Считаем, что указывался путь относительно корня текущего шаблона
*/
$sSeparate = '/';
if (isset($aParams['plugin']) and $aParams['plugin']) {
/**
* Относительно шаблона плагина
*/
$sPath = Plugin::GetTemplateWebPath($aParams['plugin']) . $sFile;
} else {
$sPath = Router::GetFixPathWeb(Config::Get('path.skin.web')) . $sSeparate . $sFile;
}
return $sPath;
}
/**
* Могут встречаться двойные слеши, поэтому делаем замену
*/
$sPath = preg_replace("#([\\\/])+#", $sSeparate, $sPath);
/**
* Возвращаем результат
*/
return $sProtocol . $sPath;
}
Приводит путь до файла к единому виду
PrepareParams()
method
public array PrepareParams($aParams $aParams)
| ||
$aParams | $aParams | |
{return} | array |
Source Code: /framework/classes/modules/asset/Asset.class.php#183 (show)
public function PrepareParams($aParams)
{
$aResult = array();
$aResult['merge'] = (isset($aParams['merge']) and !$aParams['merge']) ? false : true;
$aResult['compress'] = (isset($aParams['compress']) and !$aParams['compress']) ? false : true;
$aResult['browser'] = (isset($aParams['browser']) and $aParams['browser']) ? $aParams['browser'] : null;
$aResult['plugin'] = (isset($aParams['plugin']) and $aParams['plugin']) ? $aParams['plugin'] : null;
$aResult['name'] = (isset($aParams['name']) and $aParams['name']) ? strtolower($aParams['name']) : null;
if (isset($aParams['file'])) {
$aResult['file'] = $this->GetFileWeb($aParams['file'], $aParams);
} else {
$aResult['file'] = null;
}
return $aResult;
}
Производит предварительную обработку параметров
Processing()
method
public array Processing()
| ||
{return} | array | Возвращает список результирующих файлов вида array( 'css'=>array( 'name'=>$aParams, ... ), ... ) |
Source Code: /framework/classes/modules/asset/Asset.class.php#305 (show)
public function Processing()
{
$aTypes = array_keys($this->aAssets);
$aFilesMain = $aResult = array_combine($aTypes, array_pad(array(), count($aTypes), array()));
/**
* Сначала добавляем файлы из конфига
*/
$aConfigAssets = (array)Config::Get('head.default');
foreach ($aConfigAssets as $sType => $aAssets) {
if (!$this->CheckAssetType($sType)) {
continue;
}
/**
* Перебираем файлы
*/
foreach ($aAssets as $sFile => $aParams) {
if (is_numeric($sFile)) {
$sFile = $aParams;
$aParams = array();
}
$aParams['file'] = $sFile;
/**
* Подготавливаем параметры
*/
$aParams = $this->PrepareParams($aParams);
/**
* В качестве уникального ключа использется имя или путь до файла
*/
$sFileKey = $aParams['name'] ? $aParams['name'] : $aParams['file'];
$aFilesMain[$sType][$sFileKey] = $aParams;
}
}
foreach ($aTypes as $sType) {
/**
* Объединяем списки
*/
$aFilesMain[$sType] = array_merge(
$this->aAssets[$sType]['prepend'],
$aFilesMain[$sType],
$this->aAssets[$sType]['append']
);
/**
* Выделяем файлы для конкретных браузеров
*/
$aFilesBrowser = array_filter(
$aFilesMain[$sType],
function ($aParams) {
return $aParams['browser'] ? true : false;
}
);
/**
* Исключаем файлы из основного списка
*/
$aFilesMain[$sType] = array_diff_key($aFilesMain[$sType], $aFilesBrowser);
/**
* Если необходимо сливать файлы, то выделяем исключения
*/
$aFilesNoMerge = array();
if (Config::Get("module.asset.{$sType}.merge")) {
$aFilesNoMerge = array_filter(
$aFilesMain[$sType],
function ($aParams) {
return !$aParams['merge'];
}
);
/**
* Исключаем файлы из основного списка
*/
$aFilesMain[$sType] = array_diff_key($aFilesMain[$sType], $aFilesNoMerge);
}
/**
* Обрабатываем основной список
*/
if (Config::Get("module.asset.{$sType}.merge")) {
$sFilePath = $this->Merge($aFilesMain[$sType], $sType,
(bool)Config::Get("module.asset.{$sType}.compress"));
$aResult[$sType][$sFilePath] = array('file' => $sFilePath);
} else {
$aResult[$sType] = array_merge($aResult[$sType], $aFilesMain[$sType]);
}
/**
* Обрабатываем список исключения объединения
*/
$aResult[$sType] = array_merge($aResult[$sType], $aFilesNoMerge);
/**
* Обрабатываем список для отдельных браузеров
*/
$aResult[$sType] = array_merge($aResult[$sType], $aFilesBrowser);
}
return $aResult;
}
Производит обработку файлов
RemoveLockMerge()
method
protected void RemoveLockMerge()
|
Source Code: /framework/classes/modules/asset/Asset.class.php#414 (show)
protected function RemoveLockMerge()
{
if ($this->hDescriptorMergeLock) {
$this->Fs_RemoveLock($this->hDescriptorMergeLock);
$this->hDescriptorMergeLock = null;
}
}
Удаляет блокировку
Shutdown()
method
public void Shutdown()
|
Source Code: /framework/classes/modules/asset/Asset.class.php#532 (show)
public function Shutdown()
{
/**
* Удаляем блокировку
*/
$this->RemoveLockMerge();
}