<?php declare(strict_types=1); /* * This file is part of vonRotenberg WMFGO Cevisio Bundle. * * (c) vonRotenberg * * @license proprietary */ namespace vonRotenberg\AldegottSwNlBundle\Cron; use Contao\Config; use Contao\CoreBundle\Controller\AbstractController; use Contao\Date; use Contao\StringUtil; use Contao\System; use Contao\Validator; use Doctrine\DBAL\Connection; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Finder\Finder; use Symfony\Component\Serializer\Encoder\CsvEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; use vonRotenberg\ShopwareApiBundle\API\Shopware; use vonRotenberg\ShopwareApiBundle\Helper\ShopwareMappings; use vonRotenberg\AldegottSwNlBundle\Model\Import\ProductModel; class ShopwareExportNewsletterJob extends AbstractController { /** @var LoggerInterface */ private $logger; /** @var SerializerInterface */ private $serializer; /** @var Shopware */ private $shopware; /** @var ShopwareMappings */ private $mappings; private $csvContext = []; /** @var Finder */ private $finder; /** @var Connection */ private $db; /** * Remote * @var Connection */ private $rdb; public function __construct(Finder $finder, Shopware $shopware, ShopwareMappings $mappings, Connection $db, LoggerInterface $logger) { $this->finder = $finder; $this->db = $db; $this->logger = $logger; $this->shopware = $shopware; $this->mappings = $mappings; $encoder = [new CsvEncoder()]; $normalizer = [new ObjectNormalizer()]; $this->serializer = new Serializer($normalizer,$encoder); $this->csvContext = [ 'csv_delimiter' => ';', 'csv_enclosure' => '"', 'no_headers' => true ]; } public function export(string $scope, ?string $start=null, ?string $stop=null, ?string $email, ?SymfonyStyle &$io = null): void { $intCounter = 0; $isCli = false; if (strtolower($scope) == 'cli' && $io !== null) { $isCli = true; } $translator = System::getContainer()->get('translator'); $translator->setLocale('de'); // date_default_timezone_set('Europe/Berlin'); $projectDir = System::getContainer()->getParameter('kernel.project_dir'); $srcDir = $projectDir.'/export/newsletter_recipients'; if (!file_exists($srcDir)) { mkdir($srcDir, 0777,true); } $Today = new Date(); if (($start || $stop) && ($start === null || $stop === null)) { return; } // Set working period if ($start && $stop) { $StartDate = new Date($start,'Y-m-d'); $StopDate = new Date($stop,'Y-m-d'); $intStart = $StartDate->dayBegin; $intEnd = $StopDate->dayEnd; } else { $WorkingDate = new Date($Today->dayBegin); $intStart = strtotime(date('Y-m-d',$WorkingDate->dayBegin) . ' -1 day'); $intEnd = $WorkingDate->dayBegin; } if ($isCli) { $io->definitionList('Using export timeframe:',['Start'=>Date::parse(Date::getNumericDateFormat(),$intStart)],['End'=>Date::parse(Date::getNumericDateFormat(),$intEnd)]); } $arrBody = [ 'filter' => [ [ 'type'=> 'range', 'field'=> 'createdAt', 'parameters'=> [ 'gte'=> date(\DateTime::ATOM,$intStart), 'lte'=> date(\DateTime::ATOM,$intEnd), ], ], [ 'type'=> 'equals', 'field'=> 'status', 'value'=> 'optIn' ] ], ]; $Response = $this->shopware->queryAPI('search/newsletter-recipient',$arrBody,'POST',true); if ($Response->getStatusCode() !== 200 || !json_validate($Response->getContent())) { if ($isCli) $io->error('Could not export newsletter recipients'); dump($Response->getContent(false)); } $Content = json_decode($Response->getContent(), true); $arrCSV = [ [ 'email', 'firstName', 'lastName', 'status', 'confirmedAt' ] ]; foreach ($Content['data'] as $recipient) { $arrCSV[] = [ $recipient['email'], $recipient['firstName'], $recipient['lastName'], $recipient['status'], $recipient['confirmedAt'] ]; } $strRandomPrefix = (!empty($email) && Validator::isEmail($email) ? substr(md5(uniqid()), 0, 10) . '_' : ''); $filename = $srcDir . '/' . $strRandomPrefix . 'recipients_' . date("Ymd", $intStart) . '_' . date("Ymd", $intEnd) . '.csv'; \file_put_contents($filename, $this->serializer->encode($arrCSV, 'csv', $this->csvContext)); // If email is provided, send the CSV file if (!empty($email) && Validator::isEmail($email)) { list($fromName,$fromMail) = StringUtil::splitFriendlyEmail(Config::get('adminEmail')); $mailer = System::getContainer()->get('mailer'); $emailMessage = (new \Symfony\Component\Mime\Email()) ->from($fromMail) // Change this to your desired "from" address ->to($email) ->subject('Newsletter Export') ->text('Attached is the exported list of newsletter recipients.') ->attachFromPath($filename, str_replace($strRandomPrefix,'',basename($filename)), 'text/csv'); try { $mailer->send($emailMessage); // Delete the file after sending the email if (file_exists($filename)) { unlink($filename); } if ($isCli) { $io->success('CSV file has been successfully sent to ' . $email); } } catch (\Exception $e) { if ($isCli) { $io->error('Failed to send email: ' . $e->getMessage()); } $this->logger->error('Failed to send the email with the CSV file.', ['exception' => $e]); } } } }