From 00daad2092c6fe4c05f3ffd2a30d8496ffe6464f Mon Sep 17 00:00:00 2001 From: Patrick Berenschot Date: Thu, 9 Sep 2021 07:43:13 +0000 Subject: [PATCH] [SeoBundle] Added event to populate robots.txt --- .../SeoBundle/Controller/RobotsController.php | 32 +++++---- src/Kunstmaan/SeoBundle/Event/RobotsEvent.php | 24 +++++++ .../EventListener/AdminRobotsTxtListener.php | 41 ++++++++++++ .../EventListener/FileRobotsTxtListener.php | 31 +++++++++ .../ParameterRobotsTxtListener.php | 31 +++++++++ .../SeoBundle/Resources/config/services.yml | 23 +++++++ .../SeoBundle/Tests/Event/RobotsEventTest.php | 32 +++++++++ .../AdminRobotsTxtListenerTest.php | 67 +++++++++++++++++++ .../FileRobotsTxtListenerTest.php | 43 ++++++++++++ .../ParameterRobotsTxtListenerTest.php | 32 +++++++++ 10 files changed, 339 insertions(+), 17 deletions(-) create mode 100644 src/Kunstmaan/SeoBundle/Event/RobotsEvent.php create mode 100644 src/Kunstmaan/SeoBundle/EventListener/AdminRobotsTxtListener.php create mode 100644 src/Kunstmaan/SeoBundle/EventListener/FileRobotsTxtListener.php create mode 100644 src/Kunstmaan/SeoBundle/EventListener/ParameterRobotsTxtListener.php create mode 100644 src/Kunstmaan/SeoBundle/Tests/Event/RobotsEventTest.php create mode 100644 src/Kunstmaan/SeoBundle/Tests/EventListener/AdminRobotsTxtListenerTest.php create mode 100644 src/Kunstmaan/SeoBundle/Tests/EventListener/FileRobotsTxtListenerTest.php create mode 100644 src/Kunstmaan/SeoBundle/Tests/EventListener/ParameterRobotsTxtListenerTest.php diff --git a/src/Kunstmaan/SeoBundle/Controller/RobotsController.php b/src/Kunstmaan/SeoBundle/Controller/RobotsController.php index e1e86f6449..b83a9e7e65 100644 --- a/src/Kunstmaan/SeoBundle/Controller/RobotsController.php +++ b/src/Kunstmaan/SeoBundle/Controller/RobotsController.php @@ -2,36 +2,34 @@ namespace Kunstmaan\SeoBundle\Controller; -use Kunstmaan\SeoBundle\Entity\Robots; +use Kunstmaan\SeoBundle\Event\RobotsEvent; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -class RobotsController extends Controller +final class RobotsController extends AbstractController { + private $dispatcher; + + public function __construct(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + /** - * Generates the robots.txt content when available in the database and falls back to normal robots.txt if exists - * * @Route(path="/robots.txt", name="KunstmaanSeoBundle_robots", defaults={"_format": "txt"}) * @Template(template="@KunstmaanSeo/Admin/Robots/index.html.twig") * * @return array */ - public function indexAction(Request $request) + public function __invoke(Request $request) { - $entity = $this->getDoctrine()->getRepository(Robots::class)->findOneBy([]); - $robots = $this->getParameter('robots_default'); + $event = new RobotsEvent(); - if ($entity && $entity->getRobotsTxt()) { - $robots = $entity->getRobotsTxt(); - } else { - $file = $request->getBasePath() . 'robots.txt'; - if (file_exists($file)) { - $robots = file_get_contents($file); - } - } + $event = $this->dispatcher->dispatch($event); - return ['robots' => $robots]; + return ['robots' => $event->getContent()]; } } diff --git a/src/Kunstmaan/SeoBundle/Event/RobotsEvent.php b/src/Kunstmaan/SeoBundle/Event/RobotsEvent.php new file mode 100644 index 0000000000..ae5eb1c1cc --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Event/RobotsEvent.php @@ -0,0 +1,24 @@ +content = $content; + } + + public function setContent(string $content): void + { + $this->content = $content; + } + + public function getContent(): string + { + return $this->content; + } +} diff --git a/src/Kunstmaan/SeoBundle/EventListener/AdminRobotsTxtListener.php b/src/Kunstmaan/SeoBundle/EventListener/AdminRobotsTxtListener.php new file mode 100644 index 0000000000..04f302f27a --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/AdminRobotsTxtListener.php @@ -0,0 +1,41 @@ +repository = $repository; + } + + public static function getSubscribedEvents(): array + { + return [ + RobotsEvent::class => ["__invoke", 100] + ]; + } + + public function __invoke(RobotsEvent $event): void + { + $entity = $this->repository->findOneBy([]); + if (!$entity instanceof Robots) { + return; + } + + $content = $entity->getRobotsTxt(); + if ($content === null) { + return; + } + + $event->setContent($content); + } +} diff --git a/src/Kunstmaan/SeoBundle/EventListener/FileRobotsTxtListener.php b/src/Kunstmaan/SeoBundle/EventListener/FileRobotsTxtListener.php new file mode 100644 index 0000000000..48b4ebce3d --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/FileRobotsTxtListener.php @@ -0,0 +1,31 @@ +path = $path; + } + + public static function getSubscribedEvents(): array + { + return [ + RobotsEvent::class => ["__invoke", 0] + ]; + } + + public function __invoke(RobotsEvent $event): void + { + if (empty($event->getContent()) && file_exists($this->path)) { + $event->setContent(file_get_contents($this->path)); + } + } +} diff --git a/src/Kunstmaan/SeoBundle/EventListener/ParameterRobotsTxtListener.php b/src/Kunstmaan/SeoBundle/EventListener/ParameterRobotsTxtListener.php new file mode 100644 index 0000000000..0a159a2d65 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/ParameterRobotsTxtListener.php @@ -0,0 +1,31 @@ +fallback = $fallback; + } + + public static function getSubscribedEvents(): array + { + return [ + RobotsEvent::class => ["__invoke", -100] + ]; + } + + public function __invoke(RobotsEvent $event): void + { + if (empty($event->getContent())) { + $event->setContent($this->fallback); + } + } +} diff --git a/src/Kunstmaan/SeoBundle/Resources/config/services.yml b/src/Kunstmaan/SeoBundle/Resources/config/services.yml index bdc7f1a8d0..cfcfdcdaa9 100644 --- a/src/Kunstmaan/SeoBundle/Resources/config/services.yml +++ b/src/Kunstmaan/SeoBundle/Resources/config/services.yml @@ -39,3 +39,26 @@ services: arguments: ['@security.authorization_checker'] tags: - { name: 'kunstmaan_admin.menu.adaptor' } + + kunstmaanseobundle.repository.robots: + class: Doctrine\ORM\EntityRepository + factory: ["@doctrine.orm.entity_manager", getRepository] + arguments: ['Kunstmaan\SeoBundle\Entity\Robots'] + + Kunstmaan\SeoBundle\EventListener\AdminRobotsTxtListener: + autoconfigure: true + arguments: + $repository: '@kunstmaanseobundle.repository.robots' + + Kunstmaan\SeoBundle\EventListener\FileRobotsTxtListener: + autoconfigure: true + arguments: ["robots.txt", '@request_stack'] + + Kunstmaan\SeoBundle\EventListener\ParameterRobotsTxtListener: + autoconfigure: true + arguments: ['%robots_default%'] + + Kunstmaan\SeoBundle\Controller\RobotsController: + autowire: true + tags: ['controller.service_arguments'] + diff --git a/src/Kunstmaan/SeoBundle/Tests/Event/RobotsEventTest.php b/src/Kunstmaan/SeoBundle/Tests/Event/RobotsEventTest.php new file mode 100644 index 0000000000..e34a6f6ffc --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/Event/RobotsEventTest.php @@ -0,0 +1,32 @@ +getContent(); + $this->assertEquals($initialContent, $result); + + $newContent = "$result\nAdded"; + $object->setContent($newContent); + + $this->assertEquals($newContent, $object->getContent()); + } + + public function testShouldDefaultToEmptyContent(): void + { + $object = new RobotsEvent(); + + $result = $object->getContent(); + $this->assertEquals("", $result); + } +} diff --git a/src/Kunstmaan/SeoBundle/Tests/EventListener/AdminRobotsTxtListenerTest.php b/src/Kunstmaan/SeoBundle/Tests/EventListener/AdminRobotsTxtListenerTest.php new file mode 100644 index 0000000000..b8ae54428b --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/EventListener/AdminRobotsTxtListenerTest.php @@ -0,0 +1,67 @@ +setRobotsTxt(self::CONTENT); + + $this->repoMock = $this->createMock(EntityRepository::class); + $this->repoMock->expects($this->any()) + ->method("findOneBy") + ->with([]) + ->willReturn($filled); + + $event = new RobotsEvent(); + $listener = new AdminRobotsTxtListener($this->repoMock); + $listener->__invoke($event); + + $this->assertEquals(self::CONTENT, $event->getContent()); + } + + public function testShouldDoNothingWhenEntityMissing() + { + $this->repoMock = $this->createMock(EntityRepository::class); + $this->repoMock->expects($this->any()) + ->method("findOneBy") + ->with([]) + ->willReturn(null); + + $event = new RobotsEvent("untouched"); + $listener = new AdminRobotsTxtListener($this->repoMock); + $listener->__invoke($event); + + $this->assertEquals("untouched", $event->getContent()); + } + + public function testShouldDoNothingWhenEntityEmpty() + { + $empty = new Robots(); + + $this->repoMock = $this->createMock(EntityRepository::class); + $this->repoMock->expects($this->any()) + ->method("findOneBy") + ->with([]) + ->willReturn($empty); + + $event = new RobotsEvent("untouched"); + $listener = new AdminRobotsTxtListener($this->repoMock); + $listener->__invoke($event); + + $this->assertEquals("untouched", $event->getContent()); + } +} diff --git a/src/Kunstmaan/SeoBundle/Tests/EventListener/FileRobotsTxtListenerTest.php b/src/Kunstmaan/SeoBundle/Tests/EventListener/FileRobotsTxtListenerTest.php new file mode 100644 index 0000000000..d6cfeed534 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/EventListener/FileRobotsTxtListenerTest.php @@ -0,0 +1,43 @@ +setContent(self::CONTENT); + $listener = new FileRobotsTxtListener(__FILE__); + $listener->__invoke($event); + + $this->assertEquals(self::CONTENT, $event->getContent()); + } + + public function testShouldSetContentFromFileWhenEmpty(): void + { + $event = new RobotsEvent(); + $listener = new FileRobotsTxtListener(__FILE__); + $listener->__invoke($event); + + $this->assertEquals(file_get_contents(__FILE__), $event->getContent()); + } + + public function testShouldDoNothingWhenFileDoesNotExists(): void { + + $event = new RobotsEvent(); + $listener = new FileRobotsTxtListener("/some/none/existing/file"); + $listener->__invoke($event); + + $this->assertEquals("", $event->getContent()); + } +} diff --git a/src/Kunstmaan/SeoBundle/Tests/EventListener/ParameterRobotsTxtListenerTest.php b/src/Kunstmaan/SeoBundle/Tests/EventListener/ParameterRobotsTxtListenerTest.php new file mode 100644 index 0000000000..463879f6e7 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/EventListener/ParameterRobotsTxtListenerTest.php @@ -0,0 +1,32 @@ +__invoke($event); + + $this->assertEquals("fallback content", $event->getContent()); + } + + public function testShouldSetDoNothingWhenFilled() + { + $event = new RobotsEvent(self::CONTENT); + $listener = new ParameterRobotsTxtListener("fallback content"); + $listener->__invoke($event); + + $this->assertEquals(self::CONTENT, $event->getContent()); + } +}