diff --git a/src/Kunstmaan/SeoBundle/Controller/RobotsController.php b/src/Kunstmaan/SeoBundle/Controller/RobotsController.php index e1e86f6449..2034be09c5 100644 --- a/src/Kunstmaan/SeoBundle/Controller/RobotsController.php +++ b/src/Kunstmaan/SeoBundle/Controller/RobotsController.php @@ -2,17 +2,23 @@ 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\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; class RobotsController extends Controller { + 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") * @@ -20,18 +26,10 @@ class RobotsController extends Controller */ public function indexAction(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..5b3e6f6e2f --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Event/RobotsEvent.php @@ -0,0 +1,25 @@ +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..f32780ba19 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/AdminRobotsTxtListener.php @@ -0,0 +1,42 @@ +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..28ec63b5c1 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/FileRobotsTxtListener.php @@ -0,0 +1,32 @@ +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..2cc0663aec --- /dev/null +++ b/src/Kunstmaan/SeoBundle/EventListener/ParameterRobotsTxtListener.php @@ -0,0 +1,32 @@ +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..b029397ad8 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..0004df12bf --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/Event/RobotsEventTest.php @@ -0,0 +1,33 @@ +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..50aae7d0bd --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/EventListener/AdminRobotsTxtListenerTest.php @@ -0,0 +1,68 @@ +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..35a731aa54 --- /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..e08acd9f97 --- /dev/null +++ b/src/Kunstmaan/SeoBundle/Tests/EventListener/ParameterRobotsTxtListenerTest.php @@ -0,0 +1,33 @@ +__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()); + } +}