I want to launch command into a controller symfony. I wrote method and it run correctly command mechanism because I have a return message.
But All command available in my symfony prompt shell command (php bin/console) is not recognize in my launcher command controller method.
I have all the time the same error message into outputBuffered object :
"There are no commands defined in the "XXXX" namespace"
Just one command seems to be run correctly : "help"
But "list" command doesn't run.
My controller method which launch command component :
public function executeDoctrineSchemaAction()
{
\Symfony\Component\VarDumper\VarDumper::dump('here 1');
$kernel = $this->get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(['command' => 'debug:router']);
$output = new BufferedOutput();
$retval = $application->run($input, $output);
$content = $output->fetch();
\Symfony\Component\VarDumper\VarDumper::dump($content);
return true;
}
Can you help me to understand why command run perfectly into my prompt application admin but not in my controller ?
EDIT : I use this class in my file :
use Symfony\Component\Console\Application;
There is no similar with this kind of solution
The error is catched because it seems that not found namespace
Related
I am having trouble with Webhook Endpoints.
#[Route("/web_hook", name: 'web_hook')]
public function webhook(Request $request)
{
$data = json_decode($request->getContent(), true);
if ($data === null){
throw new \Exception('bad bad');
}
$txt = 'samle of some text text text';
$myfile = fopen("test.txt", "w") or die("Unable to open file!");
fwrite($myfile, $txt);
fwrite($myfile, $data->id);
fclose($myfile);
$response = new Response();
$response->setStatusCode(200);
return $response;
}
I am having 0 luck getting it to work, I am sending a POST request to it VIA Postman and it keeps coming back with error 500.
When I visit then URL it gives me this error
"Cannot autowire argument $request of "App\Controller\WebHookController::webhook()": it references class "Symfony\Component\HTTPFoundation\Request" but no such service exists.
"
I based this method off of
https://symfonycasts.com/screencast/stripe-level2/webhook-endpoint-setup.
any ideas on what im doing wrong would be greatly appreciated.
if you get error message like this
Cannot autowire argument $request of
"App\Controller\WebHookController::webhook()": it references class
"Symfony\Component\HTTPFoundation\Request" but no such service exists.
mean this service is not available. please try install http-foundation component first.
composer require symfony/http-foundation
and try to change use Symfony\Component\HTTPFoundation\Request to use Symfony\Component\HttpFoundation\Request
I have a custom command in my symfony project to populate the database with the default data that the application need to work in both dev and prod environments.
For the dev environment I have a fixture script that depends on these default common data.
I'm trying to call my custom Symfony command in the fixture script so that I'm sure to have the required data to properly load my fixtures.
This is my custom command app:db:populate in "pseudo script", just creating a bunch of entities, persit & flush. My custom command works fine when I call it through php bin/console app:db:populate
protected function execute(InputInterface $input, OutputInterface $output)
{
// Creating a bunch of default entities, persist them and flush
$data = new MyDefaultEntity();
// ...
$this->manager->persist($data);
// ...
$this->manager->flush();
}
Then, in my fixture script, I want to call app:db:populate first, because fixtures depends on these data. So I tried to use the Process class to execute my script this way :
public function load(ObjectManager $manager)
{
// Execute the custom command
$cmd = 'php bin/console app:db:populate';
$process = new Process($cmd);
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
// Then load the fixtures !
// ...
}
The custom command seems to execute well until the $this->manager->flush();
I have the following error in my console (Data is obfuscated for the post):
In AbstractMySQLDriver.php line 36:
An exception occurred while executing 'INSERT INTO ....(..., ..., ...) VALUES (?, ?, ?)' with params ["...", "...", "..."]:
SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
I don't know what to do regarding this error ... Why the command is working normally when used through a classic console call and why it is not working in a Process?
So, the short answer is
Quoting Symfony documentation :
You may have the need to execute some function that is only available in a console command. Usually, you should refactor the command and move some logic into a service that can be reused in the controller.
I ended up making a service class that handles all the app:db:populate logic (read a json file and insert basic app entities in the database). Then I call this service in both app:db:populate execute methods and AppFixtures load methods.
Hope this will help someone.
I want to execute my service on kernel.terminate event to make it asynchronously .
What i am doing in my controller before returning response is this
$this->eventDispatcher->addListener(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($vat) {
// Launch the job
$command = new WebDriverCommand();
$command->setContainer($this->container);
$input = new ArrayInput(array('id' => $vat->getId()));
$output = new NullOutput();
$command->run($input, $output);
});
My question is : Is there a difference between running the command that executes my service AND calling the service directly without command ?
Thanks in advance.
Absolutely no difference. Your command must not have any logic anyway. Both event listeners and your commands should invoke a service anyway - be kind of a glue between the framework and your domain logic.
Your classes will in effect be easier to unit test and maintain.
I have a pretty complex command (not written by me) in my symfony API to send notifications, and I would like to have it run everytime a PostPersist event happens.
For this, I've set up a listener triggered by the PostPersist event and this part works perfectly. However, I can't manage to launch the command. I first tried to launch it like I did in a controller with the following piece of code:
$kernel = $this->get('kernel');
$application = new Application($kernel);
$application->setAutoExit(false);
$input = new ArrayInput(array(
'command' => 'acme:send-notifications',
));
// You can use NullOutput() if you don't need the output
$output = new NullOutput();
$application->run($input, $output);
return new Response("");
but of course, it doesn't work in a Listener, since I can't get the kernel
So I tried to add the command to the services:
command.send-notifications:
class: WD\ApiBundle\Command\SendNotificationsCommand
tags:
- { name: 'console.command', command: 'acme:send-notifications' }
and then call it this way:
$output = new NullOutput();
$this->sendNotifCommand->execute(null, $output);
but then I get the following error message:
The container cannot be retrieved as the application instance is not yet set.
I have to admit I don't quite understand what it means. Also, I must confess this part of symfony (listeners, commands) are quite new to me and I don't even know if I'm doing it the right way, or if there is a better system to send notifications everytime a persist happens in a specific entity...
Never tried it in a listener but you can try to launch your command with a Process :
$process = new Process("cd " . $this->projectDir . "; php bin/console YOUR_COMMAND_NAME");
$process->start();
My app starts locally by http : //sm1/app/web/app_dev.php (symfony3).
PHPUnit test has been build by framework.
namespace Tests\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class GoodControllerTest extends WebTestCase
{
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient([], ['HTTP_HOST' => 'sm1']);
// Create a new entry in the database
$crawler = $client->request('GET', '/good/');
$this->assertEquals(200,
$client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /good/"
);
$crawler = $client->click(
$crawler->selectLink('Create a new entry')->link());
But after test running I've got an error
There was 1 error:
1) Tests\AppBundle\Controller\GoodControllerTest::testCompleteScenario
InvalidArgumentException: The current node list is empty.
/home/sm1/www/app/vendor/symfony/symfony/src/Symfony/Component/DomCrawler/Crawler.php:735
/home/sm1/www/app/tests/AppBundle/Controller/GoodControllerTest.php:18
and in a log file this message:
request.INFO: Matched route "{route}".
{"route":"good_index","route_parameters":
{"_controller":"AppBundle\Controller\GoodController::indexAction",
"_route":"good_index"},
"request_uri":"http://sm1/good/","method":"GET"} []
How to fix "request_uri" from "http : //sm1/good/"
to "http : //sm1/app/web/app_dev.php/good/" ?
It is necessary to start web app only by http://app. That is, to use PHPUnit you need a virtual host. If the name of the input script is different from the default, note this in the file .htaccess.