src/EventListener/MembershipModuleListener.php line 37

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use App\Services\Functions;
  4. use Pimcore\Event\Model\ElementEventInterface;
  5. use Pimcore\Event\Model\DataObjectEvent;
  6. use Pimcore\Log\ApplicationLogger;
  7. use Symfony\Component\Messenger\MessageBusInterface;
  8. use Carbon\Carbon;
  9. use Pimcore\Model\DataObject;
  10. use Pimcore\Model\DataObject\Attestation;
  11. use Pimcore\Model\DataObject\LocationSource;
  12. use Pimcore\Model\DataObject\MembershipModule;
  13. use Pimcore\Model\WebsiteSetting;
  14. use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
  15. use Sabre\DAV\Client;
  16. use Symfony\Component\Filesystem\Filesystem;
  17. use Pimcore\Model\Asset;
  18. use Pimcore\Model\Asset\Document;
  19. class MembershipModuleListener
  20. {
  21.     private $bus;
  22.     private $logger;
  23.     private $params;
  24.     private $csvPath;
  25.     public function __construct(MessageBusInterface $busApplicationLogger $loggerContainerBagInterface $params)
  26.     {
  27.         $this->csvPath PIMCORE_PROJECT_ROOT '/membership' '/membership.csv';
  28.         $this->bus $bus;
  29.         $this->logger $logger;
  30.         $this->params $params;
  31.     }
  32.     public function onPostAdd(ElementEventInterface $e)
  33.     {
  34.         if ($e instanceof DataObjectEvent) {
  35.             $object $e->getObject();
  36.             if ($object instanceof MembershipModule) {
  37.                 $this->updateCsv($object);
  38.                 if (WebsiteSetting::getByName('enableMembershipUpload')->getData() == true) {
  39.                     $this->uploadMembershipFile();
  40.                 }
  41.             }
  42.         }
  43.     }
  44.     protected function uploadMembershipFile()
  45.     {
  46.         try {
  47.             $assetCsv Asset::getByPath('/restricted-assets/membership/membership.csv');
  48.             if ($assetCsv instanceof Asset) {
  49.                 $assetCsv->setData(file_get_contents($this->csvPath));
  50.             } else {
  51.                 $folder WebsiteSetting::getByName('assetMembershipFolder')->getData();
  52.                 $assetCsv = new Asset();
  53.                 $assetCsv->setParentId($folder->getId());
  54.                 $assetCsv->setFilename('membership.csv');
  55.                 $assetCsv->setData(file_get_contents($this->csvPath));
  56.                 $assetCsv->setMimetype('text/csv');
  57.             }
  58.             $assetCsv->save();
  59.         } catch (\Exception $e) {
  60.             $this->logger->error($e);
  61.         }
  62.         try {
  63.             $user_webdav_url $this->params->get('user_webdav_url');
  64.             $user_webdav_username $this->params->get('user_webdav_username');
  65.             $user_webdav_password $this->params->get('user_webdav_password');
  66.             $settings = array(
  67.                 'baseUri' => $user_webdav_url,
  68.                 'userName' => $user_webdav_username,
  69.                 'password' => $user_webdav_password
  70.             );
  71.             $client = new Client($settings);
  72.             $csvContent file_get_contents($this->csvPath);
  73.             if ($csvContent === false) {
  74.                 return;
  75.             }
  76.             $client->request('PUT''https://webdav.opendrive.com/users/associati_portale.csv'$csvContent, [
  77.                 'Content-Type' => 'text/csv'
  78.             ]);
  79.         } catch (\Exception $e) {
  80.             $this->logger->error($e);
  81.         }
  82.     }
  83.     private function updateCsv(MembershipModule $object): void
  84.     {
  85.         $filesystem = new Filesystem();
  86.         $fileExists $filesystem->exists($this->csvPath);
  87.         $header = [
  88.             'ID Oggetto'// Aggiungi ID come primo campo per identificazione univoca
  89.             'Nome Iscritto',
  90.             'Cognome Iscritto/Insegna',
  91.             'Numero Tessera',
  92.             'Modulo Adesione',
  93.             'luogo nascita',
  94.             'iscritto',
  95.             'data nascita',
  96.             'Indirizzo Iscritto',
  97.             'Citta Iscritto',
  98.             'Codice Fiscale Iscritto',
  99.             'Data richiesta',
  100.             'Data Accettazione',
  101.             'Data Scadenza',
  102.             'Quota Sociale',
  103.             'Quota Altre attività',
  104.             'Telefono 1',
  105.             'Telefono 2',
  106.             'Cellulare',
  107.             'Email',
  108.             'Provenienza'
  109.         ];
  110.         $newData = [
  111.             $object->getId(), // ID univoco per identificare il record
  112.             $object->getName(),
  113.             $object->getSurname(),
  114.             '',
  115.             'Si',
  116.             $object->getBirthPlace(),
  117.             '',
  118.             $object->getBirthDate()?->format('d/m/Y'),
  119.             $object->getAddress() . ' ' $object->getAddressNumber(),
  120.             $object->getCity(),
  121.             $object->getFiscalcode(),
  122.             Carbon::createFromTimestamp($object->getCreationDate())->format('d/m/Y'),
  123.             '',
  124.             '',
  125.             '',
  126.             '',
  127.             '',
  128.             '',
  129.             $object->getMobile(),
  130.             $object->getEmail(),
  131.             ''
  132.         ];
  133.         $rows = [];
  134.         $recordFound false;
  135.         if ($fileExists) {
  136.             $handle fopen($this->csvPath'r');
  137.             if ($handle === false) {
  138.                 $this->logger->error('Cannot open CSV file for reading: ' $this->csvPath);
  139.                 return;
  140.             }
  141.             $existingHeader fgetcsv($handle);
  142.             // Controlla se l'header è corretto, altrimenti aggiorna
  143.             if ($existingHeader !== $header) {
  144.                 $rows[] = $header;
  145.                 // Se l'header è diverso, rileggi il file senza header
  146.                 if ($existingHeader !== false) {
  147.                     // Se aveva un header diverso, considera la prima riga come dati
  148.                     rewind($handle);
  149.                     fgetcsv($handle); // Salta il vecchio header
  150.                 }
  151.             } else {
  152.                 $rows[] = $existingHeader;
  153.             }
  154.             // Leggi tutte le righe e cerca duplicati
  155.             while (($row fgetcsv($handle)) !== false) {
  156.                 // Controlla se il record esiste già usando l'ID (primo campo)
  157.                 if (isset($row[0]) && $row[0] == $object->getId()) {
  158.                     // Aggiorna il record esistente
  159.                     $rows[] = $newData;
  160.                     $recordFound true;
  161.                     $this->logger->info('Updated existing record for ID: ' $object->getId());
  162.                 } else {
  163.                     // Controllo aggiuntivo per evitare duplicati basati su codice fiscale + email
  164.                     $isDuplicate false;
  165.                     if (count($row) >= 20) { // Assicurati che la riga abbia abbastanza campi
  166.                         $existingFiscalCode $row[10] ?? ''// Codice Fiscale Iscritto
  167.                         $existingEmail $row[18] ?? ''// Email
  168.                         if (
  169.                             !empty($existingFiscalCode) && !empty($existingEmail) &&
  170.                             $existingFiscalCode === $object->getFiscalcode() &&
  171.                             $existingEmail === $object->getEmail()
  172.                         ) {
  173.                             // Trovato duplicato basato su CF + Email, aggiorna invece di aggiungere
  174.                             $rows[] = $newData;
  175.                             $recordFound true;
  176.                             $isDuplicate true;
  177.                             $this->logger->info('Updated duplicate record based on FiscalCode+Email for ID: ' $object->getId());
  178.                         }
  179.                     }
  180.                     if (!$isDuplicate) {
  181.                         $rows[] = $row;
  182.                     }
  183.                 }
  184.             }
  185.             fclose($handle);
  186.         } else {
  187.             // File non esiste, crea con header
  188.             $rows[] = $header;
  189.         }
  190.         // Aggiungi il nuovo record solo se non è stato trovato/aggiornato
  191.         if (!$recordFound) {
  192.             $rows[] = $newData;
  193.             $this->logger->info('Added new record for ID: ' $object->getId());
  194.         }
  195.         // Assicurati che la directory esista
  196.         $directory dirname($this->csvPath);
  197.         if (!$filesystem->exists($directory)) {
  198.             $filesystem->mkdir($directory0755);
  199.         }
  200.         // Scrivi il file CSV
  201.         $handle fopen($this->csvPath'w');
  202.         if ($handle === false) {
  203.             $this->logger->error('Cannot open CSV file for writing: ' $this->csvPath);
  204.             return;
  205.         }
  206.         foreach ($rows as $row) {
  207.             if (fputcsv($handle$row) === false) {
  208.                 $this->logger->error('Error writing CSV row');
  209.                 break;
  210.             }
  211.         }
  212.         fclose($handle);
  213.         $this->logger->info('CSV file updated successfully: ' $this->csvPath);
  214.     }
  215.     /**
  216.      * Metodo di utilità per pulire eventuali duplicati esistenti nel CSV
  217.      */
  218.     public function cleanupDuplicates(): void
  219.     {
  220.         if (!file_exists($this->csvPath)) {
  221.             return;
  222.         }
  223.         $handle fopen($this->csvPath'r');
  224.         if ($handle === false) {
  225.             return;
  226.         }
  227.         $header fgetcsv($handle);
  228.         $rows = [$header];
  229.         $seenIds = [];
  230.         $seenFiscalEmailCombos = [];
  231.         while (($row fgetcsv($handle)) !== false) {
  232.             $id $row[0] ?? '';
  233.             $fiscalCode $row[10] ?? '';
  234.             $email $row[18] ?? '';
  235.             $combo $fiscalCode '|' $email;
  236.             // Rimuovi duplicati basati su ID o combinazione CF+Email
  237.             if (!in_array($id$seenIds) && !in_array($combo$seenFiscalEmailCombos)) {
  238.                 $rows[] = $row;
  239.                 if (!empty($id)) $seenIds[] = $id;
  240.                 if (!empty($fiscalCode) && !empty($email)) $seenFiscalEmailCombos[] = $combo;
  241.             }
  242.         }
  243.         fclose($handle);
  244.         // Riscrivi il file pulito
  245.         $handle fopen($this->csvPath'w');
  246.         foreach ($rows as $row) {
  247.             fputcsv($handle$row);
  248.         }
  249.         fclose($handle);
  250.         $this->logger->info('CSV duplicates cleaned up');
  251.     }
  252.     public function regenerateCompleteCsv(): void
  253.     {
  254.         $this->logger->info('Starting complete CSV regeneration');
  255.         $filesystem = new Filesystem();
  256.         // Assicurati che la directory esista
  257.         $directory dirname($this->csvPath);
  258.         if (!$filesystem->exists($directory)) {
  259.             $filesystem->mkdir($directory0755);
  260.         }
  261.         $header = [
  262.             'ID Oggetto',
  263.             'Nome Iscritto',
  264.             'Cognome Iscritto/Insegna',
  265.             'Numero Tessera',
  266.             'Modulo Adesione',
  267.             'luogo nascita',
  268.             'iscritto',
  269.             'data nascita',
  270.             'Indirizzo Iscritto',
  271.             'Citta Iscritto',
  272.             'Codice Fiscale Iscritto',
  273.             'Data richiesta',
  274.             'Data Accettazione',
  275.             'Data Scadenza',
  276.             'Quota Sociale',
  277.             'Quota Altre attività',
  278.             'Telefono 1',
  279.             'Telefono 2',
  280.             'Cellulare',
  281.             'Email',
  282.             'Provenienza'
  283.         ];
  284.         // Apri il file per scrittura (sovrascrivi completamente)
  285.         $handle fopen($this->csvPath'w');
  286.         if ($handle === false) {
  287.             $this->logger->error('Cannot open CSV file for writing: ' $this->csvPath);
  288.             return;
  289.         }
  290.         // Scrivi l'header
  291.         if (fputcsv($handle$header) === false) {
  292.             $this->logger->error('Error writing CSV header');
  293.             fclose($handle);
  294.             return;
  295.         }
  296.         // Recupera tutti i MembershipModule
  297.         $membershipListing = new MembershipModule\Listing();
  298.         $membershipListing->setOrderKey('o_creationDate');
  299.         $membershipListing->setOrder('ASC');
  300.         $processedCount 0;
  301.         $seenCombinations = []; // Per evitare duplicati basati su CF+Email
  302.         foreach ($membershipListing as $membership) {
  303.             if (!$membership instanceof MembershipModule) {
  304.                 continue;
  305.             }
  306.             // Controlla duplicati basati su codice fiscale + email
  307.             $fiscalCode $membership->getFiscalcode();
  308.             $email $membership->getEmail();
  309.             $combination $fiscalCode '|' $email;
  310.             if (!empty($fiscalCode) && !empty($email) && in_array($combination$seenCombinations)) {
  311.                 $this->logger->info('Skipping duplicate record for CF+Email: ' $combination ' (ID: ' $membership->getId() . ')');
  312.                 continue;
  313.             }
  314.             $rowData = [
  315.                 $membership->getId(),
  316.                 $membership->getName(),
  317.                 $membership->getSurname(),
  318.                 ''// Numero Tessera
  319.                 'Si'// Modulo Adesione
  320.                 $membership->getBirthPlace(),
  321.                 ''// iscritto
  322.                 $membership->getBirthDate() ? $membership->getBirthDate()->format('d/m/Y') : '',
  323.                 trim(($membership->getAddress() ?: '') . ' ' . ($membership->getAddressNumber() ?: '')),
  324.                 $membership->getCity(),
  325.                 $fiscalCode,
  326.                 Carbon::createFromTimestamp($membership->getCreationDate())->format('d/m/Y'),
  327.                 ''// Data Accettazione
  328.                 ''// Data Scadenza
  329.                 ''// Quota Sociale
  330.                 ''// Quota Altre attività
  331.                 ''// Telefono 1
  332.                 ''// Telefono 2
  333.                 $membership->getMobile(),
  334.                 $email,
  335.                 '' // Provenienza
  336.             ];
  337.             if (fputcsv($handle$rowData) === false) {
  338.                 $this->logger->error('Error writing CSV row for ID: ' $membership->getId());
  339.                 break;
  340.             }
  341.             // Aggiungi la combinazione ai già processati
  342.             if (!empty($fiscalCode) && !empty($email)) {
  343.                 $seenCombinations[] = $combination;
  344.             }
  345.             $processedCount++;
  346.         }
  347.         fclose($handle);
  348.         $this->logger->info("CSV regeneration completed. Processed {$processedCount} records");
  349.         // Opzionalmente, carica anche l'asset se abilitato
  350.         if (WebsiteSetting::getByName('enableMembershipUpload') && WebsiteSetting::getByName('enableMembershipUpload')->getData() == true) {
  351.             $this->uploadMembershipFile();
  352.             $this->logger->info('CSV uploaded to external services');
  353.         }
  354.     }
  355.     /**
  356.      * Ottieni statistiche sul CSV corrente
  357.      */
  358.     public function getCsvStats(): array
  359.     {
  360.         if (!file_exists($this->csvPath)) {
  361.             return [
  362.                 'file_exists' => false,
  363.                 'total_records' => 0,
  364.                 'file_size' => 0,
  365.                 'last_modified' => null
  366.             ];
  367.         }
  368.         $handle fopen($this->csvPath'r');
  369.         if ($handle === false) {
  370.             return ['error' => 'Cannot open CSV file'];
  371.         }
  372.         $header fgetcsv($handle); // Salta l'header
  373.         $recordCount 0;
  374.         while (fgetcsv($handle) !== false) {
  375.             $recordCount++;
  376.         }
  377.         fclose($handle);
  378.         return [
  379.             'file_exists' => true,
  380.             'total_records' => $recordCount,
  381.             'file_size' => filesize($this->csvPath),
  382.             'last_modified' => date('Y-m-d H:i:s'filemtime($this->csvPath)),
  383.             'file_path' => $this->csvPath
  384.         ];
  385.     }
  386. }