Nullable value in command file - symfony

I'm actually working on a symfony project where i have to get into the DB all the taxis with some informations about them and make them write in a CSV file.
For this, i've create a CiblageCommand File :
<?php
namespace AppBundle\Command;
use AppBundle\Entity\Taxi;
use AppBundle\Entity\StatutTaxi;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
class CiblageCommand extends ContainerAwareCommand
{
private $em;
public function __construct(EntityManagerInterface $em)
{
parent::__construct();
$this->em = $em;
}
protected function configure()
{
$this
//the short description shown while running "php bin/console list"
->setDescription('cible les taxis')
//commande
->setname('ciblage')//php bin/console ciblage
//the full command descriptionn shown when running the command with
//the "--help" option
->setHelp('Cette commande permet de cibler les taxis valides présents'
.' dans la BDD et de leur générer un PDF conforme.')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$io->title("Lancement de la génération");
$io->title("\nListage des taxis");
$this->create();/*
$io->title("\nCiblage terminé");
$io->title("\nGénération des courriers");
$this->generation();
*/
$io->success("\nGénération terminée");
}
protected function create()
{
$repository_taxi = $this->em->getRepository('AppBundle:Taxi');
$listTaxi = $repository_taxi->findAll();
$doctrine = $this->getContainer()->get('doctrine');
$em = $doctrine->getEntityManager();
$handle = fopen('CSVTaxi', 'w+');
fputcsv($handle, ['IDENTIFIANT', 'RAISON SOCIALE', 'STATUT', 'ETAT'], ';');
foreach ($listTaxi as $taxi)
{
if($taxi == null){
$listTaxi[$taxi] = "NULL" ;
}
fputcsv(
$handle,
[
$taxi->getNumAm(),
$taxi->getRaisonSociale(),
$taxi->getStatutTaxi()->getLibelleStatut(),
$taxi->getEtatTaxi()->getLibelleEtat()],
';'
);
}
fclose($handle);
echo("nbr taxi : ".count($listTaxi)."\n");
}
}
However, when i tried to do a "getStatutTaxi()" the value return is null and i cant write on the file despite the if before.
there is the error my terminal gave me
[apl4e04#l11750300app2dev 10:23:23] [~/web/html/scot] $ php bin/console ciblage
Lancement de la génération
==========================
Listage des taxis
==================
10:17:16 ERROR [console] Error thrown while running command "ciblage". Message: "Call to a
member function getLibelleStatut() on null" ["exception" => Error { …},"command" =>
"ciblage","message" => "Call to a member function getLibelleStatut() on null"]
PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member
function getLibelleStatut() on null in
/app/apl4e04/web/html/scot/src/AppBundle/Command/CiblageCommand.php:74
Stack trace:
#0 /app/apl4e04/web/html/scot/src/AppBundle/Command/CiblageCommand.php(44):
AppBundle\Command\CiblageCommand->create()#1/app/apl4e04/web/html/scot/vendor/
symfony/symfony/src/Symfony/Component/Console/Command/Command.php(255):
AppBundle\Command\CiblageCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput),
Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 /app/apl4e04/web/html/scot/vendor/symfony/symfony/src/Symfony/
Component/Console/Application.php(987): Symfony\Component\Console\Command\Command-
>run(Object(Symfony\Component\Console\Input\ArgvInput),
Object(Symfony\Component\Console\Output\ConsoleOutput))
#3/app/apl4e04/web/html/scot/vendor/symfony/symfony/
src/Symfony/Bundle/FrameworkBundle/Console/Application
.php(86): Symfony\Component\Console\Application->doRunCommand(Object(AppBundl in
/app/apl4e04/web/html/scot/src/AppBundle/Command/CiblageCommand.php on line 74
How can i fix this and make this work ?
Thanks in advance for your help.
Cordially,

We can fix this by checking the value instance before adding to the csv file.
$statusLibelleStatut = $taxi->getStatutTaxi() instance of StatutTaxi ? $taxi->getStatutTaxi()->getLibelleStatut() : '';
$etatLibelleEtat = $taxi->getEtatTaxi() instance of LibelleEtat ? $taxi->getEtatTaxi()->getLibelleEtat() : '';
fputcsv(
$handle,
[
$taxi->getNumAm(),
$taxi->getRaisonSociale(),
$statusLibelleStatut,
$etatLibelleEtat],
';'
);

UPDATE : i just add a ternary function at my 'getLibelleStatut()' who resolve the probleme.
protected function create()
{
$repository_taxi = $this->em->getRepository('AppBundle:Taxi');
$listTaxi = $repository_taxi->findAll();
//$doctrine = $this->getContainer()->get('doctrine');
//$em = $doctrine->getEntityManager();
$handle = fopen('CSVTaxi.csv', 'w+');
fputcsv($handle, [' IDENTIFIANT', 'RAISON SOCIALE', 'STATUT', 'ETAT'], ';');
foreach ($listTaxi as $taxi)
{
fputcsv(
$handle,
[
$taxi->getNumAm(),
$taxi->getRaisonSociale(),
($taxi->getStatutTaxi()==null)?"":$taxi->getStatutTaxi()->getLibelleStatut(),
$taxi->getEtatTaxi()->getLibelleEtat()],
';'
);
}
fclose($handle);
echo("nbr taxi : ".count($listTaxi)."\n");
}

Related

Doctrine remove have to be done twice to work

I have a strange behavior on doctrine remove and i don't understand why.
it'an ajax delete action inside a symfony 5 controller.
If i launch the requete once = nothing appends
If i lauch the requete twice, the delete opperation occur correctly.
Why ?
thanks for your help
/**
* #Route("/permissions_ajaxDelete", name="permissions_ajaxDelete")
*/
public function ajaxDelete(Request $request)
{
$responseArray = array();
$statusCode = 200;
//if ($request->isXmlHttpRequest()) {
$id = $request->get('id');
$permission = $this->getDoctrine()->getRepository(Permissions::class)->find($id);
//test si la permission existe
if ($permission != null) {
$responseArray["successMessage"] = "La permission \"".$permission->getName()."\" d'id ".$permission->getId()." a été supprimée!";
$this->getDoctrine()->getManager()->remove($permission);
$this->getDoctrine()->getManager()->flush();
$permission = $this->getDoctrine()->getRepository(Permissions::class)->find($id);
if ($permission != null) {
dd($permission);
$responseArray["successMessage"] = "bugg";
// On a first call, permission is find after the flush/ remove
}
}else{
$responseArray["errorMessage"] = "Vous essayez de supprimer une permissions qui n'existe pas.";
$statusCode = 403;
}
return new JsonResponse($responseArray,$statusCode);
/*}else{
//Requete non ajax.
$responseArray["errorMessage"] = "Erreur : Mauvais format de requette (Ajax)";
return new JsonResponse($responseArray,400);
}*/
}
I think after the first 'find' doctrine add entity into unit of work
The second 'find' dont call data base, but only use unit of work to get entity allready loaded !
Using profiler to verify what SQL doctrine call.

Gedmo Translatable persist default translation

I have a website built with Symfony 2.8 and Gedmo Translatable.
In order to use HINT_INNER_JOIN and filter items which don't have a translation I had to set persist_default_translation to true:
stof_doctrine_extensions:
default_locale: '%locale%' # TODO: what does it happen when removing this line?
translation_fallback: true
persist_default_translation: true
orm:
default:
timestampable: true
blameable: true
translatable: true
Unfortunately this caused that my existing translations for the default language are no more persisted (and they appear empty).
I would need to force re-save all of my entities to generate the default locale again.
How can I do that? I tried with clone and persist but it creates a duplicate of the entity.
Is it possible to force Doctrine to update all the fields again?
I ended up creating a custom command to migrate all the translations. I created a fake translation called "kr" and then updated all the record with "kr" to "fr" with an SQL query.
I used reflection and other "black magic" to get the properties with the Translatable annotation, maybe this could help someone with the same problem. Here is the code:
class NormalizeTranslationsCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
// the name of the command (the part after "app/console")
->setName('app:normalize-translations')
// the short description shown while running "php app/console list"
->setDescription('Normalizes the translations.')
// the full command description shown when running the command with
// the "--help" option
->setHelp('This command allows you to normalize the translations...')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// all the translatable classes
$classes = [
Entities\MyClass1::class,
Entities\MyClass2::class,
];
foreach ($classes as $class) {
$this->processClass($class, $output);
}
}
private function processClass($class, $output)
{
$output->writeln(sprintf('Processing class <info>%s</info>', $class));
// gets all the properties
$properties = $this->getProperties($class);
// gets the translatable properties
$translatableProperties = $this->getTranslatableProperties($properties, $class);
$output->writeln(sprintf('Found %d translatable properties: %s', count($translatableProperties), implode(', ', $translatableProperties)));
$defaultLanguage = 'kr'; // fake language
$em = $this->getContainer()->get('doctrine')->getManager();
$repository = $em->getRepository('Gedmo\\Translatable\\Entity\\Translation');
$items = $em->getRepository($class)->findAll();
$propertyAccessor = PropertyAccess::createPropertyAccessor();
foreach ($items as $item) {
foreach ($translatableProperties as $translatableProperty) {
$value = $propertyAccessor->getValue($item, $translatableProperty);
$repository->translate($item, $translatableProperty, $defaultLanguage, $value);
}
$em->flush();
}
}
private function getProperties($class)
{
$phpDocExtractor = new PhpDocExtractor();
$reflectionExtractor = new ReflectionExtractor();
// array of PropertyListExtractorInterface
$listExtractors = array($reflectionExtractor);
// array of PropertyTypeExtractorInterface
$typeExtractors = array($phpDocExtractor, $reflectionExtractor);
// array of PropertyDescriptionExtractorInterface
$descriptionExtractors = array($phpDocExtractor);
// array of PropertyAccessExtractorInterface
$accessExtractors = array($reflectionExtractor);
$propertyInfo = new PropertyInfoExtractor(
$listExtractors,
$typeExtractors,
$descriptionExtractors,
$accessExtractors
);
return $propertyInfo->getProperties($class);
}
private function getTranslatableProperties($properties, $class)
{
$translatableProperties = [];
// https://gist.github.com/Swop/5990316
$annotationReader = new AnnotationReader();
foreach ($properties as $property) {
try {
$reflectionProperty = new \ReflectionProperty($class, $property);
$propertyAnnotations = $annotationReader->getPropertyAnnotations($reflectionProperty);
foreach ($propertyAnnotations as $propertyAnnotation) {
if ($propertyAnnotation instanceof Translatable) {
// this property is translatable
$translatableProperties[] = $property;
}
}
} catch (\ReflectionException $e) {
// missing property
continue;
}
}
return $translatableProperties;
}
}

Doctrine DQL query produces Error: Expected Literal, got end of string

I am currently trying to build a blog website following a course that uses
Symfony 2.5.2. (PHP -v 7.0)
To retrieve a post I am using a following Controller
/**
* #Route(
* "/{slug}",
* name = "blog_post"
* )
* #Template()
*/
public function postAction($slug)
{
$PostRepo = $this->getDoctrine()->getRepository('AniaBlogBundle:Post');
$Post = $PostRepo->getPublishedPost($slug);
if(null === $Post){
throw $this->createNotFoundException('Post not found');
}
return array(
'post'=> $Post
);
}
and here is my getPublishedPost function :
public function getPublishedPost($slug){
$qb = $this->getQueryBuilder(array(
'status' => 'published'
));
$qb->andWhere('p.slug = :slug')
->setParameter('slug', $slug);
return $qb->getQuery()->getOneOrNullResult();
}
and getQueryBuilder function :
public function getQueryBuilder(array $params = array()){
$qb = $this->createQueryBuilder('p')
->select('p, c, t')
->leftJoin('p.category', 'c')
->leftJoin('p.tags', 't');
if(!empty($params['status'])){
if('published' == $params['status']){
$qb->where('p.publishedDate <= :currDate AND p.publishedDate IS NOT NULL')
->setParameter('currDate', new \DateTime());
}else if('unpublished' == $params['status']) {
$qb->where('p.publishedDate > :currDate OR p.publishedDate IS NULL')
->setParameter('currDate', new \DateTime());
}
}
if(!empty($params['orderBy'])){
$orderDir = !empty($params['orderDir']) ? $params['orderDir'] : NULL;
$qb->orderBy($params['orderBy'], $orderDir);
}
if(!empty($params['categorySlug'])){
$qb->andWhere('c.slug = :categorySlug')
->setParameter('categorySlug', $params['categorySlug']);
}
if(!empty($params['tagSlug'])){
$qb->andWhere('t.slug = :tagSlug')
->setParameter('tagSlug', $params['tagSlug']);
}
if(!empty($params['search'])) {
$searchParam = '%'.$params['search'].'%';
$qb->andWhere('p.title LIKE :searchParam OR p.content LIKE :searchParam')
->setParameter('searchParam', $searchParam);
}
return $qb;
}
}
However i get the 500 error saying : [Syntax Error] line 0, col -1: Error: Expected Literal, got end of string.
Thank you in advance for any suggestions!

GuzzleHttp Client class not found in symfony2

I have loaded in GuzzleHttp from
http://docs.guzzlephp.org/en/5.3/quickstart.html
and have the
use GuzzleHttp\Client;
When i call this action...
public function googlevolumeAction(Request $request)
{
$data = $request->request->all();
$searchStr = $data['search'];
$client = new Client();
$req = $client->request('GET', 'https://www.googleapis.com/books/v1/volumes?q=intitle:' .$searchStr, []);
$decode = json_decode($req->getBody());
$total = $decode->totalItems;
$search = null;
if ($total != 0) {
$search = $decode->items;
}
return $this->render('BloggerBlogBundle:Page:googlevolume.html.twig',
['items' => $search]);
}
I get this error...
Attempted to load class "Client" from namespace "GuzzleHttp".
Did you forget a "use" statement for e.g. "Guzzle\Http\Client",
"Guzzle\Service\Client", "Symfony\Component\BrowserKit\Client",
"Symfony\Component\HttpKernel\Client" or
"Symfony\Bundle\FrameworkBundle\Client"?
Any ideas why?
thanks
Looks like you have a different version of guzzle installed than the docs you are looking at. From the error message you got it seems that if you change your use statement to:
use Guzzle\Http\Client;
It should work.

mail() function not working inside Wordpress but works on server and from php command line

I've got a vagrant box running ubuntu and postfix is installed and I can send a test mail from it on the command line. I can also start a php session and send a mail with the mail function from it.
However, from a script in Wordpress the mail() function doesn't work and if I debug the error it is an error coming from the phpmailer class "Could not instantiate mail function".
So it looks like phpmailer class is overriding the php mail function in Wordpress. Any ideas how I can resolve this problem. I've got a feeling it is to do with missing required attributes of the mail that phpmailer class is expecting.
error is coming from the following function:
protected function mailSend($header, $body)
{
$toArr = array();
foreach ($this->to as $toaddr) {
$toArr[] = $this->addrFormat($toaddr);
}
write_log('to arr');
write_log($toArr);
$to = implode(', ', $toArr);
write_log('to');
write_log($to);
write_log('sender');
write_log($this->Sender);
if (empty($this->Sender)) {
$params = ' ';
} else {
$params = sprintf('-f%s', $this->Sender);
}
write_log('params');
write_log($params);
if ($this->Sender != '' and !ini_get('safe_mode')) {
write_log('old_from');
write_log($old_from);
$old_from = ini_get('sendmail_from');
ini_set('sendmail_from', $this->Sender);
}
$result = false;
write_log($this->SingleTo);
if ($this->SingleTo && count($toArr) > 1) {
foreach ($toArr as $toAddr) {
$result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
$this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
} else {
$result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
$this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
}
if (isset($old_from)) {
ini_set('sendmail_from', $old_from);
}
if (!$result) {
throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
}
return true;
}
and in the logs sender, params and old_from are not set
If mail function is not working in your wordpress then your SMTP mail function and try

Resources