Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.3][Enhancement][WIP] Cachebundle #3225

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/Symfony/Bundle/CacheBundle/CacheBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/


namespace Symfony\Bundle\CacheBundle;

use Symfony\Bundle\CacheBundle\DependencyInjection\Compiler\ServiceCreationCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Bundle\CacheBundle\DependencyInjection\CacheExtension;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\MemcachedBackendFactory;
use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\MemcachedProviderFactory;
use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\ApcBackendFactory;
use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\ApcProviderFactory;

/**
* @author Victor Berchet <victor@suumit.com>
*/
class CacheBundle extends Bundle
{
private $kernel;

public function build(ContainerBuilder $container)
{
parent::build($container);

$ext = $container->getExtension('cache');

$ext->addBackendFactory(new MemcachedBackendFactory());
$ext->addBackendFactory(new ApcBackendFactory());

$ext->addProviderFactory(new MemcachedProviderFactory());
//$ext->addProviderFactory(new ApcProviderFactory());


//$container->addCompilerPass(new ServiceCreationCompilerPass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend;

use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* @author Victor Berchet <victor@suumit.com>
*/
abstract class AbstractBackendFactory implements BackendFactoryInterface
{
public function init(ContainerBuilder $container, $config)
{
}

public function getType()
{
return strtolower($this->getName());
}

public function getConfigKey()
{
return strtolower(preg_replace(
array('/[^a-z0-9.-_]/i', '/(?<=[a-zA-Z0-9])[A-Z]/'),
array('', '_\\0'),
$this->getName())
);
}

protected function getName()
{
$class = get_class($this);
$pos = strrpos($class, '\\');
$class = false === $pos ? $class : substr($class, $pos + 1);

if ('BackendFactory' !== substr($class, -14)) {
throw new \LogicException('The factory name could not be determined.');
}

return substr($class,0, -14);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend;

use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* @author Victor Berchet <victor@suumit.com>
*/
class ApcBackendFactory extends AbstractBackendFactory
{
public function addConfiguration(NodeBuilder $builder)
{
$builder->scalarNode($this->getConfigKey())->end();
}

public function createService($id, ContainerBuilder $container, $config)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

/**
* @author Victor Berchet <victor@suumit.com>
*/
interface BackendFactoryInterface
{
function init(ContainerBuilder $container, $config);
function getType();
function getConfigKey();
function addConfiguration(NodeBuilder $builder);
function createService($id, ContainerBuilder $container, $config);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\CacheBundle\DependencyInjection\Backend;

use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Alias;

/**
* Memcached backend.
*
* @author Victor Berchet <victor@suumit.com>
*/
class MemcachedBackendFactory extends AbstractBackendFactory
{
private $factories = array();

public function addConfiguration(NodeBuilder $builder)
{
// TODO fix config
$builder
->arrayNode($this->getConfigKey())
->fixXmlConfig('server')
->children()
->arrayNode('servers')
->useAttributeAsKey('name')
->prototype('array')
->children()
->scalarNode('host')
->beforeNormalization()
->ifInArray(array('127.0.0.1', '::1', '0:0:0:0:0:0:0:1'))
->then(function($v) { return 'localhost'; })
->end()
->defaultValue('%cache.memcached.defaults.host%')
->end()
->scalarNode('port')->defaultValue('%cache.memcached.defaults.port%')->end()
->scalarNode('weight')->defaultValue('%cache.memcached.defaults.weight%')->end()
;
}

public function createService($id, ContainerBuilder $container, $config)
{
$signature = $this->getSignature($config);
$servers = array();

if (isset($this->factories[$signature])) {
$container->setAlias($id, $this->factories[$signature]);
} else {
$definition = new DefinitionDecorator('cache.backend.memcached');
foreach ($config['servers'] as $server) {
$servers[] = array($server['host'], $server['port'], $server['weight']);
}

if (count($servers) > 1) {
$definition->addMethodCall('addServers', $servers);
} else if (count($servers)) {
// TODO remove the if above once the config gets fixed
$definition->addMethodCall('addServer', $servers[0]);
}

$container->setDefinition($id, $definition);
$this->factories[$signature] = $id;
}
}

protected function getSignature(array $config)
{
// TODO check if the server ordering is significative
$description = "";
foreach ($config['servers'] as $server) {
$description .= serialize($server);
}
return md5($description);
}

}
103 changes: 103 additions & 0 deletions src/Symfony/Bundle/CacheBundle/DependencyInjection/CacheExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\CacheBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Bundle\CacheBundle\DependencyInjection\Backend\BackendFactoryInterface;
use Symfony\Bundle\CacheBundle\DependencyInjection\Provider\ProviderFactoryInterface;

/**
* CacheExtension is an extension for the Doctrine\Common\Cache interface.
*
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
* @author Victor Berchet <victor@suumit.com>
*/
class CacheExtension extends Extension
{
private $beFactories = array();
private $providerFactories = array();

public function load(array $configs, ContainerBuilder $container)
{
$processor = new Processor();
$configuration = $this->getConfiguration($configs, $container);
$config = $processor->processConfiguration($configuration, $configs);

$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');

$container->setParameter('cache.debug', $config['debug']);

$this->initBackends($container, $config['backends']);

$this->configureBackends($container, $config['backends']);

//$this->configureProviders($container, $config['providers']);

//$container->setParameter($this->getAlias().'.namespaces', $config['namespaces']);
}

public function addBackendFactory(BackendFactoryInterface $beFactory)
{
$this->beFactories[$beFactory->getType()] = $beFactory;
}

public function addProviderFactory(ProviderFactoryInterface $providerFactory)
{
$this->providerFactories[$providerFactory->getName()] = $providerFactory;
}

private function initBackends(ContainerBuilder $container, $backends)
{
foreach ($backends as $name => $configs) {
foreach ($configs as $type => $config) {
$this->beFactories[$type]->init($container, $config);
}
}
}

private function configureBackends(ContainerBuilder $container, $backends)
{
foreach ($backends as $name => $configs) {
foreach ($configs as $type => $config) {
$this->beFactories[$type]->createService('cache.backend.concrete.'.$name, $container, $config);
}
}
}

private function configureProviders(ContainerBuilder $container, $configs)
{
foreach ($configs as $name => $config) {
$type = $config['type'];
$this->providerFactories[$type]->configure($container, $name, $config);
}
}

public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($this->beFactories, $this->providerFactories);
}

public function getXsdValidationBasePath()
{
return __DIR__.'/../Resources/config/schema';
}

public function getNamespace()
{
return 'http://symfony.com/schema/dic/cache';
}
}
Loading