file CdnAsset.php

Namespace

Drupal\bootstrap\Plugin\Provider
  1. <?php
  2. namespace Drupal\bootstrap\Plugin\Provider;
  3. use Drupal\bootstrap\Bootstrap;
  4. use Drupal\bootstrap\Utility\Crypt;
  5. use Drupal\bootstrap\Utility\Unicode;
  6. use Drupal\Component\Render\HtmlEscapedText;
  7. use Drupal\Component\Utility\Html;
  8. use Drupal\Component\Utility\NestedArray;
  9. use Drupal\Component\Utility\ToStringTrait;
  10. use Drupal\Core\DependencyInjection\DependencySerializationTrait;
  11. use Drupal\Core\StringTranslation\StringTranslationTrait;
  12. /**
  13. * Class CdnAsset.
  14. */
  15. class CdnAsset {
  16. use StringTranslationTrait;
  17. use DependencySerializationTrait;
  18. use ToStringTrait;
  19. /**
  20. * Invalid asset regular expression.
  21. *
  22. * @var string
  23. */
  24. const INVALID_FILE_REGEXP = '`^/2|/bower_components`';
  25. /**
  26. * Valid asset regular expression.
  27. *
  28. * @var string
  29. */
  30. const VALID_FILE_REGEXP = '`([^/]*)/(?:[\w-]+)?bootstrap(?:-([\w]+))?(\.min)?\.(js|css)$`';
  31. /**
  32. * A list of available Bootswatch themes, keyed by major Bootstrap version.
  33. *
  34. * @var array
  35. */
  36. protected static $bootswatchThemes = [
  37. 3 => [
  38. 'cerulean',
  39. 'cosmo',
  40. 'cyborg',
  41. 'darkly',
  42. 'flatly',
  43. 'journal',
  44. 'lumen',
  45. 'paper',
  46. 'readable',
  47. 'sandstone',
  48. 'simplex',
  49. 'slate',
  50. 'spacelab',
  51. 'superhero',
  52. 'united',
  53. 'yeti',
  54. ],
  55. 4 => [
  56. 'cerulean',
  57. 'cosmo',
  58. 'cyborg',
  59. 'darkly',
  60. 'flatly',
  61. 'journal',
  62. 'litera',
  63. 'lumen',
  64. 'lux',
  65. 'materia',
  66. 'minty',
  67. 'pulse',
  68. 'sandstone',
  69. 'simplex',
  70. 'sketchy',
  71. 'slate',
  72. 'solar',
  73. 'spacelab',
  74. 'superhero',
  75. 'united',
  76. 'yeti',
  77. ],
  78. ];
  79. /**
  80. * A unique identifier.
  81. *
  82. * @var string
  83. */
  84. protected $id;
  85. /**
  86. * Additional information supplied from the CDN API.
  87. *
  88. * @var array
  89. */
  90. protected $info;
  91. /**
  92. * A human readable label for the CDN Asset.
  93. *
  94. * @var \Drupal\Component\Render\MarkupInterface
  95. */
  96. protected $label;
  97. /**
  98. * The library this URL references.
  99. *
  100. * @var string
  101. */
  102. protected $library;
  103. /**
  104. * Flag indicating whether the URL is minified.
  105. *
  106. * @var bool
  107. */
  108. protected $minified;
  109. /**
  110. * The theme this URL references.
  111. *
  112. * @var string
  113. */
  114. protected $theme;
  115. /**
  116. * The type of resource, e.g. css or js.
  117. *
  118. * @var string
  119. */
  120. protected $type;
  121. /**
  122. * The URL.
  123. *
  124. * @var string
  125. */
  126. protected $url;
  127. /**
  128. * The version this URL references.
  129. *
  130. * @var string
  131. */
  132. protected $version;
  133. /**
  134. * CdnAsset constructor.
  135. *
  136. * @param string $url
  137. * The absolute URL to to the CDN asset.
  138. * @param string $library
  139. * The specific library this asset is associated with, if known.
  140. * @param string $version
  141. * The specific version this asset is associated with, if known.
  142. * @param array $info
  143. * Additional information provided by the CDN.
  144. */
  145. public function __construct($url, $library = NULL, $version = NULL, array $info = []) {
  146. // Extract the necessary data from the file.
  147. list($path, $theme, $minified, $type) = static::extractParts($url);
  148. // @todo Remove once PHP 5.5 is no longer supported (use array access).
  149. $major = substr(Bootstrap::FRAMEWORK_VERSION, 0, 1);
  150. // Bootstrap's example theme.
  151. if ($theme === 'theme') {
  152. $theme = 'bootstrap_theme';
  153. $label = $this->t('Example Theme');
  154. if (!isset($library)) {
  155. $library = 'bootstrap';
  156. }
  157. }
  158. // Core bootstrap library.
  159. elseif (!$theme && ($path === 'css' || $path === 'js' || $path === Bootstrap::PROJECT_BRANCH)) {
  160. $theme = 'bootstrap';
  161. $label = $this->t('Default');
  162. if (!isset($library)) {
  163. $library = 'bootstrap';
  164. }
  165. }
  166. // Other (e.g. bootswatch theme).
  167. else {
  168. $bootswatchThemes = isset(static::$bootswatchThemes[$major]) ? static::$bootswatchThemes[$major] : [];
  169. if (!$theme || ($theme && !in_array($theme, $bootswatchThemes))) {
  170. $theme = in_array($path, $bootswatchThemes) ? $path : 'bootstrap';
  171. }
  172. $label = new HtmlEscapedText(ucfirst($theme));
  173. if (!isset($library)) {
  174. $library = in_array($theme, $bootswatchThemes) ? 'bootswatch' : 'unknown';
  175. }
  176. }
  177. // If no version was provided, attempt to extract it.
  178. // @todo Move regular expression to a constant once PHP 5.5 is no longer
  179. // supported.
  180. if (!isset($version) && preg_match('`(' . $major . '\.\d+\.\d+)`', $url, $matches)) {
  181. $version = $matches[1];
  182. }
  183. $this->id = Crypt::generateBase64HashIdentifier([
  184. 'url' => $url,
  185. 'info' => $info,
  186. ], [$library, $version, $theme, basename($url)]);
  187. $this->info = $info;
  188. $this->label = $label;
  189. $this->library = $library;
  190. $this->minified = $minified;
  191. $this->theme = $theme;
  192. $this->type = $type;
  193. $this->url = $url;
  194. $this->version = $version;
  195. }
  196. /**
  197. * Extracts the necessary parts of the URL.
  198. *
  199. * @param string $url
  200. * The URL to parse.
  201. *
  202. * @return array
  203. */
  204. protected static function extractParts($url) {
  205. preg_match(static::VALID_FILE_REGEXP, $url, $matches);
  206. $path = isset($matches[1]) ? mb_strtolower(Html::escape($matches[1])) : NULL;
  207. $theme = isset($matches[2]) ? mb_strtolower(Html::escape($matches[2])) : NULL;
  208. $minified = isset($matches[3]) ? !!$matches[3] : FALSE;
  209. $type = isset($matches[4]) ? mb_strtolower(Html::escape($matches[4])) : NULL;
  210. return [$path, $theme, $minified, $type];
  211. }
  212. /**
  213. * Indicates whether the provided URL is valid.
  214. *
  215. * @param string $url
  216. * The URL to check.
  217. *
  218. * @return bool
  219. * TRUE or FALSE
  220. */
  221. public static function isFileValid($url) {
  222. if (preg_match(static::INVALID_FILE_REGEXP, $url)) {
  223. return FALSE;
  224. }
  225. list($path, $example, $minified, $type) = static::extractParts($url);
  226. return $path && $type;
  227. }
  228. /**
  229. * Retrieves the unique identifier for this asset.
  230. *
  231. * @return string
  232. * The unique identifier.
  233. */
  234. public function getId() {
  235. return $this->id;
  236. }
  237. /**
  238. * Retrieves information provided by the CDN API, if available.
  239. *
  240. * @param string $key
  241. * Optional. A specific key of the item to retrieve. Note: this can be in
  242. * the form of dot notation if the value is nested in an array. If not
  243. * provided, the entire contents of the info will be returned.
  244. * @param mixed $default
  245. * The default value to use if $key was provided and does not exist.
  246. *
  247. * @return mixed
  248. * The specified information or the entire contents of the array if $key
  249. * was not provided.
  250. */
  251. public function getInfo($key = NULL, $default = NULL) {
  252. $info = $this->info ?: [];
  253. if (isset($key)) {
  254. $parts = Unicode::splitDelimiter($key);
  255. $value = NestedArray::getValue($info, $parts, $exists);
  256. return $exists ? $value : $default;
  257. }
  258. return $info;
  259. }
  260. /**
  261. * Retrieves the human readable label.
  262. *
  263. * @return \Drupal\Component\Render\MarkupInterface
  264. * The label.
  265. */
  266. public function getLabel() {
  267. return $this->label;
  268. }
  269. /**
  270. * Retrieves the library this CDN asset is associated with, if any.
  271. *
  272. * @return string
  273. * The library.
  274. */
  275. public function getLibrary() {
  276. return $this->library;
  277. }
  278. /**
  279. * Retrieves the theme this CDN asset is associated with, if any.
  280. *
  281. * @return string
  282. * The theme.
  283. */
  284. public function getTheme() {
  285. return $this->theme;
  286. }
  287. /**
  288. * Retrieves the type of CDN asset this is (e.g. css or js).
  289. *
  290. * @return string
  291. */
  292. public function getType() {
  293. return $this->type;
  294. }
  295. /**
  296. * Retrieves the absolute URL this CDN asset represents.
  297. *
  298. * @return string
  299. */
  300. public function getUrl() {
  301. return $this->url;
  302. }
  303. /**
  304. * Retrieves the version this CDN asset is associated with, if any.
  305. *
  306. * @return string
  307. */
  308. public function getVersion() {
  309. return $this->version;
  310. }
  311. /**
  312. * Indicates whether the CDN asset is minified.
  313. *
  314. * @return bool
  315. * TRUE or FALSE
  316. */
  317. public function isMinified() {
  318. return $this->minified;
  319. }
  320. /**
  321. * {@inheritdoc}
  322. */
  323. public function render() {
  324. return $this->getUrl();
  325. }
  326. }

Classes

Name Description
CdnAsset Class CdnAsset.