mirror of
https://github.com/Mibew/mibew.git
synced 2024-11-15 16:44:11 +03:00
Create Asset/Package class to reduce code duplication
This commit is contained in:
parent
f8d4d074d5
commit
71d2b234c6
@ -43,13 +43,22 @@ class AssetManager implements AssetManagerInterface
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $jsAssets = array();
|
||||
protected $jsAssets = null;
|
||||
/**
|
||||
* List of attached CSS assets.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cssAssets = array();
|
||||
protected $cssAssets = null;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->jsAssets = new Package();
|
||||
$this->cssAssets = new Package();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a request which will be used as a context.
|
||||
@ -66,8 +75,8 @@ class AssetManager implements AssetManagerInterface
|
||||
|
||||
// The request has been changed thus all attaches assets are outdated
|
||||
// now. Clear them all.
|
||||
$this->jsAssets = array();
|
||||
$this->cssAssets = array();
|
||||
$this->jsAssets = new Package();
|
||||
$this->cssAssets = new Package();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,11 +104,7 @@ class AssetManager implements AssetManagerInterface
|
||||
*/
|
||||
public function attachJs($content, $type = AssetManagerInterface::RELATIVE_URL, $weight = 0)
|
||||
{
|
||||
$this->jsAssets[] = array(
|
||||
'content' => $content,
|
||||
'type' => $type,
|
||||
'weight' => $weight,
|
||||
);
|
||||
$this->jsAssets->addAsset($content, $type, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,12 +112,16 @@ class AssetManager implements AssetManagerInterface
|
||||
*/
|
||||
public function getJsAssets()
|
||||
{
|
||||
return $this->sort(
|
||||
array_merge(
|
||||
$this->jsAssets,
|
||||
$this->triggerJsEvent()
|
||||
)
|
||||
);
|
||||
// If plugins assets are stored in $this->jsAssets several calls to the
|
||||
// method will duplicate The temporary package is used to avoid such
|
||||
// behaviour.
|
||||
$combined_assets = clone $this->jsAssets;
|
||||
$combined_assets->merge($this->triggerJsEvent());
|
||||
|
||||
$assets = $combined_assets->getAssets();
|
||||
unset($combined_assets);
|
||||
|
||||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,11 +129,7 @@ class AssetManager implements AssetManagerInterface
|
||||
*/
|
||||
public function attachCss($content, $type = AssetManagerInterface::RELATIVE_URL, $weight = 0)
|
||||
{
|
||||
$this->cssAssets[] = array(
|
||||
'content' => $content,
|
||||
'type' => $type,
|
||||
'weight' => $weight,
|
||||
);
|
||||
$this->cssAssets->addAsset($content, $type, $weight);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,12 +137,16 @@ class AssetManager implements AssetManagerInterface
|
||||
*/
|
||||
public function getCssAssets()
|
||||
{
|
||||
return $this->sort(
|
||||
array_merge(
|
||||
$this->cssAssets,
|
||||
$this->triggerCssEvent()
|
||||
)
|
||||
);
|
||||
// If plugins assets are stored in $this->cssAssets several calls to the
|
||||
// method will duplicate The temporary package is used to avoid such
|
||||
// behaviour.
|
||||
$combined_assets = clone $this->cssAssets;
|
||||
$combined_assets->merge($this->triggerCssEvent());
|
||||
|
||||
$assets = $combined_assets->getAssets();
|
||||
unset($combined_assets);
|
||||
|
||||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,7 +188,7 @@ class AssetManager implements AssetManagerInterface
|
||||
* are plugins options. Modify this array to add or change plugins
|
||||
* options.
|
||||
*
|
||||
* @return array Assets list.
|
||||
* @return Package Assets list.
|
||||
*/
|
||||
protected function triggerJsEvent()
|
||||
{
|
||||
@ -198,13 +207,13 @@ class AssetManager implements AssetManagerInterface
|
||||
'plugins' => array(),
|
||||
);
|
||||
EventDispatcher::getInstance()->triggerEvent('pageAddJSPluginOptions', $event);
|
||||
$assets[] = array(
|
||||
'content' => sprintf(
|
||||
$assets->addAsset(
|
||||
sprintf(
|
||||
'var Mibew = Mibew || {}; Mibew.PluginOptions = %s;',
|
||||
json_encode($event['plugins'])
|
||||
),
|
||||
'type' => AssetManagerInterface::INLINE,
|
||||
'weight' => 0,
|
||||
AssetManagerInterface::INLINE,
|
||||
0
|
||||
);
|
||||
|
||||
return $assets;
|
||||
@ -224,7 +233,7 @@ class AssetManager implements AssetManagerInterface
|
||||
* of their meaning. Modify this array to add or remove additional CSS
|
||||
* files.
|
||||
*
|
||||
* @return array Assets list.
|
||||
* @return Package Assets list.
|
||||
*/
|
||||
protected function triggerCssEvent()
|
||||
{
|
||||
@ -244,24 +253,29 @@ class AssetManager implements AssetManagerInterface
|
||||
* string or an asset array. If a string is used it is treated as an
|
||||
* absolute URL of the asset. If an array is used it is treated as a
|
||||
* normal asset array and must have "content" and "type" items.
|
||||
* @return array A list of normalized assets.
|
||||
* @return Package A list of normalized assets.
|
||||
* @throws \InvalidArgumentException If the passed in assets list is not
|
||||
* valid.
|
||||
*/
|
||||
protected function normalizeAssets($assets)
|
||||
{
|
||||
$normalized_assets = array();
|
||||
$normalized_assets = new Package();
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if (is_string($asset)) {
|
||||
$normalized_assets[] = array(
|
||||
'content' => $asset,
|
||||
'type' => AssetManagerInterface::RELATIVE_URL,
|
||||
'weight' => 0,
|
||||
$normalized_assets->addAsset(
|
||||
$asset,
|
||||
AssetManagerInterface::RELATIVE_URL,
|
||||
0
|
||||
);
|
||||
} elseif (is_array($asset) && !empty($asset['type']) && !empty($asset['content'])) {
|
||||
// Weight is optional so we have to make sure it is in place.
|
||||
$normalized_assets[] = $asset + array('weight' => 0);
|
||||
$asset += array('weight' => 0);
|
||||
$normalized_assets->addAsset(
|
||||
$asset['content'],
|
||||
$asset['type'],
|
||||
$asset['weight']
|
||||
);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Invalid asset item');
|
||||
}
|
||||
@ -269,46 +283,4 @@ class AssetManager implements AssetManagerInterface
|
||||
|
||||
return $normalized_assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort assets according to their weights.
|
||||
*
|
||||
* If weights of two assets are equal the order from the original array will
|
||||
* be kept.
|
||||
*
|
||||
* @param array $assets The original List of assets.
|
||||
* @return array Sorted list of assets.
|
||||
*/
|
||||
protected function sort($assets)
|
||||
{
|
||||
// We should keep order for assets with equal weight. Thus we must
|
||||
// combine original order and weight property before real sort.
|
||||
$tmp = array();
|
||||
$offset = 0;
|
||||
foreach ($assets as $asset) {
|
||||
$key = $asset['weight'] . '|' . $offset;
|
||||
$tmp[$key] = $asset;
|
||||
$offset++;
|
||||
}
|
||||
|
||||
uksort($tmp, function ($a, $b) {
|
||||
list($a_weight, $a_offset) = explode('|', $a, 2);
|
||||
list($b_weight, $b_offset) = explode('|', $b, 2);
|
||||
|
||||
if ($a_weight != $b_weight) {
|
||||
return ($a_weight < $b_weight) ? -1 : 1;
|
||||
}
|
||||
|
||||
// Weights are equal. Check the offset to determine which asset was
|
||||
// attached first.
|
||||
if ($a_offset != $b_offset) {
|
||||
return ($a_offset < $b_offset) ? -1 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Artificial sorting keys should be removed from the resulting array.
|
||||
return array_values($tmp);
|
||||
}
|
||||
}
|
||||
|
@ -29,15 +29,15 @@ interface AssetManagerInterface
|
||||
/**
|
||||
* Indicates that content of an asset is an absolute URL.
|
||||
*/
|
||||
const ABSOLUTE_URL = 'absolute';
|
||||
const ABSOLUTE_URL = Package::ABSOLUTE_URL;
|
||||
/**
|
||||
* Indicates that content of an asset is a relative URL.
|
||||
*/
|
||||
const RELATIVE_URL = 'relative';
|
||||
const RELATIVE_URL = Package::RELATIVE_URL;
|
||||
/**
|
||||
* Indicates that content of an asset is raw CSS or JS.
|
||||
*/
|
||||
const INLINE = 'inline';
|
||||
const INLINE = Package::INLINE;
|
||||
|
||||
/**
|
||||
* Gets an instance of Assets URL Generator.
|
||||
|
161
src/mibew/libs/classes/Mibew/Asset/Package.php
Normal file
161
src/mibew/libs/classes/Mibew/Asset/Package.php
Normal file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is a part of Mibew Messenger.
|
||||
*
|
||||
* Copyright 2005-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Mibew\Asset;
|
||||
|
||||
/**
|
||||
* Represents a manageable set of assets.
|
||||
*/
|
||||
class Package
|
||||
{
|
||||
/**
|
||||
* Indicates that assets sould not be sorted.
|
||||
*/
|
||||
const SORT_NONE = 'none';
|
||||
/**
|
||||
* Indicates that assets should be sorted according their weights.
|
||||
*/
|
||||
const SORT_WEIGHT = 'weight';
|
||||
|
||||
/**
|
||||
* Indicates that content of an asset is an absolute URL.
|
||||
*/
|
||||
const ABSOLUTE_URL = 'absolute';
|
||||
/**
|
||||
* Indicates that content of an asset is a relative URL.
|
||||
*/
|
||||
const RELATIVE_URL = 'relative';
|
||||
/**
|
||||
* Indicates that content of an asset is raw file content.
|
||||
*/
|
||||
const INLINE = 'inline';
|
||||
|
||||
/**
|
||||
* @var array Assets list
|
||||
*/
|
||||
protected $assets = array();
|
||||
|
||||
/**
|
||||
* Attaches an asset to the package.
|
||||
*
|
||||
* @param type $content Content of the asset. It can be a kind of URL of
|
||||
* plain content depends on the second argument of the method.
|
||||
* @param mixed $type Determines asset type. It can be one of
|
||||
* {@link Package::ABSOLUTE_URL}, {@link Package::RELATIVE_URL}
|
||||
* or {@link Package::INLINE} constants.
|
||||
* @param int $weight Weight of the assets. Assets with lower weight will be
|
||||
* "float" to the begging of the resulting assets array.
|
||||
*/
|
||||
public function addAsset($content, $type, $weight)
|
||||
{
|
||||
$asset = array(
|
||||
'content' => $content,
|
||||
'type' => $type,
|
||||
'weight' => $weight,
|
||||
);
|
||||
|
||||
if ($type == self::INLINE) {
|
||||
$this->assets[] = $asset;
|
||||
} else {
|
||||
// Relative and absolute URLs should not be added twice.
|
||||
$this->assets[$content] = $asset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all attached assets.
|
||||
*
|
||||
* @param mixed $sort Indicates if assets should be sorted. Can be equal to
|
||||
* either {@link Package::SORT_NONE} or {@link Package::SORT_WEIGHT}
|
||||
* constant.
|
||||
* @return array List of attached assets. Each item is an array with
|
||||
* the following keys:
|
||||
* - content: string, can be either a kind of URL or raw CSS content.
|
||||
* - type: mixed, determines asset type. It can be one of
|
||||
* AssetManagerInterface::ABSOLUTE_URL,
|
||||
* AssetManagerInterface::RELATIVE_URL or AssetManagerInterface::INLINE
|
||||
* constants.
|
||||
* - weight: int, weight of the asset which was set via
|
||||
* AssetManagerInterface::attachCss method.
|
||||
*/
|
||||
public function getAssets($sort = self::SORT_WEIGHT)
|
||||
{
|
||||
if ($sort == self::SORT_NONE) {
|
||||
// Internal artificial keys should be removed
|
||||
return array_values($this->assets);
|
||||
}
|
||||
|
||||
return $this->sort($this->assets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the package with another one.
|
||||
*
|
||||
* @param Package $package A package that should be merged in the current
|
||||
* one.
|
||||
*/
|
||||
public function merge(Package $package)
|
||||
{
|
||||
foreach ($package->getAssets(self::SORT_NONE) as $asset) {
|
||||
$this->addAsset($asset['content'], $asset['type'], $asset['weight']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort assets according to their weights.
|
||||
*
|
||||
* If weights of two assets are equal the order from the original array will
|
||||
* be kept.
|
||||
*
|
||||
* @param array $assets The original List of assets.
|
||||
* @return array Sorted list of assets.
|
||||
*/
|
||||
protected function sort($assets)
|
||||
{
|
||||
// We should keep order for assets with equal weight. Thus we must
|
||||
// combine original order and weight property before real sort.
|
||||
$tmp = array();
|
||||
$offset = 0;
|
||||
foreach ($assets as $asset) {
|
||||
$key = $asset['weight'] . '|' . $offset;
|
||||
$tmp[$key] = $asset;
|
||||
$offset++;
|
||||
}
|
||||
|
||||
uksort($tmp, function ($a, $b) {
|
||||
list($a_weight, $a_offset) = explode('|', $a, 2);
|
||||
list($b_weight, $b_offset) = explode('|', $b, 2);
|
||||
|
||||
if ($a_weight != $b_weight) {
|
||||
return ($a_weight < $b_weight) ? -1 : 1;
|
||||
}
|
||||
|
||||
// Weights are equal. Check the offset to determine which asset was
|
||||
// attached first.
|
||||
if ($a_offset != $b_offset) {
|
||||
return ($a_offset < $b_offset) ? -1 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Artificial sorting keys should be removed from the resulting array.
|
||||
return array_values($tmp);
|
||||
}
|
||||
}
|
@ -226,6 +226,35 @@ abstract class AbstractController implements
|
||||
*/
|
||||
public function render($template, array $parameters = array())
|
||||
{
|
||||
// Attach all needed JavaScript files. This is done here to decouple
|
||||
// templates and JavaScript applications.
|
||||
$assets = array(
|
||||
// External libs
|
||||
'js/libs/jquery.min.js',
|
||||
'js/libs/json2.js',
|
||||
'js/libs/underscore-min.js',
|
||||
'js/libs/backbone-min.js',
|
||||
'js/libs/backbone.marionette.min.js',
|
||||
'js/libs/handlebars.min.js',
|
||||
// Client side templates
|
||||
$this->getStyle()->getFilesPath() . '/templates_compiled/client_side/templates.js',
|
||||
// Default client side application files
|
||||
'js/compiled/mibewapi.js',
|
||||
'js/compiled/default_app.js',
|
||||
);
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
$this->getAssetManager()->attachJs($asset, AssetManagerInterface::RELATIVE_URL, -1000);
|
||||
}
|
||||
|
||||
// Localization file is added as absolute URL because URL Generator
|
||||
// already prepended base URL to its result.
|
||||
$this->getAssetManager()->attachJs(
|
||||
$this->generateUrl('js_translation', array('locale' => get_current_locale())),
|
||||
AssetManagerInterface::ABSOLUTE_URL,
|
||||
-1000
|
||||
);
|
||||
|
||||
return $this->getStyle()->render($template, $parameters);
|
||||
}
|
||||
|
||||
|
@ -9,24 +9,6 @@
|
||||
<!-- Extra CSS files -->
|
||||
{{cssAssets}}
|
||||
|
||||
<!-- External libs -->
|
||||
<script type="text/javascript" src="{{asset "js/libs/jquery.min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/json2.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/underscore-min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/backbone-min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/backbone.marionette.min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/handlebars.min.js"}}"></script>
|
||||
|
||||
<!-- Javascript templates -->
|
||||
<script type="text/javascript" src="{{asset "@CurrentStyle/templates_compiled/client_side/templates.js"}}"></script>
|
||||
|
||||
<!-- Default application files -->
|
||||
<script type="text/javascript" src="{{asset "js/compiled/mibewapi.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/compiled/default_app.js"}}"></script>
|
||||
|
||||
<!-- Localized string -->
|
||||
<script type="text/javascript" src="{{route "js_translation" locale=currentLocale}}"></script>
|
||||
|
||||
<!-- Extra JavaScript files -->
|
||||
{{jsAssets}}
|
||||
|
||||
|
@ -14,24 +14,6 @@
|
||||
<!-- Extra CSS files -->
|
||||
{{cssAssets}}
|
||||
|
||||
<!-- External libs -->
|
||||
<script type="text/javascript" src="{{asset "js/libs/jquery.min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/json2.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/underscore-min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/backbone-min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/backbone.marionette.min.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/libs/handlebars.min.js"}}"></script>
|
||||
|
||||
<!-- Client side templates -->
|
||||
<script type="text/javascript" src="{{asset "@CurrentStyle/templates_compiled/client_side/templates.js"}}"></script>
|
||||
|
||||
<!-- Default application files -->
|
||||
<script type="text/javascript" src="{{asset "js/compiled/mibewapi.js"}}"></script>
|
||||
<script type="text/javascript" src="{{asset "js/compiled/default_app.js"}}"></script>
|
||||
|
||||
<!-- Localized string -->
|
||||
<script type="text/javascript" src="{{route "js_translation" locale=currentLocale}}"></script>
|
||||
|
||||
<!-- Extra JavaScript files -->
|
||||
{{jsAssets}}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user