123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- <?php
- /**
- * @package Grav\Common\Assets
- *
- * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Common\Assets;
- use Grav\Common\Assets\Traits\AssetUtilsTrait;
- use Grav\Common\Config\Config;
- use Grav\Common\Grav;
- use Grav\Common\Uri;
- use Grav\Common\Utils;
- use Grav\Framework\Object\PropertyObject;
- use SplFileInfo;
- /**
- * Class BaseAsset
- * @package Grav\Common\Assets
- */
- abstract class BaseAsset extends PropertyObject
- {
- use AssetUtilsTrait;
- protected const CSS_ASSET = true;
- protected const JS_ASSET = false;
- /** @var string|false */
- protected $asset;
- /** @var string */
- protected $asset_type;
- /** @var int */
- protected $order;
- /** @var string */
- protected $group;
- /** @var string */
- protected $position;
- /** @var int */
- protected $priority;
- /** @var array */
- protected $attributes = [];
- /** @var string */
- protected $timestamp;
- /** @var int|false */
- protected $modified;
- /** @var bool */
- protected $remote;
- /** @var string */
- protected $query = '';
- // Private Bits
- /** @var bool */
- private $css_rewrite = false;
- /** @var bool */
- private $css_minify = false;
- /**
- * @return string
- */
- abstract function render();
- /**
- * BaseAsset constructor.
- * @param array $elements
- * @param string|null $key
- */
- public function __construct(array $elements = [], $key = null)
- {
- $base_config = [
- 'group' => 'head',
- 'position' => 'pipeline',
- 'priority' => 10,
- 'modified' => null,
- 'asset' => null
- ];
- // Merge base defaults
- $elements = array_merge($base_config, $elements);
- parent::__construct($elements, $key);
- }
- /**
- * @param string|false $asset
- * @param array $options
- * @return $this|false
- */
- public function init($asset, $options)
- {
- $config = Grav::instance()['config'];
- $uri = Grav::instance()['uri'];
- // set attributes
- foreach ($options as $key => $value) {
- if ($this->hasProperty($key)) {
- $this->setProperty($key, $value);
- } else {
- $this->attributes[$key] = $value;
- }
- }
- // Force priority to be an int
- $this->priority = (int) $this->priority;
- // Do some special stuff for CSS/JS (not inline)
- if (!Utils::startsWith($this->getType(), 'inline')) {
- $this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
- $this->remote = static::isRemoteLink($asset);
- // Move this to render?
- if (!$this->remote) {
- $asset_parts = parse_url($asset);
- if (isset($asset_parts['query'])) {
- $this->query = $asset_parts['query'];
- unset($asset_parts['query']);
- $asset = Uri::buildUrl($asset_parts);
- }
- $locator = Grav::instance()['locator'];
- if ($locator->isStream($asset)) {
- $path = $locator->findResource($asset, true);
- } else {
- $path = GRAV_WEBROOT . $asset;
- }
- // If local file is missing return
- if ($path === false) {
- return false;
- }
- $file = new SplFileInfo($path);
- $asset = $this->buildLocalLink($file->getPathname());
- $this->modified = $file->isFile() ? $file->getMTime() : false;
- }
- }
- $this->asset = $asset;
- return $this;
- }
- /**
- * @return string|false
- */
- public function getAsset()
- {
- return $this->asset;
- }
- /**
- * @return bool
- */
- public function getRemote()
- {
- return $this->remote;
- }
- /**
- * @param string $position
- * @return $this
- */
- public function setPosition($position)
- {
- $this->position = $position;
- return $this;
- }
- /**
- * Receive asset location and return the SRI integrity hash
- *
- * @param string $input
- * @return string
- */
- public static function integrityHash($input)
- {
- $grav = Grav::instance();
- $assetsConfig = $grav['config']->get('system.assets');
- if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] )
- {
- $dataToHash = file_get_contents( GRAV_WEBROOT . $input);
- $hash = hash('sha256', $dataToHash, true);
- $hash_base64 = base64_encode($hash);
- return ' integrity="sha256-' . $hash_base64 . '"';
- }
- return '';
- }
- /**
- *
- * Get the last modification time of asset
- *
- * @param string $asset the asset string reference
- *
- * @return string the last modifcation time or false on error
- */
- // protected function getLastModificationTime($asset)
- // {
- // $file = GRAV_WEBROOT . $asset;
- // if (Grav::instance()['locator']->isStream($asset)) {
- // $file = $this->buildLocalLink($asset, true);
- // }
- //
- // return file_exists($file) ? filemtime($file) : false;
- // }
- /**
- *
- * Build local links including grav asset shortcodes
- *
- * @param string $asset the asset string reference
- *
- * @return string|false the final link url to the asset
- */
- protected function buildLocalLink($asset)
- {
- if ($asset) {
- return $this->base_url . ltrim(Utils::replaceFirstOccurrence(GRAV_WEBROOT, '', $asset), '/');
- }
- return false;
- }
- /**
- * Implements JsonSerializable interface.
- *
- * @return array
- */
- public function jsonSerialize()
- {
- return ['type' => $this->getType(), 'elements' => $this->getElements()];
- }
- /**
- * Placeholder for AssetUtilsTrait method
- *
- * @param string $file
- * @param string $dir
- * @param bool $local
- * @return string
- */
- protected function cssRewrite($file, $dir, $local)
- {
- return;
- }
- }
|