+Базовая версия Asset manager'а

master
Andrey Pokidov 4 years ago
commit fb50e3a1c9

@ -0,0 +1,20 @@
{
"name": "artmark/assets",
"description": "Asset manager",
"type": "library",
"license": "Proprietary",
"authors": [
{
"name": "Andrey Pokidov",
"email": "pokidov@e-traffic.ru"
}
],
"require": {
"php": ">=7.0.0",
},
"autoload": {
"psr-0": {
"Artmark\\Assets\\": "src/"
}
}
}

@ -0,0 +1,166 @@
<?php
namespace Artmark\Assets;
/**
* Description of Asset
*
* @author Andrey Pokidov <pokidov@e-traffic.ru>
*/
class Asset
{
const TYPE_JAVASCRIPT = 'js';
const TYPE_CSS = 'css';
const POSITION_HEAD = 'head';
const POSITION_TOP = 'top';
const POSITION_BOTTOM = 'bottom';
private $name = '';
private $type = self::TYPE_JAVASCRIPT;
private $position = self::POSITION_HEAD;
private $url = '';
private $version = '';
/**
* Создаёт новый объекс Script, описывающий данные о скрипте
* @param string $url URL скрипта
* @param string|int $version Версия скрипта
* @param string $type Тип скрипта, может принимать одно из значений Script::TYPE_JAVASCRIPT или Script::TYPE_CSS
* @param string $position Место скрипта в коде страницы, может принимать одно из значений:
* <ul>
* <li>Script::POSITION_HEAD в секции &lt;head&gt;...&lt;/head&gt;</li>
* <li>Script::POSITION_TOP сразу после открывающего тега &lt;body&gt;</li>
* <li>Script::POSITION_BOTTOM непосредственно перед закрывающим тегом &lt;/body&gt;</li>
* </ul>
*/
public function __construct($name, $url, $version, $type = self::TYPE_JAVASCRIPT, $position = self::POSITION_HEAD)
{
self::checkName($name);
self::checkUrl($url);
self::checkVersion($url);
self::checkAssetType($type);
self::checkAssetPosition($position);
$this->name = self::correctName($name);
$this->url = trim($url);
$this->version = is_string($version) ? trim($version) : $version;
$this->type = $type;
$this->position = $position;
}
public function name()
{
return $this->name;
}
public function type()
{
return $this->type;
}
public function isJavaScript()
{
return $this->type == self::TYPE_JAVASCRIPT;
}
public function isCss()
{
return $this->type == self::TYPE_CSS;
}
public function position()
{
return $this->position;
}
public function isAtHead()
{
return $this->position == self::POSITION_HEAD;
}
public function isAtTop()
{
return $this->position == self::POSITION_TOP;
}
public function isAtBottom()
{
return $this->position == self::POSITION_BOTTOM;
}
public function url()
{
return $this->url;
}
public function urlWithVersion()
{
if (!$this->hasVersion())
{
return $this->url;
}
return $this->url . (strpos($this->url, '?') === false ? '?' : '&') . 'v=' . urlencode($this->version);
}
public function hasVersion()
{
return !empty($this->version);
}
public function version()
{
return $this->version;
}
public static function correctName($name)
{
return strtolower(trim(strval($name)));
}
public static function checkName($name)
{
if (!is_string($name)) {
throw new AssetException('Incorrect name type: `' . gettype($name) . '`, the name of an asset must be a string');
}
if (trim($name) == '') {
throw new AssetException('The name of an asset cannot be an empty string');
}
}
public static function checkUrl($url)
{
if (!is_string($url)) {
throw new AssetException('Incorrect URL type: `' . gettype($url) . '`, the URL of an asset must be a string');
}
if (trim($url) == '') {
throw new AssetException('The URL of an asset cannot be an empty string');
}
}
public static function checkVersion($verison)
{
if (!is_string($verison) && !is_int($verison)) {
throw new AssetException('Incorrect version type: `' . gettype($verison) . '`, the version of an asset must be a string or an integer number');
}
}
public static function checkAssetType($type)
{
if ($type != self::TYPE_JAVASCRIPT && $type != self::TYPE_CSS) {
throw new AssetException('Incorrect asset type: `' . $type . '`');
}
}
public static function checkAssetPosition($position)
{
if ($position != self::POSITION_HEAD && $position != self::POSITION_TOP && $position != self::POSITION_BOTTOM) {
throw new AssetException('Incorrect asset position: `' . $position . '`');
}
}
}

@ -0,0 +1,16 @@
<?php
namespace Artmark\Assets;
/**
* Description of AssetException
*
* @author Andrey Pokidov <pokidov@e-traffic.ru>
*/
class AssetException extends \Exception
{
public function __construct(string $message = "", int $code = 0, \Throwable $previous = NULL)
{
parent::__construct($message, $code, $previous);
}
}

@ -0,0 +1,167 @@
<?php
namespace Artmark\Assets;
/**
* Description of AssetManager
*
* @author Andrey Pokidov <pokidov@e-traffic.ru>
*/
class AssetManager
{
/**
* @var AssetManager
*/
private static $manager = null;
/**
*
* @var Asset[]
*/
private $assets = [];
private function __construct()
{
}
/**
*
* @return AssetManager
*/
public static function instance()
{
if (is_null(self::$manager)) {
self::$manager = new AssetManager();
}
return self::$manager;
}
/**
*
* @return $this
*/
public function resetAssets()
{
$this->assets = [];
return $this;
}
/**
*
* @param string $name
* @return $this
*/
public function loadCollection($name)
{
$assets = config('assets.' . $name);
if (!is_array($assets) || count($assets) == 0) {
return $this;
}
foreach ($assets as $name => $assetInfo) {
$this->loadAsset($name, $assetInfo);
}
return $this;
}
private function loadAsset($name, $assetInfo)
{
if (!is_array($assetInfo) || !array_key_exists('type', $assetInfo) || !array_key_exists('path', $assetInfo)) {
return;
}
$version = array_key_exists('version', $assetInfo) ? $assetInfo['version'] : '';
$position = array_key_exists('position', $assetInfo) ? $assetInfo['position'] : Asset::POSITION_HEAD;
$this->pushAsset(new Asset($name, $assetInfo['path'], $version, $assetInfo['type'], $position));
}
/**
*
* @param string $name
* @return boolean
*/
public function has($name)
{
return array_key_exists(Asset::correctName($name), $this->assets);
}
/**
*
* @param string $name
* @return Asset
*/
public function get($name)
{
$correctedName = Asset::correctName($name);
return array_key_exists($correctedName, $this->assets) ? $this->assets[$correctedName] : null;
}
/**
*
* @param Asset $asset
* @return $this
*/
public function pushAsset(Asset $asset)
{
$this->assets[$asset->name()] = $asset;
return $this;
}
/**
*
* @param string $name
* @param string $url
* @param string|int $version
* @param string $position
* @return $this
*/
public function setStyleSheet($name, $url, $version = '', $position = Asset::POSITION_HEAD)
{
$asset = new Asset($name, $url, $version, Asset::TYPE_CSS, $position);
$this->pushAsset($asset);
return $this;
}
/**
*
* @param string $name
* @param string $url
* @param string|int $version
* @param string $position
* @return $this
*/
public function setJavaScript($name, $url, $version = '', $position = Asset::POSITION_HEAD)
{
$asset = new Asset($name, $url, $version, Asset::TYPE_JAVASCRIPT, $position);
$this->pushAsset($asset);
return $this;
}
/**
*
* @param string $position
* @param string $type
* @return Asset[]
*/
public function getAssetsFor($position, $type)
{
if (!is_string($position) || !is_string($type)) {
return [];
}
$assets = [];
foreach ($this->assets as $asset) {
if ($asset->type() == $type && $asset->position() == $position) {
$assets[] = $asset;
}
}
return $assets;
}
}

@ -0,0 +1,95 @@
<?php
namespace Artmark\Assets;
use Illuminate\Support\Facades\Blade;
/**
* Description of AssetRenderer
*
* @author Andrey Pokidov <pokidov@e-traffic.ru>
*/
class AssetRenderer
{
/**
*
* @var AssetRenderer
*/
private static $render = null;
private static $registered = false;
private function __construct()
{
}
public static function register()
{
if (self::$registered) {
return;
}
self::$registered = true;
Blade::directive('css_assets', function ($expression) { return '<?php echo \Artmark\Assets\AssetRenderer::instance()->showStyleSheet(' . $expression . '); ?>'; });
Blade::directive('js_assets', function ($expression) { return '<?php echo \Artmark\Assets\AssetRenderer::instance()->showJavaScript(' . $expression . '); ?>'; });
}
/**
*
* @return AssetRenderer
*/
public static function instance()
{
if (is_null(self::$render)) {
self::$render = new AssetRenderer();
}
return self::$render;
}
public function showJavaScript($position)
{
return $this->show($position, Asset::TYPE_JAVASCRIPT);
}
public function showStyleSheet($position)
{
return $this->show($position, Asset::TYPE_CSS);
}
public function show($position, $type)
{
$assets = AssetManager::instance()->getAssetsFor($position, $type);
if (empty($assets)) {
return '';
}
$html = '';
foreach ($assets as $asset) {
$html .= $this->getAssetHtml($asset);
}
return $html;
}
private function getAssetHtml(Asset $asset)
{
if ($asset->isCss()) {
return $this->getCssHtml($asset);
}
return $this->getJavaAssetHtml($asset);
}
private function getCssHtml(Asset $stylesheet)
{
return '<link href="' . $stylesheet->urlWithVersion() . '" type="text/css" rel="stylesheet" />' . "\n";
}
private function getJavaAssetHtml(Asset $javascript)
{
return '<script src="' . $javascript->urlWithVersion() . '"></script>' . "\n";
}
}
Loading…
Cancel
Save