BaseAsset.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. * @package Grav\Common\Assets
  4. *
  5. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Assets;
  9. use Grav\Common\Assets\Traits\AssetUtilsTrait;
  10. use Grav\Common\Grav;
  11. use Grav\Common\Uri;
  12. use Grav\Common\Utils;
  13. use Grav\Framework\Object\PropertyObject;
  14. abstract class BaseAsset extends PropertyObject
  15. {
  16. use AssetUtilsTrait;
  17. protected const CSS_ASSET = true;
  18. protected const JS_ASSET = false;
  19. /** @const Regex to match CSS import content */
  20. protected const CSS_IMPORT_REGEX = '{@import(.*?);}';
  21. protected $asset;
  22. protected $asset_type;
  23. protected $order;
  24. protected $group;
  25. protected $position;
  26. protected $priority;
  27. protected $attributes = [];
  28. protected $timestamp;
  29. protected $modified;
  30. protected $remote;
  31. protected $query = '';
  32. // Private Bits
  33. private $base_url;
  34. private $fetch_command;
  35. private $css_rewrite = false;
  36. private $css_minify = false;
  37. abstract function render();
  38. public function __construct(array $elements = [], $key = null)
  39. {
  40. $base_config = [
  41. 'group' => 'head',
  42. 'position' => 'pipeline',
  43. 'priority' => 10,
  44. 'modified' => null,
  45. 'asset' => null
  46. ];
  47. // Merge base defaults
  48. $elements = array_merge($base_config, $elements);
  49. parent::__construct($elements, $key);
  50. }
  51. public function init($asset, $options)
  52. {
  53. $config = Grav::instance()['config'];
  54. $uri = Grav::instance()['uri'];
  55. // set attributes
  56. foreach ($options as $key => $value) {
  57. if ($this->hasProperty($key)) {
  58. $this->setProperty($key, $value);
  59. } else {
  60. $this->attributes[$key] = $value;
  61. }
  62. }
  63. // Force priority to be an int
  64. $this->priority = (int) $this->priority;
  65. // Do some special stuff for CSS/JS (not inline)
  66. if (!Utils::startsWith($this->getType(), 'inline')) {
  67. $this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
  68. $this->remote = static::isRemoteLink($asset);
  69. // Move this to render?
  70. if (!$this->remote) {
  71. $asset_parts = parse_url($asset);
  72. if (isset($asset_parts['query'])) {
  73. $this->query = $asset_parts['query'];
  74. unset($asset_parts['query']);
  75. $asset = Uri::buildUrl($asset_parts);
  76. }
  77. $locator = Grav::instance()['locator'];
  78. if ($locator->isStream($asset)) {
  79. $path = $locator->findResource($asset, true);
  80. } else {
  81. $path = GRAV_ROOT . $asset;
  82. }
  83. // If local file is missing return
  84. if ($path === false) {
  85. return false;
  86. }
  87. $file = new \SplFileInfo($path);
  88. $asset = $this->buildLocalLink($file->getPathname());
  89. $this->modified = $file->isFile() ? $file->getMTime() : false;
  90. }
  91. }
  92. $this->asset = $asset;
  93. return $this;
  94. }
  95. public function getAsset()
  96. {
  97. return $this->asset;
  98. }
  99. public function getRemote()
  100. {
  101. return $this->remote;
  102. }
  103. public function setPosition($position)
  104. {
  105. $this->position = $position;
  106. return $this;
  107. }
  108. /**
  109. *
  110. * Get the last modification time of asset
  111. *
  112. * @param string $asset the asset string reference
  113. *
  114. * @return string the last modifcation time or false on error
  115. */
  116. // protected function getLastModificationTime($asset)
  117. // {
  118. // $file = GRAV_ROOT . $asset;
  119. // if (Grav::instance()['locator']->isStream($asset)) {
  120. // $file = $this->buildLocalLink($asset, true);
  121. // }
  122. //
  123. // return file_exists($file) ? filemtime($file) : false;
  124. // }
  125. /**
  126. *
  127. * Build local links including grav asset shortcodes
  128. *
  129. * @param string $asset the asset string reference
  130. *
  131. * @return string the final link url to the asset
  132. */
  133. protected function buildLocalLink($asset)
  134. {
  135. if ($asset) {
  136. return $this->base_url . ltrim(Utils::replaceFirstOccurrence(GRAV_ROOT, '', $asset), '/');
  137. }
  138. return false;
  139. }
  140. /**
  141. * Implements JsonSerializable interface.
  142. *
  143. * @return array
  144. */
  145. public function jsonSerialize()
  146. {
  147. return ['type' => $this->getType(), 'elements' => $this->getElements()];
  148. }
  149. /**
  150. * Placeholder for AssetUtilsTrait method
  151. *
  152. * @param string $file
  153. * @param string $dir
  154. * @param bool $local
  155. */
  156. protected function cssRewrite($file, $dir, $local)
  157. {
  158. return;
  159. }
  160. }