diff --git a/.idea/php.xml b/.idea/php.xml index 6d17c06..d34eca7 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -139,6 +139,8 @@ <path value="$PROJECT_DIR$/vendor/consolidation/robo" /> <path value="$PROJECT_DIR$/vendor/consolidation/filter-via-dot-access-data" /> <path value="$PROJECT_DIR$/vendor/cweagans/composer-patches" /> + <path value="$PROJECT_DIR$/vendor/laminas/laminas-zendframework-bridge" /> + <path value="$PROJECT_DIR$/vendor/laminas/laminas-stdlib" /> </include_path> </component> <component name="PhpProjectSharedConfiguration" php_language_level="7.4" /> diff --git a/web/modules/custom/custom/custom.services.yml b/web/modules/custom/custom/custom.services.yml index 21bb957..1993b99 100644 --- a/web/modules/custom/custom/custom.services.yml +++ b/web/modules/custom/custom/custom.services.yml @@ -2,3 +2,6 @@ services: Drupal\custom\EventSubscriber\UpdateTalkNodeBeforeSave: tags: - { name: event_subscriber } + + Drupal\custom\Service\TalkCounter: + autowire: true diff --git a/web/modules/custom/custom/src/Service/TalkCounter.php b/web/modules/custom/custom/src/Service/TalkCounter.php new file mode 100644 index 0000000..933ab00 --- /dev/null +++ b/web/modules/custom/custom/src/Service/TalkCounter.php @@ -0,0 +1,41 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\custom\Service; + +use Carbon\Carbon; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\custom\Entity\Node\Talk; +use Drupal\node\NodeInterface; +use Drupal\paragraphs\ParagraphInterface; +use Illuminate\Support\Collection; + +final class TalkCounter { + + private EntityStorageInterface $nodeStorage; + + public function __construct(EntityTypeManagerInterface $entityTypeManager) { + $this->nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getCount(): int { + $today = Carbon::today()->format('Y-m-d H:i:s'); + + return $this->getTalks() + ->flatMap->getEvents() + ->filter(fn(ParagraphInterface $event) => $event->get('field_date')->getString() <= $today) + ->count(); + } + + private function getTalks(): Collection { + $talks = $this->nodeStorage->loadByProperties([ + 'status' => NodeInterface::PUBLISHED, + 'type' => 'talk', + ]); + + return new Collection($talks); + } + +} diff --git a/web/modules/custom/custom/tests/src/Kernel/CountPreviousTalksTest.php b/web/modules/custom/custom/tests/src/Kernel/CountPreviousTalksTest.php new file mode 100644 index 0000000..861f5fa --- /dev/null +++ b/web/modules/custom/custom/tests/src/Kernel/CountPreviousTalksTest.php @@ -0,0 +1,66 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\custom\Kernel; + +use Carbon\Carbon; +use Drupal\custom\Service\TalkCounter; +use Drupal\node\NodeInterface; +use PHPUnit\Framework\Assert; + +class CountPreviousTalksTest extends TalksTestBase { + + private TalkCounter $talkCounter; + + /** @test */ + public function previous_talks_are_counted(): void { + $this->createTalk([ + 'field_events' => [ + $this->createEvent(), + $this->createEvent(), + ], + ]); + + $this->createTalk([ + 'field_events' => [ + $this->createEvent(), + ], + ]); + + Assert::assertSame(3, $this->talkCounter->getCount()); + } + + /** @test */ + public function future_talks_are_not_counted(): void { + $this->createTalk([ + 'field_events' => [ + $this->createEvent([ + 'field_date' => Carbon::now()->subDay(), + ]), + $this->createEvent([ + 'field_date' => Carbon::now()->addDay(), + ]), + ], + ]); + + Assert::assertSame(1, $this->talkCounter->getCount()); + } + + /** @test */ + public function unpublished_talks_are_not_counted(): void { + $this->createTalk([ + 'field_events' => [$this->createEvent()], + 'status' => NodeInterface::NOT_PUBLISHED, + ]); + + Assert::assertSame(0, $this->talkCounter->getCount()); + } + + protected function setUp() { + parent::setUp(); + + $this->talkCounter = $this->container->get(TalkCounter::class); + } + +}