<?php declare(strict_types=1);
namespace EmcgnGewerbeschein\Resources\Subscriber;
use Shopware\Core\Content\Media\File\FileSaver;
use Shopware\Core\Content\Media\File\MediaFile;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Context;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Checkout\Customer\CustomerEvents;
class TradelicenseData implements EventSubscriberInterface
{
private $fileSaver;
private $mediaRepository;
private $mediaFolderRepository;
private $gewerbescheinRepository;
public function __construct(
FileSaver $fileSaver,
EntityRepositoryInterface $mediaRepository,
EntityRepositoryInterface $mediaFolderRepository,
EntityRepositoryInterface $gewerbescheinRepository
)
{
$this->fileSaver = $fileSaver;
$this->mediaRepository = $mediaRepository;
$this->mediaFolderRepository = $mediaFolderRepository;
$this->gewerbescheinRepository = $gewerbescheinRepository;
}
public static function getSubscribedEvents(): array
{
return [
CustomerEvents::CUSTOMER_WRITTEN_EVENT => 'handleTradeLicense',
];
}
/**
* Create new database entry in relation and media table
* Upload file to server
*
* @param EntityWrittenEvent $event
* @return bool
*/
public function handleTradeLicense(EntityWrittenEvent $event)
{
if(!empty($_FILES['emcgnTradeLicense']['name'][0])){
$files = $this->reFilesArray($_FILES['emcgnTradeLicense']);
/* ID des Kunden ermitteln */
$customerId = $event->getIds();
$customerId = $customerId[0];
/* Anhand der CustomerId ermitteln, ob schon ein Eintrag exisitert */
$tradeLicenseIds = $this->getEntryIds($customerId, $event->getContext());
/* Wenn Eintrag existiert -> löschen & File löschen */
if(!empty($tradeLicenseIds)){
/* FileId anhand von KundenId ermitteln */
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customerId', $customerId));
$oldMediaEntries = $this->gewerbescheinRepository->search($criteria, $event->getContext());
/* DB-Einträge löschen */
foreach($tradeLicenseIds as $tradeLicenseId){
$this->gewerbescheinRepository->delete(
[
[ 'id' => $tradeLicenseId ]
], $event->getContext()
);
}
/* Files löschen */
foreach($oldMediaEntries as $oldMediaEntry){
$this->mediaRepository->delete(
[
[ 'id' => $oldMediaEntry->getFileId() ]
], $event->getContext()
);
}
}
foreach($files as $file){
$filename = Uuid::randomHex();
$filetype = $file['type'];
$fileext = pathinfo($file['name'], PATHINFO_EXTENSION);
$filetmp = $file['tmp_name'];
$filesize = $file['size'];
/* Wenn Datei keine .pdf order .jpeg Datei, Prozess beenden */
$allowedTypes = array('application/pdf', 'image/jpeg');
if(in_array($filetype, $allowedTypes)){
/* Mediendatei aus Datei erstellen */
$mediaFile = new MediaFile(
$filetmp,
$filetype,
$fileext,
$filesize
);
/* MedienordnerID ermitteln und Datei in Datenbank schreiben */
$mediaId = $this->createMediaInFolder('Emcgn_Trade_Licenses', $event->getContext(), false);
/* Datei auf dem Server ablegen */
$this->fileSaver->persistFileToMedia($mediaFile, $filename, $mediaId, $event->getContext());
/* ID der hochgeladenen Datei ermitteln */
$fileId = $this->getMediafileId($filename, $event->getContext());
/* Datenbankeintrag erstellen */
$this->gewerbescheinRepository->create(
[
[ 'fileId' => $fileId, 'customerId' => $customerId ]
], $event->getContext()
);
}
}
}
return true;
}
/**
* Creates media on server
* @param string $folder
* @param Context $context
* @param bool $private
* @return string
*/
private function createMediaInFolder(string $folder, Context $context, bool $private = true): string
{
$mediaId = Uuid::randomHex();
$this->mediaRepository->create(
[
[
'id' => $mediaId,
'private' => $private,
'mediaFolderId' => $this->getMediaFolderId($folder, $context),
],
],
$context
);
return $mediaId;
}
/**
* Get ID of custom folder
* @param string $folder
* @param Context $context
* @return string
*/
private function getMediaFolderId(string $folder, Context $context): ?string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('media_folder.name', $folder));
$criteria->setLimit(1);
$customFolder = $this->mediaFolderRepository->search($criteria, $context);
$customFolderId = null;
if ($customFolder->count() === 1) {
$customFolderId = $customFolder->first()->getId();
}
return $customFolderId;
}
/**
* Get ID of media file
* @param string $filename
* @param Context $context
* @return string
*/
private function getMediafileId(string $filename, Context $context)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('fileName', $filename));
$criteria->setLimit(1);
$fileId = $this->mediaRepository->searchIds($criteria, $context)->getIds();
return $fileId[0];
}
/**
* Get ID of trade license table-entry
* @param string $customerId
* @param Context $context
* @return array
*/
private function getEntryIds(string $customerId, Context $context)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('customerId', $customerId));
$tradeLicenseId = $this->gewerbescheinRepository->searchIds($criteria, $context)->getIds();
return $tradeLicenseId;
}
/**
* Rearrange files array, so that we can loop through files as file
* @param $postFiles
* @return array
*/
private function reFilesArray($postFiles) {
$reFileArray = [];
$countFiles = count($postFiles['name']);
$fileKeys = array_keys($postFiles);
for ($i=0; $i<$countFiles; $i++) {
foreach ($fileKeys as $key) {
$reFileArray[$i][$key] = $postFiles[$key][$i];
}
}
return $reFileArray;
}
}