after hours of research I can't find the solution, I want to display the content of $results in an excel file I tried to do that in the download function but I can't add the table data result in the variable $myvariableCSV. i hope it's clear
<?php
namespace App\Controller\MissingPDV;
use App\Entity\Upload;
use App\Form\UploadType;
use App\Repository\UploadRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
/**
* #Route("/upload")
*/
class UploadController extends AbstractController
{
/**
* #Route("/new", name="app_upload_new", methods={"GET", "POST"})
*/
public function new(Request $request): Response
{
$upload = new Upload();
$form = $this->createForm(UploadType::class, $upload);
$form->handleRequest($request);
$results=[];
$cells1=[];
$cells2=[];
if ($form->isSubmitted() && $form->isValid()) {
//add date information
$upload->setDate(new \DateTime('now'));
$NamesOfFiles=[];
// adding File1
$file1= $form->get('file1')->getData();
$NamesOfFiles[]=$file1->getClientOriginalName();
$fileName1 =md5(uniqid()).'.csv';
$file1->move($this->getParameter('upload_directory'),$fileName1);
$upload->setFile1($fileName1);
// adding File 2
$file2= $form->get('file2')->getData();
$NamesOfFiles[]=$file2->getClientOriginalName();
$fileName2 =md5(uniqid()).'.csv';
$file2->move($this->getParameter('upload_directory'),$fileName2);
$upload->setFile2($fileName2);
// Adding text 1 fields
$text1= $form->get('text1')->getData();
$upload->setText1($text1);
// Adding text 2 fields
$text2= $form->get('text2')->getData();
$upload->setText2($text2);
// Read first File and find column according to text (Spout)
$filePath= dirname(__DIR__).'/../../public/uploads/'.$fileName1;
$reader = ReaderEntityFactory::createCSVReader();
$reader->open($filePath);
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
// do stuff with the row
$cells1[] = $row->getCells();
}
}
$reader->close();
//Reading File2 wth spout Library Reader
$filePath2= dirname(__DIR__).'/../../public/uploads/'.$fileName2;
$reader2 = ReaderEntityFactory::createCSVReader();
$reader2->open($filePath2);
foreach ($reader2->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
$cells2[] = $row->getCells();
}
}
$reader2->close();
// put in array File 1 element
$goodcolonne='';
foreach ($cells1[0] as $colonne=>$nom){
if ($nom == $text1){
$goodcolonne = $colonne;
break;
}
}
$basepdv=[];
for ($i=1;$i<count($cells1);$i++){
$basepdv[]=$cells1[$i][$goodcolonne];
}
// put in array File 2 element
foreach ($cells2[0] as $colonne=>$nom){
if ($nom == $text2){
$goodcolonne = $colonne;
break;
}
}
$newpdv=[];
for ($i=1;$i<count($cells2);$i++){
$newpdv[]=$cells2[$i][$goodcolonne];
}
// comparer et sortir les pdv manquants
foreach ($newpdv as $pdv){
if(!in_array($pdv,$basepdv)){
$results[]=$pdv;
}
}
return $this->render('vuejs/resultat.html.twig',[
'resultats' => $results,
'namesOfFiles' => $NamesOfFiles,
]);
}
// ici on charge le formulaire vide
return $this->renderForm('upload/new.html.twig', [
'upload' => $upload,
'form' => $form,
]);
}
/**
* #Route("/download", name="download")
*/
public function download($results)
{
//Nom des colonnes en première lignes
// le \n à la fin permets de faire un saut de ligne, super important en CSV
// le point virgule sépare les données en colonnes
$myVariableCSV = "code_pdv;\n";
//Ajout de données (avec le . devant pour ajouter les données à la variable existante)
$myVariableCSV .= ;\n;
//On donne la variable en string à la response, nous définissons le code HTTP à 200
return new Response(
$myVariableCSV,
200,
[
//Définit le contenu de la requête en tant que fichier Excel
'Content-Type' => 'application/vnd.ms-excel',
//On indique que le fichier sera en attachment donc ouverture de boite de téléchargement ainsi que le nom du fichier
"Content-disposition" => "attachment; filename= PDV_manquants.csv"
]
);
}
}
i try to do download fonction it's works when i add some string variables but i want do add results
If you use EasyAdmin you can export your data easily by "goodby-csv" composer. Please take a look at this link:
https://symfonycasts.com/screencast/easyadminbundle/global-action
Related
I have a collection form called Paragraphe with a text and a file (an Image):
class ParagrapheType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('text')
->add('image', FileType::class, ['mapped'=>false, 'required'=>false])
And it's inside another form called Article.
Here, how I add a Paragraphe inside formulaire.html.twig of Article (I just followed How to Embed a Collection of Forms from the official Symfony doc) :
<h3>Paragraphes:</h3>
{# the data-index attribute is required for the JavaScript code below #}
<ul class="paragraphes" data-index="{{ (formArticle.paragraphes|length) > 0 ? formArticle.paragraphes|last.vars.name + 1 : 0 }}" data-prototype="{{ form_widget(formArticle.paragraphes.vars.prototype)|e( 'html_attr' ) }}"></ul>
<button type="button" class="add_item_link" data-collection-holder-class="paragraphes">Add an paragraphe</button>
<script>
//event listener sur le bouton document.querySelectorAll('.add_item_link') ➡️ adds a new Paragraphe form on the Article form when push the button⤵️
const addFormToCollection = (e) => { const collectionHolder =
document.querySelector('.' + e.currentTarget.dataset.collectionHolderClass);
const item = document.createElement('li');
item.innerHTML = collectionHolder .dataset .prototype .replace( /__name__/g, collectionHolder.dataset.index );
collectionHolder.appendChild(item);
collectionHolder.dataset.index++; };
document
.querySelectorAll('.add_item_link')
.forEach(btn => { btn.addEventListener("click", addFormToCollection) });
Here what I try to save my Image in my ArticleControler.php:
foreach ($form->get('paragraphes')->getData() as $paragraphe) {
$imageParagraphe= $paragraphe->get('image')->getData(); //get() method doesn't exist so I don't know how to get the file.
if($imageParagraphe){
$fileNameImageParagraphe = $articleSlug . uniqid() . '.' . $imageParagraphe->guessExtension();
//move the image as parametred in service.yaml
try {
$imageParagraphe->move($this->getParameter('article_images'), $fileNameImageParagraphe);
} catch (FileException $e) {
$this->addFlash('erreur', "Image cannot be uploaded.");
}
$paragraphe->setImage($fileNameImageParagraphe);
} else $paragraphe->setImage($imageParagraphe);
}
As my comment says, I didn't find a way to get the file inside the second form. Did I need to do it from my script inside my twig?
Thanks to this question, I was able to find that I needed to loop through $formParagraphe and not through $formParagraphe->getData().
Here my updated contoller:
foreach ($form->get('paragraphes') as $formParagraphe) {
$imageParagraphe= $formParagraphe->get('image')->getData();
$paragraphe= $formParagraphe->getData();
if($imageParagraphe){
$fileNameImageParagraphe = $articleSlug . uniqid() . '.' . $imageParagraphe->guessExtension();
//déplace l'image dans le dossier paramétré dans service.yaml
try {
$imageParagraphe->move($this->getParameter('article_images'), $fileNameImageParagraphe );
} catch (FileException $e) {
$this->addFlash('erreur', "L'image n'a pas pu être uploadé.");
}
$paragraphe->setImage($fileNameImageParagraphe);
} else $paragraphe->setImage($imageParagraphe);
}
if ($article->getSlug() !== $articleSlug) {
$article->setSlug($articleSlug);
}
PS: I'm gonna update this when I find out how to keep the old Image in the form...
I have a problem when trying to add an image to a folder on a website that I'm developping currently. When I try to rename the file, I would like it to be : idOfMyObject.jpg
But when I want to add it on my form, this error code pops up : "Object of class App\Entity\Vegetal could not be converted to string".
The problem's apparently inside the isset, but I can't find a solution to convert my id to string.
Here is the Controller :
public function ajouterVegetal(Request $request): Response
{
$fFeuille = new FormeFeuille();
$vegetal = new Vegetal();
$formVegetal = $this->createForm(VegetalType::class, $vegetal);
$formVegetal->handleRequest($request);
//Si le formulaire est bien valide (tous les champs remplis) et que le bouton submit est appuyé
if ($formVegetal->isSubmitted() && $formVegetal->isValid()) {
//on récupère les données du formaulaire
$vegetal = $formVegetal->getData();
$entityManager = $this->getDoctrine()->getManager();
//on récupère les données de la variable image dans le formulaire d'ajout
$fileDownload = $formVegetal['images']->getData();
//si le fichier existe, on le renomme avec l'id du végétal, pour le sauvegarder dans le dossier configuré dans service.yaml
if (isset($fileDownload))
{
$nomImage = $fFeuille->getVegetals()->{$this->$vegetal->getId()}.'.'.$fileDownload->guessExtension();
$fileDownload->move(
$this->getParameter('upload_directory'),
$nomImage
);
}
//on ajoute les données dans la base
$entityManager->persist($vegetal);
$entityManager->flush();
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('listerVegetal');
} else {
return $this->render('Vegetal/ajouterVegetal.html.twig', [
'vegetal' => $vegetal,
'form' => $formVegetal->createView(),
]);
}
}
I will allow myself to assume that this error is caused when rendering the form.
And most likely you are using EntityType for Vegetal in formBilder. I'm guessing that when you render the form, you get this error because formBilder tries to convert Vegetal to render it in "select", but it fails because it doesn't know what value to take.
The code below will just help php decide what value to return when converting this object to a string.
Add in Entity Vegetal
public function __toString(): string
{
return $this->getName(); // or some string field in your Vegetal Entity
}
It also might not work for you, but usually my similar errors were solved by this.
I have an Entry which is used to ask a riddle. I put certain conditions there. My guess is displayed correctly and I can enter answers but the success message does not appear.
The objective was to limit to 3 response attempts and to display a Dysplayalert in the event of an error. Otherwise, there was a Label which displayed the rest of the scenario.
What would be my mistake?
My XAML :
<!--Row 08-->
<Entry x:Name="Enigme01"
IsVisible="false"
Placeholder="Ecrire la réponse."
ClearButtonVisibility="WhileEditing"
IsTextPredictionEnabled="False"
ReturnType="Send"
Grid.ColumnSpan="2"
Grid.Row="8"/>
My XAML.CS
public void Entry_Completed (object sender, EventArgs e)
{
var reponseEnigme01 = Enigme01.Text;
string soluce1 = "chaussette";
int CompteurEnigme = 0;
while ((soluce1 != reponseEnigme01) & (CompteurEnigme < 3))
{
DisplayAlert("Info:", "Mauvaise réponse", "ok");
CompteurEnigme++;
if (CompteurEnigme >= 3)
{
Reponse04.TextColor = Color.DarkRed;
Reponse04.Text = "A force de cogiter pour trouver la réponse, vous ne voyez pas les gardes arriver. Ils vous attrapent et finisser ainsi votre carrière d'aventurier dans une geôle.";
}
}
if (reponseEnigme01 == soluce1)
{
Reponse04.Text = "Bravo, vous avez donné la bonne réponse et la porte s'ouvre.";
Reponse04.IsVisible = true;
}
}
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.
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");
}