Skip to content
This repository was archived by the owner on Jul 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from adeg/improvements
Browse files Browse the repository at this point in the history
some improvements
  • Loading branch information
tonydspaniard authored Jul 26, 2023
2 parents 06038b9 + c47af38 commit bb6dcac
Show file tree
Hide file tree
Showing 6 changed files with 401 additions and 120 deletions.
13 changes: 13 additions & 0 deletions EAssetManagerBoost.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
*/
class EAssetManagerBoost extends CAssetManager {

/**
* @var array $ignoredPaths specify the path parts that
* the extension will check against in order to not compress/minify the
* files/directories.
*/
public $ignoredPaths = array(
'bootstrap',
'ckeditor',
'highcharts',
);
/**
* @var mixed $minifiedExtensionFlags specify the extension names that
* the extension will check against in order to not compress/minify the
Expand Down Expand Up @@ -87,6 +97,9 @@ public function publish($path, $hashByName=false, $level=-1, $forceCopy=false)
return $this->_published[$path];
else if (($src = realpath($path)) !== false)
{
if ($this->strpos_arr($path, $this->ignoredPaths))
return parent::publish($path, $hashByName, $level, $forceCopy);

if (is_file($src))
{
$dir = $this->hash($hashByName ? basename($src) : dirname($src));
Expand Down
156 changes: 147 additions & 9 deletions EClientScriptBoost.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,157 @@
*/
class EClientScriptBoost extends CClientScript
{
public $cacheDuration = 0;
public $cacheDuration = 0;

public function registerScript($id, $script, $position=self::POS_READY)
/**
* @var boolean Allows to put the component into debug mode. Registered content will be checked
* against its cached version (if present) and a warning will be issued if the
* freshly compressed and cached content do not match.
* If there is a mismatch, it means that wrong content is being served from cache. There could be two
* reasons for that:
* 1. Original script has been changed, but the cache holds the previous version. Flushing or
* clearing cache will resolve this.
* 2. There are views or components that are using same IDs in the registerScript() and registerCss()
* calls. The debug message includes the IDs with mismatch, which will help to identify the source.
* It is recommended to run your project for couple days or weeks with this debug mode on to catch
* such overlapping IDs.
* NOTE: When debug mode is off, cached content will silently served. If you have overlapping content
* IDs, then this will most likely result in all kinds of unxpected behaviour! Make sure to run
* EClientScriptBoost in debug mode after you introduce changes or add new scripts. Also, DO NOT include
* dynamic stuff like model IDs, links etc. in the scripts you register. It is a good practice to write
* the scripts to use variables defined by the view itself, for example in a <script></script> section.
*/
public $debug;

/**
* @var array Ids for scripts that should not be cached.
* For instance: when the cached script has a CSRF token.
* The solution for application controlled scripts is to add the CSRF Value to the ID,
* but for scripts in extensions or the framework, it is not recommended to change the framework
* nor the extension, so they are added in this list.
*/
public $skipList=array(
'CActiveForm#',
'CButtonColumn',
'CGridView#',
'CJuiDialog',
'CJuiButton',
'EditableField#',
'JToggleColumn#',
'TbBulkActions#',
'TbEditableField#',
'TbEditable#',
'TbGridView#',
'TbSelect2#',
'Yii2Debug#',
'Yii.CHtml.#',
);

/**
* @see CClientScript::registerScript()
*/
public function registerScript($id,$script,$position=null,array $htmlOptions=array())
{
return $this->registerContent('script', $id, $script, $position, $htmlOptions);
}

/**
* @see CClientScript::registerCss()
*/
public function registerCss($id, $css, $media = '')
{
return $this->registerContent('css', $id, $css, $media);
}

/**
* All minifying and caching logic for registerScript() and registerCss() is defined here
* for much of this logic is the same between the two methods.
* @param string $type either 'script' or 'css', determines which minify function
* is used on the content.
* @param string $id ID that uniquely identifies this piece of JavaScript code
* @param string $content content that should be compressed (either JS or CSS) and registered
* @param integer|string $registerParam CClientScript::POS_* value when called
* by {@link registerScript()}, CSS media string when called by {@link registerContent()}
* @param array $htmlOptions additional HTML attributes (only for scripts)
* Note: HTML attributes are not allowed for script positions "CClientScript::POS_LOAD" and "CClientScript::POS_READY".
* @return CClientScript the CClientScript object itself (to support method chaining, available since version 1.1.5)
* @throws CException
*/
protected function registerContent($type, $id, $content, $registerParam=null, array $htmlOptions=array())
{
// assumed config includes the required path aliases to use
// EScriptBoost
$compressed = YII_DEBUG ? $script : Yii::app()->cache->get($id);
if ($type != 'script' && $type != 'css')
throw new CException(__CLASS__ . " supports only registerScript() and registerCss()");

// if debug mode has not been specified by the Yii config part of clientScript
// set the mode based on global YII_DEBUG
$debug = $this->debug === null ? YII_DEBUG : $this->debug;

// Check if this script is in the exceptions - if so, skip caching.
// Should be checked for both script and CSS content
$skip = false;
foreach($this->skipList as $s) {
$skip|=strpos($id, $s) === 0;
if($skip) break;
}

if($compressed === false)
// Do not use cache for content with IDs listed in {@link $this->skipList}
if ($skip)
{
if ($type == 'script')
$compressed = EScriptBoost::minifyJs($content);
else if ($type == 'css')
$compressed = EScriptBoost::minifyCss($content);
}
else
$compressed = Yii::app()->cache->get($id);

// if in debug mode -- recompress the content and compare with the
// cached version if present
if ($debug && $compressed !== false)
{
// During debug check that the newly minified content is not different from the cached one.
// If so, log the difference so that it can be fixed.
if ($type == 'script')
$recompressed = EScriptBoost::minifyJs($content);
else if ($type == 'css')
$recompressed = EScriptBoost::minifyCss($content);

if ($recompressed !== $compressed)
{
Yii::log(
"Recompressed {$type} with id '$id' does not match to the previously cached version.\n\n"
. "Newly compressed version:\n\n"
. "----------------------- < begin > -----------------------\n\n"
. CVarDumper::dumpAsString($recompressed)
. "\n\n----------------------- < end > -----------------------\n\n"
. PHP_EOL
. "Cached compressed version:\n\n"
. "----------------------- < begin > -----------------------\n\n"
. CVarDumper::dumpAsString($compressed)
. "\n\n----------------------- < end > -----------------------\n\n"
, CLogger::LEVEL_WARNING
);
}
}
elseif ($compressed === false)
{
if ($type == 'script')
$compressed = EScriptBoost::minifyJs($content);
else if ($type == 'css')
$compressed = EScriptBoost::minifyCss($content);

Yii::app()->cache->set($id, $compressed, $this->cacheDuration);
}

if ($type == 'script')
{
$position = empty($registerParam) ? null : $registerParam;
return parent::registerScript($id, $compressed, $registerParam, $htmlOptions);
}
else if ($type == 'css')
{
$compressed = EScriptBoost::minifyJs($script);
Yii::app()->cache->set($id, $compressed, $this->cacheDuration);
$media = empty($registerParam) ? '' : $registerParam;
return parent::registerCss($id, $compressed, $media);
}
parent::registerScript($id, $compressed, $position);
}
}
8 changes: 4 additions & 4 deletions EScriptBoost.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

Yii::import('scriptboostjs.*');
Yii::import('scriptboostcss.*');
Yii::import('scriptboosthtml.HTMLMin');
Yii::import('scriptboosthtml.*');

class EScriptBoost extends CComponent {

Expand Down Expand Up @@ -124,12 +124,12 @@ public static function minifyJs($content, $adapter = self::JS_MIN, $options = ar
*
* @param string $content the content to parse
* @param array $options
* @see HTMLMin class to check the options
* @see Minify_HTML class to check the options
* @return minified content
*/
public static function minifyHTML($content, $options = array())
{
return HTMLMin::minify($content, $options);
return Minify_HTML::minify($content, $options);
}

/**
Expand Down Expand Up @@ -169,4 +169,4 @@ public static function registerScript($id, $script, $cacheDuration=0, $position=
}
Yii::app()->clientScript->registerScript($id, $js, $position);
}
}
}
37 changes: 37 additions & 0 deletions EScriptBoostController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* This Controller allows you automatically minify all content rendered by the views.
* All application controller classes should extend from this class to enable the
* functionality or processOutput() method below should be ported to your code.
* Note that this will not enable minification of CSS and JavaScript published through
* the assetmanager or registered with clientscript. You will need to use EAssetManager
* and EClientScriptBoost components to minify CSS and scripts registered via Yii functions.
*/
class EScriptBoostController extends CController
{
public function processOutput($output)
{
// check if needed classes exist in order not to break the whole application if
// they are not yet available
if
(
class_exists('EScriptBoost')
&& class_exists('CssMin')
&& class_exists('JSMin')
)
{
// set up handlers to minify CSS and JavaScript in <style> and <script> tags
$minifyHTMLOptions = array();
$minifyHTMLOptions['cssMinifier'] = array('CssMin','minify');
$minifyHTMLOptions['jsMinifier'] = array('JSMin','minify');

$compressedHtmlOutput = EScriptBoost::minifyHTML($output, $minifyHTMLOptions);
if (!empty($compressedHtmlOutput))
$output = $compressedHtmlOutput;
else
Yii::log("EScriptBoost::minifyHTML() on ".strlen($output)." byte long output returned empty. Returning original output.", CLogger::LEVEL_WARNING, __METHOD__);
}

return parent::processOutput($output);
}
}
Loading

0 comments on commit bb6dcac

Please sign in to comment.