AssetBundle.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. namespace yiins\web;
  3. use yiins\Yii;
  4. /**
  5. * Class AssetBundle
  6. * @package base\web
  7. *
  8. */
  9. class AssetBundle extends \CApplicationComponent
  10. {
  11. /**
  12. * @var AssetBundle[]
  13. */
  14. protected static $registeredBundles = [];
  15. /**
  16. * @var string the directory that contains the source asset assets for this asset bundle.
  17. * A source asset file is a file that is part of your source code repository of your Web application.
  18. *
  19. * You must set this property if the directory containing the source asset assets is not Web accessible.
  20. * By setting this property, [[AssetManager]] will publish the source asset assets
  21. * to a Web-accessible directory automatically when the asset bundle is registered on a page.
  22. */
  23. public $sourcePath;
  24. /**
  25. * @var array list of bundle class names that this bundle depends on.
  26. *
  27. * For example:
  28. *
  29. * ```php
  30. * public $depends = [
  31. * 'base\assets\JQueryAssets',
  32. * '\base\bootstrap\BootstrapAssets',
  33. * ];
  34. * ```
  35. */
  36. public $depends = [];
  37. /**
  38. * @var array list of JavaScript assets that this bundle contains. Each JavaScript file can be
  39. * specified in one of the following formats:
  40. *
  41. * - an absolute URL representing an external asset. For example,
  42. * `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or
  43. * `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`.
  44. * - a relative path representing a local asset (e.g. `js/main.js`). The actual file path of a local
  45. * asset can be determined by prefixing [[basePath]] to the relative path, and the actual URL
  46. * of the asset can be determined by prefixing [[baseUrl]] to the relative path.
  47. * - an array, with the first entry being the URL or relative path as described before, and a list of key => value pairs
  48. * that will be used to overwrite [[jsOptions]] settings for this entry.
  49. * This functionality is available since version 2.0.7.
  50. *
  51. * Note that only a forward slash "/" should be used as directory separator.
  52. */
  53. public $js = [];
  54. /**
  55. * @var array list of CSS assets that this bundle contains. Each CSS file can be specified
  56. * in one of the three formats as explained in [[js]].
  57. *
  58. * Note that only a forward slash "/" should be used as directory separator.
  59. */
  60. public $css = [];
  61. /**
  62. * @var \CAssetManager
  63. */
  64. protected $assetManager = null;
  65. /**
  66. * @var string the base URL for the relative asset assets listed in [[js]] and [[css]].
  67. */
  68. protected $baseUrl;
  69. private $isRegistered = false;
  70. public function __construct()
  71. {
  72. $this->init();
  73. }
  74. /**
  75. * Initializes the bundle.
  76. * If you override this method, make sure you call the parent implementation in the last.
  77. */
  78. public function init()
  79. {
  80. if ($this->sourcePath !== null) {
  81. $sourcePath = trim($this->sourcePath);
  82. $path = Yii::getPathOfAlias(str_replace(['\\', '/'], '.', trim($sourcePath, '/\\')));
  83. if (!$path) {
  84. $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, rtrim($sourcePath, '/\\'));
  85. }
  86. $this->sourcePath = $path;
  87. }
  88. if ($this->baseUrl !== null) {
  89. $this->baseUrl = rtrim($this->baseUrl, '/');
  90. }
  91. parent::init();
  92. }
  93. /**
  94. * Get asset URL
  95. * @param $asset
  96. * @return string URL of the asset
  97. */
  98. public static function getAsset($asset)
  99. {
  100. if (!isset(self::$registeredBundles[static::class])) {
  101. self::$registeredBundles[static::class] = new static();
  102. self::$registeredBundles[static::class]->publish();
  103. }
  104. return self::$registeredBundles[static::class]->getAssetUrl($asset);
  105. }
  106. protected function publish()
  107. {
  108. if ($this->sourcePath) {
  109. $this->baseUrl = $this->getAssetManager()->publish($this->sourcePath);
  110. }
  111. }
  112. public function getAssetManager()
  113. {
  114. return Yii::web()->getAssetManager();
  115. }
  116. /**
  117. * @param $asset
  118. * @return string
  119. */
  120. protected function getAssetUrl($asset)
  121. {
  122. if (strncmp($asset, 'http', 4) === 0 || strncmp($asset, '//', 2) === 0) {
  123. return $asset;
  124. } else {
  125. return $this->baseUrl . '/' . trim($asset);
  126. }
  127. }
  128. public static function getUrl()
  129. {
  130. if (!isset(self::$registeredBundles[static::class])) {
  131. self::$registeredBundles[static::class] = new static();
  132. self::$registeredBundles[static::class]->publish();
  133. }
  134. return self::$registeredBundles[static::class]->baseUrl;
  135. }
  136. public static function register($scriptFilesPosition = false, $defaultRegisterDependencies = true)
  137. {
  138. if (isset(self::$registeredBundles[static::class]) && self::$registeredBundles[static::class]->isRegistered) {
  139. return true;
  140. }
  141. $instance = new static;
  142. return $instance->registerBundle($scriptFilesPosition, $defaultRegisterDependencies);
  143. }
  144. public function registerBundle($scriptFilesPosition, $defaultRegisterDependencies = true)
  145. {
  146. if ($defaultRegisterDependencies) {
  147. $this->resolveDependencies($scriptFilesPosition);
  148. }
  149. if ($scriptFilesPosition === false) {
  150. $scriptFilesPosition = Yii::web()->clientScript->defaultScriptFilePosition;
  151. }
  152. $this->publish();
  153. foreach ($this->css as $key => $value) {
  154. $file = $value;
  155. $media = '';
  156. if (is_string($key)) {
  157. $file = $key;
  158. $media = $value;
  159. }
  160. Yii::web()->clientScript
  161. ->registerCssFile($this->getAssetUrl($file), $media);
  162. }
  163. foreach ($this->js as $key => $value) {
  164. $file = $value;
  165. $params = [];
  166. if (is_array($value)) {
  167. $file = $value[0];
  168. unset($value[0]);
  169. $params = $value;
  170. $position = $scriptFilesPosition;
  171. if (isset($params['position'])) {
  172. $position = $params['position'];
  173. }
  174. $this->registerScriptFile($file, $position, $params);
  175. } elseif (is_string($key)) {
  176. $this->registerScriptFile($key, $value, $params);
  177. } else {
  178. $this->registerScriptFile($file, $scriptFilesPosition, $params);
  179. }
  180. }
  181. self::$registeredBundles[static::class] = $this;
  182. self::$registeredBundles[static::class]->isRegistered = true;
  183. return true;
  184. }
  185. protected function resolveDependencies($scriptFilesPosition)
  186. {
  187. $defaultScriptFilePosition = $scriptFilesPosition;
  188. $defaultRegisterDependencies = true;
  189. foreach ($this->depends as $key => $value) {
  190. $bundle = $value;
  191. $registerDependencies = $defaultRegisterDependencies;
  192. if (is_string($key)) {
  193. $bundle = $key;
  194. if (is_array($value)) {
  195. $scriptFilesPosition = $value[0];
  196. $registerDependencies = $value[1];
  197. } else {
  198. $scriptFilesPosition = $value;
  199. }
  200. }
  201. $bundle::register($scriptFilesPosition, $registerDependencies);
  202. $scriptFilesPosition = $defaultScriptFilePosition;
  203. }
  204. }
  205. private function registerScriptFile($file, $position, $params)
  206. {
  207. if (!Yii::web()->clientScript->isScriptFileRegistered($this->getAssetUrl($file), $position)) {
  208. Yii::web()->clientScript
  209. ->registerScriptFile($this->getAssetUrl($file), $position, $params);
  210. }
  211. }
  212. }