Skip to content

Commit

Permalink
Updated the Configuration and Extension in order to enable the creati…
Browse files Browse the repository at this point in the history
…on of multiple cache services.
  • Loading branch information
jhallbachner committed Sep 30, 2012
1 parent 03b846f commit 363eece
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 209 deletions.
252 changes: 140 additions & 112 deletions DependencyInjection/Configuration.php
Expand Up @@ -10,116 +10,144 @@
class Configuration implements ConfigurationInterface
{

protected $handlerSettings = array(
'FileSystem' => array(
'dirSplit' => 2,
'path' => '%kernel.cache_dir%/stash',
'filePermissions' => 0660,
'dirPermissions' => 0770,
'memKeyLimit' => 200
),
'SQLite' => array(
'filePermissions' => 0660,
'dirPermissions' => 0770,
'busyTimeout' => 500,
'nesting' => 0,
'subhandler' => 'PDO',
'version' => null,
'path' => '%kernel.cache_dir%/stash',
),
'APC' => array(
'ttl' => 300,
'namespace' => null,
),
);

public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('tedivm_stash');

$handlers = array_keys(Handlers::getHandlers());
$default = current($handlers);

$next = $rootNode
->children()
->scalarNode('handler')
->defaultValue($default)
->validate()
->ifNotInArray($handlers)
->thenInvalid('No Stash handler named %s registered.')
->end()
->end()
->end()
;

foreach($handlers as $handler) {
$this->addHandlerSettings($handler, $rootNode);
}

return $treeBuilder;
}

public function addHandlerSettings($handler, $rootNode)
{
if($handler == 'Memcached') {
$rootNode
->children()
->variableNode($handler)
->defaultValue(array())
->end()
->end()
;
return;
} elseif ($handler == 'MultiHandler') {
$this->addMultiHandlerSettings($rootNode);
return;
} else {
$node = $rootNode->children()->arrayNode($handler)->addDefaultsIfNotSet()->children();

if(!isset($this->handlerSettings[$handler])) {
$node->end()->end()->end();
return;
}

foreach($this->handlerSettings[$handler] as $setting => $default) {
$set = $node->scalarNode($setting);
if(isset($default))
$set = $set->defaultValue($default);
$end = $set->end();
}

$end->end()->end();
}
}

public function addMultiHandlerSettings($rootNode)
{
$node = $rootNode
->children()
->arrayNode('MultiHandler')
->addDefaultsIfNotSet()
->children();

$node
->VariableNode('handlers')
->defaultValue(array('FileSystem'))
->end()
;

$node = $node
->end();

$handlers = array_keys(Handlers::getHandlers());
foreach($handlers as $handler) {
if($handler !== 'MultiHandler') {
$this->addHandlerSettings($handler, $node);
}
}

$node->end()
->end()
;

}
protected $handlerSettings = array(
'FileSystem' => array(
'dirSplit' => 2,
'path' => '%kernel.cache_dir%/stash',
'filePermissions' => 0660,
'dirPermissions' => 0770,
'memKeyLimit' => 200
),
'SQLite' => array(
'filePermissions' => 0660,
'dirPermissions' => 0770,
'busyTimeout' => 500,
'nesting' => 0,
'subhandler' => 'PDO',
'version' => null,
'path' => '%kernel.cache_dir%/stash',
),
'Apc' => array(
'ttl' => 300,
'namespace' => null,
),
);

public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('stash');

$rootNode
->beforeNormalization()
->ifTrue(function ($v) { return is_array($v) && !array_key_exists('default_cache', $v) && array_key_exists('caches', $v); })
->then(function ($v) {
$names = array_keys($v['caches']);
$v['default_cache'] = reset($names);

return $v;
})
->end()
->beforeNormalization()
->ifTrue(function ($v) { return is_array($v) && !array_key_exists('caches', $v) && !array_key_exists('cache', $v); })
->then(function ($v) {
$cache = array();
foreach ($v as $key => $value) {
if ($key === 'default_cache') {
continue;
}
$cache[$key] = $v[$key];
unset($v[$key]);
}
$v['default_cache'] = isset($v['default_cache']) ? (string) $v['default_cache'] : 'default';
$v['caches'] = array($v['default_cache'] => $cache);

return $v;
})
->end()
->children()
->scalarNode('default_cache')->end()
->end()
->fixXmlConfig('cache')
->append($this->getCachesNode())
;

return $treeBuilder;
}

protected function getCachesNode()
{
$handlers = array_keys(Handlers::getHandlers());

$treeBuilder = new TreeBuilder();
$node = $treeBuilder->root('caches');

$childNode = $node
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('array')
->children()
->arrayNode('handlers')
->requiresAtLeastOneElement()
->defaultValue(array('FileSystem'))
->prototype('scalar')
->validate()
->ifNotInArray($handlers)
->thenInvalid('A handler of that name is not registered.')
->end()
->end()
->end()
;

foreach($handlers as $handler) {
if($handler !== 'MultiHandler') {
$this->addHandlerSettings($handler, $childNode);
}
}

$childNode->end()
;

return $node;
}


public function addHandlerSettings($handler, $rootNode)
{
$handlerNode = $rootNode
->arrayNode($handler);

if($handler == 'Memcache') {
$finalNode = $handlerNode
->arrayNode('servers')
->prototype('array')
->children()
->scalarNode('server')->defaultIfNotSet('127.0.0.1')->end()
->scalarNode('port')->defaultIfNotSet('11211')->end()
->scalarNode('weight')->end()
->end()
->end()
;
} else {
$defaults = isset($this->handlerSettings[$handler]) ? $this->handlerSettings[$handler] : array();

$node = $handlerNode
->addDefaultsIfNotSet()
->children();

foreach($defaults as $setting => $default) {
$node
->scalarNode($setting)
->defaultValue($default)
->end()
;
}

$finalNode = $node->end()
;
}

$finalNode->end()
;
}
}
46 changes: 38 additions & 8 deletions DependencyInjection/TedivmStashExtension.php
Expand Up @@ -2,12 +2,14 @@

namespace Tedivm\StashBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Definition\Processor;

/**
* Bundle extension to handle configuration of the Stash bundle. Based on the specification provided
Expand All @@ -25,16 +27,44 @@ public function load(array $configs, ContainerBuilder $container)

$processor = new Processor();
$config = $processor->processConfiguration(new Configuration(), $configs);
var_dump($config);
$container->setAlias('cache', sprintf('stash.%s_cache', $config['default_cache']));

$caches = array();
foreach($config['caches'] as $name => $cache) {
$caches[$name] = sprintf('stash.%s_cache', $name);
$this->addCacheService($name, $cache, $container);
}

$handler = $config['handler'];
$params = $config[$handler];
$container->setParameter('stash.caches', $caches);
$container->setParameter('stash.default_cache', $config['default_cache']);
}

protected function addCacheService($name, $cache, $container)
{
$handlers = $cache['handlers'];
unset($cache['handlers']);

$container->setParameter('stash.handler.type', $handler);
$container->setParameter('stash.handler.options', $params);
$container
->setDefinition(sprintf('stash.handler.%s_cache', $name), new DefinitionDecorator('stash.handler'))
->setArguments(array(
$handlers,
$cache
))
->setAbstract(false)
;
var_dump($container);
$container
->setDefinition(sprintf('stash.%s_cache', $name), new DefinitionDecorator('stash.cache'))
->setArguments(array(
new Reference(sprintf('stash.handler.%s_cache', $name))
))
->setAbstract(false)
;
}

public function getAlias()
{
return 'tedivm_stash';
return 'stash';
}
}
21 changes: 10 additions & 11 deletions Factory/HandlerFactory.php
Expand Up @@ -5,24 +5,23 @@

class HandlerFactory {

static function createHandler($type, $options)
static function createHandler($types, $options)
{
$handlers = Handlers::getHandlers();

$class = $handlers[$type];
$h = array();

if($type !== 'MultiHandler') {
return new $class($options);
foreach($types as $type) {
$class = $handlers[$type];
$opts = isset($options[$type]) ? $options[$type] : array();
$h[] = new $class[$opts];
}

$h = array();
$subhandlers = isset($options['handlers']) ? $options['handlers'] : array();
foreach($subhandlers as $subhandler) {
$shoptions = isset($options[$subhandler]) ? $options[$subhandler] : array();
$h[] = self::createHandler($subhandler, $shoptions);
if(count($h) == 1) {
return reset($h);
}
$options['handlers'] = $h;

return new $class($options);
$class = $handlers['MultiHandler'];
return new $class(array('handlers' => $h);
}
}
30 changes: 11 additions & 19 deletions Resources/config/services.yml
@@ -1,23 +1,15 @@
parameters:
stash.class: Tedivm\StashBundle\Service\Cache
stash_factory.class: Tedivm\StashBundle\Factory\HandlerFactory
stash.cache.class: Tedivm\StashBundle\Service\Cache
stash.handler.class: Tedivm\Stash\Handler\HandlerInterface
stash.factory.class: Tedivm\StashBundle\Factory\HandlerFactory

services:
stash:
arguments: [@stash_handler]
class: %stash.class%
stash_handler:
class: %stash.class%
factory_class: %stash_factory.class%
stash.cache:
class: %stash.cache.class%
abstract: true
stash.handler:
class: %stash.handler.class%
abstract: true
synthetic: true
factory_method: createHandler
arguments:
- %stash.handler.type%
- %stash.handler.options%
data_collector.stash:
class: Tedivm\StashBundle\Collector\CacheDataCollector
arguments: [ %stash.handler.type%, %stash.handler.options% ]
tags:
-
name: data_collector
template: "TedivmStashBundle:Profiler:layout"
id: "stash"
factory_class: %stash.factory.class%

0 comments on commit 363eece

Please sign in to comment.