1
<service id="my_service">
    <tag name="my_transport" supports="feature1, feature2, feature3" />
</service>

Would be possible to define supports attribute as array when dealing with XML configuration, instead of doing a preg_split?

2
  • maybe create multiple <tag> elements? Commented Nov 25, 2012 at 21:38
  • @WouterJ well I think that creating multiple tag with the same name will result in just one entry in the resulting array, as tag names are used as indexes. Commented Nov 25, 2012 at 21:41

1 Answer 1

5

There is no way do define attribute as array.

DependencyInjection loaders don't support this. (Ex. loading from yml throws exception A "tags" attribute must be of a scalar-type (...) if you try this)

XmlFileLoader loading tags uses phpize parse attribute value as null, boolean, numeric or string.

Adding tag to service definition doesn't override previous added tag's definition, but adds new entry to array.

public function addTag($name, array $attributes = array())
{
    $this->tags[$name][] = $attributes;

    return $this;
}

So you should try create multiple <tag> elements (like Wouter J said)

If your XML file will be like

<service id="my_service">
    <tag name="my_transport" supports="feature1" />
    <tag name="my_transport" supports="feature2" />
    <tag name="my_transport" supports="feature3" />
</service>

then $attributes for tag my_transport will be

Array
(
    [0] => Array
        (
            [supports] => feature1
        )

    [1] => Array
        (
            [supports] => feature2
        )

    [2] => Array
        (
            [supports] => feature3
        )

)

And sample usage

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class MyCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('my_transport_service');

        // Extensions must always be registered before everything else.
        // For instance, global variable definitions must be registered
        // afterward. If not, the globals from the extensions will never
        // be registered.
        $calls = $definition->getMethodCalls();
        $definition->setMethodCalls(array());
        foreach ($container->findTaggedServiceIds('my_transport') as $id => $attributes) {
            // print_r($attributes);
            foreach($attributes as $attrs)
            {
                switch($attrs['supports']){
                  case 'feature1':
                      $definition->addMethodCall('addTransportFeature1', array(new Reference($id)));
                      break;
                  case 'feature2':
                      $definition->addMethodCall('addTransportFeature2', array(new Reference($id)));
                      break;
                  case 'feature3':
                      $definition->addMethodCall('addTransportFeature3', array(new Reference($id)));
                      break;
                }
            }
        }
        $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls));
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.