Permalink
Browse files

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 8931c362c2b256bb52507ca2d367b72eea421d84
Showing with 58 additions and 2 deletions.
  1. +58 −2 cookbook/console/console_command.rst
@@ -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)
{
@@ -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
----------------

0 comments on commit 8931c36

Please sign in to comment.