Rename and re-organise custom modules
- Rename `opd_talks` to `opdavies_talks` - Rename `custom` to `opdavies_blog`
This commit is contained in:
parent
e4e898f22c
commit
9b1a8fb3be
53 changed files with 125 additions and 116 deletions
57
web/modules/custom/opdavies_talks/src/Entity/Node/Talk.php
Normal file
57
web/modules/custom/opdavies_talks/src/Entity/Node/Talk.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\opdavies_talks\Entity\Node;
|
||||
|
||||
use Drupal\discoverable_entity_bundle_classes\ContentEntityBundleInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\paragraphs\ParagraphInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Defines an talk node class.
|
||||
*
|
||||
* @ContentEntityBundleClass(
|
||||
* label = @Translation("Talk"),
|
||||
* entity_type = "node",
|
||||
* bundle = "talk"
|
||||
* );
|
||||
*/
|
||||
class Talk extends Node implements ContentEntityBundleInterface {
|
||||
|
||||
public function addEvent(ParagraphInterface $event): void {
|
||||
$this->set(
|
||||
'field_events',
|
||||
$this->getEvents()->push($event)->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
public function getEvents(): Collection {
|
||||
return Collection::make($this->get('field_events')
|
||||
->referencedEntities());
|
||||
}
|
||||
|
||||
public function getNextDate(): ?int {
|
||||
if ($this->get('field_event_date')->isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (int) $this->get('field_event_date')->getString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the date for the latest event.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function findLatestEventDate(): ?string {
|
||||
return $this->getEvents()
|
||||
->map(fn(ParagraphInterface $event) => $event->get('field_date')
|
||||
->getString())
|
||||
->max();
|
||||
}
|
||||
|
||||
public function setNextDate(int $date): void {
|
||||
$this->set('field_event_date', $date);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\EventSubscriber;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Drupal\hook_event_dispatcher\Event\Entity\BaseEntityEvent;
|
||||
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
|
||||
use Drupal\opdavies_talks\Entity\Node\Talk;
|
||||
use Drupal\paragraphs\ParagraphInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Update a talk node before it's saved.
|
||||
*/
|
||||
final class UpdateTalkNodeBeforeSave implements EventSubscriberInterface {
|
||||
|
||||
public static function getSubscribedEvents() {
|
||||
return [
|
||||
HookEventDispatcherInterface::ENTITY_PRE_SAVE => 'onEntityPreSave',
|
||||
];
|
||||
}
|
||||
|
||||
public function onEntityPreSave(BaseEntityEvent $event): void {
|
||||
if ($event->getEntity()->getEntityTypeId() != 'node') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->getEntity()->bundle() != 'talk') {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \Drupal\opdavies_blog\Entity\Node\Talk $talk */
|
||||
$talk = $event->getEntity();
|
||||
$this->reorderEvents($talk);
|
||||
$this->updateCreatedDate($talk);
|
||||
}
|
||||
|
||||
private function reorderEvents(Talk $talk): void {
|
||||
$events = $talk->getEvents();
|
||||
|
||||
$eventsByDate = $events
|
||||
->sortBy(fn(ParagraphInterface $event) => $event->get('field_date')
|
||||
->getString())
|
||||
->values();
|
||||
|
||||
// If the original event IDs don't match the sorted event IDs, update the
|
||||
// event field to use the sorted ones.
|
||||
if ($events->map->id() != $eventsByDate->map->id()) {
|
||||
$talk->set('field_events', $eventsByDate->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private function updateCreatedDate(Talk $talk): void {
|
||||
if (!$eventDate = $talk->findLatestEventDate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$talkDate = Carbon::parse($eventDate)->getTimestamp();
|
||||
|
||||
if ($talkDate == $talk->get('created')->getString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$talk->set('created', $talkDate);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\Plugin\views\sort;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\views\Annotation\ViewsSort;
|
||||
use Drupal\views\Plugin\views\sort\Date;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @ViewsSort("event_sort")
|
||||
*/
|
||||
final class Event extends Date {
|
||||
|
||||
private TimeInterface $time;
|
||||
|
||||
public function __construct(
|
||||
array $configuration,
|
||||
$pluginId,
|
||||
$pluginDefinition,
|
||||
TimeInterface $time
|
||||
) {
|
||||
parent::__construct($configuration, $pluginId, $pluginDefinition);
|
||||
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
public static function create(
|
||||
ContainerInterface $container,
|
||||
array $configuration,
|
||||
$pluginId,
|
||||
$pluginDefinition
|
||||
) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$pluginId,
|
||||
$pluginDefinition,
|
||||
$container->get('datetime.time')
|
||||
);
|
||||
}
|
||||
|
||||
public function query() {
|
||||
$this->ensureMyTable();
|
||||
|
||||
$currentDate = Carbon::parse('today')->getTimestamp();
|
||||
|
||||
$dateAlias = "$this->tableAlias.$this->realField";
|
||||
|
||||
// Is this event in the past?
|
||||
$this->query->addOrderBy(
|
||||
NULL,
|
||||
sprintf("%d > %s", $currentDate, $dateAlias),
|
||||
$this->options['order'],
|
||||
"in_past"
|
||||
);
|
||||
|
||||
// How far in the past/future is this event?
|
||||
$this->query->addOrderBy(
|
||||
NULL,
|
||||
sprintf('ABS(%s - %d)', $dateAlias, $currentDate),
|
||||
$this->options['order'],
|
||||
"distance_from_now"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\Repository;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\opdavies_blog\Entity\Node\Talk;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
final class TalkRepository {
|
||||
|
||||
private EntityStorageInterface $nodeStorage;
|
||||
|
||||
public function __construct(EntityTypeManagerInterface $entityTypeManager) {
|
||||
$this->nodeStorage = $entityTypeManager->getStorage('node');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Talk[]
|
||||
*/
|
||||
public function getAll(bool $publishedOnly = FALSE): Collection {
|
||||
$properties = ['type' => 'talk'];
|
||||
|
||||
if ($publishedOnly) {
|
||||
$properties['status'] = TRUE;
|
||||
}
|
||||
|
||||
return new Collection(
|
||||
$this->nodeStorage->loadByProperties($properties)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\opdavies_talks\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
|
||||
use Drupal\opdavies_talks\Entity\Node\Talk;
|
||||
use Drupal\opdavies_talks\Repository\TalkRepository;
|
||||
use Drupal\paragraphs\ParagraphInterface;
|
||||
|
||||
final class TalkDateUpdater {
|
||||
|
||||
private TalkRepository $talkRepository;
|
||||
private TimeInterface $time;
|
||||
|
||||
public function __construct(
|
||||
TalkRepository $talkRepository,
|
||||
TimeInterface $time
|
||||
) {
|
||||
$this->talkRepository = $talkRepository;
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
public function __invoke(): void {
|
||||
foreach ($this->talkRepository->getAll() as $talk) {
|
||||
$this->updateNextEventDate($talk);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateNextEventDate(Talk $talk) {
|
||||
if (!$nextDate = $this->findNextEventDate($talk)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nextDateTimestamp = Carbon::parse($nextDate)
|
||||
->getTimestamp();
|
||||
|
||||
if ($nextDateTimestamp == $talk->getNextDate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$talk->setNextDate($nextDateTimestamp);
|
||||
$talk->save();
|
||||
}
|
||||
|
||||
private function findNextEventDate(Talk $talk): ?string {
|
||||
$currentTime = Carbon::today()
|
||||
->format(DateTimeItemInterface::DATE_STORAGE_FORMAT);
|
||||
|
||||
$dates = $talk->getEvents()
|
||||
->map(fn(ParagraphInterface $event) => $event->get('field_date')
|
||||
->getString())
|
||||
->sort();
|
||||
|
||||
if ($dates->isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If a future date is found, return it.
|
||||
if ($futureDate = $dates->first(fn(string $eventDate) => $eventDate > $currentTime)) {
|
||||
return $futureDate;
|
||||
}
|
||||
|
||||
// If no future date is found, return the last past date.
|
||||
return $dates->last();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue