<?php declare(strict_types=1);
namespace App\EventSubscriber;
use App\Entity\PageInterface;
use App\Entity\FormPageInterface;
use Symfony\Component\Finder\Finder;
use Vich\UploaderBundle\Event\Event;
use Symfony\Component\Form\FormEvent;
use Vich\UploaderBundle\Event\Events;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class PageFormSubscriber implements EventSubscriberInterface
{
private $filesystem;
private $params;
private $dirPath = '';
public function __construct(Filesystem $filesystem, ParameterBagInterface $params)
{
$this->filesystem = $filesystem;
$this->params = $params;
}
public static function getSubscribedEvents(): array
{
return [
FormEvents::PRE_SUBMIT => ['onPreSubmit'],
Events::PRE_UPLOAD => ['onVichUploaderPreUpload'],
Events::POST_UPLOAD => ['onVichUploaderPostUpload'],
];
}
public function onPreSubmit(FormEvent $event): void
{
$page = $event->getForm()->getData();
$data = $event->getData();
if (!$page instanceof PageInterface) {
return;
}
// Checks if the machine name or the site will be modified submitting the form,
// if not, we don't have to reupload files
if (
(!isset($data['machineName']) || isset($data['machineName']) && $page->getMachineName() == $data['machineName'])
&& (!isset($data['site']) || isset($data['site']) && $page->getSite()->getId() == $data['site'])
) {
return;
}
if (($fileName = $page->getTemplateFileName()) && !isset($data['templateFile']['delete'])) {
$data['templateFile'] = $this->updateFilePath(
$page,
$this->params->get('public_templates_path'),
$fileName,
'text/html'
);
}
if (($fileName = $page->getAssetsArchiveFilename()) && !isset($data['assetsArchiveFile']['delete'])) {
$data['assetsArchiveFile'] = $this->updateFilePath(
$page,
$this->params->get('public_archives_path'),
$fileName,
'application/zip');
}
if ($page instanceof FormPageInterface) {
if (($fileName = $page->getConfirmationTemplateFilename()) && !isset($data['confirmationTemplateFile']['delete'])) {
$data['confirmationTemplateFile'] = $this->updateFilePath(
$page,
$this->params->get('public_templates_path'),
$fileName,
'text/html'
);
}
if (($fileName = $page->getLeadEmailTemplateFilename()) && !isset($data['leadEmailTemplateFile']['delete'])) {
$data['leadEmailTemplateFile'] = $this->updateFilePath(
$page,
$this->params->get('public_templates_path'),
$fileName,
'text/html'
);
}
}
$event->setData($data);
}
private function updateFilePath(PageInterface $page, string $dirPath, string $fileName, string $fileMimeType): array
{
return [
'file' => new UploadedFile(
implode(DIRECTORY_SEPARATOR, [$dirPath, $page->getFilesystemPath(), $fileName]),
$fileName,
$fileMimeType,
null,
true
)
];
}
public function onVichUploaderPreUpload(Event $event): void
{
$page = $event->getObject();
switch ($event->getMapping()->getMappingName()) {
case 'page_template':
$this->dirPath = $page->getTemplateFile()->getPath();
break;
case 'page_lead_email':
$this->dirPath = $page->getLeadEmailTemplateFile()->getPath();
break;
case 'page_confirmation_template':
$this->dirPath = $page->getConfirmationTemplateFile()->getPath();
break;
case 'page_assets_archive':
$this->dirPath = $page->getAssetsArchiveFile()->getPath();
break;
}
}
public function onVichUploaderPostUpload(Event $event): void
{
$finder = new Finder();
// Checks if the path exists otherwise Finder can't find files in it
if (!$this->filesystem->exists($this->dirPath)) {
return;
}
// Changes assets path in templates (in case of links to PDF files)
$page = $event->getObject();
switch ($event->getMapping()->getMappingName()) {
case 'page_template':
$postUploadedFile = $page->getTemplateFile();
break;
case 'page_lead_email':
$postUploadedFile = $page->getLeadEmailTemplateFile();
break;
case 'page_confirmation_template':
$postUploadedFile = $page->getConfirmationTemplateFile();
break;
}
if (isset($postUploadedFile)) {
$fileContents = file_get_contents($postUploadedFile->getRealPath());
$old_file_system_path = str_replace(
$this->params->get('public_templates_path').DIRECTORY_SEPARATOR,
'',
$this->dirPath,
);
$updated_file = str_replace($old_file_system_path , $page->getFilesystemPath(), $fileContents);
file_put_contents($postUploadedFile->getPathname(), $updated_file);
}
$finder->files()->in($this->dirPath);
// Checks if the old directory is empty to remove it
if (!$finder->hasResults()) {
// Deletes old templates and archives folders
$this->filesystem->remove($this->dirPath);
$mapping = $event->getMapping();
// Deletes old extracted assets folder
if ($mapping->getMappingName() == 'page_assets_archive') {
// Creates assets path by replacing 'archives' by 'assets' in the archive path
$assetsPath = str_replace('archives', 'assets', $this->dirPath);
$this->filesystem->remove($assetsPath);
} else { // Deletes old updated templates folder
// Creates assets path by replacing 'public/uploads/templates' by 'templates/uploads' in the template path
$updatedTemplatesPath = str_replace(
$mapping->getUploadDestination(),
$this->params->get('private_templates_path'),
$this->dirPath,
);
$this->filesystem->remove($updatedTemplatesPath);
}
}
}
}