diff --git a/Block/BlockServiceManager.php b/Block/BlockServiceManager.php
index e2f39fbd..3c607704 100644
--- a/Block/BlockServiceManager.php
+++ b/Block/BlockServiceManager.php
@@ -32,6 +32,8 @@ class BlockServiceManager implements BlockServiceManagerInterface
protected $inValidate;
+ protected $contexts;
+
/**
* @param ContainerInterface $container
* @param $debug
@@ -40,6 +42,7 @@ class BlockServiceManager implements BlockServiceManagerInterface
public function __construct(ContainerInterface $container, $debug, LoggerInterface $logger = null)
{
$this->services = array();
+ $this->contexts = array();
$this->container = $container;
}
@@ -96,9 +99,17 @@ public function has($id)
/**
* {@inheritdoc}
*/
- public function add($name, $service)
+ public function add($name, $service, $contexts = array())
{
$this->services[$name] = $service;
+
+ foreach ($contexts as $context) {
+ if (!array_key_exists($context, $this->contexts)) {
+ $this->contexts[$context] = array();
+ }
+
+ $this->contexts[$context][] = $name;
+ }
}
/**
@@ -106,7 +117,9 @@ public function add($name, $service)
*/
public function setServices(array $blockServices)
{
- $this->services = $blockServices;
+ foreach($blockServices as $name => $service) {
+ $this->add($name, $service);
+ }
}
/**
@@ -123,6 +136,24 @@ public function getServices()
return $this->services;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getServicesByContext($context)
+ {
+ if (!array_key_exists($context, $this->contexts)) {
+ return array();
+ }
+
+ $services = array();
+
+ foreach ($this->contexts[$context] as $name) {
+ $services[$name] = $this->getService($name);
+ }
+
+ return $services;
+ }
+
/**
* {@inheritdoc}
*/
@@ -142,6 +173,8 @@ public function getLoadedServices()
}
/**
+ * @todo: this function should be remove into a proper statefull object
+ *
* {@inheritdoc}
*/
public function validate(ErrorElement $errorElement, BlockInterface $block)
diff --git a/Block/BlockServiceManagerInterface.php b/Block/BlockServiceManagerInterface.php
index 3f509544..c8e6404f 100644
--- a/Block/BlockServiceManagerInterface.php
+++ b/Block/BlockServiceManagerInterface.php
@@ -18,10 +18,11 @@ interface BlockServiceManagerInterface
/**
* @param string $name
* @param string $service
+ * @param array $contexts
*
* @return void
*/
- public function add($name, $service);
+ public function add($name, $service, $contexts = array());
/**
* Return the block service linked to the link
@@ -33,6 +34,8 @@ public function add($name, $service);
public function get(BlockInterface $block);
/**
+ * @deprecated will be remove in 2.4, use the add method instead
+ *
* @param array $blockServices
*
* @return void
@@ -45,7 +48,13 @@ public function setServices(array $blockServices);
public function getServices();
/**
+ * @param string $name
*
+ * @return array
+ */
+ public function getServicesByContext($name);
+
+ /**
* @param string $name
*
* @return boolean
@@ -60,6 +69,8 @@ public function has($name);
public function getService($name);
/**
+ * @deprecated will be remove in 2.4
+ *
* @return array
*/
public function getLoadedServices();
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 31be2fb6..1aadc06c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ A [BC BREAK] means the update will break the project for many reasons:
* new dependencies
* class refactoring
+### 2014-04-23
+
+* [BC BREAK] Complete support for context, add new method in BlockServiceManager (getServicesByContext)
+
### 2014-03-10
* [BC BREAK] Updated configuration: ``sonata_block.profiler.container_types`` is deprecated in favor of ``sonata_block.container.types``; please update your configuration accordingly.
diff --git a/Command/DebugBlocksCommand.php b/Command/DebugBlocksCommand.php
index 4cfb11fd..ce1708c7 100644
--- a/Command/DebugBlocksCommand.php
+++ b/Command/DebugBlocksCommand.php
@@ -12,6 +12,7 @@
namespace Sonata\BlockBundle\Command;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\OptionsResolver\OptionsResolver;
@@ -22,11 +23,19 @@ public function configure()
{
$this->setName('sonata:block:debug');
$this->setDescription('Debug all blocks available, show default settings of each block');
+
+ $this->addOption('context', 'c', InputOption::VALUE_REQUIRED, 'display service for the specified context');
}
public function execute(InputInterface $input, OutputInterface $output)
{
- foreach ($this->getBlockServiceManager()->getServices() as $code => $service) {
+ if ($input->getOption('context')) {
+ $services = $this->getBlockServiceManager()->getServicesByContext($input->getOption('context'));
+ } else {
+ $services = $this->getBlockServiceManager()->getServices();
+ }
+
+ foreach ($services as $code => $service) {
$resolver = new OptionsResolver();
$service->setDefaultSettings($resolver);
diff --git a/DependencyInjection/Compiler/TweakCompilerPass.php b/DependencyInjection/Compiler/TweakCompilerPass.php
index b23d688e..c5b33244 100644
--- a/DependencyInjection/Compiler/TweakCompilerPass.php
+++ b/DependencyInjection/Compiler/TweakCompilerPass.php
@@ -29,8 +29,10 @@ public function process(ContainerBuilder $container)
{
$manager = $container->getDefinition('sonata.block.manager');
+ $parameters = $container->getParameter('sonata_block.blocks');
+
foreach ($container->findTaggedServiceIds('sonata.block') as $id => $attributes) {
- $manager->addMethodCall('add', array($id, $id));
+ $manager->addMethodCall('add', array($id, $id, isset($parameters[$id]) ? $parameters[$id]['contexts'] : array()));
}
$services = array();
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 6ae23765..3b2c6d57 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -47,14 +47,21 @@ public function getConfigTreeBuilder()
->fixXmlConfig('block')
->fixXmlConfig('block_by_class')
->validate()
- ->ifTrue(function ($v) {
- if (isset($v['profiler']['container_types']) && !empty($v['profiler']['container_types'])
- && isset($v['container']['types']) && !empty($v['container']['types'])) {
- return 0 !== count(array_diff($v['profiler']['container_types'], $v['container']['types']));
- }
- return false;
- })
- ->thenInvalid("You cannot have different config options for sonata_block.profiler.container_types and sonata_block.container.types; the first one is deprecated, in case of doubt use the latter")
+ ->always(function($value) {
+ foreach ($value['blocks'] as $name => &$block) {
+ if (count($block['contexts']) == 0) {
+ $block['contexts'] = $value['default_contexts'];
+ }
+ }
+
+ if (isset($value['profiler']['container_types']) && !empty($value['profiler']['container_types'])
+ && isset($value['container']['types']) && !empty($value['container']['types'])
+ && 0 !== count(array_diff($value['profiler']['container_types'], $value['container']['types']))) {
+ throw new \RuntimeException("You cannot have different config options for sonata_block.profiler.container_types and sonata_block.container.types; the first one is deprecated, in case of doubt use the latter");
+ }
+
+ return $value;
+ })
->end()
->children()
->arrayNode('profiler')
diff --git a/DependencyInjection/SonataBlockExtension.php b/DependencyInjection/SonataBlockExtension.php
index 029d8ed2..c0c71795 100644
--- a/DependencyInjection/SonataBlockExtension.php
+++ b/DependencyInjection/SonataBlockExtension.php
@@ -197,9 +197,6 @@ public function configureForm(ContainerBuilder $container, array $config)
$contexts[$context][] = $service;
}
}
-
- $container->getDefinition('sonata.block.form.type.block')
- ->replaceArgument(1, $contexts);
}
/**
diff --git a/Form/Type/ServiceListType.php b/Form/Type/ServiceListType.php
index 56910f9b..6480eeea 100644
--- a/Form/Type/ServiceListType.php
+++ b/Form/Type/ServiceListType.php
@@ -23,16 +23,12 @@ class ServiceListType extends AbstractType
{
protected $manager;
- protected $contexts;
-
/**
* @param BlockServiceManagerInterface $manager
- * @param array $contexts
*/
- public function __construct(BlockServiceManagerInterface $manager, array $contexts = array())
+ public function __construct(BlockServiceManagerInterface $manager)
{
$this->manager = $manager;
- $this->contexts = $contexts;
}
/**
@@ -56,25 +52,19 @@ public function getParent()
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
- $contexts = $this->contexts;
$manager = $this->manager;
+ $resolver->setRequired(array(
+ 'context',
+ ));
+
$resolver->setDefaults(array(
- 'context' => false,
'multiple' => false,
'expanded' => false,
- 'choices' => function (Options $options, $previousValue) use ($contexts, $manager) {
- if (!isset($contexts[$options['context']])) {
- if (Kernel::MINOR_VERSION < 3) {
- throw new \RuntimeException(sprintf('Invalid context: `%s`', $options['context']));
- }
-
- throw new InvalidArgumentException(sprintf('Invalid context: `%s`', $options['context']));
- }
-
+ 'choices' => function (Options $options, $previousValue) use ($manager) {
$types = array();
- foreach ($contexts[$options['context']] as $service) {
- $types[$service] = sprintf('%s - %s', $manager->getService($service)->getName(), $service);
+ foreach ($manager->getServicesByContext($options['context']) as $code => $service) {
+ $types[$code] = sprintf('%s - %s', $service->getName(), $code);
}
return $types;
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..829424a5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
+.PHONY: test
+
+test:
+ phpunit
+ cd Resources/doc && sphinx-build -W -b html -d _build/doctrees . _build/html
diff --git a/Resources/config/form.xml b/Resources/config/form.xml
index 6ba5fc66..22ad265b 100644
--- a/Resources/config/form.xml
+++ b/Resources/config/form.xml
@@ -8,7 +8,6 @@
-
diff --git a/Tests/Block/BlockServiceManagerTest.php b/Tests/Block/BlockServiceManagerTest.php
index f5cfdf34..8004ed0b 100644
--- a/Tests/Block/BlockServiceManagerTest.php
+++ b/Tests/Block/BlockServiceManagerTest.php
@@ -67,4 +67,28 @@ public function testGetBlockServiceException()
$manager->get($block);
}
+
+ public function testGetEmptyListFromInvalidContext()
+ {
+ $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
+ $manager = new BlockServiceManager($container, true);
+
+ $service = $this->getMock('Sonata\BlockBundle\Block\BlockServiceInterface');
+
+ $manager->add('foo.bar', $service);
+
+ $this->assertEmpty($manager->getServicesByContext('fake'));
+ }
+
+ public function testGetListFromValidContext()
+ {
+ $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
+ $manager = new BlockServiceManager($container, true);
+
+ $service = $this->getMock('Sonata\BlockBundle\Block\BlockServiceInterface');
+
+ $manager->add('foo.bar', $service, array('fake'));
+
+ $this->assertNotEmpty($manager->getServicesByContext('fake'));
+ }
}
diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php
index 0237cba8..67fb8d3a 100644
--- a/Tests/DependencyInjection/ConfigurationTest.php
+++ b/Tests/DependencyInjection/ConfigurationTest.php
@@ -26,7 +26,8 @@ public function testOptions()
$processor = new Processor();
$config = $processor->processConfiguration(new Configuration($defaultTemplates), array(array(
- 'default_contexts' => array('cms')
+ 'default_contexts' => array('cms'),
+ 'blocks' => array('my.block.type' => array())
)));
@@ -62,7 +63,13 @@ public function testOptions()
),
'templates' => $defaultTemplates,
),
- 'blocks' => array(),
+ 'blocks' => array(
+ 'my.block.type' => array(
+ 'contexts' => array('cms'),
+ 'cache' => 'sonata.cache.noop',
+ 'settings' => array ()
+ )
+ ),
'menus' => array(),
'blocks_by_class' => array(),
'exception' => array(
diff --git a/Tests/Form/Type/ServiceListTypeTest.php b/Tests/Form/Type/ServiceListTypeTest.php
index 8b3281de..e5cf66d2 100644
--- a/Tests/Form/Type/ServiceListTypeTest.php
+++ b/Tests/Form/Type/ServiceListTypeTest.php
@@ -27,13 +27,11 @@ public function testFormType()
$this->assertEquals('choice', $type->getParent());
}
+ /**
+ * @expectedException Symfony\Component\OptionsResolver\Exception\MissingOptionsException
+ */
public function testOptionsWithInvalidContext()
{
- if (Kernel::MINOR_VERSION < 3) {
- $this->setExpectedException('RuntimeException');
- } else {
- $this->setExpectedException('\Symfony\Component\Form\Exception\InvalidArgumentException');
- }
$blockServiceManager = $this->getMock('Sonata\BlockBundle\Block\BlockServiceManagerInterface');
@@ -52,7 +50,12 @@ public function testOptionWithValidContext()
$blockService->expects($this->once())->method('getName')->will($this->returnValue('value'));
$blockServiceManager = $this->getMock('Sonata\BlockBundle\Block\BlockServiceManagerInterface');
- $blockServiceManager->expects($this->once())->method('getService')->will($this->returnValue($blockService));
+ $blockServiceManager
+ ->expects($this->once())
+ ->method('getServicesByContext')
+ ->with($this->equalTo('cms'))
+ ->will($this->returnValue(array('my.service.code' => $blockService)));
+
$type = new ServiceListType($blockServiceManager, array(
'cms' => array('my.service.code')
));