Symfony CLI commands and Compiler pass - php

I just want to know how to get all my commands Symfony services into my compiler pass ?
Is there a mean to find services by implemented interfaces ? Or perhaps i have to tag them all ?
Thanks,
KL.

You should tag them all. There is no way to retreive services which are instance of some expected class/interface.
Anyway, you can just get all, iterate over them, and filter only those which extends your interface. But it's much slower, and the most awful way to do it.

I hope I understood you question correctly. If you're trying to get all commands defined in your application then:
$kernel = $this->container->get('kernel');
$application = new Application($kernel);
$commands = $application->all('doctrine');
var_dump($commands);die;
This example with a fresh symfony install you can fetch all doctrine commands. Just replace 'doctrine' with your commands prefix.
Take a look in \Symfony\Bundle\FrameworkBundle\Console\Application especially registerCommands method. I'm using latest version Symfony 3.2.4

Related

Symfony : use a 3rd-party service inside another 3rd-party bundle

I'm writing a 3-rd party bundle (let's call it Bundle1), which needs to use another 3rd-party bundle (Bundle2). I've declared the dependency in Bundle1's composer.json, so Bundle2 is successfully downloaded.
But in my AppKernel.php, i've only declared Bundle1 :
$bundles = [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
[...]
new MyCompany\Bundle1(),
];
As far as i know, It would not be correct to declare Bundle2 here. So obviously, I can't access any service provided by Bundle2 in my application. That's ok, as far as my application is concerned, but I need Bundle1 to use thoses services in its own inner classes.
How can I pass them to Bundle1, and how can I use them ? Should I declare them in Bundle1's services.yml and point them to Bundle2's classes ? I guess that would be a duplication with Bundle2's own services ? I can't think of any other way to do that.
What would be the correct way to achieve this ? Many thanks in advance.
I'm running Symfony 3.2.4 by the way.

Using Doctrine in a custom Symfony command?

I created a custom Symfony command to manage entities in my DB but I don't know how to use doctrine in it (e.g. import it like in a controller).
Thanks!
Using a ContainerAwareCommand is fine.
$this->getContainer()->get('doctrine');
Using the container directly is not a good practice. Sometimes you will need to modify class code and when that time comes you will need to review the whole code to find any dependencies.
Register the command as a serivce and pass serivces that are actually will be used in the logic.
Check How to Define Commands as Services

Use PEAR-Package inside Symfony

I am writing an PHPUnit WebTestCase for a Symfony repository. In some tests I want to print out time measurements. For that case I found the PEAR Console\Table package. Via Composer I get it installed, but how can I use it within my test?
The Console_Table.php doesn't have a namespace. So I think I could not use
use Console\Table;
or?
So when I must use the require_once statement, which is the right relativ path, when Composer installed the Table.php into vendor/pear/console_table/.
At this point I would say I am really new to PHP.
Thanks for your replies.
Ok,
I get it. absalon.valdes was right. $table = \Console_Table(); is the solution.
Important was to do a clean build of the project in Eclipse. After that, the compiler recognizes the class.
My bad.
Thanks.

Symfony console application: dependency injection [duplicate]

This question already has an answer here:
How to use DependencyInjection from symfony in stand alone application with commands?
(1 answer)
Closed last year.
A Symfony novice here. After reading some of the Symfony documentation and some answers here at SO, I am now almost completely confused.
I am trying to use the console application component and create a small db-aware console application.
Many people state that in order to use Symfony's DI features it would be enough to inherit my command class not from Symfony\Component\Console\Command\Command but from ContainerAwareCommand.
However when I try this I get a Method Not Found error on an application::getKernel() call.
I have a feeling that DI features are in fact not available in a console application based on the console component. Is there another kind of Symfony console application, for example, based on the full-blown framework?
I very much like the simple framework provided by the console component Symfony\Component\Console\Application. But the question is then - what to do for dependency injection and DBAL? All examples that I find seem to refer to the full Symfony framework and get me just all the more stuck.
Just a quick update on my progress if anybody stumbles upon the same problems.
I incorporated into my project the PHP-DI dependency injection framework, which seems to be working fairly well with no configuration (so far) - it figures out quite a lot by reflection, actually.
The same way, Doctrine\DBAL is included as a standalone library (I opted against the O/RM part of it, as it is really a tiny project and I'm on a much firmer ground with SQL than anything else) and the connection is simply returned by a connection provider which is injected wherever needed by the DI.
One thing I couldn't figure out is how to have the command classes instantiated by the DI library without my help, so I actually had to inject the container itself into my overridden application class and override the getDefaultCommands() where I then pull the instances out of the container manually. Not ideal but will have to do for now.
If your command extends ContainerAwareCommand
...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...
class MyCommand extends ContainerAwareCommand
{
The DI container is available with the getContainer() method. (like in a standard controller), ex:
$this->validator = $this->getContainer()->get('validator');
I don't know if your question is still relevant, but I have an answer as I stumbled across the same problem here.
You just have to create the kernel yourself and give it to the \Symfony\Bundle\FrameworkBundle\Console\Application that extends the basic \Symfony\Component\Console\Application.
<?php
// CronRun.php
require __DIR__.'/../../../../vendor/autoload.php';
require_once __DIR__.'/../../../../app/AppKernel.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
$application->add(new \KingdomHall\TaskBundle\Command\CronCommand());
$input = new \Symfony\Component\Console\Input\StringInput('k:c:r');
$application->run($input);
You could use a solution I just pushed it to packagist.org. Includes full working symfony/dependency-injection. You're welcome to give it a shot. use composer to create your own project composer create-project coral-media/crune project_dir or just clone the repository.
https://packagist.org/packages/coral-media/crune
You only need to install DBAL dependencies (I don't suggest ORM if you don't really need it). Configure connection parameters in .env and just define a service to handle connection. That service can be injected in your Commands using public setMyService($myService) method with #required annotation. Also you could create a Connection class and bind is as parameter in your command constructor.The crune boilerplate also supports autowire and autoconfiguring features.

How to use the 'raw' PHP Mongodb PECL driver within Symfony2 [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Using Imagick in Symfony2?
I'm new to Symfony so this might be a dummy question. But since after several hours of google I haven't found any related answer it might worth a try here.
So basically I was using Windows, Apache, pure PHP, Mongodb and the 'raw' PHP_Mongodb PECL driver (the word 'raw' is used here to differ from the Doctrine Mongodb ODM bundle in Symfony2) for web application development. The PECL driver worked perfectly fine, and I could just write something like this:
<?php
$m = new Mongo();
$db = $m->myDB;
$db->find();
//Do Other DB Operations.
The above code worked fine without any 'use', 'include' or 'require' statements since I followed the standard instructions and setup the PECL driver extension in php.ini. When showing phpinfo() in the web browser, the Mongodb driver information shows up correctly. Everything's perfect.
Then I start to use Symfony2 because it provides url rewriting, MVC pattern, security and other useful stuff. The Doctrine Mongodb ODM bundle works nice except that, seems to me, it can only persist PHP objects. I do have a bunch of javascript object in my project to persist and there is simply no way of doing that except to put a 'PHP wrapper' on top of it (to create a PHP object which contains only that javascript object).
When I was trying to use the good old PECL trick to talk to the database with the same block of code above, I got this error:
Fatal error: Class 'MyProject\Controller\Mongo' not found in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\Symfony\src\MyProject\Controller\DefaultController.php on line 47.
Seems Symfony2 blocked or overwrited the extension paths in php.ini while only looking for its auto class loader. I guess I'll need to change the autoload.php and/or AppKernel.php to include that extension? Please help me understand what's going on here. Can I use the PECL driver in Symfony2 at all? Or is Doctrine Mongodb ODM the only way to access database in Symfony2? Thanks!
Symfony2 works with namespace php. This makes working with non-namespace libraries/classes a bit tricky, but you really just need to know the tricks.
When you try to use new Mongo() to grab a mongodb object, PHP looks in your current namespace, which means it looks for a mongo() function within your class. To make this work, you need to specify the namespace for mongo. Since it does not use namespaces, PHP places it in the global namespace . So, to correctly reference the function, you need to use new \Mongo(), and PHP will look in your \ namespace instead of your current one.

Categories