Zend_View_Helper_InlineScript Appends Scripts Twice

Double Trouble

duplicate
This is a well known problem, which is well described as a bug in Zend Framework’s issue tracker. Once you add some scripts with the inlineScript helper you’ll receive them twice in the code. This makes the page slower and leads to some crashes.

$scripts->appendFile('my-file1.js')
        ->appendFile('my-file2.js')
        ->appendScript('alert("test")');

This will print the alert twice.

<script src="my-file1.js"></script>
<script src="my-file2.js"></script>
<script>
//<!--
alert("test");
//-->
</script>
<script>
//<!--
alert("test");
//-->
</script>

Quick Solution

Although this is the worst solution I’ve ever made – it works! There is a check for duplicates in the HeadScript helper around line 240:

if (!$this->_isDuplicate($content)) {
...

and then a check in the _isDuplicate method(), ~ line 270:

if (($item->source === null)
    && array_key_exists('src', $item->attributes)
    && ($file == $item->attributes['src']))
{
    return true;
}

The thing you’ve to do is to add such a check for the appendScript() and not only for appendFile() method – again ~ line 230:

case 'script':
	if (!$this->_isDuplicate($content)) {
	    $item = $this->createData($type, $attrs, $content);
	    if ('offsetSet' == $action) {
	        $this->offsetSet($index, $item);
	    } else {
	        $this->$action($item);
	    }
	}
	break;

And then slightly modify the _isDuplicate method:

foreach ($this->getContainer() as $item) {
    if (($item->source === null)
        && array_key_exists('src', $item->attributes)
        && ($file == $item->attributes['src']))
    {
        return true;
    }
    if ($item->source == $file) {
        return true;
    }
}
return false;

2 thoughts on “Zend_View_Helper_InlineScript Appends Scripts Twice

  1. I had the same issue and its really annoying.

    I used a solution which is also not that great, but at least one don’t have to alter the core files.

    create an array and store the added code in it, then every time before calling the script object first check if it was already added.

    Something like this:

    if(!in_array($jsCode, $this->inlineScriptBugFixArray)){
     
            $scripts->headScript('SCRIPT', $jsCode);
    	$this->inlineScriptBugFixArray[]=$jsCode;
    }

    and the above will obviously be inside a method that can be called every time a script needs to be added, ensuring its unique everytime, at the cost of some memory for storing $jsCode in the array.

Leave a Reply

Your email address will not be published. Required fields are marked *