Skip to content

Commit

Permalink
Use of custom cache (Zend Cache Adapter) for the Asset ViewHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
pensiero committed Aug 28, 2015
1 parent 7be4e09 commit 504a48b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 21 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ return array(
),
),
),
'view_helper' => array(
// Note: You will need to require the factory used for the cache yourself.
'cache' => 'Application\Cache\Redis',
),
'caching' => array(
'js/d.js' => array(
'cache' => 'Apc',
Expand Down
3 changes: 1 addition & 2 deletions src/AssetManager/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ public function getViewHelperConfig()
return array(
'factories' => array(
'asset' => function ($serviceManager) {
$serviceLocator = $serviceManager->getServiceLocator();
return new AssetViewHelper($serviceLocator->get('config'), $serviceLocator->get('AssetManager\Service\AssetCacheManager'));
return new AssetViewHelper($serviceManager->getServiceLocator());
},
),
);
Expand Down
95 changes: 80 additions & 15 deletions src/AssetManager/View/Helper/Asset.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?php
namespace AssetManager\View\Helper;

use AssetManager\Service\AssetCacheManager;
use AssetManager\Exception\InvalidArgumentException;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper\AbstractHelper;
use Zend\Cache\Storage\Adapter\AbstractAdapter as AbstractCacheAdapter;

class Asset extends AbstractHelper
{
Expand All @@ -12,35 +14,98 @@ class Asset extends AbstractHelper
private $config;

/**
* @var AssetCacheManager The AssetCacheManager service.
* @var ServiceLocatorInterface
*/
protected $cacheManager;
private $serviceLocator;

public function __construct($config, $assetCacheManager)
/**
* @param ServiceLocatorInterface $serviceLocator
*/
public function __construct(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
$this->config = $serviceLocator->get('config')['asset_manager'];
}

/**
* find the file and if it exists, append its unix modification time to the filename
*
* @param string $assetsPath
* @param string $filename
* @param string $queryString
* @return string
*/
private function elaborateFilePath($assetsPath, $filename, $queryString)
{
$this->config = $config;
$this->cacheManager = $assetCacheManager;
// double quotes to single quotes
$originalPath = str_replace('//', '/', $assetsPath . $filename);
if (file_exists($originalPath)) {
return $filename . '?' . $queryString . '=' . filemtime($originalPath);
}
}

/**
* Output the filepath with its unix modification time as query param
*
* @param string $filename
* @return string
*/
public function __invoke($filename)
{
// find assets path specified from cache
if (isset($this->config['asset_manager']['caching']['default']['options']['dir'])) {
// search the cache config for the specific file requested (if none, use the default one)
if (isset($this->config['caching'][$filename])) {
$cacheConfig = $this->config['caching'][$filename];
} else if (isset($this->config['caching']['default'])) {
$cacheConfig = $this->config['caching']['default'];
}

if (isset($cacheConfig) && isset ($cacheConfig['options']['dir'])) {

$assetsPath = $this->config['asset_manager']['caching']['default']['options']['dir'];
// find assets path specified from cache
$assetsPath = $cacheConfig['options']['dir'];

// query string params
$queryString = isset($this->config['asset_manager']['query_string'])
? $this->config['asset_manager']['query_string']
$queryString = isset($this->config['view_helper']['query_string'])
? $this->config['view_helper']['query_string']
: '_';

// find the file and if it exists, append its unix modification time to the filename
$originalPath = $assetsPath . $filename;
if (file_exists($originalPath)) {
return $filename . '?' . $queryString . '=' . filemtime($originalPath);
// cache
if (isset($this->config['view_helper']['cache']) && $this->config['view_helper']['cache'] != null) {

// get the cache, if it's a string, search it among services
$cache = $this->config['view_helper']['cache'];
if (is_string($cache)) {
$cache = $this->serviceLocator->get($cache);
}

if ($cache != null) {

// exception in case cache is not an Adapter that extend the AbstractAdapter of Zend\Cache\Storage
if (!($cache instanceof AbstractCacheAdapter)) {
throw new InvalidArgumentException(
'Invalid cache provided, you must pass a Cache Adapter that extend Zend\Cache\Storage\Adapter\AbstractAdapter'
);
}

// cache key based on the filename
$cacheKey = md5($filename);
$itemIsFoundInCache = false;
$filePath = $cache->getItem($cacheKey, $itemIsFoundInCache);

// if there is no element in the cache, elaborate and cache it
if ($itemIsFoundInCache === false) {
$filePath = $this->elaborateFilePath($assetsPath, $filename, $queryString);
$cache->setItem($cacheKey, $filePath);
}

return $filePath;
}
}

return $this->elaborateFilePath($assetsPath, $filename, $queryString);
}

// if nothing done, return the original filename
return $filename;
}
}
9 changes: 5 additions & 4 deletions tests/AssetManagerTest/View/Helper/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@

use PHPUnit_Framework_TestCase as TestCase;
use AssetManager\View\Helper\Asset;
use Zend\ServiceManager\ServiceManager;

class AssetTest extends TestCase
{
public function testInvoke()
{
$filename = '';
$config = [];
$helper = new Asset($config);
$serviceManager = new ServiceManager();
$filename = 'js/js.js';
$helper = new Asset($serviceManager);

$this->assertContains("?u=", $helper->__invoke($filename));
$this->assertContains('?_=', $helper->__invoke($filename));
}
}

0 comments on commit 504a48b

Please sign in to comment.