[], 'css'=>[], 'rss'=>[]];
/**
* @var string Specifies a path to the asset directory.
*/
public $assetPath;
/**
* Disables the use, and subequent broadcast, of assets. This is useful
* to call during an AJAX request to speed things up. This method works
* by specifically targeting the hasAssetsDefined method.
* @return void
*/
public function flushAssets()
{
$this->assets = ['js'=>[], 'css'=>[], 'rss'=>[]];
}
/**
* Outputs `` and `' . PHP_EOL;
}
}
return $result;
}
/**
* Adds JavaScript asset to the asset list. Call $this->makeAssets() in a view
* to output corresponding markup.
* @param string $name Specifies a path (URL) to the script.
* @param array $attributes Adds extra HTML attributes to the asset link.
* @return void
*/
public function addJs($name, $attributes = [])
{
if (is_array($name)) {
$name = $this->combineAssets($name, $this->getLocalPath($this->assetPath));
}
$jsPath = $this->getAssetPath($name);
if (isset($this->controller)) {
$this->controller->addJs($jsPath, $attributes);
}
if (is_string($attributes)) {
$attributes = ['build' => $attributes];
}
$jsPath = $this->getAssetScheme($jsPath);
if (!in_array($jsPath, $this->assets['js'])) {
$this->assets['js'][] = ['path' => $jsPath, 'attributes' => $attributes];
}
}
/**
* Adds StyleSheet asset to the asset list. Call $this->makeAssets() in a view
* to output corresponding markup.
* @param string $name Specifies a path (URL) to the script.
* @param array $attributes Adds extra HTML attributes to the asset link.
* @return void
*/
public function addCss($name, $attributes = [])
{
if (is_array($name)) {
$name = $this->combineAssets($name, $this->getLocalPath($this->assetPath));
}
$cssPath = $this->getAssetPath($name);
if (isset($this->controller)) {
$this->controller->addCss($cssPath, $attributes);
}
if (is_string($attributes)) {
$attributes = ['build' => $attributes];
}
$cssPath = $this->getAssetScheme($cssPath);
if (!in_array($cssPath, $this->assets['css'])) {
$this->assets['css'][] = ['path' => $cssPath, 'attributes' => $attributes];
}
}
/**
* Adds an RSS link asset to the asset list. Call $this->makeAssets() in a view
* to output corresponding markup.
* @param string $name Specifies a path (URL) to the RSS channel
* @param array $attributes Adds extra HTML attributes to the asset link.
* @return void
*/
public function addRss($name, $attributes = [])
{
$rssPath = $this->getAssetPath($name);
if (isset($this->controller)) {
$this->controller->addRss($rssPath, $attributes);
}
if (is_string($attributes)) {
$attributes = ['build' => $attributes];
}
$rssPath = $this->getAssetScheme($rssPath);
if (!in_array($rssPath, $this->assets['rss'])) {
$this->assets['rss'][] = ['path' => $rssPath, 'attributes' => $attributes];
}
}
/**
* Run the provided assets through the Asset Combiner
* @param array $assets Collection of assets
* @param string $localPath Prefix all assets with this path (optional)
* @return string
*/
public function combineAssets(array $assets, $localPath = '')
{
// Short circuit if no assets actually provided
if (empty($assets)) {
return '';
}
$assetPath = !empty($localPath) ? $localPath : $this->assetPath;
return Url::to(CombineAssets::combine($assets, $assetPath));
}
/**
* Returns an array of all registered asset paths.
* @return array
*/
public function getAssetPaths()
{
$this->removeDuplicates();
$assets = [];
foreach ($this->assets as $type => $collection) {
$assets[$type] = [];
foreach ($collection as $asset) {
$assets[$type][] = $this->getAssetEntryBuildPath($asset);
}
}
return $assets;
}
/**
* Locates a file based on it's definition. If the file starts with
* a forward slash, it will be returned in context of the application public path,
* otherwise it will be returned in context of the asset path.
* @param string $fileName File to load.
* @param string $assetPath Explicitly define an asset path.
* @return string Relative path to the asset file.
*/
public function getAssetPath($fileName, $assetPath = null)
{
if (starts_with($fileName, ['//', 'http://', 'https://'])) {
return $fileName;
}
if (!$assetPath) {
$assetPath = $this->assetPath;
}
if (substr($fileName, 0, 1) == '/' || $assetPath === null) {
return $fileName;
}
return $assetPath . '/' . $fileName;
}
/**
* Returns true if assets any have been added.
* @return bool
*/
public function hasAssetsDefined()
{
return count($this->assets, COUNT_RECURSIVE) > 3;
}
/**
* Internal helper, attaches a build code to an asset path
* @param array $asset Stored asset array
* @return string
*/
protected function getAssetEntryBuildPath($asset)
{
$path = $asset['path'];
if (isset($asset['attributes']['build'])) {
$build = $asset['attributes']['build'];
if ($build == 'core') {
$build = 'v' . Parameter::get('system::core.build', 1);
}
elseif ($pluginVersion = PluginVersion::getVersion($build)) {
$build = 'v' . $pluginVersion;
}
$path .= '?' . $build;
}
return $path;
}
/**
* Internal helper, get asset scheme
* @param string $asset Specifies a path (URL) to the asset.
* @return string
*/
protected function getAssetScheme($asset)
{
if (starts_with($asset, ['//', 'http://', 'https://'])) {
return $asset;
}
if (substr($asset, 0, 1) == '/') {
$asset = Url::asset($asset);
}
return $asset;
}
/**
* Removes duplicate assets from the entire collection.
* @return void
*/
protected function removeDuplicates()
{
foreach ($this->assets as $type => &$collection) {
$pathCache = [];
foreach ($collection as $key => $asset) {
if (!$path = array_get($asset, 'path')) {
continue;
}
if (isset($pathCache[$path])) {
array_forget($collection, $key);
continue;
}
$pathCache[$path] = true;
}
}
}
protected function getLocalPath(string $relativePath)
{
$relativePath = File::symbolizePath($relativePath);
if (!starts_with($relativePath, [base_path()])) {
$relativePath = base_path($relativePath);
}
return $relativePath;
}
}