3namespace Bitrix\Main\Page;
7use Bitrix\Main\Config\Option;
8use Bitrix\Main\Web\Json;
28 AssetLocation::BEFORE_CSS => [],
29 AssetLocation::AFTER_CSS => [],
30 AssetLocation::AFTER_JS_KERNEL => [],
31 AssetLocation::AFTER_JS => [],
35 private $moduleInfo = [
'CSS' => [],
'JS' => []];
36 private $kernelAsset = [
'CSS' => [],
'JS' => []];
37 private $assetList = [
'CSS' => [],
'SOURCE_CSS' => [],
'JS' => [],
'SOURCE_JS' => []];
38 private $fileList = [
'CSS' => [],
'JS' => []];
39 private $mode = AssetMode::STANDARD;
42 private $xhtmlStyle =
'/';
44 private $optimizeCss =
true;
45 private $optimizeJs =
true;
47 private $headString =
false;
48 private $headScript =
false;
49 private $bodyScript =
false;
50 private $moveJsToBody =
null;
52 private $templateExists =
false;
53 private $siteTemplateID =
'';
54 private $templatePath =
'';
57 private $assetCSSCnt = 0;
58 private $assetJSCnt = 0;
60 const SOURCE_MAP_TAG =
"\n//# sourceMappingURL=";
61 const HEADER_START_TAG =
"; /* Start:\"";
62 const HEADER_END_TAG =
"\"*/";
68 $this->targetList[
'KERNEL'] = [
79 'MODE' => AssetMode::ALL
82 $this->targetList[
'BODY'] = $this->targetList[
'TEMPLATE'] = $this->targetList[
'PAGE'] = $this->targetList[
'KERNEL'];
83 $this->targetList[
'PAGE'][
'NAME'] =
'PAGE';
84 $this->targetList[
'PAGE'][
'UNIQUE'] =
false;
85 $this->targetList[
'PAGE'][
'PREFIX'] =
'page';
86 $this->targetList[
'TEMPLATE'][
'NAME'] =
'TEMPLATE';
87 $this->targetList[
'TEMPLATE'][
'UNIQUE'] =
false;
88 $this->targetList[
'TEMPLATE'][
'PREFIX'] =
'template';
89 $this->targetList[
'BODY'][
'NAME'] =
'BODY';
90 $this->targetList[
'BODY'][
'UNIQUE'] =
false;
91 $this->targetList[
'BODY'][
'PREFIX'] =
'body';
94 $this->targetList[
'KERNEL'][
'CSS_LIST'][
'KERNEL_main'] = [];
95 $this->targetList[
'KERNEL'][
'JS_LIST'][
'KERNEL_main'] = [];
97 $this->target = &$this->targetList[
'TEMPLATE'];
98 $this->documentRoot = Main\Loader::getDocumentRoot();
115 public static function getInstance()
117 if (is_null(self::$instance))
119 self::$instance =
new Asset();
122 return self::$instance;
130 public function setMode($mode = AssetMode::STANDARD)
139 public static function gzipEnabled()
145 Option::get(
'main',
'compres_css_js_files',
'N') ==
'Y'
146 && extension_loaded(
'zlib')
147 && function_exists(
'gzopen')
157 public function enableOptimizeCss()
159 $this->optimizeCss =
true;
166 public function disableOptimizeCss()
168 $this->optimizeCss =
false;
175 public function enableOptimizeJs()
177 $this->optimizeJs =
true;
184 public function disableOptimizeJs()
186 $this->optimizeJs =
false;
193 public function setXhtml($value)
195 $this->xhtmlStyle = (
$value ===
true ?
'/':
'');
203 public function setMaxCss($value)
213 public function setShowHeadString($value =
true)
215 $this->headString =
$value;
222 public function getShowHeadString()
224 return $this->headString;
232 public function setShowHeadScript($value =
true)
234 $this->headScript =
$value;
242 public function setShowBodyScript($value =
true)
244 $this->bodyScript =
$value;
251 public function setAjax()
253 $newInstance = self::$instance =
new Asset();
254 $newInstance->ajax =
true;
261 public function getTargetName()
263 return $this->target[
'NAME'];
269 public function getTarget()
271 return $this->target;
280 public function startSet($id =
'', $mode = AssetMode::ALL)
282 return $this->startTarget($id, $mode);
291 public function startTarget($id =
'', $mode = AssetMode::ALL)
293 $id = strtoupper(trim($id));
299 if ($id ==
'TEMPLATE')
301 $this->templateExists =
true;
305 ($this->target[
'NAME'] ==
'TEMPLATE' || $this->target[
'NAME'] ==
'PAGE')
306 && ($id ==
'TEMPLATE' || $id ==
'PAGE')
309 $this->target[
'START'] =
false;
310 $this->targetList[$id][
'START'] =
true;
311 $this->target = &$this->targetList[$id];
313 elseif ($id !=
'TEMPLATE' && $id !=
'PAGE')
315 if (isset($this->targetList[$id]))
321 $this->targetList[$id] = [
333 $this->target = &$this->targetList[$id];
343 public function stopTarget($id =
'')
345 $id = strtoupper(trim($id));
346 if ($id ==
'TEMPLATE')
348 if($this->target[
'NAME'] ==
'TEMPLATE')
350 $this->target[
'START'] =
false;
351 $this->target = &$this->targetList[
'PAGE'];
355 $this->targetList[
'TEMPLATE'][
'START'] =
false;
360 if ($this->target[
'NAME'] ==
'TEMPLATE')
364 elseif ($this->targetList[
'TEMPLATE'][
'START'])
366 $this->target[
'START'] =
false;
367 $this->target = &$this->targetList[
'TEMPLATE'];
371 $this->target[
'START'] =
false;
372 $this->target = &$this->targetList[
'PAGE'];
385 public function getAssetInfo($id, $mode)
387 $id = strtoupper(trim($id));
388 $emptyData = [
'JS' => [],
'BUNDLE_JS' => [],
'CSS' => [],
'BUNDLE_CSS' => [],
'STRINGS' => []];
390 if (!isset($this->targetList[$id]))
395 static $cacheInfo = [
396 AssetMode::STANDARD =>
null,
397 AssetMode::COMPOSITE =>
null,
398 AssetMode::ALL =>
null,
399 AssetMode::SPECIAL => null
402 if ($cacheInfo[$mode] ===
null)
404 $cacheInfo[$mode] = $emptyData;
410 if ($mode == $item[
'MODE'])
412 $cacheInfo[$mode][
'STRINGS'][$item[
'TARGET'][0]][] = $item[
'CONTENT'];
417 foreach ([
'JS',
'CSS'] as
$type)
419 foreach ($this->getTargetList(
$type) as $set)
421 $cache = &$cacheInfo[$mode][
$type][$set[
'NAME']];
422 $cacheFull = &$cacheInfo[$mode][
'BUNDLE_'.$type][$set[
'NAME']];
424 if (!is_array($cache))
429 if (!is_array($cacheFull))
434 $fileList = $this->fileList[
$type][$set[
'NAME']] ?? [];
435 $targetList = $this->targetList[
'KERNEL'][
$type.
'_LIST'][$set[
'NAME']] ?? [];
438 if ($mode === $set[
'MODE'] && isset($fileList[
'FILES']))
440 $items = $fileList[
'FILES'];
442 elseif (isset($fileList[
'UP_NEW_FILES']))
444 $items = $fileList[
'UP_NEW_FILES'];
456 if (isset($fileList[
'FULL_FILES'][$item]))
458 $cacheFull = array_merge($cacheFull, $fileList[
'FULL_FILES'][$item]);
461 if ($set[
'PARENT_NAME'] ==
'KERNEL')
463 foreach ($targetList[
'WHERE_USED'] as $target =>
$tmp)
465 $cacheInfo[$mode][
$type][$target][] = $item;
467 if (isset($fileList[
'FULL_FILES'][$item]))
469 if (!isset($cacheInfo[$mode][
'BUNDLE_'.
$type][$target]))
471 $cacheInfo[$mode][
'BUNDLE_'.$type][$target] = [];
474 $cacheInfo[$mode][
'BUNDLE_'.$type][$target] = array_merge(
475 $cacheInfo[$mode][
'BUNDLE_'.
$type][$target],
476 $fileList[
'FULL_FILES'][$item]
487 'JS' => $cacheInfo[$mode][
'JS'][$id] ?? [],
488 'BUNDLE_JS' => $cacheInfo[$mode][
'BUNDLE_JS'][$id] ?? [],
489 'CSS' => $cacheInfo[$mode][
'CSS'][$id] ?? [],
490 'BUNDLE_CSS' => $cacheInfo[$mode][
'BUNDLE_CSS'][$id] ?? [],
491 'STRINGS' => $cacheInfo[$mode][
'STRINGS'][$id] ?? []
500 public function compositeTarget($id =
'')
502 $id = strtoupper(trim($id));
503 if ($id ==
'' || !isset($this->targetList[$id]))
509 $this->targetList[$id][
'MODE'] = AssetMode::COMPOSITE;
519 public function getTargetList(
$type =
'CSS')
521 static $res = [
'CSS_LIST' =>
null,
'JS_LIST' =>
null];
522 $key = (
$type ==
'CSS' ?
'CSS_LIST' :
'JS_LIST');
526 foreach ($this->targetList as $targetName => $targetInfo)
529 'NAME' => $targetName,
530 'PARENT_NAME' => $targetName,
531 'UNIQUE' => $targetInfo[
'UNIQUE'],
532 'PREFIX' => ($targetInfo[
'PREFIX'] ??
''),
533 'MODE' => $targetInfo[
'MODE'],
534 'MODULE_NAME' => ($targetInfo[
'MODULE_NAME'] ??
''),
537 if (!empty($targetInfo[
$key]))
539 foreach ($targetInfo[
$key] as $subSetName =>
$val)
542 'NAME' => $subSetName,
543 'PARENT_NAME' => $targetName,
544 'UNIQUE' => (
$val[
'UNIQUE'] ??
''),
545 'PREFIX' => (
$val[
'PREFIX'] ??
''),
546 'MODE' => (
$val[
'MODE'] ?? 0),
547 'MODULE_NAME' => (
$val[
'MODULE_NAME'] ??
''),
564 function addString(
$str, $unique =
false,
$location = AssetLocation::AFTER_JS_KERNEL, $mode =
null)
575 $this->strings[
$location][$chkSum][
'TARGET'][] = $this->getTargetName();
576 $this->strings[
$location][$chkSum][
'MODE'] = $mode;
580 $this->strings[
$location][] = [
'CONTENT' =>
$str,
'MODE' => $mode,
'TARGET' => [$this->getTargetName()]];
590 public function getStrings(
$location = AssetLocation::AFTER_JS_KERNEL)
592 static $firstExec =
true;
595 $this->prepareString();
602 $res =
"<script>if(!window.BX)window.BX={};if(!window.BX.message)window.BX.message=function(mess){if(typeof mess==='object'){for(let i in mess) {BX.message[i]=mess[i];} return true;}};</script>\n";
607 foreach ($this->strings[
$location] as $item)
609 if ($this->mode & $item[
'MODE'])
611 $res .= $item[
'CONTENT'].
"\n";
616 return (
$res ==
'') ?
'' :
$res.
"\n";
625 public function addCss(
$path, $additional =
false)
632 $css = $this->getAssetPath(
$path);
633 $this->css[$css][
'TARGET'][] = $this->getTargetName();
634 $this->css[$css][
'ADDITIONAL'] = (isset($this->css[$css][
'ADDITIONAL']) && $this->css[$css][
'ADDITIONAL'] ?
true : $additional);
644 public function addJs(
$path, $additional =
false)
651 $js = $this->getAssetPath(
$path);
652 $this->js[$js][
'TARGET'][] = $this->getTargetName();
653 $this->js[$js][
'ADDITIONAL'] = (isset($this->js[$js][
'ADDITIONAL']) && $this->js[$js][
'ADDITIONAL'] ?
true : $additional);
667 '#([;\s:]*(?:url|@import)\s*\(\s*)(\'|"|)(.+?)(\2)\s*\)#si',
676 '#(\s*@import\s*)([\'"])([^\'"]+)(\2)#si',
693 public function groupJs($from =
'', $to =
'')
695 if (empty($from) || empty($to))
700 $to = $this->movedJsTo($to);
701 if (array_key_exists($from, $this->moduleInfo[
'JS']))
703 $this->moduleInfo[
'JS'][$from][
'MODULE_ID'] = $to;
707 $this->moduleInfo[
'JS'][$from] = [
'MODULE_ID' => $to,
'FILES_INFO' =>
false,
'BODY' =>
false];
710 foreach ($this->moduleInfo[
'JS'] as
$moduleID => $moduleInfo)
712 if ($moduleInfo[
'MODULE_ID'] == $from)
714 $this->moduleInfo[
'JS'][
$moduleID][
"MODULE_ID"] = $to;
725 public function groupCss($from =
'', $to =
'')
727 if (empty($from) || empty($to))
732 $to = $this->movedCssTo($to);
733 if (array_key_exists($from, $this->moduleInfo[
'CSS']))
735 $this->moduleInfo[
'CSS'][$from][
'MODULE_ID'] = $to;
739 $this->moduleInfo[
'CSS'][$from] = [
'MODULE_ID' => $to,
'FILES_INFO' =>
false];
742 foreach ($this->moduleInfo[
'CSS'] as
$moduleID => $moduleInfo)
744 if($moduleInfo[
'MODULE_ID'] == $from)
746 $this->moduleInfo[
'CSS'][
$moduleID][
"MODULE_ID"] = $to;
755 private function movedJsTo($to)
757 if (isset($this->moduleInfo[
'JS'][$to][
'MODULE_ID']) && $this->moduleInfo[
'JS'][$to][
'MODULE_ID'] != $to)
759 $to = $this->movedJsTo($this->moduleInfo[
'JS'][$to][
'MODULE_ID']);
769 private function movedCssTo($to)
771 if (isset($this->moduleInfo[
'CSS'][$to][
'MODULE_ID']) && $this->moduleInfo[
'CSS'][$to][
'MODULE_ID'] != $to)
773 $to = $this->movedCssTo($this->moduleInfo[
'JS'][$to][
'MODULE_ID']);
784 public function moveJs($module =
'')
786 if (empty($module) || $module ===
"main")
791 if (array_key_exists($module, $this->moduleInfo[
'JS']))
793 $this->moduleInfo[
'JS'][$module][
'BODY'] =
true;
797 $this->moduleInfo[
'JS'][$module] = [
'MODULE_ID' => $module,
'FILES_INFO' =>
false,
'BODY' =>
true];
806 public function setJsToBody($flag)
808 $this->moveJsToBody = (bool)$flag;
814 protected function getJsToBody()
816 if ($this->moveJsToBody ===
null)
818 $this->moveJsToBody = Option::get(
"main",
"move_js_to_body") ===
"Y" && (!defined(
"ADMIN_SECTION") ||
ADMIN_SECTION !==
true);
820 return $this->moveJsToBody;
829 public function moveJsToBody(&
$content)
831 if (!$this->getJsToBody())
839 $areas = $this->getScriptAreas(
$content);
840 foreach ($areas as $area)
842 if (str_contains($area->attrs,
"data-skip-moving") || !self::isValidScriptType($area->attrs))
847 $js .= substr(
$content, $area->openTagStart, $area->closingTagEnd - $area->openTagStart);
848 $newContent .= substr(
$content, $offset, $area->openTagStart - $offset);
849 $offset = $area->closingTagEnd;
857 $newContent .= substr(
$content, $offset);
858 $bodyEnd = strripos($newContent,
"</body>");
859 if ($bodyEnd ===
false)
865 $content = substr_replace($newContent, $js, $bodyEnd, 0);
874 private function getScriptAreas(
$content)
876 $openTag =
"<script";
877 $closingTag =
"</script";
883 while (($openTagStart = strpos(
$content, $openTag, $offset)) !==
false)
885 $endingPos = strpos(
$content, $ending, $openTagStart);
886 if ($endingPos ===
false)
891 $attrsStart = $openTagStart + strlen($openTag);
892 $attrs = substr(
$content, $attrsStart, $endingPos - $attrsStart);
893 $openTagEnd = $endingPos + strlen($ending);
895 $realClosingTag = $closingTag.$ending;
896 $closingTagStart = strpos(
$content, $realClosingTag, $openTagEnd);
897 if ($closingTagStart ===
false)
899 $offset = $openTagEnd;
903 $closingTagEnd = $closingTagStart + strlen($realClosingTag);
904 while (isset(
$content[$closingTagEnd]) &&
$content[$closingTagEnd] ===
"\n")
909 $area = new \stdClass();
910 $area->attrs = $attrs;
911 $area->openTagStart = $openTagStart;
912 $area->openTagEnd = $openTagEnd;
913 $area->closingTagStart = $closingTagStart;
914 $area->closingTagEnd = $closingTagEnd;
917 $offset = $closingTagEnd;
926 public function canMoveJsToBody()
929 $this->getJsToBody() &&
930 !Main\Application::getInstance()->getContext()->getRequest()->isAjaxRequest() &&
931 !defined(
"BX_BUFFER_SHUTDOWN");
940 private static function isValidScriptType($attrs)
942 if ($attrs ===
"" || !preg_match(
"/type\\s*=\\s*(['\"]?)(.*?)\\1/i", $attrs, $match))
947 $type = mb_strtolower($match[2]);
948 return $type ===
"" ||
$type ===
"text/javascript" ||
$type ===
"application/javascript";
959 public static function replaceUrlCss(
$url, $quote,
$path)
962 str_contains(
$url,
"://")
963 || str_contains(
$url,
"data:")
964 || str_starts_with(
$url,
"#")
967 return $quote.$url.$quote;
970 $url = trim(stripslashes(
$url),
"'\" \r\n\t");
971 if (str_starts_with(
$url,
"/"))
973 return $quote.$url.$quote;
976 return $quote.$path.
'/'.
$url.$quote;
984 public static function getAssetPath($src)
986 if ((
$p = mb_strpos($src,
"?")) > 0 && !\CMain::IsExternalLink($src))
988 $src = mb_substr($src, 0,
$p);
996 public function optimizeCss()
998 $optimize = $this->optimizeCss
1000 && Option::get(
'main',
'optimize_css_files',
'N') ==
'Y'
1009 public function optimizeJs()
1011 $optimize = $this->optimizeJs
1013 && Option::get(
'main',
'optimize_js_files',
'N') ==
'Y'
1022 public static function canUseMinifiedAssets()
1024 static $canLoad =
null;
1025 if ($canLoad ===
null)
1027 $canLoad = Option::get(
"main",
"use_minified_assets",
"Y") ==
"Y";
1036 public function sliceKernel()
1038 return (!defined(
"ADMIN_SECTION") ||
ADMIN_SECTION !==
true);
1048 public function insertCss($css, $label =
false, $inline =
false)
1050 if ($label ===
true)
1052 $label =
' data-template-style="true" ';
1054 elseif ($label ===
false)
1061 return "<style type=\"text/css\" {$label}>\n{$css}\n</style>\n";
1065 return "<link href=\"{$css}\" type=\"text/css\" {$label} rel=\"stylesheet\" {$this->xhtmlStyle}>\n";
1076 public function insertJs($js, $label =
'', $inline =
false)
1080 return "<script {$label}>\n{$js}\n</script>\n";
1084 return "<script {$label} src=\"$js\"></script>\n";
1092 private function setTemplateID()
1094 static $firstExec =
true;
1095 if ($firstExec && !$this->ajax && (!defined(
"ADMIN_SECTION") ||
ADMIN_SECTION !==
true))
1097 if (defined(
"SITE_TEMPLATE_PREVIEW_MODE"))
1099 $this->templatePath = BX_PERSONAL_ROOT.
'/tmp/templates/__bx_preview';
1101 elseif (defined(
'SITE_TEMPLATE_ID'))
1103 $this->siteTemplateID = SITE_TEMPLATE_ID;
1104 $this->templatePath = SITE_TEMPLATE_PATH;
1108 $this->siteTemplateID =
'.default';
1109 $this->templatePath = BX_PERSONAL_ROOT.
"/templates/.default";
1119 private function addTemplateCss()
1124 && $this->templateExists
1127 $this->css[$this->templatePath .
'/styles.css'][
'TARGET'][] =
'TEMPLATE';
1128 $this->css[$this->templatePath .
'/styles.css'][
'ADDITIONAL'] =
false;
1130 $this->css[$this->templatePath .
'/template_styles.css'][
'TARGET'][] =
'TEMPLATE';
1131 $this->css[$this->templatePath .
'/template_styles.css'][
'ADDITIONAL'] =
false;
1139 private function prepareString()
1141 foreach ($this->strings as
$location => $stringLocation)
1143 foreach ($stringLocation as
$key => $item)
1146 $this->strings[
$location][
$key][
'MODE'] = ($item[
'MODE'] ===
null ? $this->targetList[$item[
'TARGET'][0]][
'MODE'] : $item[
'MODE']);
1158 private function getAssetPaths($assetPath)
1161 if (self::canUseMinifiedAssets() && preg_match(
"/(.+)\\.(js|css)$/i", $assetPath,
$matches))
1170 $filePath = $this->documentRoot.$path;
1171 if (file_exists($filePath) && ($mtime = filemtime($filePath)) > $maxMtime && filesize($filePath) > 0)
1176 "FILE_PATH" => $filePath,
1177 "FULL_PATH" => \CUtil::GetAdditionalFileURL(
$path,
true),
1193 public function getFullAssetPath($sourcePath)
1195 $result = $this->getAssetPaths($sourcePath);
1201 if (\CMain::IsExternalLink($sourcePath))
1215 private function prepareCss() : void
1219 foreach ($this->css as $css => $set)
1222 $assetTID = $set[
'ADDITIONAL'] ?
'TEMPLATE' : $set[
'TARGET'][0];
1225 'FULL_PATH' =>
false,
1226 'FILE_PATH' =>
false,
1228 'TARGET' => $assetTID,
1229 'EXTERNAL' => \CMain::IsExternalLink($css),
1230 'ADDITIONAL' => $set[
'ADDITIONAL']
1233 if ($cssInfo[
'EXTERNAL'])
1235 if ($set[
'ADDITIONAL'])
1237 $tmpKey =
'TEMPLATE';
1238 $tmpPrefix =
'template';
1243 $tmpPrefix =
'kernel';
1246 $cssInfo[
'MODULE_ID'] = $this->assetCSSCnt;
1247 $cssInfo[
'TARGET'] = $tmpKey.
'_'.$this->assetCSSCnt;
1248 $cssInfo[
'PREFIX'] = $tmpPrefix.
'_'.$this->assetCSSCnt;
1249 $cssInfo[
'FULL_PATH'] = $cssInfo[
'PATH'];
1250 $cssInfo[
'SKIP'] =
true;
1251 $this->assetCSSCnt++;
1253 $this->targetList[$tmpKey][
'CSS_LIST'][$cssInfo[
'TARGET']] = [
1254 'TARGET' => $cssInfo[
'TARGET'],
1255 'PREFIX' => $cssInfo[
'PREFIX'],
1256 'MODE' => $this->targetList[$assetTID][
'MODE'],
1263 if ((
$paths = $this->getAssetPaths($css)) !==
null)
1265 $cssInfo[
"PATH"] = $css;
1266 $cssInfo[
"FILE_PATH"] =
$paths[
"FILE_PATH"];
1267 $cssInfo[
"FULL_PATH"] =
$paths[
"FULL_PATH"];
1271 unset($this->css[$css]);
1275 $moduleInfo = $this->isKernelCSS($cssInfo[
'PATH']);
1278 if ($this->sliceKernel() && $this->optimizeCss() && is_array($moduleInfo))
1280 $cssInfo[
'MODULE_ID'] = $moduleInfo[
'MODULE_ID'];
1281 $cssInfo[
'TARGET'] =
'KERNEL_'.$moduleInfo[
'MODULE_ID'];
1282 $cssInfo[
'PREFIX'] =
'kernel_'.$moduleInfo[
'MODULE_ID'];
1283 $cssInfo[
'SKIP'] = $moduleInfo[
'SKIP'] ??
false;
1287 $cssInfo[
'MODULE_ID'] = $this->assetCSSCnt;
1288 $cssInfo[
'TARGET'] =
'KERNEL_'.$this->assetCSSCnt;
1289 $cssInfo[
'PREFIX'] =
'kernel_'.$this->assetCSSCnt;
1290 $cssInfo[
'SKIP'] =
true;
1291 $this->assetCSSCnt++;
1294 if (isset($this->targetList[
'KERNEL'][
'CSS_LIST'][$cssInfo[
'TARGET']][
'MODE']))
1296 $this->targetList[
'KERNEL'][
'CSS_LIST'][$cssInfo[
'TARGET']][
'MODE'] |= $this->targetList[$assetTID][
'MODE'];
1300 $this->targetList[
'KERNEL'][
'CSS_LIST'][$cssInfo[
'TARGET']] = [
1301 'TARGET' => $cssInfo[
'TARGET'],
1302 'PREFIX' => $cssInfo[
'PREFIX'],
1303 'MODE' => $set[
'ADDITIONAL'] ? $this->targetList[$set[
'TARGET'][0]][
'MODE'] : $this->targetList[$assetTID][
'MODE'],
1309 if (is_array($moduleInfo))
1311 $this->targetList[
'KERNEL'][
'CSS_LIST'][$cssInfo[
'TARGET']][
'MODULE_NAME'] = $moduleInfo[
'MODULE_ID'];
1315 foreach ($set[
'TARGET'] as $setID)
1317 $this->targetList[
'KERNEL'][
'CSS_LIST'][$cssInfo[
'TARGET']][
'WHERE_USED'][$setID] =
true;
1320 elseif (strncmp($cssInfo[
'PATH'],
'/bitrix/js/', 11) != 0 )
1322 $cssInfo[
'SKIP'] = !(
1323 strncmp($cssInfo[
'PATH'],
'/bitrix/panel/', 14) != 0
1324 && strncmp($cssInfo[
'PATH'],
'/bitrix/themes/', 15) != 0
1325 && strncmp($cssInfo[
'PATH'],
'/bitrix/modules/', 16) != 0
1330 if ($cssInfo[
'ADDITIONAL'])
1332 $additional[] = $cssInfo;
1336 $this->css[$cssInfo[
'TARGET']][] = $cssInfo;
1339 unset($this->css[$css]);
1342 foreach ($additional as $cssInfo)
1344 $this->css[$cssInfo[
'TARGET']][] = $cssInfo;
1354 private function prepareJs()
1357 foreach ($this->js as $js => $set)
1360 $assetTID = $set[
'ADDITIONAL'] ?
'TEMPLATE' : $set[
'TARGET'][0];
1363 'FULL_PATH' =>
false,
1364 'FILE_PATH' =>
false,
1366 'TARGET' => $assetTID,
1367 'EXTERNAL' => \CMain::IsExternalLink($js),
1369 'ADDITIONAL' => $set[
'ADDITIONAL']
1372 if ($jsInfo[
'EXTERNAL'])
1374 if ($set[
'ADDITIONAL'])
1376 $tmpKey =
'TEMPLATE';
1377 $tmpPrefix =
'template';
1382 $tmpPrefix =
'kernel';
1385 $jsInfo[
'MODULE_ID'] = $this->assetJSCnt;
1386 $jsInfo[
'TARGET'] = $tmpKey.
'_'.$this->assetJSCnt;
1387 $jsInfo[
'PREFIX'] = $tmpPrefix.
'_'.$this->assetJSCnt;
1388 $jsInfo[
'FULL_PATH'] = $jsInfo[
'PATH'];
1389 $jsInfo[
'SKIP'] =
true;
1390 $this->assetJSCnt++;
1392 $this->targetList[$tmpKey][
'JS_LIST'][$jsInfo[
'TARGET']] = [
1393 'TARGET' => $jsInfo[
'TARGET'],
1394 'PREFIX' => $jsInfo[
'PREFIX'],
1395 'MODE' => $this->targetList[$assetTID][
'MODE'],
1402 if ((
$paths = $this->getAssetPaths($js)) !==
null)
1404 $jsInfo[
"PATH"] = $js;
1405 $jsInfo[
"FILE_PATH"] =
$paths[
"FILE_PATH"];
1406 $jsInfo[
"FULL_PATH"] =
$paths[
"FULL_PATH"];
1410 unset($this->js[$js]);
1414 if ($moduleInfo = $this->isKernelJS($jsInfo[
'PATH']))
1416 if ($this->sliceKernel() && $this->optimizeJs())
1418 $jsInfo[
'MODULE_ID'] = $moduleInfo[
'MODULE_ID'];
1419 $jsInfo[
'TARGET'] =
'KERNEL_'.$moduleInfo[
'MODULE_ID'];
1420 $jsInfo[
'PREFIX'] =
'kernel_'.$moduleInfo[
'MODULE_ID'];
1421 $jsInfo[
'SKIP'] = $moduleInfo[
'SKIP'] ??
false;
1422 $jsInfo[
'BODY'] = $moduleInfo[
'BODY'];
1426 $jsInfo[
'MODULE_ID'] = $this->assetJSCnt;
1427 $jsInfo[
'TARGET'] =
'KERNEL_'.$this->assetJSCnt;
1428 $jsInfo[
'PREFIX'] =
'kernel_'.$this->assetJSCnt;
1429 $jsInfo[
'SKIP'] =
true;
1430 $this->assetJSCnt++;
1433 if ($jsInfo[
'BODY'])
1435 $this->targetList[
'BODY'][
'JS_LIST'][$jsInfo[
'TARGET']] = [
1436 'TARGET' => $jsInfo[
'TARGET'],
1437 'PREFIX' => $jsInfo[
'PREFIX'],
1438 'MODE' => $this->targetList[$assetTID][
'MODE'],
1445 if (isset($this->targetList[
'KERNEL'][
'JS_LIST'][$jsInfo[
'TARGET']][
'MODE']))
1447 $this->targetList[
'KERNEL'][
'JS_LIST'][$jsInfo[
'TARGET']][
'MODE'] |= $this->targetList[$assetTID][
'MODE'];
1451 $this->targetList[
'KERNEL'][
'JS_LIST'][$jsInfo[
'TARGET']] = [
1452 'TARGET' => $jsInfo[
'TARGET'],
1453 'PREFIX' => $jsInfo[
'PREFIX'],
1454 'MODE' => $set[
'ADDITIONAL'] ? $this->targetList[$set[
'TARGET'][0]][
'MODE'] : $this->targetList[$assetTID][
'MODE'],
1462 foreach ($set[
'TARGET'] as $setID)
1464 $this->targetList[
'KERNEL'][
'JS_LIST'][$jsInfo[
'TARGET']][
'WHERE_USED'][$setID] =
true;
1467 elseif (strncmp($jsInfo[
'PATH'],
'/bitrix/js/', 11) != 0)
1469 $jsInfo[
'SKIP'] = !(
1470 strncmp($jsInfo[
'PATH'],
'/bitrix/panel/', 14) != 0
1471 && strncmp($jsInfo[
'PATH'],
'/bitrix/themes/', 15) != 0
1472 && strncmp($jsInfo[
'PATH'],
'/bitrix/modules/', 16) != 0
1477 if ($jsInfo[
'ADDITIONAL'])
1479 $additional[] = $jsInfo;
1483 $this->js[$jsInfo[
'TARGET']][] = $jsInfo;
1485 unset($this->js[$js]);
1489 foreach ($this->targetList[
'BODY'][
'JS_LIST'] as $item)
1491 unset($this->targetList[
'KERNEL'][
'JS_LIST'][$item[
'TARGET']]);
1494 foreach ($additional as $jsInfo)
1496 $this->js[$jsInfo[
'TARGET']][] = $jsInfo;
1507 public function getCss(
$type = AssetShowTargetType::ALL)
1511 static $setList = [];
1512 static $ajaxList = [];
1514 if (empty($setList))
1516 $this->setTemplateID();
1517 $this->addTemplateCss();
1518 $this->prepareCss();
1519 $setList = $this->getTargetList();
1520 $optimizeCss = $this->optimizeCss();
1522 foreach ($setList as $setInfo)
1524 if (!isset($this->css[$setInfo[
'NAME']]))
1530 if (!empty($this->moduleInfo[
'CSS'][$setInfo[
'MODULE_NAME']][
'DATA']))
1532 $data = $this->moduleInfo[
'CSS'][$setInfo[
'MODULE_NAME']][
'DATA'];
1536 if (!empty($this->moduleInfo[
'CSS'][$setInfo[
'MODULE_NAME']][
'LOCATION']))
1538 $location = $this->moduleInfo[
'CSS'][$setInfo[
'MODULE_NAME']][
'LOCATION'];
1543 $showLabel = ($setInfo[
'NAME'] ==
'TEMPLATE');
1545 foreach ($this->css[$setInfo[
'NAME']] as $cssFile)
1547 $css = $cssFile[
'FULL_PATH'];
1550 $this->assetList[
'CSS'][] = $cssFile[
'PATH'];
1553 elseif ($cssFile[
'EXTERNAL'])
1555 $resCss .= $this->insertCss($css, $showLabel);
1556 $this->fileList[
'CSS'][$setInfo[
'NAME']][
'FILES'][] = $css;
1560 if ($cssFile[
'SKIP'])
1562 $resCss .= $this->insertCss($css, $showLabel);
1563 $this->fileList[
'CSS'][$setInfo[
'NAME']][
'FILES'][] = $css;
1567 $listAsset[] = $cssFile;
1572 $resCss .= $this->insertCss($css, $showLabel);
1573 $this->fileList[
'CSS'][$setInfo[
'NAME']][
'FILES'][] = $css;
1577 $optimizedAsset = $this->optimizeAsset($listAsset, $setInfo[
'UNIQUE'], $setInfo[
'PREFIX'], $setInfo[
'NAME'],
'css',
$data);
1579 $resCss = $optimizedAsset[
'RESULT'].$resCss;
1580 if (
$location == AssetLocation::AFTER_CSS)
1583 'FILES' => $optimizedAsset[
'FILES'],
1584 'SOURCE_FILES' => $optimizedAsset[
'SOURCE_FILES'],
1590 $this->assetList[
'CSS'][$setInfo[
'PARENT_NAME']][$setInfo[
'NAME']] = $optimizedAsset[
'FILES'];
1591 $this->assetList[
'SOURCE_CSS'][$setInfo[
'PARENT_NAME']][$setInfo[
'NAME']] = ($optimizedAsset[
'SOURCE_FILES'] ?? []);
1592 $this->targetList[$setInfo[
'PARENT_NAME']][
'CSS_RES'][$setInfo[
'NAME']][] = $resCss;
1596 foreach ($additional as $bundle)
1598 $templateFiles = $this->assetList[
'CSS'][
'TEMPLATE'][
'TEMPLATE'] ?? [];
1600 $this->assetList[
'CSS'][
'TEMPLATE'][
'TEMPLATE'] = array_merge($templateFiles, $bundle[
'FILES']);
1601 $this->assetList[
'SOURCE_CSS'][
'TEMPLATE'][
'TEMPLATE'] = array_merge($templateFiles, $bundle[
'SOURCE_FILES']);
1602 $this->targetList[
'TEMPLATE'][
'CSS_RES'][
'TEMPLATE'][] = $bundle[
'RES'];
1605 unset($additional, $templateFiles, $bundle);
1608 if ($this->ajax && !empty($ajaxList))
1610 $res .=
'<script>'.
"BX.loadCSS(['".implode(
"','", $ajaxList).
"']);".
'</script>';
1613 if (
$type == AssetShowTargetType::KERNEL)
1615 $res .= $this->showAsset($setList,
'css',
'KERNEL');
1617 elseif (
$type == AssetShowTargetType::TEMPLATE_PAGE)
1619 foreach ($this->targetList as $setName => $set)
1621 if ($setName !=
'TEMPLATE' && $setName !=
'KERNEL')
1623 $res .= $this->showAsset($setList,
'css', $setName);
1627 $res .= $this->showAsset($setList,
'css',
'TEMPLATE');
1631 foreach ($this->targetList as $setName => $set)
1633 if ($setName !=
'TEMPLATE')
1635 $res .= $this->showAsset($setList,
'css', $setName);
1639 $res .= $this->showAsset($setList,
'css',
'TEMPLATE');
1652 function getJs(
$type = AssetShowTargetType::ALL)
1654 static $setList = [];
1658 $type = ((
$type == AssetShowTargetType::KERNEL && $this->headString && !$this->headScript) ? AssetShowTargetType::ALL :
$type);
1659 $optimize = $this->optimizeJs();
1660 if (empty($setList))
1663 $setList = $this->getTargetList(
'JS');
1665 foreach ($setList as $setInfo)
1667 if (!isset($this->js[$setInfo[
'NAME']]))
1673 if (!empty($this->moduleInfo[
'JS'][$setInfo[
'MODULE_NAME']][
'DATA']))
1675 $data = $this->moduleInfo[
'JS'][$setInfo[
'MODULE_NAME']][
'DATA'];
1680 foreach ($this->js[$setInfo[
'NAME']] as $jsFile)
1682 $js = $jsFile[
'FULL_PATH'];
1685 if ($jsFile[
'SKIP'])
1687 $this->fileList[
'JS'][$setInfo[
'NAME']][
'FILES'][] = $js;
1688 $resJs .=
"<script src=\"{$js}\"></script>\n";
1692 $listAsset[] = $jsFile;
1697 $this->fileList[
'JS'][$setInfo[
'NAME']][
'FILES'][] = $js;
1698 $resJs .=
"<script src=\"{$js}\"></script>\n";
1701 $optAsset = $this->optimizeAsset($listAsset, $setInfo[
'UNIQUE'], $setInfo[
'PREFIX'], $setInfo[
'NAME'],
'js',
$data);
1702 $this->assetList[
'JS'][$setInfo[
'PARENT_NAME']][$setInfo[
'NAME']] = $optAsset[
'FILES'];
1703 $this->assetList[
'SOURCE_JS'][$setInfo[
'PARENT_NAME']][$setInfo[
'NAME']] = ($optAsset[
'SOURCE_FILES'] ?? []);
1704 $this->targetList[$setInfo[
'PARENT_NAME']][
'JS_RES'][$setInfo[
'NAME']][] = $optAsset[
'RESULT'].$resJs;
1706 unset($optAsset, $resJs, $listAsset);
1709 if (
$type == AssetShowTargetType::KERNEL && ($this->mode & $this->targetList[
'KERNEL'][
'MODE']))
1711 $setName =
'KERNEL';
1712 $res .= $this->getStrings(AssetLocation::AFTER_CSS);
1713 $res .= $this->showAsset($setList,
'js', $setName);
1714 $res .= $this->showFilesList();
1715 $res .= $this->getStrings(AssetLocation::AFTER_JS_KERNEL);
1717 if (!$this->bodyScript)
1719 $res .= $this->getStrings(AssetLocation::BODY_END);
1720 $res .= $this->showAsset($setList,
'js',
'BODY');
1723 elseif (
$type == AssetShowTargetType::TEMPLATE_PAGE)
1725 foreach ($this->targetList as $setName => $set)
1727 if ($setName !=
'KERNEL' && $setName !=
'BODY')
1729 $setName = $this->fixJsSetOrder($setName);
1730 $res .= $this->showAsset($setList,
'js', $setName);
1733 $res .= $this->getStrings(AssetLocation::AFTER_JS);
1735 elseif (
$type == AssetShowTargetType::BODY && ($this->mode & $this->targetList[
'BODY'][
'MODE']))
1738 $res .= $this->getStrings(AssetLocation::BODY_END);
1739 $res .= $this->showAsset($setList,
'js', $setName);
1743 foreach ($this->targetList as $setName => $set)
1745 if ($this->mode & $set[
'MODE'])
1747 $setName = $this->fixJsSetOrder($setName);
1748 if ($setName ==
'KERNEL')
1750 $res .= $this->getStrings(AssetLocation::AFTER_CSS);
1751 $res .= $this->showAsset($setList,
'js', $setName);
1752 $res .= $this->showFilesList();
1753 $res .= $this->getStrings(AssetLocation::AFTER_JS_KERNEL);
1755 if (!$this->bodyScript)
1757 $res .= $this->getStrings(AssetLocation::BODY_END);
1758 $res .= $this->showAsset($setList,
'js',
'BODY');
1761 elseif ($setName !=
'BODY')
1763 $res .= $this->showAsset($setList,
'js', $setName);
1768 $res .= $this->getStrings(AssetLocation::AFTER_JS);
1779 public static function getLocationByName(
$location)
1783 $location = AssetLocation::AFTER_JS_KERNEL;
1797 public function showFilesList()
1805 if (!empty($this->assetList[
'JS']))
1808 foreach ($this->getTargetList(
'JS') as $set)
1810 if ($this->mode & $set[
'MODE']
1811 && isset($this->assetList[
'SOURCE_JS'][$set[
'PARENT_NAME']][$set[
'NAME']])
1812 && is_array($this->assetList[
'SOURCE_JS'][$set[
'PARENT_NAME']][$set[
'NAME']]))
1814 $assets = array_merge($assets, $this->assetList[
'SOURCE_JS'][$set[
'PARENT_NAME']][$set[
'NAME']]);
1818 if (!empty($assets))
1820 $res .=
'<script>BX.setJSList(' . Json::encode($assets) .
');</script>';
1825 if (!empty($this->assetList[
'CSS']))
1828 foreach ($this->getTargetList(
'CSS') as $set)
1830 if ($this->mode & $set[
'MODE']
1831 && isset($this->assetList[
'SOURCE_CSS'][$set[
'PARENT_NAME']][$set[
'NAME']])
1832 && is_array($this->assetList[
'SOURCE_CSS'][$set[
'PARENT_NAME']][$set[
'NAME']])
1835 $assets = array_merge($assets, $this->assetList[
'SOURCE_CSS'][$set[
'PARENT_NAME']][$set[
'NAME']]);
1839 if (!empty($assets))
1841 $res .=
'<script>BX.setCSSList(' . Json::encode($assets) .
');</script>';
1855 function addCssKernelInfo($module =
'', $css = [],
$settings = [])
1857 if (empty($module) || empty($css))
1862 if (!array_key_exists($module, $this->moduleInfo[
'CSS']))
1864 $this->moduleInfo[
'CSS'][$module] = [
1865 'MODULE_ID' => $module,
1867 'FILES_INFO' =>
true,
1868 'IS_KERNEL' =>
true,
1874 foreach ($css as
$key)
1877 $this->kernelAsset[
'CSS'][
$key] = $module;
1880 $this->moduleInfo[
'CSS'][$module][
'FILES_INFO'] =
true;
1883 $this->moduleInfo[
'CSS'][$module][
'DATA'] =
$settings[
'DATA'];
1888 $this->moduleInfo[
'CSS'][$module][
'LOCATION'] =
$settings[
'LOCATION'];
1899 function addJsKernelInfo($module =
'', $js = [],
$settings = [])
1901 if (empty($module) || empty($js))
1906 if (!array_key_exists($module, $this->moduleInfo[
'JS']))
1908 $this->moduleInfo[
'JS'][$module] = [
1909 'MODULE_ID' => $module,
1911 'FILES_INFO' =>
true,
1912 'IS_KERNEL' =>
true,
1918 foreach ($js as
$key)
1921 $this->kernelAsset[
'JS'][
$key] = $module;
1924 $this->moduleInfo[
'JS'][$module][
'FILES_INFO'] =
true;
1927 $this->moduleInfo[
'JS'][$module][
'DATA'] =
$settings[
'DATA'];
1936 function isKernelCSS($css)
1939 if (!($this->sliceKernel() && $this->optimizeCss()))
1941 return ((strncmp($css,
'/bitrix/js/', 11) == 0) || (strncmp($css,
'/bitrix/css/', 12) == 0));
1945 if (array_key_exists($css, $this->kernelAsset[
'CSS']))
1947 return $this->moduleInfo[
'CSS'][$this->kernelAsset[
'CSS'][$css]];
1949 elseif ((strncmp($css,
'/bitrix/js/', 11) == 0) || (strncmp($css,
'/bitrix/css/', 12) == 0))
1951 $tmp = explode(
'/', $css);
1961 'MODULE_ID' =>
$moduleID.
'_'.$this->assetCSSCnt++,
1963 'FILES_INFO' =>
false,
1964 'IS_KERNEL' =>
true,
1978 function isKernelJS($js)
1981 if (!($this->sliceKernel() && $this->optimizeJs()))
1983 return (strncmp($js,
'/bitrix/js/', 11) == 0);
1987 if (array_key_exists($js, $this->kernelAsset[
'JS']))
1989 return $this->moduleInfo[
'JS'][$this->kernelAsset[
'JS'][$js]];
1991 elseif (strncmp($js,
'/bitrix/js/', 11) == 0)
1993 $tmp = explode(
'/', $js);
2003 'MODULE_ID' =>
$moduleID.
'_'.$this->assetJSCnt++,
2005 'FILES_INFO' =>
false,
2006 'IS_KERNEL' =>
true,
2021 public function setUnique($setID =
'', $uniqueID =
'')
2023 $setID = preg_replace(
'#[^a-z0-9_]#i',
'', $setID);
2024 $uniqueID = preg_replace(
'#[^a-z0-9_]#i',
'', $uniqueID);
2025 if (!(empty($setID) || empty($uniqueID)) && isset($this->targetList[$setID]))
2027 $this->targetList[$setID][
'UNIQUE'] =
true;
2028 $this->targetList[$setID][
'PREFIX'] .= ($uniqueID ==
'' ?
'' :
'_'.$uniqueID);
2041 private function showAsset($setList = [],
$type =
'css', $setName =
'')
2044 $type = (
$type ==
'css' ?
'CSS_RES' :
'JS_RES');
2045 $skipCheck = ($setName ==
'');
2047 foreach ($setList as $setInfo)
2050 ($skipCheck || $setName == $setInfo[
'PARENT_NAME'])
2051 && $this->mode & $setInfo[
'MODE']
2052 && isset($this->targetList[$setInfo[
'PARENT_NAME']][
$type][$setInfo[
'NAME']]))
2054 $res .= implode(
"\n", $this->targetList[$setInfo[
'PARENT_NAME']][
$type][$setInfo[
'NAME']]);
2066 private function fixJsSetOrder($setName =
'')
2068 if ($setName ==
'PAGE')
2070 $setName =
'TEMPLATE';
2072 elseif ($setName ==
'TEMPLATE')
2085 public static function getAssetTime($file =
'')
2087 $qpos = mb_strpos($file,
'?');
2088 if ($qpos ===
false)
2094 return mb_substr($file, $qpos);
2102 private function getAssetChecksum($assetList = [])
2105 foreach ($assetList as $asset)
2107 $result[$asset[
'PATH']] = $asset[
'FULL_PATH'];
2111 return md5(implode(
'_',
$result));
2122 private function isAssetChanged($assetList = [], $infoFile =
'', $optimFile =
'', $unique =
false)
2127 'FILE_EXIST' =>
false,
2131 if (file_exists($infoFile) && file_exists($optimFile))
2137 $result[
'FILES_INFO'] = is_array($filesInfo) ? $filesInfo : [];
2141 if (is_array($filesInfo))
2143 foreach ($assetList as $asset)
2145 if (isset($filesInfo[$asset[
'PATH']]))
2147 if ($this->getAssetTime($asset[
'FULL_PATH']) != $filesInfo[$asset[
'PATH']])
2150 'FILE' => $assetList,
2167 'FILE' => $assetList,
2194 private function optimizeAsset($files = [], $unique =
false, $prefix =
'default', $setName =
'',
$type =
'css',
$data =
'')
2196 if ((!is_array($files) || empty($files)))
2198 return [
'RESULT' =>
'',
'FILES' => []];
2201 $this->setTemplateID();
2203 $prefix = trim($prefix);
2204 $prefix = mb_strlen($prefix) < 1 ?
'default' : $prefix;
2205 $add2End = (strncmp($prefix,
'kernel', 6) == 0);
2209 $noCheckOnly = !defined(
'BX_HEADFILES_CACHE_CHECK_ONLY');
2210 $prefix = ($unique ? $prefix : $prefix.
'_'.$this->getAssetChecksum($files));
2212 $optimPath = BX_PERSONAL_ROOT.
'/cache/'.
$type.
'/'.
SITE_ID.
'/'.$this->siteTemplateID.
'/'.$prefix.
'/';
2214 $infoFile = $this->documentRoot.BX_PERSONAL_ROOT.
'/managed_cache/'.$this->dbType.
'/'.
$type.
'/'.
SITE_ID.
'/'.$this->siteTemplateID.
'/'.$prefix.
'/info_v'.self::version.
'.php';
2216 $optimFile = $optimPath.$prefix.
'_v'.self::version.($type ==
'css' ?
'.css' :
'.js');
2217 $optimFName = $this->documentRoot.$optimFile;
2219 $tmpInfo = $this->isAssetChanged($files, $infoFile, $optimFName, $unique);
2220 $filesInfo = $tmpInfo[
'FILES_INFO'];
2222 $files = $tmpInfo[
'FILE'];
2223 $optimFileExist = $tmpInfo[
'FILE_EXIST'] ??
false;
2225 $writeResult = (
$action !=
'NEW');
2226 $currentFileList = &$this->fileList[strtoupper(
$type)][$setName];
2230 foreach ($tmpInfo[
'FILE'] as $newFile)
2232 $currentFileList[
'UP_NEW_FILES'][] = $newFile[
'FULL_PATH'];
2239 $contents .= file_get_contents($optimFName);
2243 $writeResult =
false;
2252 foreach ($files as $file)
2254 $assetContent = file_get_contents($file[
'FILE_PATH']);
2257 $comments .=
"/* ".$file[
'FULL_PATH'].
" */\n";
2258 $assetContent = $this->fixCSSIncludes($assetContent, $file[
'PATH']);
2259 $assetContent =
"\n/* Start:".$file[
'FULL_PATH'].
"*/\n".$assetContent.
"\n/* End */\n";
2260 $newContent .=
"\n".$assetContent;
2265 "full" => $file[
'FULL_PATH'],
2266 "source" => $file[
'PATH'],
2271 if (preg_match(
"/\\.min\\.js$/i", $file[
'FILE_PATH']))
2273 $sourceMap = self::cutSourceMap($assetContent);
2274 if ($sourceMap <>
'')
2276 $dirPath = IO\Path::getDirectory($file[
'PATH']);
2277 $info[
"map"] = $dirPath.
"/".$sourceMap;
2278 $info[
"min"] = self::getAssetPath($file[
'FULL_PATH']);
2283 $comments .=
"; /* ".$file[
'FULL_PATH'].
"*/\n";
2284 $newContent .=
"\n".self::HEADER_START_TAG.serialize(
$info).self::HEADER_END_TAG.
"\n".$assetContent.
"\n/* End */\n;";
2287 $filesInfo[$file[
'PATH']] = $this->getAssetTime($file[
'FULL_PATH']);
2293 $sourceMap = self::cutSourceMap(
$contents);
2294 $mapNeeded = $mapNeeded || $sourceMap <>
'';
2297 $contents = ($add2End ? $comments.$contents.$newContent : $newContent.$contents.$comments);
2300 $contents .= self::SOURCE_MAP_TAG.$prefix.
".map.js";
2303 if ($writeResult = $this->write($optimFName,
$contents))
2305 $cacheInfo =
'<?php $filesInfo = [';
2309 $cacheInfo .=
'"'.EscapePHPString(
$key).
'" => "'.
$hash.
'",';
2312 $cacheInfo .=
"]; ?>";
2313 $this->write($infoFile, $cacheInfo,
false);
2317 $this->write($this->documentRoot.$optimPath.$prefix.
".map.js", self::generateSourceMap($prefix.
".js",
$contents),
false);
2323 $writeResult =
true;
2329 $label = ((
$type ==
'css') && ($prefix ==
'template' || str_starts_with($prefix,
'template_')) ?
' data-template-style="true" ' :
'');
2332 $extendData = (
$data !=
'' ?
' '.trim(
$data) :
'');
2333 $extendData .= ($label !=
'' ?
' '.trim($label) :
'');
2335 if ($writeResult || $unique &&
$action ==
'UP')
2337 $bundleFile = \CUtil::GetAdditionalFileURL($optimFile);
2338 $currentFileList[
'FILES'][] = $bundleFile;
2342 $res .= $this->insertCss($bundleFile, $extendData);
2346 $res .= $this->insertJs($bundleFile, $extendData);
2352 foreach ($files as $file)
2354 $currentFileList[
'FILES'][] = $file[
'FULL_PATH'];
2357 $res .= $this->insertCss($file[
'FULL_PATH'], $extendData);
2361 $res .= $this->insertJs($file[
'FULL_PATH'], $extendData);
2367 if (is_array($filesInfo))
2378 if ($bundleFile !=
'')
2380 $currentFileList[
'FULL_FILES'][$bundleFile] = $resultFiles;
2382 return [
'RESULT' =>
$res,
'FILES' => $resultFiles,
'SOURCE_FILES' => array_keys($filesInfo)];
2390 private static function cutSourceMap(&
$content)
2392 $sourceMapName =
"";
2395 $position = $length > 512 ? $length - 512 : 0;
2396 $lastLine = strpos(
$content, self::SOURCE_MAP_TAG, $position);
2397 if ($lastLine !==
false)
2399 $nameStart = $lastLine + strlen(self::SOURCE_MAP_TAG);
2400 if (($newLinePos = strpos(
$content,
"\n", $nameStart)) !==
false)
2402 $sourceMapName = substr(
$content, $nameStart, $newLinePos - $nameStart);
2406 $sourceMapName = substr(
$content, $nameStart);
2409 $sourceMapName = trim($sourceMapName);
2413 return $sourceMapName;
2421 private static function getFilesInfo(
$content)
2427 while (($newLinePos = strpos(
$content,
"\n", $offset)) !==
false)
2430 $offset = $newLinePos + 1;
2431 if (substr(
$content, $offset, strlen(self::HEADER_START_TAG)) === self::HEADER_START_TAG)
2433 $endingPos = strpos(
$content, self::HEADER_END_TAG, $offset);
2434 if ($endingPos ===
false)
2439 $startData = $offset + strlen(self::HEADER_START_TAG);
2440 $data = unserialize(substr(
$content, $startData, $endingPos - $startData), [
'allowed_classes' =>
false]);
2442 if (is_array(
$data))
2444 $data[
"line"] = $line + 1;
2448 $offset = $endingPos;
2465 foreach ($files as $file)
2467 if (!isset($file[
"map"]) || mb_strlen($file[
"map"]) < 1)
2472 $filePath = Main\Loader::getDocumentRoot().$file[
"map"];
2473 if (file_exists($filePath) && (
$content = file_get_contents($filePath)) !==
false)
2475 if ($sections !==
"")
2480 $dirPath = IO\Path::getDirectory($file[
"source"]);
2481 $sourceName = IO\Path::getName($file[
"source"]);
2482 $minName = IO\Path::getName($file[
"min"]);
2484 $sourceMap = str_replace(
2485 [$sourceName, $minName],
2486 [$dirPath.
"/".$sourceName, $dirPath.
"/".$minName],
2489 $sections .=
'{"offset": { "line": '.$file[
"line"].
', "column": 0 }, "map": '.$sourceMap.
'}';
2493 return '{"version":3, "file":"'.$fileName.
'", "sections": ['.$sections.
']}';
2503 function write($filePath,
$content, $gzip =
true)
2505 $fnTmp = $filePath.
'.tmp';
2507 if (!
CheckDirPath($filePath) || !$fh = fopen($fnTmp,
"wb"))
2516 if (file_exists($filePath))
2522 if ($written === $len)
2525 rename($fnTmp, $filePath);
2526 @chmod($filePath, BX_FILE_PERMISSIONS);
2527 if ($gzip && self::gzipEnabled())
2529 $fnTmpGz = $filePath.
'.tmp.gz';
2530 $fnGz = $filePath.
'.gz';
2532 if ($gz = gzopen($fnTmpGz,
'wb9f'))
2534 $writtenGz = @gzwrite ($gz,
$content);
2537 if (file_exists($fnGz))
2542 if ($writtenGz === $len)
2544 rename($fnTmpGz, $fnGz);
2545 @chmod($fnGz, BX_FILE_PERMISSIONS);
2548 if (file_exists($fnTmpGz))
2556 if (file_exists($fnTmp))
if(!is_array($prop["VALUES"])) $tmp
foreach(['Bitrix\\Main'=> '/lib', 'Psr\\Container'=> '/vendor/psr/container/src', 'Psr\\Log'=> '/vendor/psr/log/src', 'Psr\\Http\\Message'=> '/vendor/psr/http-message/src', 'Psr\\Http\\Client'=> '/vendor/psr/http-client/src', 'Http\\Promise'=> '/vendor/php-http/promise/src', 'PHPMailer\\PHPMailer'=> '/vendor/phpmailer/phpmailer/src', 'GeoIp2'=> '/vendor/geoip2/geoip2/src', 'MaxMind\\Db'=> '/vendor/maxmind-db/reader/src/MaxMind/Db', 'PhpParser'=> '/vendor/nikic/php-parser/lib/PhpParser', 'Recurr'=> '/vendor/simshaun/recurr/src/Recurr',] as $namespace=> $namespacePath) $documentRoot
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
__construct(?int $storeId, int $productId, string $barcode, int $userId)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key