We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Prevent duplicate resources in Asset Manager

I'm in a situation where I could have the same resource (a javascript file) added to the Asset Manager by a couple different sources. I'd like to prevent that duplication so I've written my own Asset Manager that extends the built-in Asset Manager. Basically all it does is keep a record of the URLs that have been added, and doesn't add URLs that have already been added. The code for it is below. I've also overridden the Asset Manager object in my DI. That code is also below.

The trouble I'm having is that while I can add resources, they don't get added to my view. Calling {{ assets.outputJs() }} simply doesn't output anything. I'm not sure what I have to do to get {{ assets.outputJS() }} to work.

My Asset Manager class

<?PHP
/**
 * This file contains the Asset Manager class
 */

namespace MW\Component;

/**
 * This class is a wrapper for the built-in-Phalcon Asset Manager.  All it adds is a log of already included assets,
 * so the same URL won't get added multiple times
 */

class AssetManager extends \Phalcon\Assets\Manager{
    /** @var array $url_cache A record of all included asset URLs */
    private $url_cache = [];

    /**
     * Add a CSS resource
     * 
     * @param string $path The path to the resource
     * @param boolean $local See Phalcon documentation: https://docs.phalcon.io/en/latest/reference/assets.html
     * @param boolean $filter See Phalcon documentation
     * @param array $attributes See Phalcon documentation
     * @return object self To allow chaining
     */
    public function addCss($path,$local = NULL,$filter = NULL,$attributes = NULL){
        if(!in_array($path, $this->url_cache)){
            $this->url_cache[] = $path;
            parent::addCss($path,$local,$filter,$attributes);   
        }

        return $this;
    }

    /**
     * Add a Javascript resource
     * 
     * @param string $path The path to the resource
     * @param boolean $local See Phalcon documentation: https://docs.phalcon.io/en/latest/reference/assets.html
     * @param boolean $filter See Phalcon documentation
     * @param array $attributes See Phalcon documentation
     * @return object self To allow chaining
     */
    public function addJs($path,$local = NULL,$filter = NULL,$attributes = NULL){
        if(!in_array($path, $this->url_cache)){
            $this->url_cache[] = $path;
            parent::addJs($path,$local,$filter,$attributes);    
        }

        return $this;
    }
}

The part of my bootstrap.php that sets the Asset Manager:


$DI->set('assets',function(){
    $Manager =  new \MW\Component\AssetManager();
    return $Manager;
});
edited Aug '16

@quasipickle If you are using dispacher forward and setting up assets in beforeExecuteRoute or IN initialize make sure you don't call assets script twice inside forward


class ControllerBase extends Controller
{

    public function beforeExecuteRoute()
    {
        if(!$this->dispatcher->getPreviousActionName()){
            $this->setAssets();
        }

    }

}