Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
added new View Helper - Asset helper
Browse files Browse the repository at this point in the history
  • Loading branch information
michalbundyra committed Jun 15, 2016
1 parent bace31c commit 11e9437
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 0 deletions.
74 changes: 74 additions & 0 deletions doc/book/helpers/asset.md
@@ -0,0 +1,74 @@
# Asset

The `Asset` helper is used to translate asset names.
It could be used to prevent browser caching for assets.

## Configuration and Basic Usage

`Zend\View\Helper\Service\AssetFactory` checks the application
configuration, making it possible to set up the resource map through
your `module.config.php`. The next example will set up `Asset` helper:

```php
'view_helper_config' => [
'asset' => [
'resource_map' => [
'css/style.css' => 'css/style-3a97ff4ee3.css',
'js/vendor.js' => 'js/vendor-a507086eba.js',
],
],
],
```

Then in your view you can use:

```php
// Usable in any of your .phtml files:
echo $this->asset('css/style.css');
```

and you would receive following output:

```html
css/style-3a97ff4ee3.css
```

The first argument of the `asset` helper is the regular asset name,
which will be replaced by versioned asset name defined in `resource_map`
of the configuration.

### Note

When `asset` key is defined but `resource_map` is not provided or is not
an array exception `Zend\View\Exception\RuntimeException` will be
thrown.

When you call `asset` helper with parameter which is not defined on your
`resource_map` exception `Zend\View\Exception\InvalidArgumentException`
will be thrown.

## Resource map in JSON file

If you have JSON file with resource map, for example
`rev-manifest.json`:

```javascript
{
"css/style.css": "css/style-3a97ff4ee3.css",
"js/vendor.js": "js/vendor-a507086eba.js"
}
```

then you can have in your configuration:

```php
'view_helper_config' => [
'asset' => [
'resource_map' => json_decode(file_get_contents('/path/to/rev-manifest.json'), true),
],
],
```

and when you have enabled cache config this file will be also cached in
compiled configuration cache, so it prevents reading the file on each
page load.
1 change: 1 addition & 0 deletions doc/book/helpers/intro.md
Expand Up @@ -55,6 +55,7 @@ variables. Additionally, there are a rich set of helpers for providing values
for, and rendering, the various HTML `<head>` tags, such as `HeadTitle`,
`HeadLink`, and `HeadScript`. The currently shipped helpers include:

- [Asset](asset.md)
- [BasePath](base-path.md)
- [Cycle](cycle.md)
- [Doctype](doctype.md)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -9,6 +9,7 @@ pages:
- "The ViewEvent": view-event.md
- Helpers:
- Intro: helpers/intro.md
- Asset: helpers/asset.md
- BasePath: helpers/base-path.md
- Cycle: helpers/cycle.md
- Doctype: helpers/doctype.md
Expand Down
48 changes: 48 additions & 0 deletions src/Helper/Asset.php
@@ -0,0 +1,48 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zendframework for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\View\Helper;

use Zend\View\Exception;

/**
* View helper plugin to fetch asset from resource map.
*/
class Asset extends AbstractHelper
{
/**
* @var array
*/
protected $resourceMap = [];

/**
* @param string $asset
* @return string
*/
public function __invoke($asset)
{
if (!array_key_exists($asset, $this->resourceMap)) {
throw new Exception\InvalidArgumentException('Asset is not defined.');
}

return $this->resourceMap[$asset];
}

public function setResourceMap($resourceMap)
{
$this->resourceMap = $resourceMap;

return $this;
}

public function getResourceMap()
{
return $this->resourceMap;
}
}
61 changes: 61 additions & 0 deletions src/Helper/Service/AssetFactory.php
@@ -0,0 +1,61 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zendframework for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\View\Helper\Service;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Exception;
use Zend\View\Helper\Asset;

class AssetFactory implements FactoryInterface
{
/**
* {@inheritDoc}
*
* @param ContainerInterface $container
* @param string $name
* @param null|array $options
* @return Asset
*/
public function __invoke(ContainerInterface $container, $name, array $options = null)
{
// test if we are using Zend\ServiceManager v2 or v3
if (! method_exists($container, 'configure')) {
$container = $container->getServiceLocator();
}
$helper = new Asset();

$config = $container->get('config');
if (isset($config['view_helper_config']['asset'])) {
$configHelper = $config['view_helper_config']['asset'];
if (isset($configHelper['resource_map']) && is_array($configHelper['resource_map'])) {
$helper->setResourceMap($configHelper['resource_map']);
} else {
throw new Exception\RuntimeException('Invalid resource map configuration.');
}
}

return $helper;
}

/**
* Create service
*
* @param ServiceLocatorInterface $serviceLocator
* @param string|null $rName
* @param string|null $cName
* @return Asset
*/
public function createService(ServiceLocatorInterface $serviceLocator, $rName = null, $cName = null)
{
return $this($serviceLocator, $cName);
}
}
4 changes: 4 additions & 0 deletions src/HelperPluginManager.php
Expand Up @@ -37,6 +37,8 @@ class HelperPluginManager extends AbstractPluginManager
* @var string[]
*/
protected $aliases = [
'asset' => Helper\Asset::class,
'Asset' => Helper\Asset::class,
'basePath' => Helper\BasePath::class,
'BasePath' => Helper\BasePath::class,
'basepath' => Helper\BasePath::class,
Expand Down Expand Up @@ -148,6 +150,7 @@ class HelperPluginManager extends AbstractPluginManager
* @var array
*/
protected $factories = [
Helper\Asset::class => Helper\Service\AssetFactory::class,
Helper\FlashMessenger::class => Helper\Service\FlashMessengerFactory::class,
Helper\Identity::class => Helper\Service\IdentityFactory::class,
Helper\BasePath::class => InvokableFactory::class,
Expand Down Expand Up @@ -186,6 +189,7 @@ class HelperPluginManager extends AbstractPluginManager

// v2 canonical FQCNs

'zendviewhelperasset' => Helper\Service\AssetFactory::class,
'zendviewhelperflashmessenger' => Helper\Service\FlashMessengerFactory::class,
'zendviewhelperidentity' => Helper\Service\IdentityFactory::class,
'zendviewhelperbasepath' => InvokableFactory::class,
Expand Down
89 changes: 89 additions & 0 deletions test/Helper/AssetTest.php
@@ -0,0 +1,89 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zendframework for the canonical source repository
* @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\View\Helper;

use PHPUnit_Framework_TestCase as TestCase;
use Zend\ServiceManager\ServiceManager;
use Zend\View\Exception;
use Zend\View\Helper\Asset;
use Zend\View\HelperPluginManager;

class AssetTest extends TestCase
{
/** @var array */
protected $resourceMap = [
'css/style.css' => 'css/style-3a97ff4ee3.css',
'js/vendor.js' => 'js/vendor-a507086eba.js',
];

/** @var Asset */
protected $asset;

protected function setUp()
{
parent::setUp();

$this->asset = new Asset();
$this->asset->setResourceMap($this->resourceMap);
}

public function testHelperPluginManagerReturnsAssetHelper()
{
$helpers = $this->getHelperPluginManager();
$asset = $helpers->get('asset');

$this->assertInstanceOf(Asset::class, $asset);
}

public function testHelperPluginManagerReturnsAssetHelperByClassName()
{
$helpers = $this->getHelperPluginManager();
$asset = $helpers->get(Asset::class);

$this->assertInstanceOf(Asset::class, $asset);
}

public function testInvalidAssetName()
{
$this->setExpectedException(Exception\InvalidArgumentException::class, 'Asset is not defined.');

$this->asset->__invoke('unknown');
}

/**
* @dataProvider assets
*
* @param string $name
* @param string $expected
*/
public function testInvokeResult($name, $expected)
{
$result = $this->asset->__invoke($name);

$this->assertEquals($expected, $result);
}

public function assets()
{
$data = [];
foreach ($this->resourceMap as $key => $value) {
$data[] = [$key, $value];
}
return $data;
}

protected function getHelperPluginManager(array $config = [])
{
$services = $this->prophesize(ServiceManager::class);
$services->get('config')->willReturn($config);

return new HelperPluginManager($services->reveal());
}
}

0 comments on commit 11e9437

Please sign in to comment.