LazyAssetManager.php 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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\AssetManager;
  12. use Assetic\Factory\Loader\FormulaLoaderInterface;
  13. use Assetic\Factory\Resource\ResourceInterface;
  14. /**
  15. * A lazy asset manager is a composition of a factory and many formula loaders.
  16. *
  17. * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  18. */
  19. class LazyAssetManager extends AssetManager
  20. {
  21. private $factory;
  22. private $loaders;
  23. private $resources;
  24. private $formulae;
  25. private $loaded;
  26. private $loading;
  27. /**
  28. * Constructor.
  29. *
  30. * @param AssetFactory $factory The asset factory
  31. * @param array $loaders An array of loaders indexed by alias
  32. */
  33. public function __construct(AssetFactory $factory, $loaders = array())
  34. {
  35. $this->factory = $factory;
  36. $this->loaders = array();
  37. $this->resources = array();
  38. $this->formulae = array();
  39. $this->loaded = false;
  40. $this->loading = false;
  41. foreach ($loaders as $alias => $loader) {
  42. $this->setLoader($alias, $loader);
  43. }
  44. }
  45. /**
  46. * Adds a loader to the asset manager.
  47. *
  48. * @param string $alias An alias for the loader
  49. * @param FormulaLoaderInterface $loader A loader
  50. */
  51. public function setLoader($alias, FormulaLoaderInterface $loader)
  52. {
  53. $this->loaders[$alias] = $loader;
  54. $this->loaded = false;
  55. }
  56. /**
  57. * Adds a resource to the asset manager.
  58. *
  59. * @param ResourceInterface $resource A resource
  60. * @param string $loader The loader alias for this resource
  61. */
  62. public function addResource(ResourceInterface $resource, $loader)
  63. {
  64. $this->resources[$loader][] = $resource;
  65. $this->loaded = false;
  66. }
  67. /**
  68. * Returns an array of resources.
  69. *
  70. * @return array An array of resources
  71. */
  72. public function getResources()
  73. {
  74. $resources = array();
  75. foreach ($this->resources as $r) {
  76. $resources = array_merge($resources, $r);
  77. }
  78. return $resources;
  79. }
  80. /**
  81. * Checks for an asset formula.
  82. *
  83. * @param string $name An asset name
  84. *
  85. * @return Boolean If there is a formula
  86. */
  87. public function hasFormula($name)
  88. {
  89. if (!$this->loaded) {
  90. $this->load();
  91. }
  92. return isset($this->formulae[$name]);
  93. }
  94. /**
  95. * Returns an asset's formula.
  96. *
  97. * @param string $name An asset name
  98. *
  99. * @return array The formula
  100. *
  101. * @throws InvalidArgumentException If there is no formula by that name
  102. */
  103. public function getFormula($name)
  104. {
  105. if (!$this->loaded) {
  106. $this->load();
  107. }
  108. if (!isset($this->formulae[$name])) {
  109. throw new \InvalidArgumentException(sprintf('There is no "%s" formula.', $name));
  110. }
  111. return $this->formulae[$name];
  112. }
  113. /**
  114. * Sets a formula on the asset manager.
  115. *
  116. * @param string $name An asset name
  117. * @param array $formula A formula
  118. */
  119. public function setFormula($name, array $formula)
  120. {
  121. $this->formulae[$name] = $formula;
  122. }
  123. /**
  124. * Loads formulae from resources.
  125. *
  126. * @throws LogicException If a resource has been added to an invalid loader
  127. */
  128. public function load()
  129. {
  130. if ($this->loading) {
  131. return;
  132. }
  133. if ($diff = array_diff(array_keys($this->resources), array_keys($this->loaders))) {
  134. throw new \LogicException('The following loader(s) are not registered: '.implode(', ', $diff));
  135. }
  136. $this->loading = true;
  137. foreach ($this->resources as $loader => $resources) {
  138. foreach ($resources as $resource) {
  139. $this->formulae = array_replace($this->formulae, $this->loaders[$loader]->load($resource));
  140. }
  141. }
  142. $this->loaded = true;
  143. $this->loading = false;
  144. }
  145. public function get($name)
  146. {
  147. if (!$this->loaded) {
  148. $this->load();
  149. }
  150. if (!parent::has($name) && isset($this->formulae[$name])) {
  151. list($inputs, $filters, $options) = $this->formulae[$name];
  152. $options['name'] = $name;
  153. parent::set($name, $this->factory->createAsset($inputs, $filters, $options));
  154. }
  155. return parent::get($name);
  156. }
  157. public function has($name)
  158. {
  159. if (!$this->loaded) {
  160. $this->load();
  161. }
  162. return isset($this->formulae[$name]) || parent::has($name);
  163. }
  164. public function getNames()
  165. {
  166. if (!$this->loaded) {
  167. $this->load();
  168. }
  169. return array_unique(array_merge(parent::getNames(), array_keys($this->formulae)));
  170. }
  171. public function isDebug()
  172. {
  173. return $this->factory->isDebug();
  174. }
  175. }