src/EventSubscriber/EasyAdminSubscriber.php line 473
<?php# src/EventSubscriber/EasyAdminSubscriber.phpnamespace App\EventSubscriber;use App\Entity\ExportExcel;use App\Entity\FrontTheme;use App\Entity\Settings;use App\Entity\User;use Doctrine\Common\Collections\ArrayCollection;use Doctrine\Common\Collections\Collection;use Doctrine\Persistence\ManagerRegistry;use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityPersistedEvent;use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;use RecursiveDirectoryIterator;use RecursiveIteratorIterator;use ReflectionClass;use ReflectionMethod;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\Security\Core\Security;use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;use Symfony\Component\Filesystem\Exception\IOExceptionInterface;use Symfony\Component\Filesystem\Filesystem;use Symfony\Component\Filesystem\Path;use Symfony\Component\Finder\Finder;use Symfony\Component\HttpFoundation\File\Exception\FileException;use Symfony\Component\Yaml\Yaml;use ZipArchive;use Symfony\Contracts\Translation\TranslatorInterface;class EasyAdminSubscriber implements EventSubscriberInterface{public function __construct(private readonly Security $security,private readonly UserPasswordHasherInterface $passwordEncoder,private readonly ManagerRegistry $doctrine,private readonly TranslatorInterface $translatorInterface){}public static function getSubscribedEvents(){return [BeforeEntityPersistedEvent::class => ['beforePersist'],BeforeEntityUpdatedEvent::class => ['beforeUpdated'],BeforeEntityDeletedEvent::class => ['beforeDelete']];}public function beforePersist(BeforeEntityPersistedEvent $event){$entity = $event->getEntityInstance();if($entity instanceof FrontTheme){$filesystem = new Filesystem();$finder = new Finder();$path = __DIR__."/../../public/uploads/".$entity->getName();if(!$filesystem->exists($path) ){$filesystem->mkdir($path,0777);$filesystem->mkdir($path."/pages",0777);$filesystem->mkdir($path."/shop",0777);}$pathFrontBundle = __DIR__."/../Flexy/FrontBundle";$themePath = $pathFrontBundle."/Themes";$filesystem->mirror($themePath."/Default",$themePath."/".ucfirst($entity->getName()));//$filesystem->mkdir(__DIR__."/../../public/themes/".strtolower($entity->getName()),0777);$filesystem->symlink($themePath."/".$entity->getName()."/assets", __DIR__."/../../public/themes/".strtolower($entity->getName()));//Step 1 : Copy Controllers$finder->in($themePath."/".ucfirst($entity->getName())."/Controller");$finder->files()->contains("Default");foreach ($finder as $file) {$file_contents = file_get_contents($file->getPathname());$file_contents = str_replace("Default\Controller", ucfirst($entity->getName())."\Controller", $file_contents);$file_contents = str_replace("Default\Form", ucfirst($entity->getName())."\Form", $file_contents);file_put_contents($file->getPathname(), $file_contents);}//Step 2 : Copy Forms$finder->in($themePath."/".ucfirst($entity->getName())."/Form");$finder->files()->contains("Default");//dd($finder->hasResults());foreach ($finder as $file) {$file_contents = file_get_contents($file->getPathname());$file_contents = str_replace("Default\Form", ucfirst($entity->getName())."\Form", $file_contents);file_put_contents($file->getPathname(), $file_contents);}//Step 3 : Copy assets//$assetsPath = $pathFrontBundle."/Resources/public/assets";//$filesystem->mirror($assetsPath."/default",$assetsPath."/".strtolower($entity->getName()));//Step 4 : Copy Templates$finder->in($themePath."/".ucfirst($entity->getName())."/templates");$finder->files()->contains("default");//dd($finder->hasResults());foreach ($finder as $file) {$file_contents = file_get_contents($file->getPathname());$file_contents = str_replace("default/", strtolower($entity->getName())."/", $file_contents);file_put_contents($file->getPathname(), $file_contents);}}if($entity instanceof Settings){if($entity->getFrontTheme()){$entity->setAssetFolderName(strtolower($entity->getFrontTheme()->getName()));}$filesystem = new Filesystem();$path = __DIR__."/../../public/uploads/".$entity->getAssetFolderName();if(!$filesystem->exists($path) ){$filesystem->mkdir($path,0777);$filesystem->mkdir($path."/pages",0777);$filesystem->mkdir($path."/shop",0777);}$pathFrontBundleRoutes = __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";if($filesystem->exists($pathFrontBundleRoutes)){$configArray = Yaml::parseFile($pathFrontBundleRoutes);$configArray["controllers"]["resource"] = "../../Controller/".ucfirst($entity->getAssetFolderName());$yamlConfig = Yaml::dump($configArray);file_put_contents($pathFrontBundleRoutes, $yamlConfig);}}if ($entity instanceof ExportExcel) {$entityNameSpace = $entity->getEntityNameSpace();$directFields = $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->getColumnNames();$associationFields = $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->getAssociationMappings();$entityRepository = $this->doctrine->getRepository($entityNameSpace);$repositoryMethods = $this->getAllRepositoryMethods($entityRepository);$reflectionClass = $this->doctrine->getManager()->getClassMetadata($entityNameSpace)->reflClass->getMethods();// All methods detailled//-------------//dd($reflectionClass[0]->name);$fields = [];$translatedFields = [];foreach($reflectionClass as $singleRefClass){if(count($entity->getFields()) > 0 ){if($entity->isExcludeFields()){if(in_array($singleRefClass->name,$entity->getFields())){continue;}}else{if(!in_array($singleRefClass->name,$entity->getFields())){continue;}}}if (substr($singleRefClass->name, 0, 3) === "get") {$fields[]=$singleRefClass->name;} else {continue;}}foreach($repositoryMethods as $singleMethod){$fields[]=$singleMethod;}//dd($fields);//$selectedFieldsToExport = ["name","categoryProduct","subCategoryProduct","price"];$selectedFieldsToExport = [];$selectedFieldsToExport = array_merge($selectedFieldsToExport,$fields);//$selectedFieldsToExport = array_merge($selectedFieldsToExport,$reflectionClass);if(count($entity->getFindBy())>0){$queryBuilder = $this->doctrine->getManager()->createQueryBuilder();$queryBuilder->select('e')->from($entityNameSpace, 'e');//->join('e.relatedEntity', 'r')foreach($entity->getFindBy() as $key => $value){$queryBuilder->where('e.'.$key.' '.$value);}if(count($entity->getOrderBy())>0){foreach($entity->getOrderBy() as $key => $value){if(gettype($key)=="integer"){$queryBuilder->orderBy("e.".$value);}else{$queryBuilder->orderBy("e.".$key,$value);}}}$entityFetchAll = $queryBuilder->getQuery()->getResult();}else{$entityFetchAll = $this->doctrine->getManager()->getRepository($entityNameSpace)->findAll();}$arrayToExport = [];//$arrayToExport[]=$selectedFieldsToExport;$correctedFieldsName =[];foreach($fields as $field){$name = $this->getAbsoluteNameMethod($field);$correctedFieldsName[]= $this->translatorInterface->trans($name);}$arrayToExport[]=$correctedFieldsName;foreach($entityFetchAll as $singleEntityInstance){$singleRow =[];foreach($fields as $singleField){$value=null;$valueSub=null;$valueParent=null;if(method_exists($singleEntityInstance,$singleField)){$value = $singleEntityInstance->{$singleField}();if($value instanceof Collection){$value = implode("\n", $value->toArray());//dd($value);}elseif(is_array($value)){$value = implode("\n", $value);//dd($value);}elseif(gettype($value) == "string"){$value = $this->translatorInterface->trans($value);}}elseif(method_exists($entityRepository,$singleField)){$value = $entityRepository->{$singleField}($singleEntityInstance->getId());if(is_array($value)){// find the index of the value 'orange'$field = $this->getAbsoluteNameMethod($singleField);$translatedField = $this->translatorInterface->trans($field);$index = array_search($translatedField, $arrayToExport[0]);// if the value exists in the array, remove itif ($index !== false) {unset($arrayToExport[0][$index]);}// re-index the array//$arrayToExport = array_values($arrayToExport[0]);// dd($value);foreach($value as $singleData){$translatedKey = $this->translatorInterface->trans($singleData["key"]);if(!in_array($translatedKey,$arrayToExport[0])){$arrayToExport[0][] = $this->translatorInterface->trans($translatedKey);}$singleRow[]=$singleData["value"];}continue;}else{$value = $this->translatorInterface->trans($value);}}$singleRow[]=$value;}$arrayToExport[]=$singleRow;}$mySpreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();$mySpreadsheet->removeSheetByIndex(0);$worksheet1 = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($mySpreadsheet, "List Produits");$mySpreadsheet->addSheet($worksheet1, 0);$worksheet1->fromArray($arrayToExport,null,"A1");// Set the auto filter to cover all the data$lastColumn = $worksheet1->getHighestColumn();$lastRow = $worksheet1->getHighestDataRow();$range = "A1:$lastColumn$lastRow";$worksheet1->setAutoFilter($range);foreach ($worksheet1->getColumnIterator() as $column){$worksheet1->getColumnDimension($column->getColumnIndex())->setAutoSize(true);}foreach ($worksheet1->getRowIterator() as $row) {foreach ($row->getCellIterator() as $cell) {$cell->getStyle()->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);}}$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($mySpreadsheet);$parts = explode("\\", $entityNameSpace);$nameOfFile = end($parts);$nameOfFile = strtolower($nameOfFile)."-".$entity->getCreatedAt()->format("Y-m-d-H-i");//echo $lastWord; // output: CategoryProduct$settings = $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);$assetFolderName = $settings->getAssetFolderName();$assetFolderName = strtolower($assetFolderName);$writer->save("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");$entity->setGeneratedFilePath("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");$entity->setEntityNameSpace($entityNameSpace);}if ($entity instanceof User) {$entity->setPassword($this->passwordEncoder->hashPassword($entity,$entity->getPassword()));}}public function beforeUpdated(BeforeEntityUpdatedEvent $event){$entity = $event->getEntityInstance();if($entity instanceof Settings){$filesystem = new Filesystem();$pathFrontBundle = __DIR__."/../Flexy/FrontBundle";$themePath = $pathFrontBundle."/Themes";if($entity->getFrontTheme()){$entity->setAssetFolderName($entity->getFrontTheme()->getName());if(!$filesystem->exists(__DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()))){$filesystem->symlink($themePath."/".$entity->getFrontTheme()->getName()."/assets", __DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()));}}$path = __DIR__."/../../public/uploads/".$entity->getAssetFolderName();if(!$filesystem->exists($path) ){$filesystem->mkdir($path,0777);$filesystem->mkdir($path."/pages",0777);$filesystem->mkdir($path."/shop",0777);}$pathFrontBundleRoutes = __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";if($filesystem->exists($pathFrontBundleRoutes)){$configArray = Yaml::parseFile($pathFrontBundleRoutes);$configArray["controllers"]["resource"] = "../../Themes/".ucfirst($entity->getAssetFolderName())."/Controller";$yamlConfig = Yaml::dump($configArray);file_put_contents($pathFrontBundleRoutes, $yamlConfig);}}}public function beforeDelete(BeforeEntityDeletedEvent $event){$entity = $event->getEntityInstance();if($entity instanceof FrontTheme){//$entity->getSettings()->setFrontTheme(null);$filesystem = new Filesystem();//dd(__DIR__."/../../");$pathFrontBundle = __DIR__."/../Flexy/FrontBundle";$themePath = $pathFrontBundle."/Themes";if($filesystem->exists($themePath."/".ucfirst($entity->getName()) ) ){$this->zipDirectory($themePath."/".ucfirst($entity->getName()),__DIR__."/../../public/archive-themes/".strtolower($entity->getName()).".zip" );$filesystem->remove($themePath."/".ucfirst($entity->getName()));}//$filesystem->remove($pathFrontBundle."/Resources/public/assets/".strtolower($entity->getName()));$settings = $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);$currentTheme = $settings->getAssetFolderName();$entity->removeSetting($settings);$settings->setAssetFolderName("Default");$this->doctrine->getManager()->persist($settings);if(strtolower($entity->getName()) == strtolower($currentTheme) ){$pathFrontBundleRoutes = __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";if($filesystem->exists($pathFrontBundleRoutes)){$configArray = Yaml::parseFile($pathFrontBundleRoutes);$configArray["controllers"]["resource"] = "../../Themes/Default/Controller";$yamlConfig = Yaml::dump($configArray);file_put_contents($pathFrontBundleRoutes, $yamlConfig);}}}}public function exportFile($records) {$heading = false;if(!empty($records))foreach($records as $row) {if(!$heading) {// display field/column names as a first rowecho implode("\t", array_keys($row)) . "\n";$heading = true;}echo implode("\t", array_values($row)) . "\n";}}public static function zipDirectory($directory, $zipName){// Get real path for our folder$rootPath = realpath($directory);// Initialize archive object$zip = new ZipArchive();$zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE);// Initialize empty "delete list"$filesToDelete = array();// Create recursive directory iterator/** @var SplFileInfo[] $files */$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootPath),RecursiveIteratorIterator::LEAVES_ONLY);foreach ($files as $name => $file){// Skip directories (they would be added automatically)if (!$file->isDir()){// Get real and relative path for current file$filePath = $file->getRealPath();$relativePath = substr($filePath, strlen($rootPath) + 1);// Add current file to archive$zip->addFile($filePath, $relativePath);// Add current file to "delete list"// delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)if ($file->getFilename() != 'important.txt'){$filesToDelete[] = $filePath;}}}// Zip archive will be created only after closing object$zip->close();return $zip;}function getAbsoluteNameMethod($input) {// Remove the "get" prefix from the input string$input = preg_replace('/^get/', '', $input);// Replace all capital letters with a space followed by the letter$output = preg_replace('/([A-Z])/', ' $1', $input);// Remove any leading or trailing spaces$output = trim($output);// Convert the first character to uppercase$output = ucfirst($output);// Return the final resultreturn $output;}public function getAllRepositoryMethods($repository){$reflectionClass = new ReflectionClass(get_class($repository));$methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);$findMethods = [];foreach ($methods as $method) {$methodName = $method->getName();if (strpos($methodName, 'export') === 0) {$findMethods[] = $methodName;}}return $findMethods;}}