Search code examples
phpsymfonysymfony-2.8akeneo

Extending the class with an interface AkeneoPimClientInterface?


How to extend generated command in Symfony with use Akeneo\Pim\AkeneoPimClientInterface ?

I have generated a command using php app/console generate:command and I got this class:

class AppTriggerBuildCommand extends ContainerAwareCommand

Then developed it to the point when I need all the categories from the API. Seamlessly it is really an easy question, how can I use AkeneoPimClientInterface in the command.

I want to use it something like this.

$categories = $this->apiClient->getCategoryApi()->all();

And the apiClient in here comes inside the _contruct metod

    public function __construct(AkeneoPimClient $apiClient, AkeneoLocaleMapper $mapper) {
    $this->apiClient = $apiClient;
    $this->mapper = $mapper;
}

And in use

use Akeneo\Pim\AkeneoPimClientInterface as AkeneoPimClient;

But when I tried to put it inside the _construct method in a command it want to use the parent _construct and it just can't see the generated command.

Could anyone help me ?

php app/console trigger build -vvv

  [Symfony\Component\Console\Exception\CommandNotFoundException]  
  Command "trigger" is not defined.                               


Exception trace:
 () at /var/www/html/iclei/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:526
 Symfony\Component\Console\Application->find() at /var/www/html/iclei/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:94
 Symfony\Bundle\FrameworkBundle\Console\Application->find() at /var/www/html/iclei/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:190
 Symfony\Component\Console\Application->doRun() at /var/www/html/iclei/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:84
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/html/iclei/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:117
 Symfony\Component\Console\Application->run() at /var/www/html/iclei/app/console:27

Solution

  • Since you extend the ContainerAwareCommand you have access to Symfony's Service Container to fetch the client like this (you might have to replace the fully qualified class name with a service id, I'm not 100% sure):

    $this->container->get('Akeneo\Pim\AkeneoPimClientInterface');
    

    If you want to use the constructor (which I encourage you to do), you are almost there. You just have to also call the parent constructor as well:

    public function __construct(AkeneoPimClient $apiClient, AkeneoLocaleMapper $mapper)
    {
        parent::__construct();
    
        $this->apiClient = $apiClient;
        $this->mapper = $mapper;
    }
    

    Both ways should work, but the latter allows you to move away from the ContainerAwareCommand to the more generic ContainerCommand, which will help you with Symfony 4 where services in the container will be private by default and therefore you can not just simply get them from the container like in the first version.

    edit regarding the command name: You can specify the name of your command as argument to parent::__construct() and also set it via the configure() method, you need to override. In there you can just call, e.g. $this->setName('trigger-build');. Be careful not to use spaces, as Symfony will treat those as separate arguments. So trigger is the name of the command and build is the first argument you "feed" to the command.