Skip to content

This is my first documentation PR.. #1471

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

Closed
wants to merge 9 commits into from
Closed
Changes from 6 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
83 changes: 83 additions & 0 deletions components/dependency_injection/tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,86 @@ run when the container is compiled::

$container = new ContainerBuilder();
$container->addCompilerPass(new TransportCompilerPass);

Adding additional attributes on tags
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the case to be:

Adding additional Attributes on Tags

The rough rule is to capitalize nouns.

------------------------------------

To begin with, change the ``TransportChain`` class::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a few more details here explaining the value behind this. We might say something like "sometimes you need additional information about each service that's tagged with your tag. For example, in our TransportChain..."


class TransportChain
{
private $transports;

public function __construct()
{
$this->transports = array();
}

public function addTransport(\Swift_Transport $transport, $alias)
{
$this->transports[$alias] = $transport;
}

public function addTransport($alias)
{
return $this->transports[];
}
}


Change the service delaration:

.. configuration-block::
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to deal with ...configuration-block.. do you have any clue ?


.. code-block:: yaml

services:
acme_mailer.transport.smtp:
class: \Swift_SmtpTransport
arguments:
- %mailer_host%
tags:
- { name: acme_mailer.transport, alias: foo }
acme_mailer.transport.sendmail:
class: \Swift_SendmailTransport
tags:
- { name: acme_mailer.transport, alias: bar }


.. code-block:: xml

<service id="acme_mailer.transport.smtp" class="\Swift_SmtpTransport">
<argument>%mailer_host%</argument>
<tag name="acme_mailer.transport" alias="foo" />
</service>

<service id="acme_mailer.transport.sendmail" class="\Swift_SendmailTransport">
<tag name="acme_mailer.transport" alias="bar" />
</service>


The last step is to update the compiler to take care of your additional information::

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

class TransportCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('acme_mailer.transport_chain')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should use ! instead of false ===

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have copied / pasted the TransportChain definition. See the beginning of this page.

return;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missleading as $attributes does not contain the attributes of a tag but an array of tags with their attrbutes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same issue: it should be on line 234

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see.
But, I'm using

foreach ($container->findTaggedServiceIds('acme_mailer.transport') as $id => $attributes) {
    $definition->addMethodCall('addTransport', array(new Reference($id), $attributes[0]["alias"]));
}

As you said, $attributes is an array of tags with their attributes.
What's the matter here because I don't understand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The matter is tat you don't read all tags but only the first one: $attributes[0] and the array of attributes is not $attributes but $attributes[$i]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, $attributes contains each tag's attributes ?
That's why I have start this documentation, because I don't really understand why there is an an array of attributes like that.

On the first time that I have used the additional information on tag, I have directly do a $attributes["alias"] without success..

To sum up, If there is many tags , each index of $attributes referes to a different tag ?
So, in the documentation, I have to do

foreach ($container->findTaggedServiceIds('acme_mailer.transport') as $id => $attributes) {
    $definition->addMethodCall('addTransport', array(new Reference($id), $attributes[$id]["alias"]));
}

In this case, what about : https://github.com/sensio/SensioFrameworkExtraBundle/blob/master/DependencyInjection/Compiler/AddParamConverterPass.php ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take care. You used $id as the key in $attributes whereas the id is something else.

you receive an array because you can apply the same tag several times on the same service (generally with different attributes). This is useful for instance to register a service as listener on several events. You can see the corresponding compiler pass

The main reason for the confusion is using $attributes to name an array which is not the array of attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok ! I was totally confused !

I have update the example. But, I don't think that the sentence is really clear :p

$definition = $container->getDefinition('acme_mailer.transport_chain');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong as it forbids using the same tag several times (as you only read the first tag)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the problem ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, you edited the PR after I loaded the page but before I commented, so the comments are in the wrong place. This one should be on the line 235

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like my previous comment, I don't understand the problem with this.. I have take this part of code inside a Sensio or a FOS Bundle I don't remember.


foreach ($container->findTaggedServiceIds('acme_mailer.transport') as $id => $tagAttributes) {
foreach ($tagAttributes as $attributes) {
$definition->addMethodCall('addTransport', array(new Reference($id), $attributes["alias"]));
}
}
}
}

Take care of ``$attributes`` variable. Because you can use the same tag many times on the same service, ``$attributes`` is an array of attributes for each tag that refers to the same service.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like what you're doing here, but I think we can explain what this $attributes variable is even more. Specifically, $attributes is an array of all of the tag details for each acme_mailer.transport tag that the service has (because a service may be tagged multiple times with the same tag). With a few more details, I think we'll have a better idea of why we have 2 foreach nested statements here.

Also, be sure to break your line after the first word that crosses the 72nd character :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm quite limited with this...
Do I have to add a other example with 2 TransportChain with the same tag ?