📜 ⬆️ ⬇️

HeadScript Focus (build into one file)

If you do this:
<? php $ this- > headScript()- > appendFile('/js/my1.js');? >
<? php $ this- > headScript()- > appendFile('/js/my2.js');? >
<? php $ this- > headScript()- > captureStart() ? >
var action = ' <? php echo $ this- > baseUrl ? > ';
<? php $ this- > headScript()- > captureEnd() ? >

<? php echo $ this- > headScript(); ? >
<? php echo $ this- > magicHeadScript(); ? >


then instead of something like this:
<script type= "text/javascript" src= "/js/my1.js" ></script>
<script type= "text/javascript" src= "/js/my2.js" ></script>
<script type= "text/javascript" >
var action = '/123' ;
</script>

get the output:
<script type= "text/javascript" src= "/cache/js/1b1004a203..._compressed.js" ></script>


Secret focus


/**
* @license Public domain
*/
class My_View_Helper_MagicHeadScript extends Zend_View_Helper_HeadScript
{
private static $cacheDir;
private static $combine = 1;
private static $compress = 1;
private static $symlinks = array();

private $_cache = array();

static public function setConfig($cacheDir, $combine = 1, $compress = 1, $symlinks = array())
{
self::$cacheDir = rtrim($dir, '/' ) . '/' ;
self::$symlinks = $symlinks;
self::$combine = $combine;
self::$compress = $compress;
}

public function magicHeadScript()
{
if (self::$combine) {
return $ this ->toString();
} else {
return $ this ->view->headScript();
}
}

public function itemToString($item, $indent, $escapeStart, $escapeEnd)
{
$attrString = '' ;
if (!empty($item->attributes)) {
foreach ($item->attributes as $key => $value) {
if (!$ this ->arbitraryAttributesAllowed()
&& !in_array($key, $ this ->_optionalAttributes))
{
continue ;
}
if ( 'defer' == $key) {
$value = 'defer' ;
}
$attrString .= sprintf( ' %s="%s"' , $key, ($ this ->_autoEscape) ? $ this ->_escape($value) : $value);
}
}

$type = ($ this ->_autoEscape) ? $ this ->_escape($item->type) : $item->type;
$html = $indent . '<script type="' . $type . '"' . $attrString . '>' ;
if (!empty($item->source)) {
$html .= PHP_EOL . $indent . ' ' . $escapeStart . PHP_EOL . $item->source . $indent . ' ' . $escapeEnd . PHP_EOL . $indent;
}
$html .= '</script>' ;

if (isset($item->attributes[ 'conditional' ])
&& !empty($item->attributes[ 'conditional' ])
&& is_string($item->attributes[ 'conditional' ]))
{
$html = '<!--[if ' . $item->attributes[ 'conditional' ] . ']> ' . $html . '<![endif]-->' ;
}

return $html;
}

public function searchJsFile($src)
{
$path = $_SERVER[ 'DOCUMENT_ROOT' ] . $src;
if (is_readable($path)) {
return $path;
}
foreach (self::$symlinks as $virtualPath => $realPath) {
$path = str_replace($virtualPath, $realPath, "/$src" );
if (is_readable($path)) {
return $path;
}
}
return false ;
}

public function isCachable($item)
{
if (isset($item->attributes[ 'conditional' ])
&& !empty($item->attributes[ 'conditional' ])
&& is_string($item->attributes[ 'conditional' ]))
{
return false ;
}

if (!empty($item->source) && false ===strpos($item->source, '//@non-cache' )) {
return true ;
}

if (!isset($item->attributes[ 'src' ]) || !$ this ->searchJsFile($item->attributes[ 'src' ])) {
return false ;
}
return true ;
}

public function cache($item)
{
if (!empty($item->source)) {
$ this ->_cache[] = $item->source;
} else {
$filePath = $ this ->searchJsFile($item->attributes[ 'src' ]);
$ this ->_cache[] = array(
'filepath' => $filePath,
'mtime' => filemtime($filePath)
);
}
}

public function toString($indent = null )
{
$headScript = $ this ->view->headScript();

$indent = ( null !== $indent)
? $headScript->getWhitespace($indent)
: $headScript->getIndent();

if ($ this ->view) {
$useCdata = $ this ->view->doctype()->isXhtml() ? true : false ;
} else {
$useCdata = $headScript->useCdata ? true : false ;
}
$escapeStart = ($useCdata) ? '//<![CDATA[' : '//<!--' ;
$escapeEnd = ($useCdata) ? '//]]>' : '//-->' ;

$items = array();
$headScript->getContainer()->ksort();
foreach ($headScript as $item) {
if (!$headScript->_isValid($item)) {
continue ;
}
if (!$ this ->isCachable($item)) {
$items[] = $ this ->itemToString($item, $indent, $escapeStart, $escapeEnd);
} else {
$ this ->cache($item);
}
}

array_unshift($items, $ this ->itemToString($ this ->getCompiledItem(), $indent, $escapeStart, $escapeEnd));

$ return = implode($headScript->getSeparator(), $items);
return $ return ;
}

private function getCompiledItem()
{
$filename = md5(serialize($ this ->_cache));
$path = self::$cacheDir . $filename . (self::$compress? '_compressed' : '' ) . '.js' ;
if (!file_exists($path)) {
//...debug("Combine javascripts to $path...");
mkdir(dirname($path), 0777, true );
$jsContent = '' ;
foreach ($ this ->_cache as $js) {
if (is_array($js)) {
$jsContent .= file_get_contents($js[ 'filepath' ]) . "\n\n" ;
//...debug($js['filepath'] . ' ... OK');
} else {
$jsContent .= $js . "\n\n" ;
//...debug('Inline JavaScript ... OK');
}
}
if ($compress) {
$jsContent = JSMin::minify($jsContent);
}
file_put_contents($path, $jsContent);
}

$url = str_replace($_SERVER[ 'DOCUMENT_ROOT' ], '' , $path);
$item = $ this ->createData( 'text/javascript' , array( 'src' =>$url));
return $item;
}
}

* This source code was highlighted with Source Code Highlighter .


Comments


The meaning of the helper's work is to bypass all the added scripts, calculate the hash taking into account the file names, the date the scripts were modified (mtime), the texts of the embedded scripts, build it all into one file and compress (optionally) finally using JSMin

If you do not need to cache any built-in script, because, for example, it often changes, then you need to add // @ non-cache:
<? php $ this- > headScript()- > captureStart() ? >
//@non-cache
var ip = <? php echo $ ip ? >
<? php $ this- > headScript()- > captureEnd() ? >


Missing embedded scripts will be connected after the assembled file, so you need to make sure that there are no dependencies from them.
')
Do not forget to place the plugin correctly and then specify Zend_View addHelperPath

If script compression is required, you need to put it in the accessible by __autoload (or add require) place of the JSMin class

Before using the helper directly, you need to specify somewhere in which folder the script should write the collected file:
My_View_Helper_MagicHeadScript::setConfig('/path/to/cache');

After modifying the JS scripts, no additional gestures need to be made - the hash will change and the helper will make the new file assembly itself (and it will already be with a different name, so there will be no problems with client caching). Naturally, the assembly is performed once at the first circulation.

MagicHeadLink is a similar solution for building CSS files, but only using Minify can be downloaded below (too lazy to make out a separate article - I'm tired of coloring the source :)).


Download


MagicHeadScript + JSMin:
mhs.zip (4 Kb)

MagicHeadLink + Minify (trimmed):
mhl.zip (8 Kb)

Source: https://habr.com/ru/post/85324/


All Articles