Skip to content

Commit

Permalink
Support resolve assets with dependences
Browse files Browse the repository at this point in the history
  • Loading branch information
puleeno committed Sep 17, 2023
1 parent c077daa commit 5267385
Show file tree
Hide file tree
Showing 14 changed files with 254 additions and 39 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# puleeno-cms
Yet another PHP CMS by Puleeno Nguyen


# Server settings

## NGINX

```
server {
listen 80;
server_name domain_name.com;
set $based /var/www;
root $based/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/(extensions|themes)/(.+)/assets/(.+)\.(eot|svg|ttf|woff|woff2|png|jpg|gif|css|js)$ {
root $based;
}
}
```
8 changes: 5 additions & 3 deletions app/Constracts/Assets/AssetConstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ public function setOptions(AssetOptions $options): AssetConstract;

public function setVersion($version): AssetConstract;

public function setPriority(int $priority): AssetConstract;

public function setAssetType(AssetTypeEnum $assetType): AssetConstract;

public function isValid(): bool;
Expand All @@ -23,11 +21,15 @@ public function getId();

public function getAssetType(): AssetTypeEnum;

public function getDeps(): array;

public function isEnqueue(): bool;

public function enqueue();

public function printHtml();
public function renderHtml();

public function isRendered(): bool;

public function getOptions(): ?AssetOptionsConstract;

Expand Down
20 changes: 14 additions & 6 deletions app/Core/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,14 @@ public function setDeps($deps): AssetConstract
return $this;
}

public function setOptions(AssetOptionsConstract $assetOptions): AssetConstract
public function getDeps(): array
{
$this->options = $assetOptions;

return $this;
return $this->deps ?? [];
}

public function setPriority(int $priority): AssetConstract
public function setOptions(AssetOptionsConstract $assetOptions): AssetConstract
{
$this->priority = $priority;
$this->options = $assetOptions;

return $this;
}
Expand Down Expand Up @@ -89,4 +87,14 @@ public function isEnqueue(): bool
{
return $this->isEnqueue;
}

public function isRendered(): bool
{
return $this->isRendered;
}

public function renderHtml()
{
$this->isRendered = true;
}
}
185 changes: 163 additions & 22 deletions app/Core/AssetManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use App\Constracts\Assets\AssetConstract;
use App\Constracts\AssetTypeEnum;
use App\Constracts\Assets\AssetExternalConstract;
use App\Constracts\Assets\AssetScriptConstract;
use App\Core\Assets\AssetOptions;
use App\Core\Assets\AssetUrl;
use App\Core\Assets\Bucket;
use MJS\TopSort\Implementations\StringSort;

final class AssetManager
{
Expand All @@ -16,6 +18,8 @@ final class AssetManager
protected Bucket $frontendBucket;
protected Bucket $backendBucket;

protected $resolvedAssets = [];


protected function __construct()
{
Expand All @@ -37,16 +41,14 @@ public static function create(
AssetTypeEnum $assetType,
$deps = [],
$version = null,
AssetOptions $assetOptions = null,
$priority = 10
AssetOptions $assetOptions = null
): AssetConstract {
$asset = Helper::createAssetByAssetType($id, $assetType);
if ($asset instanceof AssetExternalConstract) {
$asset->setUrl($url);
}
$asset->setDeps($deps);
$asset->setOptions($assetOptions);
$asset->setPriority($priority);
$asset->setVersion($version);

return $asset;
Expand All @@ -58,17 +60,15 @@ public static function registerAsset(
AssetTypeEnum $assetType,
$deps = [],
$version = null,
AssetOptions $assetOptions = null,
$priority = 10
AssetOptions $assetOptions = null
): AssetConstract {
$asset = static::create(
(string) $id,
$url,
$assetType,
$deps,
$version,
$assetOptions,
$priority
$assetOptions
);
$instance = static::getInstance();
$instance->getFrontendBucket()
Expand All @@ -83,13 +83,12 @@ public static function registerBackendAsset(
AssetTypeEnum $assetType,
$deps = [],
$version = null,
AssetOptions $assetOptions = null,
$priority = 10
AssetOptions $assetOptions = null
): AssetConstract {
/**
* @var \App\Core\Assets\JavaScript
*/
$asset = static::create($id, $url, $assetType, $deps, $version, $assetOptions, $priority);
$asset = static::create($id, $url, $assetType, $deps, $version, $assetOptions);
$instance = static::getInstance();
$instance->getBackendBucket()
->addAsset($asset);
Expand All @@ -114,48 +113,190 @@ protected function getActiveBucket(): Bucket
: $this->getBackendBucket();
}

protected function getAssetTypeFromStringType($type): ?AssetTypeEnum
{
switch ($type) {
case AssetTypeEnum::CSS()->getType():
return AssetTypeEnum::CSS();
case AssetTypeEnum::JS()->getType():
return AssetTypeEnum::JS();
case AssetTypeEnum::FONT()->getType():
return AssetTypeEnum::FONT();
case AssetTypeEnum::ICON()->getType():
return AssetTypeEnum::ICON();
case AssetTypeEnum::STYLE()->getType():
return AssetTypeEnum::STYLE();
case AssetTypeEnum::EXECUTE_SCRIPT()->getType():
return AssetTypeEnum::EXECUTE_SCRIPT();
}
}

protected function resolve(AssetConstract $asset, StringSort &$resolver)
{
$bucket = $this->getActiveBucket();
$resolver->add($asset->getId(), $asset->getDeps());
foreach ($asset->getDeps() as $assetId) {
$assetDep = $bucket->getAsset($assetId, $asset->getAssetType());
if (is_null($assetDep)) {
error_log('Asset ID #' . $assetId . ' is not exists');
continue;
}
$assetDep->enqueue();

$this->resolve($assetDep, $resolver);
}
}

/**
* @param \App\Constracts\Assets\AssetConstract[] $assets
* @param AssetTypeEnum $assetType
* @return void
*/
protected function resolveDependences($assets, AssetTypeEnum $assetType)
{
$bucket = $this->getActiveBucket();
$resolver = new StringSort();

foreach ($assets as $asset) {
$this->resolve($asset, $resolver);
}
$sortedAssets = $resolver->sort();
foreach ($sortedAssets as $assetId) {
$asset = $bucket->getAsset($assetId, $assetType);
if (is_null($asset)) {
error_log('Asset ID #' . $assetId . ' is not exists');
continue;
}
if (!isset($this->resolvedAssets[$assetType->getType()])) {
$this->resolvedAssets[$assetType->getType()] = [];
}
$this->resolvedAssets[$assetType->getType()][] = $asset;
}
}

public function resolveAllDependences()
{
$bucket = $this->getActiveBucket();
foreach ($bucket->getAssets() as $type => $assets) {
$assetType = $this->getAssetTypeFromStringType($type);
if (is_null($assetType)) {
continue;
}
$this->resolveDependences(array_filter($assets, function (AssetConstract $item) {
return $item->isEnqueue() === true;
}), $assetType);
}
}

protected function getEnqueueAssetsByType(AssetTypeEnum $assetType, $filter = null)
{
if (!isset($this->resolvedAssets[$assetType->getType()])) {
return [];
}

return is_null($filter)
? $this->resolvedAssets[$assetType->getType()]
: array_filter($this->resolvedAssets[$assetType->getType()], $filter);
}

public function printInitHeadScripts()
{
foreach ($this->getActiveBucket()->getInitScripts(false) as $initScript) {
$initScript->printHtml();
$headInitScripts = $this->getEnqueueAssetsByType(
AssetTypeEnum::INIT_SCRIPT(),
function (AssetScriptConstract $item) {
return $item->isFooterScript() === false;
}
);

foreach ($headInitScripts as $initScript) {
if ($initScript->isRendered()) {
continue;
}
$initScript->renderHtml();
}
}

public function printHeadAssets()
{
foreach ($this->getActiveBucket()->getStylesheets(true) as $css) {
$css->printHtml();
foreach ($this->getEnqueueAssetsByType(AssetTypeEnum::CSS()) as $css) {
if ($css->isRendered()) {
continue;
}
$css->renderHtml();
}

foreach ($this->getActiveBucket()->getJs(false, true) as $js) {
$js->printHtml();
if ($js->isRendered()) {
continue;
}
$js->renderHtml();
}
}

public function printExecuteHeadScripts()
{
foreach ($this->getActiveBucket()->getExecuteScripts(false) as $executeScript) {
$executeScript->printHtml();
foreach ($this->getEnqueueAssetsByType(AssetTypeEnum::STYLE()) as $interalStyle) {
if ($interalStyle->isRendered()) {
continue;
}
$interalStyle->renderHtml();
}
$headExecScripts = $this->getEnqueueAssetsByType(
AssetTypeEnum::EXECUTE_SCRIPT(),
function (AssetScriptConstract $item) {
return $item->isFooterScript() === false;
}
);

foreach ($headExecScripts as $executeScript) {
if ($executeScript->isRendered()) {
continue;
}
$executeScript->renderHtml();
}
}

public function printFooterInitScripts()
{
foreach ($this->getActiveBucket()->getInitScripts(true) as $initScript) {
$initScript->printHtml();
$footerInitScripts = $this->getEnqueueAssetsByType(
AssetTypeEnum::INIT_SCRIPT(),
function (AssetScriptConstract $item) {
return $item->isFooterScript() === true;
}
);

foreach ($footerInitScripts as $initScript) {
if ($initScript->isRendered()) {
continue;
}
$initScript->renderHtml();
}
}

public function printFooterAssets()
{
foreach ($this->getActiveBucket()->getJs(true, true) as $js) {
$js->printHtml();
if ($js->isRendered()) {
continue;
}
$js->renderHtml();
}
}

public function executeFooterScripts()
{
foreach ($this->getActiveBucket()->getExecuteScripts(true) as $executeScript) {
$executeScript->printHtml();
$footerExecScripts = $this->getEnqueueAssetsByType(
AssetTypeEnum::INIT_SCRIPT(),
function (AssetScriptConstract $item) {
return $item->isFooterScript() === true;
}
);

foreach ($footerExecScripts as $executeScript) {
if ($executeScript->isRendered()) {
continue;
}
$executeScript->renderHtml();
}
}
}
10 changes: 10 additions & 0 deletions app/Core/Assets/Bucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ public function getAssets()
return $this->assets ?? [];
}

public function getAsset($id, AssetTypeEnum $assetType): ?AssetConstract
{
if (!empty($this->assets[$assetType->getType()])) {
$assets = &$this->assets[$assetType->getType()];
if (isset($assets[$id])) {
return $assets[$id];
}
}
return null;
}

public function getStylesheets($enqueueScripts = null): array
{
Expand Down
Loading

0 comments on commit 5267385

Please sign in to comment.