<?php namespace Laravel; defined('DS') or die('No direct script access.');
class Asset {
/**
* All of the instantiated asset containers.
* 所有实例化的资源容器。
* @var array
*/
public static $containers = array();
/**
* Get an asset container instance.
* 获取资源容器实例。
* <code>
* // Get the default asset container
* $container = Asset::container();
*
* // Get a named asset container
* $container = Asset::container('footer');
* </code>
*
* @param string $container
* @return Asset_Container
*/
public static function container($container = 'default')
{
if ( ! isset(static::$containers[$container]))
{
static::$containers[$container] = new Asset_Container($container);
}
return static::$containers[$container];
}
/**
* Magic Method for calling methods on the default container.
* 用于在默认容器上调用方法的魔术方法。
* <code>
* // Call the "styles" method on the default container
* echo Asset::styles();
*
* // Call the "add" method on the default container
* Asset::add('jquery', 'js/jquery.js');
* </code>
*/
// __callStatic 当静态方法不存在时调用
public static function __callStatic($method, $parameters)
{
return call_user_func_array(array(static::container(), $method), $parameters);
}
}
class Asset_Container {
/**
* The asset container name.
* 资源容器名称。
* @var string
*/
public $name;
/**
* The bundle that the assets belong to.
* 资源所属的捆绑包。
* @var string
*/
public $bundle = DEFAULT_BUNDLE;
/**
* All of the registered assets.
* 所有注册资源。
* @var array
*/
public $assets = array();
/**
* Create a new asset container instance.
* 创建一个新的资产容器实例。
* @param string $name
* @return void
*/
public function __construct($name)
{
$this->name = $name;
}
/**
* Add an asset to the container.
* 向容器添加资产。
* The extension of the asset source will be used to determine the type of
* asset being registered (CSS or JavaScript). When using a non-standard
* extension, the style/script methods may be used to register assets.
* 资源的扩展名将用于确定注册资源的类型(CSS 或 JavaScript)。 使用非标准扩展时,样式/脚本方法可用于注册资源。
* <code>
* // Add an asset to the container
* Asset::container()->add('jquery', 'js/jquery.js');
*
* // Add an asset that has dependencies on other assets
* Asset::add('jquery', 'js/jquery.js', 'jquery-ui');
*
* // Add an asset that should have attributes applied to its tags
* Asset::add('jquery', 'js/jquery.js', null, array('defer'));
* </code>
*
* @param string $name
* @param string $source
* @param array $dependencies
* @param array $attributes
* @return void
*/
public function add($name, $source, $dependencies = array(), $attributes = array())
{
// pathinfo- 返回文件路径信息
$type = (pathinfo($source, PATHINFO_EXTENSION) == 'css') ? 'style' : 'script';
return $this->$type($name, $source, $dependencies, $attributes);
}
/**
* Add a CSS file to the registered assets.
* 将 CSS 文件添加到注册的资源中。
* @param string $name
* @param string $source
* @param array $dependencies
* @param array $attributes
* @return Asset_Container
*/
public function style($name, $source, $dependencies = array(), $attributes = array())
{
// 判断指定的key是否存在
if ( ! array_key_exists('media', $attributes))
{
$attributes['media'] = 'all';
}
$this->register('style', $name, $source, $dependencies, $attributes);
return $this;
}
/**
* Add a JavaScript file to the registered assets.
* 将 JavaScript 文件添加到已注册的资源中。
* @param string $name
* @param string $source
* @param array $dependencies
* @param array $attributes
* @return Asset_Container
*/
public function script($name, $source, $dependencies = array(), $attributes = array())
{
$this->register('script', $name, $source, $dependencies, $attributes);
return $this;
}
/**
* Returns the full-path for an asset.
* 返回资源的完整路径。
* @param string $source
* @return string
*/
public function path($source)
{
return Bundle::assets($this->bundle).$source;
}
/**
* Set the bundle that the container's assets belong to.
* 设置容器资源所属的包。
* @param string $bundle
* @return Asset_Container
*/
public function bundle($bundle)
{
$this->bundle = $bundle;
return $this;
}
/**
* Add an asset to the array of registered assets.
* 将资源添加到已注册资源的数组中。
* @param string $type
* @param string $name
* @param string $source
* @param array $dependencies
* @param array $attributes
* @return void
*/
protected function register($type, $name, $source, $dependencies, $attributes)
{
$dependencies = (array) $dependencies;
$attributes = (array) $attributes;
// compact-建立一个数组,包括它们的变量名和值
$this->assets[$type][$name] = compact('source', 'dependencies', 'attributes');
}
/**
* Get the links to all of the registered CSS assets.
* 获取所有已注册 CSS资源的链接。
* @return string
*/
public function styles()
{
return $this->group('style');
}
/**
* Get the links to all of the registered JavaScript assets.
* 获取所有已注册 JavaScript 资源的链接。
* @return string
*/
public function scripts()
{
return $this->group('script');
}
/**
* Get all of the registered assets for a given type / group.
* 获取给定类型/组的所有注册资源
* @param string $group
* @return string
*/
protected function group($group)
{
if ( ! isset($this->assets[$group]) or count($this->assets[$group]) == 0) return '';
$assets = '';
foreach ($this->arrange($this->assets[$group]) as $name => $data)
{
$assets .= $this->asset($group, $name);
}
return $assets;
}
/**
* Get the HTML link to a registered asset.
* 获取已注册资源的 HTML 链接。
* @param string $group
* @param string $name
* @return string
*/
protected function asset($group, $name)
{
if ( ! isset($this->assets[$group][$name])) return '';
$asset = $this->assets[$group][$name];
// If the bundle source is not a complete URL, we will go ahead and prepend
// the bundle's asset path to the source provided with the asset. This will
// ensure that we attach the correct path to the asset.
// filter_var-使用特定过滤器过滤一个变量 FILTER_VALIDATE_URL 验证是否为URL
if (filter_var($asset['source'], FILTER_VALIDATE_URL) === false)
{
$asset['source'] = $this->path($asset['source']);
}
return HTML::$group($asset['source'], $asset['attributes']);
}
/**
* Sort and retrieve assets based on their dependencies
* 根据依赖项对资源进行排序和检索
* @param array $assets
* @return array
*/
protected function arrange($assets)
{
list($original, $sorted) = array($assets, array());
while (count($assets) > 0)
{
foreach ($assets as $asset => $value)
{
$this->evaluate_asset($asset, $value, $original, $sorted, $assets);
}
}
return $sorted;
}
/**
* Evaluate an asset and its dependencies.
* 检测资源及其依赖项。
* @param string $asset
* @param string $value
* @param array $original
* @param array $sorted
* @param array $assets
* @return void
*/
protected function evaluate_asset($asset, $value, $original, &$sorted, &$assets)
{
// If the asset has no more dependencies, we can add it to the sorted list
// and remove it from the array of assets. Otherwise, we will not verify
// the asset's dependencies and determine if they've been sorted.
if (count($assets[$asset]['dependencies']) == 0)
{
$sorted[$asset] = $value;
unset($assets[$asset]);
}
else
{
foreach ($assets[$asset]['dependencies'] as $key => $dependency)
{
if ( ! $this->dependency_is_valid($asset, $dependency, $original, $assets))
{
unset($assets[$asset]['dependencies'][$key]);
continue;
}
// If the dependency has not yet been added to the sorted list, we can not
// remove it from this asset's array of dependencies. We'll try again on
// the next trip through the loop.
// 如果依赖项尚未添加到排序列表中,我们无法将其从该资源的依赖项数组中删除。 我们将在下一次循环中再次尝试。
if ( ! isset($sorted[$dependency])) continue;
unset($assets[$asset]['dependencies'][$key]);
}
}
}
/**
* Verify that an asset's dependency is valid.
* 验证资源的依赖项是否有效。
* A dependency is considered valid if it exists, is not a circular reference, and is
* not a reference to the owning asset itself. If the dependency doesn't exist, no
* error or warning will be given. For the other cases, an exception is thrown.
* 如果依赖项存在,则认为它是有效的,不是循环引用,也不是对拥有资源本身的引用。
* 如果依赖项不存在,则不会给出错误或警告。 对于其他情况,将引发异常。
*
* @param string $asset
* @param string $dependency
* @param array $original
* @param array $assets
* @return bool
*/
protected function dependency_is_valid($asset, $dependency, $original, $assets)
{
if ( ! isset($original[$dependency]))
{
return false;
}
elseif ($dependency === $asset)
{
throw new \Exception("Asset [$asset] is dependent on itself.");
}
elseif (isset($assets[$dependency]) and in_array($asset, $assets[$dependency]['dependencies']))
{
throw new \Exception("Assets [$asset] and [$dependency] have a circular dependency.");
}
return true;
}
}
github地址: https://github.com/liu-shilong/laravel3-scr