Symfony ExcelBundle in Command - symfony

i'll try to do something like:
<?php
namespace ExportBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
// I am extending ContainerAwareCommand so that you can have access to $container
// which you can see how it's used in method execute
class HelloCommand extends ContainerAwareCommand {
// This method is used to register your command name, also the arguments it requires (if needed)
protected function configure() {
// We register an optional argument here. So more below:
$this->setName('hello:world')
->addArgument('name', InputArgument::OPTIONAL);
}
// This method is called once your command is being called fron console.
// $input - you can access your arguments passed from terminal (if any are given/required)
// $output - use that to show some response in terminal
protected function execute(InputInterface $input, OutputInterface $output) {
// ask the service for a excel object
$phpExcelObject = $this->get('phpexcel')->createPHPExcelObject();
$phpExcelObject->getProperties()->setCreator("liuggio")
->setLastModifiedBy("Giulio De Donato")
->setTitle("Office 2005 XLSX Test Document")
->setSubject("Office 2005 XLSX Test Document")
->setDescription("Test document for Office 2005 XLSX, generated using PHP classes.")
->setKeywords("office 2005 openxml php")
->setCategory("Test result file");
$phpExcelObject->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('C1', 'Hello')
->setCellValue('B2', 'world!');
$phpExcelObject->getActiveSheet()->setTitle('Simple');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$phpExcelObject->setActiveSheetIndex(0);
// create the writer
$writer = $this->get('phpexcel')->createWriter($phpExcelObject, 'Excel2007');
// The save method is documented in the official PHPExcel library
$writer->save('filename.xlsx');
// Return a Symfony response (a view or something or this will thrown error !!!)
return "A symfony response";
$greetLine = $input->getArgument('name')
? sprintf('Hey there %s', $input->getArgument('name'))
: 'Hello world called without arguments passed!'
;
$output->writeln($greetLine);
}
}
but throw me this error:
[Symfony\Component\Debug\Exception\UndefinedMethodException]
Attempted to call an undefined method named "get" of class "ExportBundle\Command\HelloCommand".
Did you mean to call e.g. "getAliases", "getApplication", "getDefinition", "getDescription", "getHelp", "getHelper"
, "getHelperSet", "getName", "getNativeDefinition", "getProcessedHelp", "getSynopsis" or "getUsages"?
in the line:
$phpExcelObject = $this->get('phpexcel')->createPHPExcelObject();
work fine in a Controller but in command not.
how I can make it work in command?

Related

How to configure laragon/sendmail with Symfony

I'm trying to configure a Symfony 6.1 project to send mail through a fresh installed laragon and sendmail, but all my tries were unsuccessful.
I tried with many configuration and this one doesn't trigger error, but I don't receive any mail and any debug message :
#.env
MAILER_DSN=smtp://localhost
#php.ini
[mail function]
; For Win32 only.
; https://php.net/smtp
SMTP = localhost
; https://php.net/smtp-port
smtp_port = 25
; For Win32 only.
; https://php.net/sendmail-from
;sendmail_from = me#example.com
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
; https://php.net/sendmail-path
;sendmail_path =
; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail().
;mail.force_extra_parameters =
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = Off
sendmail_path="C:/laragon/bin/sendmail/sendmail.exe"
; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
;mail.log =
; Log mail to syslog (Event Log on Windows).
;mail.log = syslog
<?php
// src/Controller/MailerController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
class MailerController extends AbstractController
{
#[Route('/email')]
public function sendEmail(MailerInterface $mailer): Response
{
$email = (new Email())
->from('noreply#mydomain.com')
->to('nobody#gmail.com')
->subject('Time for Symfony Mailer!')
->text('Sending emails is fun again!')
->html('<p>See Twig integration for better HTML integration!</p>');
try {
$mailer->send($email);
} catch (TransportExceptionInterface $e) {
die("debug:".$e->getDebug());
}
return new Response('ok');
}
}
The route to test : http://127.0.0.1:8000/email
Result :

Executing Symfony 4 Custom Command in fixtures

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.

There are no commands defined with command into controller symfony

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

Symfony2 command and tcpdf whiteoctober

I use symfony and I have installed whiteoctober TCPDF with success.
It works if I use it in a controller, my PDF is generated.
However I want to use it in a command.
So I have a command called "CronInvoicesCommand" in a command folder and of course I have this error:
Attempted to call method "get" on class "OandP\boBundle\Command\CronInvoicesCommand" in C:\wamp\www\OandPlocal\src\OandP\boBundle\Command\CronInvoicesCommand.php line 187. Did you mean to call: "getAliases", "getApplication", "getDefinition", "getDescription", "getHelp", "getHelper", "getHelperSet", "getName", "getNativeDefinition", "getProcessedHelp", "getSynopsis"?
So my question is how can I load all those method in a command.
Thank you se much for your help
you can use a container aware commmand :
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
class MyCommand extends ContainerAwareCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getContainer()->get('doctrine')->getEntityManager();
// ...
Probably you are trying to get a service from a container similar to the controller method get. In a Command you can access to the container with the getContainer() method, so try to substitute something like:
$this->get('service_name');
with
$this->getContainer()->get('service_name');
More info here in the doc.
Hope this help

Symfony best practice for data export file location

I am writing a console command which generates data files to be used by external services (for example, a Google feed, inventory feed, etc). Should the location of the generated data files be within the Symfony app? I know they can actually be anywhere, I'm just wondering if there is a standard way to do it.
It's up to you, but it is better to have this path in a parameter. For example you can you have a parameter group related to your command. This allows you to have different configurations depending on the current environment:
parameters:
# /app/config.yml
# #see MyExportCommand.php
my_export_command:
base_path: '/data/ftp/export'
other_command_related_param: true
In your command, get and store those parameters in the initialize function:
// MyExportCommand.php
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->parameters = $this->getContainer()->getParameter('my_export_command');
}
Finally in your execute function, you can use something like this: ($this->fs is an instance of the Symfony2 Filesystem component)
// execute()
// Write the file
$filePath = $this->parameters['base_path']. '/'. $this->fileName;
$this->fs->dumpFile($filePath, $myContent);

Resources