src/EventSubscriber/EasyAdminSubscriber.php line 57

  1. <?php
  2. # src/EventSubscriber/EasyAdminSubscriber.php
  3. namespace App\EventSubscriber;
  4. use App\Entity\ExportExcel;
  5. use App\Entity\FrontTheme;
  6. use App\Entity\Settings;
  7. use App\Entity\User;
  8. use Doctrine\Common\Collections\ArrayCollection;
  9. use Doctrine\Common\Collections\Collection;
  10. use Doctrine\Persistence\ManagerRegistry;
  11. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
  12. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityPersistedEvent;
  13. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
  14. use RecursiveDirectoryIterator;
  15. use RecursiveIteratorIterator;
  16. use ReflectionClass;
  17. use ReflectionMethod;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Symfony\Component\Security\Core\Security;
  20. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  21. use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
  22. use Symfony\Component\Filesystem\Filesystem;
  23. use Symfony\Component\Filesystem\Path;
  24. use Symfony\Component\Finder\Finder;
  25. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  26. use Symfony\Component\Yaml\Yaml;
  27. use ZipArchive;
  28. use Symfony\Contracts\Translation\TranslatorInterface;
  29. class EasyAdminSubscriber implements EventSubscriberInterface
  30. {
  31.  
  32.     
  33.     public function __construct(
  34.         private readonly Security $security,
  35.         private readonly UserPasswordHasherInterface $passwordEncoder,
  36.         private readonly ManagerRegistry $doctrine,
  37.         private readonly TranslatorInterface $translatorInterface
  38.         
  39.         )
  40. {
  41.         
  42.     }
  43.     public static function getSubscribedEvents()
  44.     {
  45.         return [
  46.             BeforeEntityPersistedEvent::class => ['beforePersist'],
  47.             BeforeEntityUpdatedEvent::class => ['beforeUpdated'],
  48.             BeforeEntityDeletedEvent::class => ['beforeDelete']
  49.         ];
  50.     }
  51.     public function beforePersist(BeforeEntityPersistedEvent $event)
  52.     {
  53.         $entity $event->getEntityInstance();
  54.         if($entity instanceof FrontTheme){
  55.             
  56.             $filesystem = new Filesystem();
  57.             $finder = new Finder();
  58.             
  59.             $path __DIR__."/../../public/uploads/".$entity->getName();
  60.             if(!$filesystem->exists($path) )
  61.             {
  62.                 $filesystem->mkdir($path,0777);
  63.                 $filesystem->mkdir($path."/pages",0777);
  64.                 $filesystem->mkdir($path."/shop",0777);
  65.                 
  66.             }
  67.             $pathFrontBundle __DIR__."/../Flexy/FrontBundle";
  68.             
  69.             $themePath $pathFrontBundle."/Themes";
  70.             $filesystem->mirror($themePath."/Default",$themePath."/".ucfirst($entity->getName()));
  71.             //$filesystem->mkdir(__DIR__."/../../public/themes/".strtolower($entity->getName()),0777);
  72.             $filesystem->symlink($themePath."/".$entity->getName()."/assets"__DIR__."/../../public/themes/".strtolower($entity->getName()));
  73.             
  74.             
  75.             
  76.             //Step 1 : Copy Controllers
  77.             $finder->in($themePath."/".ucfirst($entity->getName())."/Controller");
  78.             $finder->files()->contains("Default");
  79.             
  80.             foreach ($finder as $file) {
  81.                 
  82.                 $file_contents file_get_contents($file->getPathname());
  83.                 $file_contents str_replace("Default\Controller"ucfirst($entity->getName())."\Controller"$file_contents);
  84.                 $file_contents str_replace("Default\Form"ucfirst($entity->getName())."\Form"$file_contents);
  85.                 
  86.                 file_put_contents($file->getPathname(), $file_contents);
  87.             }
  88.             
  89.             
  90.             
  91.             //Step 2 : Copy Forms
  92.             
  93.             $finder->in($themePath."/".ucfirst($entity->getName())."/Form");
  94.             $finder->files()->contains("Default");
  95.             //dd($finder->hasResults());
  96.             foreach ($finder as $file) {
  97.                 
  98.                 $file_contents file_get_contents($file->getPathname());
  99.                 $file_contents str_replace("Default\Form"ucfirst($entity->getName())."\Form"$file_contents);
  100.                 file_put_contents($file->getPathname(), $file_contents);
  101.             }
  102.             //Step 3 : Copy assets
  103.             
  104.             //$assetsPath = $pathFrontBundle."/Resources/public/assets";
  105.             //$filesystem->mirror($assetsPath."/default",$assetsPath."/".strtolower($entity->getName())); 
  106.                       
  107.             //Step 4 : Copy Templates
  108.             
  109.             $finder->in($themePath."/".ucfirst($entity->getName())."/templates");
  110.             
  111.             $finder->files()->contains("default");
  112.             //dd($finder->hasResults());
  113.             foreach ($finder as $file) {
  114.                 
  115.                 $file_contents file_get_contents($file->getPathname());
  116.                 $file_contents str_replace("default/"strtolower($entity->getName())."/"$file_contents);
  117.                 file_put_contents($file->getPathname(), $file_contents);
  118.             }
  119.             
  120.             
  121.         }
  122.         if($entity instanceof Settings){
  123.             if($entity->getFrontTheme()){
  124.                 $entity->setAssetFolderName(strtolower($entity->getFrontTheme()->getName()));
  125.             }
  126.             
  127.             $filesystem = new Filesystem();
  128.             
  129.             $path __DIR__."/../../public/uploads/".$entity->getAssetFolderName();
  130.             if(!$filesystem->exists($path) )
  131.             {
  132.                 $filesystem->mkdir($path,0777);
  133.                 $filesystem->mkdir($path."/pages",0777);
  134.                 $filesystem->mkdir($path."/shop",0777);
  135.                 
  136.             }
  137.             $pathFrontBundleRoutes __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";
  138.             if($filesystem->exists($pathFrontBundleRoutes)){
  139.                 $configArray Yaml::parseFile($pathFrontBundleRoutes);
  140.                 $configArray["controllers"]["resource"] = "../../Controller/".ucfirst($entity->getAssetFolderName());
  141.                 
  142.                 $yamlConfig Yaml::dump($configArray);
  143.                 file_put_contents($pathFrontBundleRoutes$yamlConfig);
  144.             }
  145.             
  146.             
  147.         } 
  148.     
  149.         
  150.         if ($entity instanceof ExportExcel) {
  151.             $entityNameSpace $entity->getEntityNameSpace();
  152.             
  153.             $directFields $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->getColumnNames();
  154.             $associationFields $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->getAssociationMappings();
  155.             
  156.             
  157.             $entityRepository $this->doctrine->getRepository($entityNameSpace);
  158.             $repositoryMethods $this->getAllRepositoryMethods($entityRepository);
  159.             
  160.             $reflectionClass $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->reflClass->getMethods();// All methods detailled
  161.             
  162.             //-------------
  163.             //dd($reflectionClass[0]->name);
  164.             $fields = [];
  165.             $translatedFields = [];
  166.             foreach($reflectionClass as $singleRefClass){
  167.                 if(count($entity->getFields()) > ){
  168.                     if($entity->isExcludeFields()){
  169.                         if(in_array($singleRefClass->name,$entity->getFields())){
  170.                             continue;
  171.                         }
  172.                     }else{
  173.                         if(!in_array($singleRefClass->name,$entity->getFields())){
  174.                             continue;
  175.                         }
  176.                     }
  177.                     
  178.                 }
  179.                 if (substr($singleRefClass->name03) === "get") {
  180.                     $fields[]=$singleRefClass->name;
  181.                 } else {
  182.                     continue;
  183.                 }
  184.             }
  185.             foreach($repositoryMethods as $singleMethod){
  186.                     $fields[]=$singleMethod;
  187.             }
  188.             
  189.             //dd($fields);
  190.             //$selectedFieldsToExport = ["name","categoryProduct","subCategoryProduct","price"];
  191.             $selectedFieldsToExport = [];
  192.             $selectedFieldsToExport array_merge($selectedFieldsToExport,$fields);
  193.             //$selectedFieldsToExport = array_merge($selectedFieldsToExport,$reflectionClass);
  194.             
  195.             if(count($entity->getFindBy())>0){
  196.                 $queryBuilder $this->doctrine->getManager()->createQueryBuilder();
  197.                 
  198.                 $queryBuilder
  199.                     ->select('e')
  200.                     ->from($entityNameSpace'e');
  201.                     //->join('e.relatedEntity', 'r')
  202.                 foreach($entity->getFindBy() as $key => $value){
  203.                     $queryBuilder   
  204.                     ->where('e.'.$key.' '.$value);
  205.                 }
  206.                 if(count($entity->getOrderBy())>0){
  207.                     foreach($entity->getOrderBy() as $key => $value){
  208.                         if(gettype($key)=="integer"){
  209.                             $queryBuilder->orderBy("e.".$value);
  210.                         }else{
  211.                             $queryBuilder->orderBy("e.".$key,$value);
  212.                         }
  213.                         
  214.                     }
  215.                     
  216.                 }
  217.                 
  218.                 $entityFetchAll $queryBuilder->getQuery()->getResult();
  219.                 
  220.                 
  221.                     
  222.             }else{
  223.                 $entityFetchAll $this->doctrine->getManager()->getRepository($entityNameSpace)->findAll();
  224.             }
  225.             
  226.             
  227.             
  228.             $arrayToExport = [];
  229.             //$arrayToExport[]=$selectedFieldsToExport;
  230.             $correctedFieldsName =[];
  231.             foreach($fields as $field){
  232.                 $name $this->getAbsoluteNameMethod($field);
  233.                 $correctedFieldsName[]= $this->translatorInterface->trans($name);
  234.             }
  235.             
  236.             
  237.             $arrayToExport[]=$correctedFieldsName;
  238.             foreach($entityFetchAll as $singleEntityInstance){
  239.                 
  240.                 $singleRow =[];
  241.                 foreach($fields as $singleField){
  242.                     $value=null;
  243.                     $valueSub=null;
  244.                     $valueParent=null;
  245.                     
  246.                    
  247.                     
  248.                     
  249.                         if(method_exists($singleEntityInstance,$singleField)){
  250.                             
  251.                             
  252.                             
  253.                             $value $singleEntityInstance->{$singleField}();
  254.                             
  255.                                 if($value instanceof Collection){
  256.                                     $value implode("\n"$value->toArray());
  257.                                     //dd($value);
  258.                                 }elseif(is_array($value)){
  259.                                     $value implode("\n"$value);
  260.                                     //dd($value);
  261.                                 }elseif(gettype($value) == "string"){
  262.                                     $value $this->translatorInterface->trans($value);
  263.                                 }
  264.                             
  265.     
  266.                         }elseif(method_exists($entityRepository,$singleField)){
  267.                             $value $entityRepository->{$singleField}($singleEntityInstance->getId());
  268.                             
  269.                         
  270.                             if(is_array($value)){
  271.                                 
  272.                                 // find the index of the value 'orange'
  273.                                 $field $this->getAbsoluteNameMethod($singleField);
  274.                                 $translatedField $this->translatorInterface->trans($field);
  275.                                 $index array_search($translatedField$arrayToExport[0]);
  276.                                 // if the value exists in the array, remove it
  277.                                 if ($index !== false) {
  278.                                     unset($arrayToExport[0][$index]);
  279.                                 }
  280.                                 // re-index the array
  281.                                 //$arrayToExport = array_values($arrayToExport[0]);
  282.                                // dd($value);
  283.                                 
  284.                                 foreach($value as $singleData){
  285.                                     $translatedKey $this->translatorInterface->trans($singleData["key"]);
  286.                                     if(!in_array($translatedKey,$arrayToExport[0])){
  287.                                         
  288.                                         $arrayToExport[0][] = $this->translatorInterface->trans($translatedKey);
  289.                                     }
  290.                                     
  291.                                     $singleRow[]=$singleData["value"];
  292.                                 }
  293.                                 
  294.                                 continue;
  295.                             }else{
  296.                                 $value $this->translatorInterface->trans($value);
  297.                             }
  298.                         }
  299.                         $singleRow[]=$value;
  300.                     
  301.                     
  302.                 }
  303.                 $arrayToExport[]=$singleRow;
  304.             }
  305.             
  306.             
  307.             
  308.             
  309.             
  310.             $mySpreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  311.             $mySpreadsheet->removeSheetByIndex(0);
  312.             $worksheet1 = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($mySpreadsheet"List Produits");
  313.             $mySpreadsheet->addSheet($worksheet10);
  314.             $worksheet1->fromArray($arrayToExport,null,"A1");
  315.             // Set the auto filter to cover all the data
  316.             $lastColumn $worksheet1->getHighestColumn();
  317.             $lastRow $worksheet1->getHighestDataRow();
  318.             $range "A1:$lastColumn$lastRow";
  319.             $worksheet1->setAutoFilter($range);
  320.             foreach ($worksheet1->getColumnIterator() as $column)
  321.                 {
  322.                     $worksheet1->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
  323.                     
  324.                     
  325.                 }
  326.                 foreach ($worksheet1->getRowIterator() as $row) {
  327.                     foreach ($row->getCellIterator() as $cell) {
  328.                         $cell->getStyle()->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  329.                     }
  330.                 }
  331.                 $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($mySpreadsheet);
  332.                 
  333.                 $parts explode("\\"$entityNameSpace);
  334.                 $nameOfFile end($parts);
  335.                 $nameOfFile strtolower($nameOfFile)."-".$entity->getCreatedAt()->format("Y-m-d-H-i");
  336.                 //echo $lastWord; // output: CategoryProduct
  337.                 $settings $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  338.                 $assetFolderName $settings->getAssetFolderName();
  339.                 $assetFolderName strtolower($assetFolderName);
  340.                 $writer->save("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");
  341.                 
  342.                 $entity->setGeneratedFilePath("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");
  343.                 $entity->setEntityNameSpace($entityNameSpace);
  344.         
  345.             
  346.         }
  347.                 if ($entity instanceof User) {
  348.                     
  349.                    $entity->setPassword(
  350.                    $this->passwordEncoder->hashPassword(
  351.                             $entity,
  352.                             $entity->getPassword()
  353.                 ));
  354.                 
  355.             
  356.             
  357.             
  358.                 
  359.         }
  360.     }
  361.     public function beforeUpdated(BeforeEntityUpdatedEvent $event)
  362.     {
  363.         $entity $event->getEntityInstance();
  364.         
  365.         if($entity instanceof Settings){
  366.             $filesystem = new Filesystem();
  367.             $pathFrontBundle __DIR__."/../Flexy/FrontBundle";
  368.             $themePath $pathFrontBundle."/Themes";
  369.             if($entity->getFrontTheme()){
  370.                 $entity->setAssetFolderName($entity->getFrontTheme()->getName());
  371.                 if(!$filesystem->exists(__DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()))){
  372.                     $filesystem->symlink($themePath."/".$entity->getFrontTheme()->getName()."/assets"__DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()));
  373.                 }
  374.                
  375.             }
  376.             
  377.             
  378.             $path __DIR__."/../../public/uploads/".$entity->getAssetFolderName();
  379.             if(!$filesystem->exists($path) )
  380.             {
  381.                 $filesystem->mkdir($path,0777);
  382.                 $filesystem->mkdir($path."/pages",0777);
  383.                 $filesystem->mkdir($path."/shop",0777);
  384.                 
  385.             }
  386.             
  387.             $pathFrontBundleRoutes __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";
  388.             if($filesystem->exists($pathFrontBundleRoutes)){
  389.                 $configArray Yaml::parseFile($pathFrontBundleRoutes);
  390.                 $configArray["controllers"]["resource"] = "../../Themes/".ucfirst($entity->getAssetFolderName())."/Controller";
  391.                 
  392.                 $yamlConfig Yaml::dump($configArray);
  393.                 file_put_contents($pathFrontBundleRoutes$yamlConfig);
  394.             }
  395.             
  396.         }
  397.       
  398.    
  399.      
  400.     }
  401.     public function beforeDelete(BeforeEntityDeletedEvent $event){
  402.         $entity $event->getEntityInstance();
  403.         if($entity instanceof FrontTheme){
  404.             //$entity->getSettings()->setFrontTheme(null);
  405.             $filesystem = new Filesystem();
  406.             //dd(__DIR__."/../../");
  407.             $pathFrontBundle __DIR__."/../Flexy/FrontBundle";
  408.             
  409.             $themePath $pathFrontBundle."/Themes";
  410.             if($filesystem->exists($themePath."/".ucfirst($entity->getName()) ) ){
  411.             
  412.             $this->zipDirectory($themePath."/".ucfirst($entity->getName()),__DIR__."/../../public/archive-themes/".strtolower($entity->getName()).".zip" );
  413.             
  414.             $filesystem->remove($themePath."/".ucfirst($entity->getName()));
  415.             
  416.                 
  417.                 
  418.             
  419.                
  420.             }
  421.             
  422.             //$filesystem->remove($pathFrontBundle."/Resources/public/assets/".strtolower($entity->getName()));
  423.             $settings $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  424.             $currentTheme $settings->getAssetFolderName();
  425.             $entity->removeSetting($settings);
  426.             $settings->setAssetFolderName("Default");
  427.             $this->doctrine->getManager()->persist($settings);
  428.             if(strtolower($entity->getName()) == strtolower($currentTheme) ){
  429.                 $pathFrontBundleRoutes __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";
  430.                 if($filesystem->exists($pathFrontBundleRoutes)){
  431.                     $configArray Yaml::parseFile($pathFrontBundleRoutes);
  432.     
  433.                     $configArray["controllers"]["resource"] = "../../Themes/Default/Controller";
  434.                     
  435.     
  436.                     $yamlConfig Yaml::dump($configArray);
  437.     
  438.                     file_put_contents($pathFrontBundleRoutes$yamlConfig);
  439.                 }
  440.             }
  441.             
  442.         }
  443.        
  444.     }
  445.     public function  exportFile($records) {
  446.         $heading false;
  447.             if(!empty($records))
  448.               foreach($records as $row) {
  449.                 if(!$heading) {
  450.                   // display field/column names as a first row
  451.                   echo implode("\t"array_keys($row)) . "\n";
  452.                   $heading true;
  453.                 }
  454.                 echo implode("\t"array_values($row)) . "\n";
  455.             }
  456.         
  457.     }
  458.     public static function zipDirectory($directory$zipName)
  459. {
  460.     // Get real path for our folder
  461. $rootPath realpath($directory);
  462. // Initialize archive object
  463. $zip = new ZipArchive();
  464. $zip->open($zipNameZipArchive::CREATE ZipArchive::OVERWRITE);
  465. // Initialize empty "delete list"
  466. $filesToDelete = array();
  467. // Create recursive directory iterator
  468. /** @var SplFileInfo[] $files */
  469. $files = new RecursiveIteratorIterator(
  470.     new RecursiveDirectoryIterator($rootPath),
  471.     RecursiveIteratorIterator::LEAVES_ONLY
  472. );
  473. foreach ($files as $name => $file)
  474. {
  475.     // Skip directories (they would be added automatically)
  476.     if (!$file->isDir())
  477.     {
  478.         // Get real and relative path for current file
  479.         $filePath $file->getRealPath();
  480.         $relativePath substr($filePathstrlen($rootPath) + 1);
  481.         // Add current file to archive
  482.         $zip->addFile($filePath$relativePath);
  483.         // Add current file to "delete list"
  484.         // delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)
  485.         if ($file->getFilename() != 'important.txt')
  486.         {
  487.             $filesToDelete[] = $filePath;
  488.         }
  489.     }
  490. }
  491. // Zip archive will be created only after closing object
  492. $zip->close();
  493. return $zip;
  494. }
  495. function getAbsoluteNameMethod($input) {
  496.     // Remove the "get" prefix from the input string
  497.   $input preg_replace('/^get/'''$input);
  498.   
  499.   // Replace all capital letters with a space followed by the letter
  500.   $output preg_replace('/([A-Z])/'' $1'$input);
  501.   
  502.   // Remove any leading or trailing spaces
  503.   $output trim($output);
  504.   
  505.   // Convert the first character to uppercase
  506.   $output ucfirst($output);
  507.   
  508.   // Return the final result
  509.   return $output;
  510.   }
  511.   public function getAllRepositoryMethods($repository)
  512. {
  513.     $reflectionClass = new ReflectionClass(get_class($repository));
  514.     $methods $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);
  515.     $findMethods = [];
  516.     foreach ($methods as $method) {
  517.         $methodName $method->getName();
  518.         if (strpos($methodName'export') === 0) {
  519.             $findMethods[] = $methodName;
  520.         }
  521.     }
  522.     return $findMethods;
  523. }
  524. }