PageRenderTime 66ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/category_tool/fuel/core/classes/asset/instance.php

https://github.com/connvoi/dev
PHP | 472 lines | 254 code | 65 blank | 153 comment | 23 complexity | 1507940e937941fa364b600609774b9b MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * @package Fuel
  6. * @version 1.0
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2012 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. /**
  14. * The Asset class allows you to easily work with your apps assets.
  15. * It allows you to specify multiple paths to be searched for the
  16. * assets.
  17. *
  18. * You can configure the paths by copying the core/config/asset.php
  19. * config file into your app/config folder and changing the settings.
  20. *
  21. * @package Fuel
  22. * @subpackage Core
  23. */
  24. class Asset_Instance
  25. {
  26. /**
  27. * @var array the asset paths to be searched
  28. */
  29. protected $_asset_paths = array(
  30. 'css' => array(),
  31. 'js' => array(),
  32. 'img' => array(),
  33. );
  34. /**
  35. * @var array the sub-folders to be searched
  36. */
  37. protected $_path_folders = array(
  38. 'css' => 'css/',
  39. 'js' => 'js/',
  40. 'img' => 'img/',
  41. );
  42. /**
  43. * @var string the URL to be prepended to all assets
  44. */
  45. protected $_asset_url = '/';
  46. /**
  47. * @var bool whether to append the file mtime to the url
  48. */
  49. protected $_add_mtime = true;
  50. /**
  51. * @var array holds the groups of assets
  52. */
  53. protected $_groups = array();
  54. /**
  55. * @var string prefix for generated output to provide proper indentation
  56. */
  57. protected $_ident = '';
  58. /**
  59. * @var bool if true, directly renders the output of no group name is given
  60. */
  61. protected $_auto_render = true;
  62. /**
  63. * @var bool if true the 'not found' exception will not be thrown and the asset is ignored.
  64. */
  65. protected $_fail_silently = false;
  66. /**
  67. * Parse the config and initialize the object instance
  68. *
  69. * @return void
  70. */
  71. public function __construct($config)
  72. {
  73. //global search path folders
  74. $this->_path_folders['css'] = $config['css_dir'];
  75. $this->_path_folders['js'] = $config['js_dir'];
  76. $this->_path_folders['img'] = $config['img_dir'];
  77. // global search paths
  78. foreach ($config['paths'] as $path)
  79. {
  80. $this->add_path($path);
  81. }
  82. // per-type search paths
  83. foreach ($config['folders'] as $type => $folders)
  84. {
  85. is_array($folders) or $folders = array($folders);
  86. foreach ($folders as $path)
  87. {
  88. $this->add_path($path, $type);
  89. }
  90. }
  91. $this->_add_mtime = $config['add_mtime'];
  92. $this->_asset_url = $config['url'];
  93. $this->_indent = str_repeat($config['indent_with'], $config['indent_level']);
  94. $this->_auto_render = $config['auto_render'];
  95. $this->_fail_silently = $config['fail_silently'];
  96. }
  97. /**
  98. * Adds the given path to the front of the asset paths array. It adds paths
  99. * in a way so that asset paths are used First in Last Out.
  100. *
  101. * @param string the path to add
  102. * @param string optional path type (js, css or img)
  103. * @return object current instance
  104. */
  105. public function add_path($path, $type = null)
  106. {
  107. is_null($type) and $type = $this->_path_folders;
  108. if( is_array($type))
  109. {
  110. foreach ($type as $key => $folder)
  111. {
  112. is_numeric($key) and $key = $folder;
  113. array_unshift($this->_asset_paths[$key], str_replace('../', '', rtrim($path, '/')).'/'.rtrim($folder, '/').'/');
  114. }
  115. }
  116. else
  117. {
  118. array_unshift($this->_asset_paths[$type], str_replace('../', '', rtrim($path, '/')).'/');
  119. }
  120. return $this;
  121. }
  122. /**
  123. * Removes the given path from the asset paths array
  124. *
  125. * @param string the path to remove
  126. * @param string optional path type (js, css or img)
  127. * @return object current instance
  128. */
  129. public function remove_path($path, $type = null)
  130. {
  131. is_null($type) and $type = $this->_path_folders;
  132. if( is_array($type))
  133. {
  134. foreach ($type as $key => $folder)
  135. {
  136. is_numeric($key) and $key = $folder;
  137. if (($found = array_search(str_replace('../', '', rtrim($path,'/').'/'.rtrim($folder, '/').'/'), $this->_asset_paths[$key])) !== false)
  138. {
  139. unset($this->_asset_paths[$key][$found]);
  140. }
  141. }
  142. }
  143. else
  144. {
  145. if (($key = array_search(str_replace('../', '', rtrim($path,'/')), $this->_asset_paths[$type])) !== false)
  146. {
  147. unset($this->_asset_paths[$type][$key]);
  148. }
  149. }
  150. return $this;
  151. }
  152. /**
  153. * Renders the given group. Each tag will be separated by a line break.
  154. * You can optionally tell it to render the files raw. This means that
  155. * all CSS and JS files in the group will be read and the contents included
  156. * in the returning value.
  157. *
  158. * @param mixed the group to render
  159. * @param bool whether to return the raw file or not
  160. * @return string the group's output
  161. */
  162. public function render($group = null, $raw = false)
  163. {
  164. is_null($group) and $group = '_default_';
  165. if (is_string($group))
  166. {
  167. isset($this->_groups[$group]) and $group = $this->_groups[$group];
  168. }
  169. is_array($group) or $group = array();
  170. $css = '';
  171. $js = '';
  172. $img = '';
  173. foreach ($group as $key => $item)
  174. {
  175. $type = $item['type'];
  176. $filename = $item['file'];
  177. $attr = $item['attr'];
  178. // only do a file search if the asset is not a URI
  179. if ( ! preg_match('|^(\w+:)?//|', $filename))
  180. {
  181. // and only if the asset is local to the applications base_url
  182. if ( ! preg_match('|^(\w+:)?//|', $this->_asset_url) or strpos($this->_asset_url, \Config::get('base_url')) === 0)
  183. {
  184. if ( ! ($file = $this->find_file($filename, $type)))
  185. {
  186. if ($this->_fail_silently)
  187. {
  188. continue;
  189. }
  190. throw new \FuelException('Could not find asset: '.$filename);
  191. }
  192. $raw or $file = $this->_asset_url.$file.($this->_add_mtime ? '?'.filemtime($file) : '');
  193. }
  194. else
  195. {
  196. $raw or $file = $this->_asset_url.$filename;
  197. }
  198. }
  199. else
  200. {
  201. $file = $filename;
  202. }
  203. switch($type)
  204. {
  205. case 'css':
  206. $attr['type'] = 'text/css';
  207. if ($raw)
  208. {
  209. return html_tag('style', $attr, PHP_EOL.file_get_contents($file).PHP_EOL).PHP_EOL;
  210. }
  211. if ( ! isset($attr['rel']) or empty($attr['rel']))
  212. {
  213. $attr['rel'] = 'stylesheet';
  214. }
  215. $attr['href'] = $file;
  216. $css .= $this->_indent.html_tag('link', $attr).PHP_EOL;
  217. break;
  218. case 'js':
  219. $attr['type'] = 'text/javascript';
  220. if ($raw)
  221. {
  222. return html_tag('script', $attr, PHP_EOL.file_get_contents($file).PHP_EOL).PHP_EOL;
  223. }
  224. $attr['src'] = $file;
  225. $js .= $this->_indent.html_tag('script', $attr, '').PHP_EOL;
  226. break;
  227. case 'img':
  228. $attr['src'] = $file;
  229. $attr['alt'] = isset($attr['alt']) ? $attr['alt'] : '';
  230. $img .= html_tag('img', $attr );
  231. break;
  232. }
  233. }
  234. // return them in the correct order
  235. return $css.$js.$img;
  236. }
  237. // --------------------------------------------------------------------
  238. /**
  239. * CSS
  240. *
  241. * Either adds the stylesheet to the group, or returns the CSS tag.
  242. *
  243. * @access public
  244. * @param mixed The file name, or an array files.
  245. * @param array An array of extra attributes
  246. * @param string The asset group name
  247. * @return string|object Rendered asset or current instance when adding to group
  248. */
  249. public function css($stylesheets = array(), $attr = array(), $group = null, $raw = false)
  250. {
  251. static $temp_group = 1000000;
  252. if ($group === null)
  253. {
  254. $render = $this->_auto_render;
  255. $group = $render ? (string) (++$temp_group) : '_default_';
  256. }
  257. else
  258. {
  259. $render = false;
  260. }
  261. $this->_parse_assets('css', $stylesheets, $attr, $group);
  262. if ($render)
  263. {
  264. return $this->render($group, $raw);
  265. }
  266. return $this;
  267. }
  268. // --------------------------------------------------------------------
  269. /**
  270. * JS
  271. *
  272. * Either adds the javascript to the group, or returns the script tag.
  273. *
  274. * @access public
  275. * @param mixed The file name, or an array files.
  276. * @param array An array of extra attributes
  277. * @param string The asset group name
  278. * @return string|object Rendered asset or current instance when adding to group
  279. */
  280. public function js($scripts = array(), $attr = array(), $group = null, $raw = false)
  281. {
  282. static $temp_group = 2000000;
  283. if ( ! isset($group))
  284. {
  285. $render = $this->_auto_render;
  286. $group = $render ? (string) (++$temp_group) : '_default_';
  287. }
  288. else
  289. {
  290. $render = false;
  291. }
  292. $this->_parse_assets('js', $scripts, $attr, $group);
  293. if ($render)
  294. {
  295. return $this->render($group, $raw);
  296. }
  297. return $this;
  298. }
  299. // --------------------------------------------------------------------
  300. /**
  301. * Img
  302. *
  303. * Either adds the image to the group, or returns the image tag.
  304. *
  305. * @access public
  306. * @param mixed The file name, or an array files.
  307. * @param array An array of extra attributes
  308. * @param string The asset group name
  309. * @return string|object Rendered asset or current instance when adding to group
  310. */
  311. public function img($images = array(), $attr = array(), $group = null)
  312. {
  313. static $temp_group = 3000000;
  314. if ( ! isset($group))
  315. {
  316. $render = $this->_auto_render;
  317. $group = $render ? (string) (++$temp_group) : '_default_';
  318. }
  319. else
  320. {
  321. $render = false;
  322. }
  323. $this->_parse_assets('img', $images, $attr, $group);
  324. if ($render)
  325. {
  326. return $this->render($group);
  327. }
  328. return $this;
  329. }
  330. // --------------------------------------------------------------------
  331. /**
  332. * Find File
  333. *
  334. * Locates a file in all the asset paths.
  335. *
  336. * @access public
  337. * @param string The filename to locate
  338. * @param string The sub-folder to look in (optional)
  339. * @return mixed Either the path to the file or false if not found
  340. */
  341. public function find_file($file, $type, $folder = '')
  342. {
  343. foreach ($this->_asset_paths[$type] as $path)
  344. {
  345. empty($folder) or $folder = trim($folder, '/').'/';
  346. if (is_file($path.$folder.ltrim($file, '/')))
  347. {
  348. $file = $path.$folder.ltrim($file, '/');
  349. strpos($file, DOCROOT) === 0 and $file = substr($file, strlen(DOCROOT));
  350. return $file;
  351. }
  352. }
  353. return false;
  354. }
  355. // --------------------------------------------------------------------
  356. /**
  357. * Get File
  358. *
  359. * Locates a file in all the asset paths, and return it relative to the docroot
  360. *
  361. * @access public
  362. * @param string The filename to locate
  363. * @param string The sub-folder to look in (optional)
  364. * @return mixed Either the path to the file or false if not found
  365. */
  366. public function get_file($file, $type, $folder = '')
  367. {
  368. if ($file = $this->find_file($file, $type, $folder))
  369. {
  370. return $this->_asset_url.$file;
  371. }
  372. return false;
  373. }
  374. // --------------------------------------------------------------------
  375. /**
  376. * Parse Assets
  377. *
  378. * Pareses the assets and adds them to the group
  379. *
  380. * @access private
  381. * @param string The asset type
  382. * @param mixed The file name, or an array files.
  383. * @param array An array of extra attributes
  384. * @param string The asset group name
  385. * @return string
  386. */
  387. protected function _parse_assets($type, $assets, $attr, $group)
  388. {
  389. if ( ! is_array($assets))
  390. {
  391. $assets = array($assets);
  392. }
  393. foreach ($assets as $key => $asset)
  394. {
  395. // Prevent duplicate files in a group.
  396. if (\Arr::get($this->_groups, "$group.$key.file") == $asset)
  397. {
  398. continue;
  399. }
  400. $this->_groups[$group][] = array(
  401. 'type' => $type,
  402. 'file' => $asset,
  403. 'attr' => (array) $attr
  404. );
  405. }
  406. }
  407. }