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;
|
||
}
|
||
|
||
} |