PageRenderTime 95ms CodeModel.GetById 36ms RepoModel.GetById 7ms app.codeStats 0ms

/vendor/assetic/src/Assetic/Factory/AssetFactory.php

https://github.com/ivanrey/Symfony-Community
PHP | 251 lines | 133 code | 35 blank | 83 comment | 23 complexity | 7f0ad10f67fcbe3ecf85ab524a9829ed MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Assetic package, an OpenSky project.
  4. *
  5. * (c) 2010-2011 OpenSky Project Inc
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Assetic\Factory;
  11. use Assetic\Asset\AssetCollection;
  12. use Assetic\Asset\AssetReference;
  13. use Assetic\Asset\FileAsset;
  14. use Assetic\Asset\GlobAsset;
  15. use Assetic\AssetManager;
  16. use Assetic\Factory\Worker\WorkerInterface;
  17. use Assetic\FilterManager;
  18. /**
  19. * The asset factory creates asset objects.
  20. *
  21. * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  22. */
  23. class AssetFactory
  24. {
  25. private $baseDir;
  26. private $output;
  27. private $debug;
  28. private $workers;
  29. private $am;
  30. private $fm;
  31. /**
  32. * Constructor.
  33. *
  34. * @param string $baseDir Path to the base directory for relative URLs
  35. * @param string $output The default output string
  36. * @param Boolean $debug Filters prefixed with a "?" will be omitted in debug mode
  37. */
  38. public function __construct($baseDir, $output = 'assetic/*', $debug = false)
  39. {
  40. $this->baseDir = rtrim($baseDir, '/').'/';
  41. $this->output = $output;
  42. $this->debug = $debug;
  43. $this->workers = array();
  44. }
  45. /**
  46. * Sets debug mode for the current factory.
  47. *
  48. * @param Boolean $debug Debug mode
  49. */
  50. public function setDebug($debug)
  51. {
  52. $this->debug = $debug;
  53. }
  54. /**
  55. * Checks if the factory is in debug mode.
  56. *
  57. * @return Boolean Debug mode
  58. */
  59. public function isDebug()
  60. {
  61. return $this->debug;
  62. }
  63. /**
  64. * Adds a factory worker.
  65. *
  66. * @param WorkerInterface $worker A worker
  67. */
  68. public function addWorker(WorkerInterface $worker)
  69. {
  70. $this->workers[] = $worker;
  71. }
  72. /**
  73. * Sets the asset manager to use when creating asset references.
  74. *
  75. * @param AssetManager $am The asset manager
  76. */
  77. public function setAssetManager(AssetManager $am)
  78. {
  79. $this->am = $am;
  80. }
  81. /**
  82. * Sets the filter manager to use when adding filters.
  83. *
  84. * @param FilterManager $fm The filter manager
  85. */
  86. public function setFilterManager(FilterManager $fm)
  87. {
  88. $this->fm = $fm;
  89. }
  90. /**
  91. * Creates a new asset.
  92. *
  93. * Prefixing a filter name with a question mark will cause it to be
  94. * omitted when the factory is in debug mode.
  95. *
  96. * Available options:
  97. *
  98. * * output: An output string
  99. * * name: An asset name for interpolation in output patterns
  100. * * debug: Forces debug mode on or off for this asset
  101. *
  102. * @param array|string $inputs An array of input strings
  103. * @param array|string $filters An array of filter names
  104. * @param array $options An array of options
  105. *
  106. * @return AssetCollection An asset collection
  107. */
  108. public function createAsset($inputs = array(), $filters = array(), array $options = array())
  109. {
  110. if (!is_array($inputs)) {
  111. $inputs = array($inputs);
  112. }
  113. if (!is_array($filters)) {
  114. $filters = array($filters);
  115. }
  116. if (!isset($options['output'])) {
  117. $options['output'] = $this->output;
  118. }
  119. if (!isset($options['name'])) {
  120. $options['name'] = $this->generateAssetName($inputs, $filters);
  121. }
  122. if (!isset($options['debug'])) {
  123. $options['debug'] = $this->debug;
  124. }
  125. $asset = $this->createAssetCollection();
  126. $extensions = array();
  127. // inner assets
  128. foreach ($inputs as $input) {
  129. $asset->add($this->parseInput($input));
  130. $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true;
  131. }
  132. // filters
  133. foreach ($filters as $filter) {
  134. if ('?' != $filter[0]) {
  135. $asset->ensureFilter($this->getFilter($filter));
  136. } elseif (!$options['debug']) {
  137. $asset->ensureFilter($this->getFilter(substr($filter, 1)));
  138. }
  139. }
  140. // append consensus extension if missing
  141. if (1 == count($extensions) && !pathinfo($options['output'], PATHINFO_EXTENSION) && $extension = key($extensions)) {
  142. $options['output'] .= '.'.$extension;
  143. }
  144. // output --> target url
  145. $asset->setTargetUrl(str_replace('*', $options['name'], $options['output']));
  146. foreach ($this->workers as $worker) {
  147. $worker->process($asset);
  148. }
  149. return $asset;
  150. }
  151. public function generateAssetName($inputs, $filters)
  152. {
  153. return substr(sha1(serialize(array_merge($inputs, $filters))), 0, 7);
  154. }
  155. /**
  156. * Parses an input string string into an asset.
  157. *
  158. * The input string can be one of the following:
  159. *
  160. * * A reference: If the string starts with an "at" sign it will be interpreted as a reference to an asset in the asset manager
  161. * * An absolute URL: If the string contains "://" it will be interpreted as a remote asset
  162. * * A glob: If the string contains a "*" it will be interpreted as a glob
  163. * * A path: Otherwise the string is interpreted as a path
  164. *
  165. * Both globs and paths will be absolutized using the current base directory.
  166. *
  167. * @param string $input An input string
  168. *
  169. * @return AssetInterface An asset
  170. */
  171. protected function parseInput($input)
  172. {
  173. if ('@' == $input[0]) {
  174. return $this->createAssetReference(substr($input, 1));
  175. }
  176. if (false !== strpos($input, '://')) {
  177. return $this->createFileAsset($input, $input);
  178. }
  179. $baseDir = self::isAbsolutePath($input) ? '' : $this->baseDir;
  180. if (false !== strpos($input, '*')) {
  181. return $this->createGlobAsset($baseDir . $input, $this->baseDir);
  182. } else {
  183. return $this->createFileAsset($baseDir . $input, $input);
  184. }
  185. }
  186. protected function createAssetCollection()
  187. {
  188. return new AssetCollection();
  189. }
  190. protected function createAssetReference($name)
  191. {
  192. if (!$this->am) {
  193. throw new \LogicException('There is no asset manager.');
  194. }
  195. return new AssetReference($this->am, $name);
  196. }
  197. protected function createGlobAsset($glob, $baseDir = null)
  198. {
  199. return new GlobAsset($glob, array(), $baseDir);
  200. }
  201. protected function createFileAsset($path, $sourceUrl = null)
  202. {
  203. return new FileAsset($path, array(), $sourceUrl);
  204. }
  205. protected function getFilter($name)
  206. {
  207. if (!$this->fm) {
  208. throw new \LogicException('There is no filter manager.');
  209. }
  210. return $this->fm->get($name);
  211. }
  212. static private function isAbsolutePath($path)
  213. {
  214. return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2]));
  215. }
  216. }