<?php
namespace App\EventListener;
use App\Services\Functions;
use Pimcore\Event\Model\ElementEventInterface;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Log\ApplicationLogger;
use Symfony\Component\Messenger\MessageBusInterface;
use Carbon\Carbon;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\Attestation;
use Pimcore\Model\DataObject\LocationSource;
use Pimcore\Model\DataObject\MembershipModule;
use Pimcore\Model\WebsiteSetting;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Sabre\DAV\Client;
use Symfony\Component\Filesystem\Filesystem;
use Pimcore\Model\Asset;
use Pimcore\Model\Asset\Document;
class MembershipModuleListener
{
private $bus;
private $logger;
private $params;
private $csvPath;
public function __construct(MessageBusInterface $bus, ApplicationLogger $logger, ContainerBagInterface $params)
{
$this->csvPath = PIMCORE_PROJECT_ROOT . '/membership' . '/membership.csv';
$this->bus = $bus;
$this->logger = $logger;
$this->params = $params;
}
public function onPostAdd(ElementEventInterface $e)
{
if ($e instanceof DataObjectEvent) {
$object = $e->getObject();
if ($object instanceof MembershipModule) {
$this->updateCsv($object);
if (WebsiteSetting::getByName('enableMembershipUpload')->getData() == true) {
$this->uploadMembershipFile();
}
}
}
}
protected function uploadMembershipFile()
{
try {
$assetCsv = Asset::getByPath('/restricted-assets/membership/membership.csv');
if ($assetCsv instanceof Asset) {
$assetCsv->setData(file_get_contents($this->csvPath));
} else {
$folder = WebsiteSetting::getByName('assetMembershipFolder')->getData();
$assetCsv = new Asset();
$assetCsv->setParentId($folder->getId());
$assetCsv->setFilename('membership.csv');
$assetCsv->setData(file_get_contents($this->csvPath));
$assetCsv->setMimetype('text/csv');
}
$assetCsv->save();
} catch (\Exception $e) {
$this->logger->error($e);
}
try {
$user_webdav_url = $this->params->get('user_webdav_url');
$user_webdav_username = $this->params->get('user_webdav_username');
$user_webdav_password = $this->params->get('user_webdav_password');
$settings = array(
'baseUri' => $user_webdav_url,
'userName' => $user_webdav_username,
'password' => $user_webdav_password
);
$client = new Client($settings);
$csvContent = file_get_contents($this->csvPath);
if ($csvContent === false) {
return;
}
$client->request('PUT', 'https://webdav.opendrive.com/users/associati_portale.csv', $csvContent, [
'Content-Type' => 'text/csv'
]);
} catch (\Exception $e) {
$this->logger->error($e);
}
}
private function updateCsv(MembershipModule $object): void
{
$filesystem = new Filesystem();
$fileExists = $filesystem->exists($this->csvPath);
$header = [
'ID Oggetto', // Aggiungi ID come primo campo per identificazione univoca
'Nome Iscritto',
'Cognome Iscritto/Insegna',
'Numero Tessera',
'Modulo Adesione',
'luogo nascita',
'iscritto',
'data nascita',
'Indirizzo Iscritto',
'Citta Iscritto',
'Codice Fiscale Iscritto',
'Data richiesta',
'Data Accettazione',
'Data Scadenza',
'Quota Sociale',
'Quota Altre attività',
'Telefono 1',
'Telefono 2',
'Cellulare',
'Email',
'Provenienza'
];
$newData = [
$object->getId(), // ID univoco per identificare il record
$object->getName(),
$object->getSurname(),
'',
'Si',
$object->getBirthPlace(),
'',
$object->getBirthDate()?->format('d/m/Y'),
$object->getAddress() . ' ' . $object->getAddressNumber(),
$object->getCity(),
$object->getFiscalcode(),
Carbon::createFromTimestamp($object->getCreationDate())->format('d/m/Y'),
'',
'',
'',
'',
'',
'',
$object->getMobile(),
$object->getEmail(),
''
];
$rows = [];
$recordFound = false;
if ($fileExists) {
$handle = fopen($this->csvPath, 'r');
if ($handle === false) {
$this->logger->error('Cannot open CSV file for reading: ' . $this->csvPath);
return;
}
$existingHeader = fgetcsv($handle);
// Controlla se l'header è corretto, altrimenti aggiorna
if ($existingHeader !== $header) {
$rows[] = $header;
// Se l'header è diverso, rileggi il file senza header
if ($existingHeader !== false) {
// Se aveva un header diverso, considera la prima riga come dati
rewind($handle);
fgetcsv($handle); // Salta il vecchio header
}
} else {
$rows[] = $existingHeader;
}
// Leggi tutte le righe e cerca duplicati
while (($row = fgetcsv($handle)) !== false) {
// Controlla se il record esiste già usando l'ID (primo campo)
if (isset($row[0]) && $row[0] == $object->getId()) {
// Aggiorna il record esistente
$rows[] = $newData;
$recordFound = true;
$this->logger->info('Updated existing record for ID: ' . $object->getId());
} else {
// Controllo aggiuntivo per evitare duplicati basati su codice fiscale + email
$isDuplicate = false;
if (count($row) >= 20) { // Assicurati che la riga abbia abbastanza campi
$existingFiscalCode = $row[10] ?? ''; // Codice Fiscale Iscritto
$existingEmail = $row[18] ?? ''; // Email
if (
!empty($existingFiscalCode) && !empty($existingEmail) &&
$existingFiscalCode === $object->getFiscalcode() &&
$existingEmail === $object->getEmail()
) {
// Trovato duplicato basato su CF + Email, aggiorna invece di aggiungere
$rows[] = $newData;
$recordFound = true;
$isDuplicate = true;
$this->logger->info('Updated duplicate record based on FiscalCode+Email for ID: ' . $object->getId());
}
}
if (!$isDuplicate) {
$rows[] = $row;
}
}
}
fclose($handle);
} else {
// File non esiste, crea con header
$rows[] = $header;
}
// Aggiungi il nuovo record solo se non è stato trovato/aggiornato
if (!$recordFound) {
$rows[] = $newData;
$this->logger->info('Added new record for ID: ' . $object->getId());
}
// Assicurati che la directory esista
$directory = dirname($this->csvPath);
if (!$filesystem->exists($directory)) {
$filesystem->mkdir($directory, 0755);
}
// Scrivi il file CSV
$handle = fopen($this->csvPath, 'w');
if ($handle === false) {
$this->logger->error('Cannot open CSV file for writing: ' . $this->csvPath);
return;
}
foreach ($rows as $row) {
if (fputcsv($handle, $row) === false) {
$this->logger->error('Error writing CSV row');
break;
}
}
fclose($handle);
$this->logger->info('CSV file updated successfully: ' . $this->csvPath);
}
/**
* Metodo di utilità per pulire eventuali duplicati esistenti nel CSV
*/
public function cleanupDuplicates(): void
{
if (!file_exists($this->csvPath)) {
return;
}
$handle = fopen($this->csvPath, 'r');
if ($handle === false) {
return;
}
$header = fgetcsv($handle);
$rows = [$header];
$seenIds = [];
$seenFiscalEmailCombos = [];
while (($row = fgetcsv($handle)) !== false) {
$id = $row[0] ?? '';
$fiscalCode = $row[10] ?? '';
$email = $row[18] ?? '';
$combo = $fiscalCode . '|' . $email;
// Rimuovi duplicati basati su ID o combinazione CF+Email
if (!in_array($id, $seenIds) && !in_array($combo, $seenFiscalEmailCombos)) {
$rows[] = $row;
if (!empty($id)) $seenIds[] = $id;
if (!empty($fiscalCode) && !empty($email)) $seenFiscalEmailCombos[] = $combo;
}
}
fclose($handle);
// Riscrivi il file pulito
$handle = fopen($this->csvPath, 'w');
foreach ($rows as $row) {
fputcsv($handle, $row);
}
fclose($handle);
$this->logger->info('CSV duplicates cleaned up');
}
public function regenerateCompleteCsv(): void
{
$this->logger->info('Starting complete CSV regeneration');
$filesystem = new Filesystem();
// Assicurati che la directory esista
$directory = dirname($this->csvPath);
if (!$filesystem->exists($directory)) {
$filesystem->mkdir($directory, 0755);
}
$header = [
'ID Oggetto',
'Nome Iscritto',
'Cognome Iscritto/Insegna',
'Numero Tessera',
'Modulo Adesione',
'luogo nascita',
'iscritto',
'data nascita',
'Indirizzo Iscritto',
'Citta Iscritto',
'Codice Fiscale Iscritto',
'Data richiesta',
'Data Accettazione',
'Data Scadenza',
'Quota Sociale',
'Quota Altre attività',
'Telefono 1',
'Telefono 2',
'Cellulare',
'Email',
'Provenienza'
];
// Apri il file per scrittura (sovrascrivi completamente)
$handle = fopen($this->csvPath, 'w');
if ($handle === false) {
$this->logger->error('Cannot open CSV file for writing: ' . $this->csvPath);
return;
}
// Scrivi l'header
if (fputcsv($handle, $header) === false) {
$this->logger->error('Error writing CSV header');
fclose($handle);
return;
}
// Recupera tutti i MembershipModule
$membershipListing = new MembershipModule\Listing();
$membershipListing->setOrderKey('o_creationDate');
$membershipListing->setOrder('ASC');
$processedCount = 0;
$seenCombinations = []; // Per evitare duplicati basati su CF+Email
foreach ($membershipListing as $membership) {
if (!$membership instanceof MembershipModule) {
continue;
}
// Controlla duplicati basati su codice fiscale + email
$fiscalCode = $membership->getFiscalcode();
$email = $membership->getEmail();
$combination = $fiscalCode . '|' . $email;
if (!empty($fiscalCode) && !empty($email) && in_array($combination, $seenCombinations)) {
$this->logger->info('Skipping duplicate record for CF+Email: ' . $combination . ' (ID: ' . $membership->getId() . ')');
continue;
}
$rowData = [
$membership->getId(),
$membership->getName(),
$membership->getSurname(),
'', // Numero Tessera
'Si', // Modulo Adesione
$membership->getBirthPlace(),
'', // iscritto
$membership->getBirthDate() ? $membership->getBirthDate()->format('d/m/Y') : '',
trim(($membership->getAddress() ?: '') . ' ' . ($membership->getAddressNumber() ?: '')),
$membership->getCity(),
$fiscalCode,
Carbon::createFromTimestamp($membership->getCreationDate())->format('d/m/Y'),
'', // Data Accettazione
'', // Data Scadenza
'', // Quota Sociale
'', // Quota Altre attività
'', // Telefono 1
'', // Telefono 2
$membership->getMobile(),
$email,
'' // Provenienza
];
if (fputcsv($handle, $rowData) === false) {
$this->logger->error('Error writing CSV row for ID: ' . $membership->getId());
break;
}
// Aggiungi la combinazione ai già processati
if (!empty($fiscalCode) && !empty($email)) {
$seenCombinations[] = $combination;
}
$processedCount++;
}
fclose($handle);
$this->logger->info("CSV regeneration completed. Processed {$processedCount} records");
// Opzionalmente, carica anche l'asset se abilitato
if (WebsiteSetting::getByName('enableMembershipUpload') && WebsiteSetting::getByName('enableMembershipUpload')->getData() == true) {
$this->uploadMembershipFile();
$this->logger->info('CSV uploaded to external services');
}
}
/**
* Ottieni statistiche sul CSV corrente
*/
public function getCsvStats(): array
{
if (!file_exists($this->csvPath)) {
return [
'file_exists' => false,
'total_records' => 0,
'file_size' => 0,
'last_modified' => null
];
}
$handle = fopen($this->csvPath, 'r');
if ($handle === false) {
return ['error' => 'Cannot open CSV file'];
}
$header = fgetcsv($handle); // Salta l'header
$recordCount = 0;
while (fgetcsv($handle) !== false) {
$recordCount++;
}
fclose($handle);
return [
'file_exists' => true,
'total_records' => $recordCount,
'file_size' => filesize($this->csvPath),
'last_modified' => date('Y-m-d H:i:s', filemtime($this->csvPath)),
'file_path' => $this->csvPath
];
}
}