Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
manager.php
1<?php
2
4
5use \Bitrix\Main\Localization\Loc;
10
11Loc::loadMessages(__FILE__);
12
20{
21 protected const MODE_STANDART = 'STANDART';
22 protected const MODE_WEBPACK = 'WEBPACK';
23
24 protected const REGISTERED_KEY_CODE = 'code';
25 protected const REGISTERED_KEY_LOCATION = 'location';
26
27 private static $instance;
28
33 protected $mode;
38 protected $registered = [];
42 protected $resources;
46 protected $builder;
47
52 public static function getInstance(): Manager
53 {
54 if (self::$instance === null)
55 {
56 self::$instance = new static;
57 }
58
59 return self::$instance;
60 }
61
65 public function __construct()
66 {
67 $this->mode = self::MODE_STANDART;
68 $this->resources = new ResourceCollection();
69 }
70
74 public function setWebpackMode(): void
75 {
76 $this->mode = self::MODE_WEBPACK;
77 }
78
82 public function setStandartMode(): void
83 {
84 $this->mode = self::MODE_STANDART;
85 }
86
91 public function getMode(): string
92 {
93 return $this->mode;
94 }
95
100 protected function isAssetRegistered($code)
101 {
102 return array_key_exists($code, $this->registered);
103 }
104
110 protected function getRegisteredAssetLocation(string $code)
111 {
112 if ($this->isAssetRegistered($code))
113 {
114 return $this->registered[$code][self::REGISTERED_KEY_LOCATION];
115 }
116
117 return false;
118 }
119
123 protected function markAssetRegistered($code, $location): void
124 {
125 $this->registered[$code] = [
126 self::REGISTERED_KEY_CODE => $code,
127 self::REGISTERED_KEY_LOCATION => $location,
128 ];
129
130 if($code !== 'main.core' && $code !== 'core')
131 {
132 \CJSCore::markExtensionLoaded($code);
133 }
134 }
135
136
143 public function addAsset($code, $location = null): void
144 {
145 // recursive for arrays
146 if (is_array($code))
147 {
148 foreach ($code as $item)
149 {
150 $this->addAsset((string)$item, $location);
151 }
152 }
153 else
154 {
155 $this->addAssetRecursive($code, $location);
156 }
157 }
158
163 protected function addAssetRecursive(string $code, $location = null): void
164 {
165 $location = Location::verifyLocation($location);
166
167 // just once, but if new location more critical - readd
168 if (!$this->isNeedAddAsset($code, $location))
169 {
170 return;
171 }
172
173 // get data from CJSCore
174 if ($ext = \CJSCore::getExtInfo($code))
175 {
176 $asset = $ext;
177 }
178 else if ($ext = Extension::getConfig($code))
179 {
180 $asset = $ext;
181 }
182 // if name - it path
183 else if ($type = self::detectType($code))
184 {
185 $asset = [$type => [$code]];
186 }
187 else
188 {
189 return;
190 }
191
192 $this->processAsset($asset, $location);
193 $this->markAssetRegistered($code, $location);
194 }
195
201 protected function isNeedAddAsset(string $code, int $location): bool
202 {
203 if ($this->isAssetRegistered($code))
204 {
205 return $location < $this->getRegisteredAssetLocation($code);
206 }
207
208 if (\CJSCore::isExtensionLoaded($code))
209 {
210 return false;
211 }
212
213 return true;
214 }
215
216
223 protected function processAsset(array $asset, int $location): void
224 {
225 foreach (Types::getAssetTypes() as $type)
226 {
227 if (!isset($asset[$type]) || empty($asset[$type]))
228 {
229 continue;
230 }
231
232 if (!is_array($asset[$type]))
233 {
234 $asset[$type] = [$asset[$type]];
235 }
236
237 switch ($type)
238 {
240 {
241 foreach ($asset[$type] as $rel)
242 {
243 $this->addAsset($rel, $location);
244 }
245 break;
246 }
247
248 case Types::TYPE_JS:
249 case Types::TYPE_CSS:
250 case Types::TYPE_LANG:
251 {
252 foreach ($asset[$type] as $path)
253 {
254 if (\CMain::isExternalLink($path))
255 {
256 $this->resources->addString($this->createStringFromPath($path, $type));
257 }
258 // todo: check is file exist
259 else if (self::detectType($path))
260 {
261 $this->resources->add($path, $type, $location);
262 }
263 }
264 break;
265 }
266
267 case Types::TYPE_FONT:
268 {
269 // preload fonts add immediately
270 foreach ($asset[$type] as $fontFile)
271 {
272 if (
273 !\CMain::isExternalLink($fontFile)
274 && File::isFileExists(Landing\Manager::getDocRoot() . $fontFile)
275 )
276 {
277 $this->resources->addString($this->createStringFromPath($fontFile, $type));
278 }
279 }
280 break;
281 }
282
283 default:
284 break;
285 }
286 }
287 }
288
295 protected function createStringFromPath(string $path, string $type): string
296 {
297 $externalLink = '';
298
299 switch ($type)
300 {
301 case Types::TYPE_CSS:
302 {
303 $externalLink = "<link href=\"$path\" type=\"text/css\" rel=\"stylesheet\">";
304 break;
305 }
306
307 case Types::TYPE_JS:
308 {
309 $externalLink = "<script type=\"text/javascript\" src=\"$path\"></script>";
310 break;
311 }
312
313 case Types::TYPE_FONT:
314 {
315 $fontType = self::checkFontLinkType($path);
316 $externalLink = '<link rel="preload" href="' . $path
317 . '" as="font" crossorigin="anonymous" type="' . $fontType . '" crossorigin>';
318 break;
319 }
320
321 default:
322 break;
323 }
324
325 return $externalLink;
326 }
327
328
335 protected static function detectType(string $path): ?string
336 {
337 $path = parse_url($path)['path'];
338 $type = mb_strtolower(mb_substr(strrchr($path, '.'), 1));
339 switch ($type)
340 {
341 case 'js':
342 return Types::TYPE_JS;
343
344 case 'css':
345 return Types::TYPE_CSS;
346
347 case 'php':
348 return Types::TYPE_LANG;
349
350 case 'woff':
351 case 'woff2':
352 return Types::TYPE_FONT;
353
354 default:
355 return null;
356 }
357 }
358
359 protected static function checkFontLinkType(string $path): string
360 {
361 //woff2 must be before woff, because strpos find woff in woff2 ;)
362 $available = [
363 'woff2' => 'font/woff2',
364 'woff' => 'font/woff',
365 'ttf' => 'font/ttf',
366 'eot' => 'application/vnd.ms-fontobject',
367 'svg' => 'image/svg+xml',
368 ];
369
370 $linkType = '';
371 foreach ($available as $type => $value)
372 {
373 if (mb_strpos($path, $type) !== false)
374 {
375 $linkType = $value;
376 break;
377 }
378 }
379
380 return $linkType;
381 }
382
388 public function addString(string $string): void
389 {
390 $this->resources->addString(trim($string));
391 }
392
397 public function setOutput(int $lid = 0): void
398 {
399 if ($lid === 0)
400 {
401 trigger_error(
402 "You must to pass ID of current landing to the \Bitrix\Landing\Assets\Manager::setOutput",
403 E_USER_WARNING
404 );
405 }
406 $this->createBuilder();
407 $this->builder->attachToLanding($lid);
408 $this->builder->setOutput();
409 }
410
415 protected function createBuilder(): void
416 {
417 $this->builder = Builder::createByType($this->resources, $this->mode);
418 }
419
423 public static function rebuildWebpack(): void
424 {
426 }
427
432 public static function rebuildWebpackForLanding($lid = []): void
433 {
435 }
436}
static createByType(ResourceCollection $resources, string $type)
Definition builder.php:55
static verifyLocation($location)
Definition location.php:43
getRegisteredAssetLocation(string $code)
Definition manager.php:110
addString(string $string)
Definition manager.php:388
processAsset(array $asset, int $location)
Definition manager.php:223
static checkFontLinkType(string $path)
Definition manager.php:359
isNeedAddAsset(string $code, int $location)
Definition manager.php:201
markAssetRegistered($code, $location)
Definition manager.php:123
createStringFromPath(string $path, string $type)
Definition manager.php:295
static detectType(string $path)
Definition manager.php:335
addAssetRecursive(string $code, $location=null)
Definition manager.php:163
addAsset($code, $location=null)
Definition manager.php:143
static rebuildWebpackForLanding($lid=[])
Definition manager.php:432
static loadMessages($file)
Definition loc.php:64