Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feature #3889 Fixed the section about getting services from a command…
… (javiereguiluz)

This PR was merged into the 2.3 branch.

Discussion
----------

Fixed the section about getting services from a command

| Q             | A
| ------------- | ---
| Doc fix?      | no
| New docs?     | yes
| Applies to    | 2.3+
| Fixed tickets | #890

Hopefully this PR fixes one of the oldest errors of the Symfony documentation.

Commits
-------

8993beb Linked the cookbook about DIC scopes
0f3c218 Fixed the section about getting services from a command
  • Loading branch information
weaverryan committed Jun 7, 2014
2 parents 8257be9 + 8993beb commit 8931c36
Showing 1 changed file with 58 additions and 2 deletions.
60 changes: 58 additions & 2 deletions cookbook/console/console_command.rst
Expand Up @@ -68,8 +68,27 @@ Getting Services from the Service Container
By using :class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`
as the base class for the command (instead of the more basic
:class:`Symfony\\Component\\Console\\Command\\Command`), you have access to the
service container. In other words, you have access to any configured service.
For example, you could easily extend the task to be translatable::
service container. In other words, you have access to any configured service::

protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$logger = $this->getContainer()->get('logger');

$logger->info('Executing command for '.$name);
// ...
}

However, due to the `container scopes </cookbook/service_container/scopes>`_ this
code doesn't work for some services. For instance, if you try to get the ``request``
service or any other service related to it, you'll get the following error:

.. code-block:: text
You cannot create a service ("request") of an inactive scope ("request").
Consider the following example that uses the ``translator`` service to
translate some contents using a console command::

protected function execute(InputInterface $input, OutputInterface $output)
{
Expand All @@ -82,6 +101,43 @@ For example, you could easily extend the task to be translatable::
}
}

If you dig into the Translator component classes, you'll see that the ``request``
service is required to get the locale into which the contents are translated::

// vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
public function getLocale()
{
if (null === $this->locale && $this->container->isScopeActive('request')
&& $this->container->has('request')) {
$this->locale = $this->container->get('request')->getLocale();
}

return $this->locale;
}

Therefore, when using the ``translator`` service inside a command, you'll get the
previous *"You cannot create a service of an inactive scope"* error message.
The solution in this case is as easy as setting the locale value explicitly
before translating contents::

protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$locale = $input->getArgument('locale');

$translator = $this->getContainer()->get('translator');
$translator->setLocale($locale);

if ($name) {
$output->writeln($translator->trans('Hello %name%!', array('%name%' => $name)));
} else {
$output->writeln($translator->trans('Hello!'));
}
}

However for other services the solution might be more complex. For more details,
see :doc:`/cookbook/service_container/scopes`.

Testing Commands
----------------

Expand Down

0 comments on commit 8931c36

Please sign in to comment.