/** * Deletes one cache directory. Works no longer than etime. * * @param integer $etime Timestamp when to stop working. * @param boolean $ar Record from b_cache_tag. * * @return void */ protected function deleteOneDir($etime = 0, $ar = false) { $deleteFromQueue = false; $dirName = Main\Loader::getDocumentRoot() . $ar["RELATIVE_PATH"]; if ($ar["RELATIVE_PATH"] != '' && file_exists($dirName)) { $dh = opendir($dirName); if (is_resource($dh)) { $counter = 0; while (($file = readdir($dh)) !== false) { if ($file != "." && $file != "..") { DeleteDirFilesEx($ar["RELATIVE_PATH"] . "/" . $file); $counter++; if (time() > $etime) { break; } } } closedir($dh); if ($counter == 0) { rmdir($dirName); $deleteFromQueue = true; } } } else { $deleteFromQueue = true; } if ($deleteFromQueue) { $con = Main\Application::getConnection(); $con->queryExecute("DELETE FROM b_cache_tag\n\t\t\t\tWHERE SITE_ID = '" . $con->getSqlHelper()->forSql($ar["SITE_ID"]) . "'\n\t\t\t\tAND CACHE_SALT = '" . $con->getSqlHelper()->forSql($ar["CACHE_SALT"]) . "'\n\t\t\t\tAND RELATIVE_PATH = '" . $con->getSqlHelper()->forSql($ar["RELATIVE_PATH"]) . "'"); } }
/** * @param array $arFile * @param bool $unique * @param string $prefix * @param string $setName * @param string $type * @return array */ private function optimizeAsset($arFile = array(), $unique = false, $prefix = 'default', $setName = '', $type = 'css') { if (!is_array($arFile) || empty($arFile)) { return array('RESULT' => '', 'FILES' => array()); } $this->setTemplateID(); $res = $assetMD5 = $strFiles = $contents = ''; $prefix = trim($prefix); $prefix = strlen($prefix) < 1 ? 'default' : $prefix; $add2End = strncmp($prefix, 'kernel', 6) == 0; $type = $type == 'js' ? 'js' : 'css'; $arIEContent = array(); /** @var bool $noCheckOnly when we cant frite files */ $noCheckOnly = !defined('BX_HEADFILES_CACHE_CHECK_ONLY'); $prefix = $unique ? $prefix : $prefix . '_' . $this->getAssetChecksum($arFile); $dbType = ToUpper(\Bitrix\Main\Application::getInstance()->getConnection()->getType()); $documentRoot = Main\Loader::getDocumentRoot(); $optimPath = BX_PERSONAL_ROOT . '/cache/' . $type . '/' . SITE_ID . '/' . $this->siteTemplateID . '/' . $prefix . '/'; $infoFile = $documentRoot . BX_PERSONAL_ROOT . '/managed_cache/' . $dbType . '/' . $type . '/' . SITE_ID . '/' . $this->siteTemplateID . '/' . $prefix . '/info.php'; $optimFile = $optimPath . $prefix . ($type == 'css' ? '.css' : '.js'); $optimFName = $documentRoot . $optimFile; $cssFNameIE = $optimPath . $prefix . '#CNT#.css'; $cssFPathIE = $documentRoot . $cssFNameIE; $tmpInfo = $this->isAssetChanged($arFile, $infoFile, $optimFName, $unique); $arFilesInfo = $tmpInfo['INFO']; $action = $tmpInfo['ACTION']; $arFile = $tmpInfo['FILE']; $optimFileExist = $tmpInfo['FILE_EXIST']; $writeResult = $action == 'NEW' ? false : true; if ($action != 'NO') { if ($type == 'css') { $this->fileList['CSS'][$setName]['UP_NEW_FILES'] = $tmpInfo['FILE']; } else { $this->fileList['JS'][$setName]['UP_NEW_FILES'] = $tmpInfo['FILE']; } $arFilesInfo['CUR_IE_CNT'] = intval($arFilesInfo['CUR_IE_CNT']); $arFilesInfo['CUR_SEL_CNT'] = intval($arFilesInfo['CUR_SEL_CNT']); if ($action == 'UP') { if ($noCheckOnly) { $contents .= file_get_contents($optimFName); if ($type == 'css') { if ($arFilesInfo['CUR_SEL_CNT'] < self::MAX_ADD_CSS_SELECTOR) { $css = str_replace('#CNT#', $arFilesInfo['CUR_IE_CNT'], $cssFPathIE); if (file_exists($css)) { $arIEContent[$arFilesInfo['CUR_IE_CNT']] .= file_get_contents($css); $arFilesInfo['CUR_SEL_CNT'] = $this->getCssSelectCnt($arIEContent[$arFilesInfo['CUR_IE_CNT']]); } } else { $arFilesInfo['CUR_IE_CNT']++; $arFilesInfo['CUR_SEL_CNT'] = 0; } } } else { $writeResult = false; } } $needWrite = false; if ($noCheckOnly) { $tmpStr = ''; foreach ($arFile as $file) { $tmpContent = file_get_contents($file['FILE_PATH']); if ($type == 'css') { $f_cnt = $this->getCssSelectCnt($tmpContent); $new_cnt = $f_cnt + $arFilesInfo['CUR_SEL_CNT']; $strFiles .= "/* " . $file['PATH'] . " */\n"; $tmpContent = $this->fixCSSIncludes($tmpContent, $file['PATH']); $tmpContent = "\n/* Start:" . $file['PATH'] . "*/\n" . $tmpContent . "\n/* End */\n"; if ($new_cnt < self::MAX_CSS_SELECTOR) { $arFilesInfo['CUR_SEL_CNT'] = $new_cnt; $arIEContent[$arFilesInfo['CUR_IE_CNT']] .= $tmpContent; } else { $arFilesInfo['CUR_SEL_CNT'] = $f_cnt; $arFilesInfo['CUR_IE_CNT']++; $arIEContent[$arFilesInfo['CUR_IE_CNT']] .= $tmpContent; } $tmpStr .= "\n\n" . $tmpContent; } else { $strFiles .= "; /* " . $file['PATH'] . "*/\n"; $tmpStr .= "\n; /* Start:" . $file['PATH'] . "*/\n" . $tmpContent . "\n/* End */\n;"; } $arFilesInfo['FILES'][$file['PATH']] = $this->getAssetTime($file['FULL_PATH']); $needWrite = true; } if ($needWrite) { // Write packed files and meta information $contents = $add2End ? $strFiles . $contents . $tmpStr : $tmpStr . $contents . $strFiles; if ($writeResult = $this->write($optimFName, $contents)) { $cacheInfo = '<? $arFilesInfo = array( \'FILES\' => array('; foreach ($arFilesInfo['FILES'] as $key => $time) { $cacheInfo .= '"' . EscapePHPString($key) . '" => "' . $time . '",'; } $cacheInfo .= "), 'CUR_SEL_CNT' => '" . $arFilesInfo['CUR_SEL_CNT'] . "', 'CUR_IE_CNT' => '" . $arFilesInfo['CUR_IE_CNT'] . "'); ?>"; $this->write($infoFile, $cacheInfo, false); if ($type == 'css') { foreach ($arIEContent as $key => $ieContent) { $css = str_replace('#CNT#', $key, $cssFPathIE); $this->write($css, $ieContent); } } } } elseif ($optimFileExist) { $writeResult = true; } unset($contents, $arIEContent); } } $label = $prefix == 'template' || substr($prefix, 0, 9) == 'template_' ? ' data-template-style="true" ' : ''; if ($type == 'css' && $this->isIE && $writeResult) { for ($i = 0; $i <= $arFilesInfo['CUR_IE_CNT']; $i++) { $css = \CUtil::GetAdditionalFileURL(str_replace('#CNT#', $i, $cssFNameIE)); $res .= '<link href="' . $this->cssDomain . $css . '" type="text/css" ' . ($i == 0 ? $label : '') . ' rel="stylesheet"' . ($this->xhtmlStyle ? ' /' : '') . '>' . "\n"; $this->fileList['CSS'][$setName]['FILES'][] = $this->cssDomain . $css; } } else { if ($type == 'css') { if ($writeResult || !$writeResult && $unique && $action == 'UP') { $css = \CUtil::GetAdditionalFileURL($optimFile); $res .= '<link href="' . $this->cssDomain . $css . '" type="text/css" ' . $label . ' rel="stylesheet"' . ($this->xhtmlStyle ? ' /' : '') . '>' . "\n"; $this->fileList['CSS'][$setName]['FILES'][] = $this->cssDomain . $css; } if (!$writeResult) { if ($this->isIE) { $cnt = 0; $resContent = ''; $ruleCount = 0; foreach ($arFile as $file) { if ($cnt < $this->maxStylesCnt) { $res .= '<link href="' . $this->cssDomain . $file['FULL_PATH'] . '" ' . ($cnt == 0 ? $label : '') . ' type="text/css" rel="stylesheet"' . ($this->xhtmlStyle ? ' /' : '') . '>' . "\n"; $this->fileList['CSS'][$setName]['FILES'][] = $this->cssDomain . $file['FULL_PATH']; } else { $tmpInfo = $this->showInlineCssIE($file['FILE_PATH'], $file['FULL_PATH'], $ruleCount, true); $ruleCount = $tmpInfo['CNT']; $resContent .= $tmpInfo['CONTENT']; } $cnt++; } if ($resContent != '') { $res .= '<style type="text/css">' . "\n" . $resContent . "\n</style>\n"; } } else { foreach ($arFile as $file) { $res .= '<link href="' . $this->cssDomain . $file['FULL_PATH'] . '" type="text/css" ' . $label . ' rel="stylesheet"' . ($this->xhtmlStyle ? ' /' : '') . '>' . "\n"; $this->fileList['CSS'][$setName]['FILES'][] = $this->jsDomain . $file['FULL_PATH']; } } } } else { if ($writeResult || !$writeResult && $unique && $action == 'UP') { $js = \CUtil::GetAdditionalFileURL($optimFile); $res .= '<script type="text/javascript" src="' . $this->jsDomain . $js . '"></script>' . "\n"; $this->fileList['JS'][$setName]['FILES'][] = $this->jsDomain . $js; } if (!$writeResult) { foreach ($arFile as $file) { $res .= '<script type="text/javascript" src="' . $this->jsDomain . $file['FULL_PATH'] . '"></script>' . "\n"; $this->fileList['JS'][$setName]['FILES'][] = $this->jsDomain . $file['FULL_PATH']; } } } } $arF = array(); foreach ($arFilesInfo['FILES'] as $key => $time) { $arF[] = str_replace($documentRoot, '', $key) . '?' . $time; } unset($arFile, $arFilesInfo); return array('RESULT' => $res, 'FILES' => $arF); }
/** * Returns server document root. * * @return null|string */ public static function getDocumentRoot() { static $documentRoot = null; if ($documentRoot != null) { return $documentRoot; } $context = Application::getInstance()->getContext(); if ($context != null) { $server = $context->getServer(); if ($server != null) { return $documentRoot = $server->getDocumentRoot(); } } return Loader::getDocumentRoot(); }
private function getPath($path) { $path = Main\Loader::getDocumentRoot() . $path; return preg_replace("'[\\\\/]+'", "/", $path); }
/** * Generates source map content * @param $fileName * @param $content * @return string */ private static function generateSourceMap($fileName, $content) { $files = self::getFilesInfo($content); $sections = ""; foreach ($files as $file) { if (!isset($file["map"]) || strlen($file["map"]) < 1) { continue; } $filePath = Main\Loader::getDocumentRoot() . $file["map"]; if (file_exists($filePath) && ($content = file_get_contents($filePath)) !== false) { if ($sections !== "") { $sections .= ","; } $dirPath = IO\Path::getDirectory($file["source"]); $sourceName = IO\Path::getName($file["source"]); $minName = IO\Path::getName($file["min"]); $sourceMap = str_replace(array($sourceName, $minName), array($dirPath . "/" . $sourceName, $dirPath . "/" . $minName), $content); $sections .= '{"offset": { "line": ' . $file["line"] . ', "column": 0 }, "map": ' . $sourceMap . '}'; } } return '{"version":3, "file":"' . $fileName . '", "sections": [' . $sections . ']}'; }
/** * @param string $lang This variable is the value language. * @param bool $systemProcesses Installing the system processes. * @param string $path This variable is the path to the file to get the data. * @param array $fileData Array for loading the data. * @throws Main\ArgumentNullException * @throws Main\IO\FileNotFoundException */ public static function loadDataProcesses($lang, $systemProcesses = true, &$fileData, $path = null) { if (empty($lang)) { throw new Main\ArgumentNullException("lang"); } if (!empty($path)) { $path = $path . "/"; } else { if ($systemProcesses) { $path = Main\Loader::getDocumentRoot() . static::PATH . $lang . "/"; } else { $path = Main\Loader::getDocumentRoot() . static::PATH_USER_PROCESSES . $lang . "/"; } } $dir = new Main\IO\Directory($path); if ($dir->isExists()) { $children = $dir->getChildren(); foreach ($children as $key => $child) { /** @var Main\IO\File $child */ if ($child->isFile() && $child->getExtension() == "prc") { $data = self::getDataProcess($path . $child->getName()); $fileData[$data['CODE']]['FILE_NAME'] = $child->getName(); $fileData[$data['CODE']]['FILE_PATH'] = str_replace(Main\Loader::getDocumentRoot(), '', $child->getPath()); $fileData[$data['CODE']]['NAME'] = $data['NAME']; $fileData[$data['CODE']]['DESCRIPTION'] = $data['DESCRIPTION']; $fileData[$data['CODE']]['CODE'] = $data['CODE']; $fileData[$data['CODE']]['IBLOCK_TYPE_ID'] = $data['IBLOCK_TYPE_ID']; $fileData[$data['CODE']]['DIRECTORY_NAME'] = $child->getDirectory()->getName(); } elseif ($child->isDirectory()) { self::loadDataProcesses($lang, $systemProcesses, $fileData, $child->getPath()); } } } }