<?php
namespace App\EventListener;
use App\Controller\Page\ApplicantController;
use App\Controller\Page\BlogPostController;
use App\Controller\Page\BlogPostsController;
use App\Controller\Page\CompaniesController;
use App\Controller\Page\CompanyController;
use App\Controller\Page\ContactController;
use App\Controller\Page\EmployeeController;
use App\Controller\Page\EventController;
use App\Controller\Page\EventRegistrationController;
use App\Controller\Page\EventsController;
use App\Controller\Page\JobAlertController;
use App\Controller\Page\NewsletterController;
use App\Controller\Page\OrderController;
use App\Controller\Page\ProductController;
use App\Controller\Page\ProductsController;
use App\Controller\Page\SearchController;
use App\Controller\Page\TestimonialController;
use App\Controller\Page\VacanciesController;
use App\Controller\Page\VacancyController;
use App\Entity\Page;
use App\Event\SiteUpdateEvent;
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\ORM\EntityManagerInterface;
class PagesAndRouteUpdateCommandListener
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
private $pageControllerMapping = [
'ContactBundle:Pages/Default:index' => ContactController::class.':indexAction',
'ContactBundle:Pages/Default:thank' => ContactController::class.':thankAction',
'VacancyBundle:Page/Vacancies:index' => VacanciesController::class.':indexAction',
'VacancyBundle:Page/Vacancy:detail' => VacancyController::class.':detailAction',
'CompanyBundle:Page/Companies:index' => CompaniesController::class.':indexAction',
'CompanyBundle:Page/Company:detail' => CompanyController::class.':detailAction',
'ApplicantBundle:Default:form' => ApplicantController::class.':formAction',
'ApplicantBundle:Default:thanks' => ApplicantController::class.':thanksAction',
'JobAlertBundle:Pages/JobAlert:index' => JobAlertController::class.':indexAction',
'JobAlertBundle:Pages/JobAlert:thanks' => JobAlertController::class.':thanksAction',
'ProductBundle:Page/Products:index' => ProductsController::class.':indexAction',
'ProductBundle:Page/Product:detail' => ProductController::class.':detailAction',
'BlogBundle:Page/BlogPosts:index' => BlogPostsController::class.':indexAction',
'BlogBundle:Page/BlogPost:detail' => BlogPostController::class.':detailAction',
'OrderBundle:Pages/Order:thanksInvoice' => OrderController::class.':thanksInvoice',
'OrderBundle:Pages/Order:requestSample' => OrderController::class.':requestSampleAction',
'OrderBundle:Pages/Order:thanksSample' => OrderController::class.':thanksSampleAction',
'SearchBundle:Pages/Search:search' => SearchController::class.':searchAction',
'NewsletterBundle:Pages/Newsletter:subscribe' => NewsletterController::class.':subscribeAction',
'EventBundle:Pages/Events:index' => EventsController::class.':indexAction',
'EventBundle:Pages/Event:detail' => EventController::class.':detailAction',
'EventBundle:Pages/Registration:registration' => EventRegistrationController::class.':registrationAction',
'EventBundle:Pages/Registration:thanksRegistration' => EventRegistrationController::class.':thanksRegistrationAction',
'TestimonialBundle:Pages/Testimonial:detail' => TestimonialController::class.':detailAction',
'EmployeeBundle:Pages/Employee:detail' => EmployeeController::class.':detailAction',
];
/**
* PageAndRouteUpdateListener constructor.
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @throws DBALException
*/
public function updatePagesAndRoutes(SiteUpdateEvent $event)
{
$this->updateExistingPages($event);
$this->validateRemainingUnchangedControllers($event);
$this->updateExistingRoutes($event);
}
/**
* @throws DBALException
*/
private function updateExistingPages(SiteUpdateEvent $event)
{
$pages = $this->entityManager->getRepository(Page::class)
->findAll()
;
$pages = array_filter($pages, function (Page $page) {
return null !== $page->getController();
});
$dbConnection = $this->entityManager->getConnection();
/** @var Page $page */
foreach ($pages as $page) {
if (!isset($this->pageControllerMapping[$page->getController()])) {
continue;
}
$event->getOutput()->writeln(sprintf(
'<comment>Updating Page</comment> change %s to %s',
$page->getController(),
$this->pageControllerMapping[$page->getController()]
));
$dbConnection->exec(
sprintf(
'UPDATE `page` SET `controller` = "%s" WHERE `id` = %d',
addslashes($this->pageControllerMapping[$page->getController()]),
$page->getId()
)
);
}
}
/**
* @throws DBALException
*/
private function updateExistingRoutes(SiteUpdateEvent $event)
{
$event->getOutput()->writeln(\PHP_EOL.'<comment>Start updating</comment> routes to sf4 namespace');
$dbConnection = $this->entityManager->getConnection();
$dbConnection->exec(
sprintf(
"UPDATE `orm_routes` SET `defaults` = REPLACE(defaults, '%s', '%s')",
'31:"Pages\\\PagesBundle',
'17:"App'
)
);
$dbConnection->exec(
sprintf(
"UPDATE `orm_routes` SET `defaults` = REPLACE(defaults, '%s', '%s')",
'32:"Pages\\\PagesBundle',
'18:"App'
)
);
$dbConnection->exec(
sprintf(
"UPDATE `orm_routes` SET `defaults` = REPLACE(defaults, '%s', '%s')",
'33:"Pages\\\PagesBundle',
'19:"App'
)
);
$event->getOutput()->writeln('<comment>Finished updating</comment> routes to sf4 namespace');
$dbConnection->exec('UPDATE `orm_routes` SET `name` = lcase(name)');
$event->getOutput()->writeln('<comment>Transformed</comment> all route names to lowercase');
}
private function validateRemainingUnchangedControllers(SiteUpdateEvent $event)
{
$event->getOutput()->writeln('<comment>Validating</comment> controllers in page table');
$pages = $this->entityManager->getRepository(Page::class)
->findAll();
$controllerNamespace = 'App\\Controller';
foreach ($pages as $page) {
$this->entityManager->refresh($page);
}
$pages = array_filter($pages, function (Page $page) use ($controllerNamespace) {
return null !== $page->getController() && mb_substr($page->getController(), 0, mb_strlen($controllerNamespace)) !== $controllerNamespace;
});
if (empty($pages)) {
return;
}
$event->getOutput()->writeln(sprintf('<error>%d invalid controllers found</error>', \count($pages)));
$event->getOutput()->writeln('<error>Invalid controllers are:</error>');
/** @var Page $page */
foreach ($pages as $page) {
$event->getOutput()->writeln(' - '.$page->getController());
}
}
}