128 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | ||
| 
 | ||
| namespace kernel;
 | ||
| 
 | ||
| use RuntimeException;
 | ||
| 
 | ||
| class AssetsCollector
 | ||
| {
 | ||
|     protected array $assetsPool = [];
 | ||
| 
 | ||
|     public function registerAsset(Assets $assets): void
 | ||
|     {
 | ||
|         $this->assetsPool[] = $assets;
 | ||
|     }
 | ||
| 
 | ||
|     public function renderCss(): void
 | ||
|     {
 | ||
|         $css = [];
 | ||
|         foreach ($this->assetsPool as $item) {
 | ||
|             /** @var Assets $item */
 | ||
|             $css = array_merge($css, $item->getCollectorCss());
 | ||
|         }
 | ||
| 
 | ||
|         try {
 | ||
|             $sortedStyles = $this->sortStyles($css);
 | ||
| 
 | ||
|             // Выводим отсортированные стили
 | ||
|             foreach ($sortedStyles as $style) {
 | ||
|                 echo '<link rel="stylesheet" href="' . htmlspecialchars($style) . '">' . "\n";
 | ||
|             }
 | ||
|         } catch (RuntimeException $e) {
 | ||
|             echo 'Ошибка: ' . $e->getMessage();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     public function renderJs(bool $body = true): void
 | ||
|     {
 | ||
|         $scripts = [];
 | ||
|         foreach ($this->assetsPool as $item) {
 | ||
|             /** @var Assets $item */
 | ||
|             $scripts = array_merge($scripts, $item->getCollectorJs());
 | ||
|         }
 | ||
| 
 | ||
|         try {
 | ||
|             $sortedScripts = $this->sortScripts($scripts);
 | ||
| 
 | ||
|             // Разделяем скрипты для head и body
 | ||
|             $headScripts = [];
 | ||
|             $bodyScripts = [];
 | ||
| 
 | ||
|             foreach ($sortedScripts as $script) {
 | ||
|                 if ($script['body']) {
 | ||
|                     $bodyScripts[] = $script['resource'];
 | ||
|                 } else {
 | ||
|                     $headScripts[] = $script['resource'];
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             // Выводим скрипты для head
 | ||
|             if ($body){
 | ||
|                 $scriptsToRender = $bodyScripts;
 | ||
|             }
 | ||
|             else {
 | ||
|                 $scriptsToRender = $headScripts;
 | ||
|             }
 | ||
|             foreach ($scriptsToRender as $script) {
 | ||
|                 echo '<script src="' . htmlspecialchars($script) . '"></script>' . "\n";
 | ||
|             }
 | ||
|         }
 | ||
|         catch (RuntimeException $e) {
 | ||
|             echo 'Ошибка: ' . $e->getMessage();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     protected function sortStyles(array $styles): array
 | ||
|     {
 | ||
|         $sorted = [];
 | ||
|         $added = [];
 | ||
| 
 | ||
|         // Пока не добавим все стили
 | ||
|         while (count($sorted) < count($styles)) {
 | ||
|             $found = false;
 | ||
| 
 | ||
|             foreach ($styles as $name => $style) {
 | ||
|                 // Если стиль еще не добавлен и его зависимости выполнены
 | ||
|                 if (!isset($added[$name]) &&
 | ||
|                     (empty($style['after']) || isset($added[$style['after']]))) {
 | ||
|                     $sorted[] = $style['resource'];
 | ||
|                     $added[$name] = true;
 | ||
|                     $found = true;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             if (!$found) {
 | ||
|                 // Если есть циклическая зависимость
 | ||
|                 throw new RuntimeException('Обнаружена циклическая зависимость в стилях');
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return $sorted;
 | ||
|     }
 | ||
| 
 | ||
|     protected function sortScripts(array $scripts): array
 | ||
|     {
 | ||
|         $sorted = [];
 | ||
|         $added = [];
 | ||
| 
 | ||
|         while (count($sorted) < count($scripts)) {
 | ||
|             $found = false;
 | ||
| 
 | ||
|             foreach ($scripts as $name => $script) {
 | ||
|                 if (!isset($added[$name]) &&
 | ||
|                     (empty($script['after']) || isset($added[$script['after']]))) {
 | ||
|                     $sorted[] = $script;
 | ||
|                     $added[$name] = true;
 | ||
|                     $found = true;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             if (!$found) {
 | ||
|                 throw new RuntimeException('Обнаружена циклическая зависимость в скриптах');
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return $sorted;
 | ||
|     }
 | ||
| 
 | ||
| } |