src/EventSubscriber/EasyAdminSubscriber.php line 557

  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.             
  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.                     ->andWhere('JSON_CONTAINS(e.metaData, :metadataAPE) = 1  OR JSON_CONTAINS(e.metaData, :metadataNAF) = 1')
  203.                     ->setParameter("metadataAPE",'{"key": "CodeAPE"}')
  204.                     ->setParameter("metadataNAF",'{"key": "CodeNAF"}')
  205.                     ;
  206.                 foreach($entity->getFindBy() as $key => $value){
  207.                     $queryBuilder   
  208.                     ->andWhere('e.'.$key.' '.$value);
  209.                 }
  210.                 if(count($entity->getOrderBy())>0){
  211.                     foreach($entity->getOrderBy() as $key => $value){
  212.                         if(gettype($key)=="integer"){
  213.                             $queryBuilder->orderBy("e.".$value);
  214.                         }else{
  215.                             $queryBuilder->orderBy("e.".$key,$value);
  216.                         }
  217.                         
  218.                     }
  219.                     
  220.                 }
  221.                 //$queryBuilder->setMaxResults(500);
  222.                 
  223.                 $entityFetchAll $queryBuilder->getQuery()->getResult();
  224.                 
  225.                 
  226.                 
  227.                 
  228.                     
  229.             }else{
  230.                 $queryBuilder $this->doctrine->getManager()->createQueryBuilder();
  231.                 
  232.                     $queryBuilder
  233.                         ->select('e')
  234.                         ->from($entityNameSpace'e');
  235.                         //->join('e.relatedEntity', 'r')
  236.                         $queryBuilder->setMaxResults(500);
  237.                     $entityFetchAll $queryBuilder->getQuery()->getResult();
  238.             }
  239.             
  240.             
  241.             
  242.             $arrayToExport = [];
  243.             $correctedFieldsName =[];
  244.             foreach($fields as $field){
  245.                 if($field == "getMetaData"){
  246.                     continue;
  247.                 }
  248.                 
  249.                 $name $this->getAbsoluteNameMethod($field);
  250.                 $correctedFieldsName[]= $this->translatorInterface->trans($name,[],"admin");
  251.             }
  252.             foreach($entity->getMetaDataFields() as $singleField){
  253.                 $correctedFieldsName[]= $this->translatorInterface->trans($singleField,[],"admin");
  254.             }
  255.             
  256.             
  257.             
  258.             $arrayToExport[]=$correctedFieldsName;
  259.             
  260.             foreach($entityFetchAll as $singleEntityInstance){
  261.                 
  262.                 $singleRow =[];
  263.                 $singleMetaDataValue = [];
  264.                 foreach($fields as $singleField){
  265.                     $value=null;
  266.                     $valueSub=null;
  267.                     $valueParent=null;
  268.                     
  269.                     
  270.                    
  271.                     
  272.                     
  273.                         if(method_exists($singleEntityInstance,$singleField)){
  274.                             
  275.                             
  276.                             
  277.                             $value $singleEntityInstance->{$singleField}();
  278.                             
  279.                                 if($value instanceof Collection){
  280.                                     $value implode("\n"$value->toArray());
  281.                                     //dd($value);
  282.                                 }elseif(is_array($value)){
  283.                                     
  284.                                     if($singleField == "getMetaData"){
  285.                                         
  286.                                         
  287.                                         foreach($entity->getMetaDataFields() as $singleField){
  288.                                             $singleMetaDataValue[] = $this->getMetaDataValue($value,$singleField);
  289.                                             continue;
  290.                                         }
  291.                                         continue;
  292.                                     
  293.                                     foreach($value as $k=>$v){
  294.                                         if(in_array($k,$entity->getMetaDataFields())){
  295.                                                 dd($k);
  296.                                                 $singleMetaDataValue[]=$v["value"];
  297.                                                 
  298.                                         }else
  299.                                         dd("None");
  300.                                             
  301.                                             
  302.                                             
  303.                                             
  304.                                         }
  305.                                         
  306.                                         continue;
  307.                                     }
  308.                                     
  309.                                     
  310.                                     $value $this->implode_multidimensional($value,"\n");
  311.                                     
  312.                                 }elseif(gettype($value) == "string"){
  313.                                     $value $this->translatorInterface->trans($value);
  314.                                 }
  315.                             
  316.     
  317.                         }elseif(method_exists($entityRepository,$singleField)){
  318.                             $value $entityRepository->{$singleField}($singleEntityInstance->getId());
  319.                             
  320.                         
  321.                             if(is_array($value)){
  322.                                 
  323.                                 // find the index of the value 'orange'
  324.                                 $field $this->getAbsoluteNameMethod($singleField);
  325.                                
  326.                                 $translatedField $this->translatorInterface->trans($field);
  327.                                 $index array_search($translatedField$arrayToExport[0]);
  328.                                 // if the value exists in the array, remove it
  329.                                 if ($index !== false) {
  330.                                     unset($arrayToExport[0][$index]);
  331.                                 }
  332.                                 // re-index the array
  333.                                 //$arrayToExport = array_values($arrayToExport[0]);
  334.                                // dd($value);
  335.                                 
  336.                                 foreach($value as $singleData){
  337.                                     $translatedKey $this->translatorInterface->trans($singleData["key"]);
  338.                                     if(!in_array($translatedKey,$arrayToExport[0])){
  339.                                         
  340.                                         $arrayToExport[0][] = $this->translatorInterface->trans($translatedKey);
  341.                                     }
  342.                                     
  343.                                     $singleRow[]=$singleData["value"];
  344.                                 }
  345.                                 
  346.                                 continue;
  347.                             }else{
  348.                                 $value $this->translatorInterface->trans($value);
  349.                             }
  350.                         }
  351.                         $singleRow[]=$value;
  352.                     
  353.                     
  354.                 }
  355.                 
  356.                 
  357.                 
  358.                 
  359.                 foreach($singleMetaDataValue  as $singleMetaDataVal){
  360.                     //dd($singleMetaDataVal);
  361.                     if(is_array($singleMetaDataVal)){
  362.                         
  363.                         $singleRow[] = $this->implode_multidimensional($singleMetaDataVal,", ");
  364.                         continue;
  365.                     }
  366.                     $singleRow[] = $singleMetaDataVal;
  367.                 }
  368.                 $arrayToExport[]=$singleRow;
  369.                 //dd($arrayToExport);
  370.             }
  371.             //dd($arrayToExport);
  372.             
  373.             
  374.             
  375.             
  376.             $mySpreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
  377.             $mySpreadsheet->removeSheetByIndex(0);
  378.             $worksheet1 = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($mySpreadsheet"List Produits");
  379.             $mySpreadsheet->addSheet($worksheet10);
  380.             $worksheet1->fromArray($arrayToExport,null,"A1");
  381.             // Set the auto filter to cover all the data
  382.             $lastColumn $worksheet1->getHighestColumn();
  383.             $lastRow $worksheet1->getHighestDataRow();
  384.             $range "A1:$lastColumn$lastRow";
  385.             $worksheet1->setAutoFilter($range);
  386.             foreach ($worksheet1->getColumnIterator() as $column)
  387.                 {
  388.                     $worksheet1->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
  389.                     
  390.                     
  391.                 }
  392.                 foreach ($worksheet1->getRowIterator() as $row) {
  393.                     foreach ($row->getCellIterator() as $cell) {
  394.                         $cell->getStyle()->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
  395.                     }
  396.                 }
  397.                 $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($mySpreadsheet);
  398.                 
  399.                 $parts explode("\\"$entityNameSpace);
  400.                 $nameOfFile end($parts);
  401.                 $nameOfFile strtolower($nameOfFile)."-".$entity->getCreatedAt()->format("Y-m-d-H-i");
  402.                 //echo $lastWord; // output: CategoryProduct
  403.                 $settings $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  404.                 $assetFolderName $settings->getAssetFolderName();
  405.                 $assetFolderName strtolower($assetFolderName);
  406.                 $writer->save("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");
  407.                 
  408.                 $entity->setGeneratedFilePath("uploads/".$assetFolderName."/exports/".$nameOfFile.".xlsx");
  409.                 $entity->setEntityNameSpace($entityNameSpace);
  410.         
  411.             
  412.         }
  413.                 if ($entity instanceof User) {
  414.                     
  415.                    $entity->setPassword(
  416.                    $this->passwordEncoder->hashPassword(
  417.                             $entity,
  418.                             $entity->getPassword()
  419.                 ));
  420.                 
  421.             
  422.             
  423.             
  424.                 
  425.         }
  426.     }
  427.     public function beforeUpdated(BeforeEntityUpdatedEvent $event)
  428.     {
  429.         $entity $event->getEntityInstance();
  430.         
  431.         if($entity instanceof Settings){
  432.             $filesystem = new Filesystem();
  433.             $pathFrontBundle __DIR__."/../Flexy/FrontBundle";
  434.             $themePath $pathFrontBundle."/Themes";
  435.             if($entity->getFrontTheme()){
  436.                 $entity->setAssetFolderName($entity->getFrontTheme()->getName());
  437.                 if(!$filesystem->exists(__DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()))){
  438.                     $filesystem->symlink($themePath."/".$entity->getFrontTheme()->getName()."/assets"__DIR__."/../../public/themes/".strtolower($entity->getFrontTheme()->getName()));
  439.                 }
  440.                
  441.             }
  442.             
  443.             
  444.             $path __DIR__."/../../public/uploads/".$entity->getAssetFolderName();
  445.             if(!$filesystem->exists($path) )
  446.             {
  447.                 $filesystem->mkdir($path,0777);
  448.                 $filesystem->mkdir($path."/pages",0777);
  449.                 $filesystem->mkdir($path."/shop",0777);
  450.                 
  451.             }
  452.             
  453.             $pathFrontBundleRoutes __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";
  454.             if($filesystem->exists($pathFrontBundleRoutes)){
  455.                 $configArray Yaml::parseFile($pathFrontBundleRoutes);
  456.                 $configArray["controllers"]["resource"] = "../../Themes/".ucfirst($entity->getAssetFolderName())."/Controller";
  457.                 
  458.                 $yamlConfig Yaml::dump($configArray);
  459.                 file_put_contents($pathFrontBundleRoutes$yamlConfig);
  460.             }
  461.             
  462.         }
  463.       
  464.    
  465.      
  466.     }
  467.     public function beforeDelete(BeforeEntityDeletedEvent $event){
  468.         $entity $event->getEntityInstance();
  469.         if($entity instanceof FrontTheme){
  470.             //$entity->getSettings()->setFrontTheme(null);
  471.             $filesystem = new Filesystem();
  472.             //dd(__DIR__."/../../");
  473.             $pathFrontBundle __DIR__."/../Flexy/FrontBundle";
  474.             
  475.             $themePath $pathFrontBundle."/Themes";
  476.             if($filesystem->exists($themePath."/".ucfirst($entity->getName()) ) ){
  477.             
  478.             $this->zipDirectory($themePath."/".ucfirst($entity->getName()),__DIR__."/../../public/archive-themes/".strtolower($entity->getName()).".zip" );
  479.             
  480.             $filesystem->remove($themePath."/".ucfirst($entity->getName()));
  481.             
  482.                 
  483.                 
  484.             
  485.                
  486.             }
  487.             
  488.             //$filesystem->remove($pathFrontBundle."/Resources/public/assets/".strtolower($entity->getName()));
  489.             $settings $this->doctrine->getManager()->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  490.             $currentTheme $settings->getAssetFolderName();
  491.             $entity->removeSetting($settings);
  492.             $settings->setAssetFolderName("Default");
  493.             $this->doctrine->getManager()->persist($settings);
  494.             if(strtolower($entity->getName()) == strtolower($currentTheme) ){
  495.                 $pathFrontBundleRoutes __DIR__."/../Flexy/FrontBundle/Resources/config/routes.yaml";
  496.                 if($filesystem->exists($pathFrontBundleRoutes)){
  497.                     $configArray Yaml::parseFile($pathFrontBundleRoutes);
  498.     
  499.                     $configArray["controllers"]["resource"] = "../../Themes/Default/Controller";
  500.                     
  501.     
  502.                     $yamlConfig Yaml::dump($configArray);
  503.     
  504.                     file_put_contents($pathFrontBundleRoutes$yamlConfig);
  505.                 }
  506.             }
  507.             
  508.         }
  509.        
  510.     }
  511.     public function  exportFile($records) {
  512.         $heading false;
  513.             if(!empty($records))
  514.               foreach($records as $row) {
  515.                 if(!$heading) {
  516.                   // display field/column names as a first row
  517.                   echo implode("\t"array_keys($row)) . "\n";
  518.                   $heading true;
  519.                 }
  520.                 echo implode("\t"array_values($row)) . "\n";
  521.             }
  522.         
  523.     }
  524.     public static function zipDirectory($directory$zipName)
  525. {
  526.     // Get real path for our folder
  527. $rootPath realpath($directory);
  528. // Initialize archive object
  529. $zip = new ZipArchive();
  530. $zip->open($zipNameZipArchive::CREATE ZipArchive::OVERWRITE);
  531. // Initialize empty "delete list"
  532. $filesToDelete = array();
  533. // Create recursive directory iterator
  534. /** @var SplFileInfo[] $files */
  535. $files = new RecursiveIteratorIterator(
  536.     new RecursiveDirectoryIterator($rootPath),
  537.     RecursiveIteratorIterator::LEAVES_ONLY
  538. );
  539. foreach ($files as $name => $file)
  540. {
  541.     // Skip directories (they would be added automatically)
  542.     if (!$file->isDir())
  543.     {
  544.         // Get real and relative path for current file
  545.         $filePath $file->getRealPath();
  546.         $relativePath substr($filePathstrlen($rootPath) + 1);
  547.         // Add current file to archive
  548.         $zip->addFile($filePath$relativePath);
  549.         // Add current file to "delete list"
  550.         // delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)
  551.         if ($file->getFilename() != 'important.txt')
  552.         {
  553.             $filesToDelete[] = $filePath;
  554.         }
  555.     }
  556. }
  557. // Zip archive will be created only after closing object
  558. $zip->close();
  559. return $zip;
  560. }
  561. function getAbsoluteNameMethod($input) {
  562.     // Remove the "get" prefix from the input string
  563.   $input preg_replace('/^get/'''$input);
  564.   
  565.   // Replace all capital letters with a space followed by the letter
  566.   $output preg_replace('/([A-Z])/'' $1'$input);
  567.   
  568.   // Remove any leading or trailing spaces
  569.   $output trim($output);
  570.   
  571.   // Convert the first character to uppercase
  572.   $output ucfirst($output);
  573.   
  574.   // Return the final result
  575.   return $output;
  576.   }
  577.   public function getAllRepositoryMethods($repository)
  578. {
  579.     $reflectionClass = new ReflectionClass(get_class($repository));
  580.     $methods $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);
  581.     $findMethods = [];
  582.     foreach ($methods as $method) {
  583.         $methodName $method->getName();
  584.         if (strpos($methodName'export') === 0) {
  585.             $findMethods[] = $methodName;
  586.         }
  587.     }
  588.     return $findMethods;
  589. }
  590. function is_multidimensional(array $array) {
  591.     foreach ($array as $element) {
  592.         if (is_array($element)) {
  593.             return true;
  594.         }
  595.     }
  596.     return false;
  597. }
  598. function implode_multidimensional(array $array$glue ', ') {
  599.     $result = [];
  600.     
  601.     foreach ($array as $key => $element) {
  602.         if (is_array($element)) {
  603.             $element $this->implode_multidimensional($element$glue);
  604.         }
  605.         //$result[] = "{$key}:{$element}";
  606.         if(!in_array("{$element}",$result)){
  607.             $result[] = "{$element}";
  608.         }
  609.         
  610.         
  611.     }
  612.     
  613.     return implode($glue$result);
  614. }
  615. public function getMetaDataValue($jsonData$searchKey)
  616.     {
  617.         
  618.         $dataArray = (array)$jsonData;
  619.         
  620.         
  621.         foreach ($dataArray as $item) {
  622.             if (isset($item['key']) && $item['key'] === $searchKey) {
  623.                 return $item['value'];
  624.             }
  625.         }
  626.         return null;
  627.     }
  628. }