Refactor
Try a different way of naming and grouping classes.
This commit is contained in:
parent
52c1b33711
commit
6b6b362a49
15 changed files with 111 additions and 59 deletions
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Drupal\Core\Render\BubbleableMetadata;
|
use Drupal\Core\Render\BubbleableMetadata;
|
||||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||||
use Drupal\opd_daily_emails\Repository\DailyEmailNodeRepository;
|
use Drupal\opd_daily_emails\DailyEmailNodeRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_token_info().
|
* Implements hook_token_info().
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
services:
|
services:
|
||||||
Drupal\opd_daily_emails\Repository\DailyEmailNodeRepository:
|
Drupal\opd_daily_emails\DailyEmailNodeRepository:
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_daily_emails\Repository;
|
namespace Drupal\opd_daily_emails;
|
||||||
|
|
||||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
use Drupal\opd_daily_emails\Collection\DailyEmailCollection;
|
|
||||||
|
|
||||||
final class DailyEmailNodeRepository implements DailyEmailRepositoryInterface {
|
final class DailyEmailNodeRepository implements DailyEmailRepositoryInterface {
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ final class DailyEmailNodeRepository implements DailyEmailRepositoryInterface {
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAll(): DailyEmailCollection {
|
public function getAll(): DailyEmails {
|
||||||
$nodeStorage = $this->entityTypeManager
|
$nodeStorage = $this->entityTypeManager
|
||||||
->getStorage('node');
|
->getStorage('node');
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ final class DailyEmailNodeRepository implements DailyEmailRepositoryInterface {
|
||||||
/** @var NodeInterface[] */
|
/** @var NodeInterface[] */
|
||||||
$nodes = $nodeStorage->loadMultiple($nodeIds);
|
$nodes = $nodeStorage->loadMultiple($nodeIds);
|
||||||
|
|
||||||
return new DailyEmailCollection($nodes);
|
return DailyEmails::new($nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Drupal\opd_daily_emails;
|
||||||
|
|
||||||
|
interface DailyEmailRepositoryInterface {
|
||||||
|
|
||||||
|
public function getAll(): DailyEmails;
|
||||||
|
|
||||||
|
}
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_daily_emails\Collection;
|
namespace Drupal\opd_daily_emails;
|
||||||
|
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
|
|
||||||
final class DailyEmailCollection implements \Countable {
|
final class DailyEmails implements \Countable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<positive-int, NodeInterface> $emails
|
* @param array<positive-int, NodeInterface> $emails
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
private function __construct(
|
||||||
private array $emails,
|
private array $emails,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
@ -24,4 +24,8 @@ final class DailyEmailCollection implements \Countable {
|
||||||
return array_values($this->emails)[0];
|
return array_values($this->emails)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function new(array $emails): self {
|
||||||
|
return new self($emails);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Drupal\opd_daily_emails\Repository;
|
|
||||||
|
|
||||||
use Drupal\opd_daily_emails\Collection\DailyEmailCollection;
|
|
||||||
|
|
||||||
interface DailyEmailRepositoryInterface {
|
|
||||||
|
|
||||||
public function getAll(): DailyEmailCollection;
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\Tests\opd_daily_emails\Kernel\Repository;
|
namespace Drupal\Tests\opd_daily_emails\Kernel;
|
||||||
|
|
||||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||||
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
||||||
use Drupal\Tests\opd_daily_emails\Traits\DailyEmailTestTrait;
|
use Drupal\Tests\opd_daily_emails\Traits\DailyEmailTestTrait;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
use Drupal\opd_daily_emails\Repository\DailyEmailNodeRepository;
|
use Drupal\opd_daily_emails\DailyEmailNodeRepository;
|
||||||
use Drupal\opd_daily_emails\Repository\DailyEmailRepositoryInterface;
|
use Drupal\opd_daily_emails\DailyEmailRepositoryInterface;
|
||||||
|
|
||||||
final class DailyEmailNodeRepositoryTest extends EntityKernelTestBase {
|
final class DailyEmailNodeRepositoryTest extends EntityKernelTestBase {
|
||||||
|
|
|
@ -5,8 +5,7 @@ declare(strict_types=1);
|
||||||
use Drupal\Core\Render\BubbleableMetadata;
|
use Drupal\Core\Render\BubbleableMetadata;
|
||||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
use Drupal\opd_podcast\Entity\PodcastEpisode;
|
use Drupal\opd_podcast\PodcastEpisode;
|
||||||
use Drupal\taxonomy\TermInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_entity_bundle_info_alter().
|
* Implements hook_entity_bundle_info_alter().
|
||||||
|
@ -86,20 +85,7 @@ function opd_podcast_tokens(string $type, array $tokens, array $data, array $opt
|
||||||
$node = $data['node'] ?? NULL;
|
$node = $data['node'] ?? NULL;
|
||||||
assert($node instanceof PodcastEpisode);
|
assert($node instanceof PodcastEpisode);
|
||||||
|
|
||||||
$guests = $node->getGuests();
|
$replacements[$original] = strval($node->getGuests());
|
||||||
assert(is_array($guests));
|
|
||||||
assert(!is_null($guests[0]));
|
|
||||||
assert($guests[0] instanceof TermInterface);
|
|
||||||
|
|
||||||
// TODO: allow for more than two guests.
|
|
||||||
if (count($guests) === 2) {
|
|
||||||
assert($guests[1] instanceof TermInterface);
|
|
||||||
|
|
||||||
$replacements[$original] = sprintf('%s %s %s', $guests[0]->label(), t('and'), $guests[1]->label());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$replacements[$original] = $guests[0]->label();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_podcast\Entity;
|
namespace Drupal\opd_podcast;
|
||||||
|
|
||||||
use Drupal\node\Entity\Node;
|
use Drupal\node\Entity\Node;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
|
@ -11,8 +11,8 @@ final class PodcastEpisode extends Node implements NodeInterface {
|
||||||
|
|
||||||
public const NODE_TYPE = 'podcast_episode';
|
public const NODE_TYPE = 'podcast_episode';
|
||||||
|
|
||||||
public function getGuests(): array {
|
public function getGuests(): PodcastGuests {
|
||||||
return $this->get('field_podcast_guests')->referencedEntities();
|
return PodcastGuests::new($this->get('field_podcast_guests')->referencedEntities());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
62
modules/opd_podcast/src/PodcastGuests.php
Normal file
62
modules/opd_podcast/src/PodcastGuests.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Drupal\opd_podcast;
|
||||||
|
|
||||||
|
use Drupal\taxonomy\TermInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implements \IteratorAggregate<TermInterface>
|
||||||
|
*/
|
||||||
|
final class PodcastGuests implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TermInterface[] $guests
|
||||||
|
*/
|
||||||
|
private function __construct(private array $guests) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count(): int {
|
||||||
|
return count($this->guests);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIterator(): \Traversable {
|
||||||
|
return new \ArrayIterator($this->guests);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetExists(mixed $offset): bool {
|
||||||
|
return isset($this->guests[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet(mixed $offset): mixed {
|
||||||
|
return $this->guests[$offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet(mixed $offset, mixed $value): void {
|
||||||
|
$this->guests[$offset] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset(mixed $offset): void {
|
||||||
|
unset($this->guests[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString(): string {
|
||||||
|
// TODO: allow for more than two guests.
|
||||||
|
if (count($this->guests) === 2) {
|
||||||
|
assert($this->guests[1] instanceof TermInterface);
|
||||||
|
|
||||||
|
return sprintf('%s %s %s', $this->guests[0]->label(), t('and'), $this->guests[1]->label());
|
||||||
|
}
|
||||||
|
|
||||||
|
return strval($this->guests[0]->label());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param TermInterface[] $guests
|
||||||
|
*/
|
||||||
|
public static function new(array $guests): self {
|
||||||
|
return new self($guests);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Drupal\opd_presentations\Entity\Event;
|
use Drupal\opd_presentations\Event;
|
||||||
use Drupal\opd_presentations\Entity\Presentation;
|
use Drupal\opd_presentations\Presentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_entity_bundle_info_alter().
|
* Implements hook_entity_bundle_info_alter().
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_presentations\Entity;
|
namespace Drupal\opd_presentations;
|
||||||
|
|
||||||
use Drupal\paragraphs\Entity\Paragraph;
|
use Drupal\paragraphs\Entity\Paragraph;
|
||||||
use Drupal\paragraphs\ParagraphInterface;
|
use Drupal\paragraphs\ParagraphInterface;
|
|
@ -2,19 +2,17 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_presentations\Collection;
|
namespace Drupal\opd_presentations;
|
||||||
|
|
||||||
use Drupal\opd_presentations\Entity\Event;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements \IteratorAggregate<Event>
|
* @implements \IteratorAggregate<Event>
|
||||||
*/
|
*/
|
||||||
readonly final class EventCollection implements \IteratorAggregate {
|
readonly final class Events implements \IteratorAggregate {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Event[] $events
|
* @param Event[] $events
|
||||||
*/
|
*/
|
||||||
public function __construct(private array $events) {
|
private function __construct(private array $events) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function first(): Event {
|
public function first(): Event {
|
||||||
|
@ -25,4 +23,11 @@ readonly final class EventCollection implements \IteratorAggregate {
|
||||||
return new \ArrayIterator($this->events);
|
return new \ArrayIterator($this->events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Event[] $events
|
||||||
|
*/
|
||||||
|
public static function new(array $events): self {
|
||||||
|
return new self($events);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,24 +2,22 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Drupal\opd_presentations\Entity;
|
namespace Drupal\opd_presentations;
|
||||||
|
|
||||||
use Drupal\Core\Datetime\DrupalDateTime;
|
use Drupal\Core\Datetime\DrupalDateTime;
|
||||||
use Drupal\node\Entity\Node;
|
use Drupal\node\Entity\Node;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
use Drupal\opd_presentations\Collection\EventCollection;
|
|
||||||
use Drupal\opd_presentations\Entity\Event;
|
|
||||||
|
|
||||||
final class Presentation extends Node implements NodeInterface {
|
final class Presentation extends Node implements NodeInterface {
|
||||||
|
|
||||||
public const NODE_TYPE = 'presentation';
|
public const NODE_TYPE = 'presentation';
|
||||||
|
|
||||||
public function getPastEvents(): EventCollection {
|
public function getPastEvents(): Events {
|
||||||
$events = $this->get('field_events')->referencedEntities();
|
$events = $this->get('field_events')->referencedEntities();
|
||||||
|
|
||||||
$today = (new DrupalDateTime('today'))->format('U');
|
$today = (new DrupalDateTime('today'))->format('U');
|
||||||
|
|
||||||
return new EventCollection(array_filter(
|
return Events::new(array_filter(
|
||||||
array: $events,
|
array: $events,
|
||||||
callback: fn (Event $event): bool => $event->getEventDate() < $today,
|
callback: fn (Event $event): bool => $event->getEventDate() < $today,
|
||||||
));
|
));
|
|
@ -7,8 +7,8 @@ namespace Drupal\Tests\opd_presentations\Traits;
|
||||||
use Drupal\Core\Datetime\DrupalDateTime;
|
use Drupal\Core\Datetime\DrupalDateTime;
|
||||||
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
||||||
use Drupal\ctools\Testing\EntityCreationTrait;
|
use Drupal\ctools\Testing\EntityCreationTrait;
|
||||||
use Drupal\opd_presentations\Entity\Event;
|
use Drupal\opd_presentations\Event;
|
||||||
use Drupal\opd_presentations\Entity\Presentation;
|
use Drupal\opd_presentations\Presentation;
|
||||||
|
|
||||||
trait PresentationCreationTrait {
|
trait PresentationCreationTrait {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue