Automatically update the created date for talks
Automatically update the created dates for talk nodes so that they match the most-future event. This means that the talks are ordered correctly on the Talks page.
This commit is contained in:
parent
fe5340d1c7
commit
7a9bf80a89
18 changed files with 412 additions and 6 deletions
|
@ -3,3 +3,7 @@ type: module
|
|||
core: 8.x
|
||||
core_version_requirements: ^8 || ^9
|
||||
package: Custom
|
||||
dependencies:
|
||||
- drupal:node
|
||||
- hook_event_dispatcher:hook_event_dispatcher
|
||||
- paragraphs:paragraphs
|
||||
|
|
4
web/modules/custom/custom/custom.services.yml
Normal file
4
web/modules/custom/custom/custom.services.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
services:
|
||||
Drupal\custom\EventSubscriber\UpdateTalkCreatedDateOnSave:
|
||||
tags:
|
||||
- { name: event_subscriber }
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\custom\EventSubscriber;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\hook_event_dispatcher\Event\Entity\BaseEntityEvent;
|
||||
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
|
||||
use Drupal\paragraphs\ParagraphInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Set the created date for a talk to be the last date that the talk is given.
|
||||
*/
|
||||
final class UpdateTalkCreatedDateOnSave implements EventSubscriberInterface {
|
||||
|
||||
public static function getSubscribedEvents() {
|
||||
return [
|
||||
HookEventDispatcherInterface::ENTITY_INSERT => 'entityInsertOrUpdate',
|
||||
HookEventDispatcherInterface::ENTITY_UPDATE => 'entityInsertOrUpdate',
|
||||
];
|
||||
}
|
||||
|
||||
public function entityInsertOrUpdate(BaseEntityEvent $event): void {
|
||||
if ($event->getEntity()->getEntityTypeId() != 'node') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->getEntity()->bundle() != 'talk') {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->updateCreatedDate($event->getEntity());
|
||||
}
|
||||
|
||||
private function updateCreatedDate(EntityInterface $talk): void {
|
||||
if (!$eventDate = $this->findLatestEventDate($talk)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$talkDate = (new \DateTime($eventDate))->getTimestamp();
|
||||
|
||||
if ($talkDate == $talk->get('created')->getString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$talk->set('created', $talkDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the date for the latest event.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function findLatestEventDate(EntityInterface $talk) {
|
||||
return Collection::make($talk->get('field_events')->referencedEntities())
|
||||
->map(fn(ParagraphInterface $event) => $event->get('field_date')
|
||||
->getString())
|
||||
->max();
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,8 @@ use Drupal\paragraphs\Entity\Paragraph;
|
|||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* A migrate destination for a talk node.
|
||||
*
|
||||
* @MigrateDestination(
|
||||
* id="opd_talk"
|
||||
* )
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.node.field_events
|
||||
- node.type.talk
|
||||
- paragraphs.paragraphs_type.event
|
||||
module:
|
||||
- entity_reference_revisions
|
||||
id: node.talk.field_events
|
||||
field_name: field_events
|
||||
entity_type: node
|
||||
bundle: talk
|
||||
label: Events
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings:
|
||||
handler: 'default:paragraph'
|
||||
handler_settings:
|
||||
negate: 0
|
||||
target_bundles:
|
||||
event: event
|
||||
target_bundles_drag_drop:
|
||||
event:
|
||||
enabled: true
|
||||
weight: 2
|
||||
field_type: entity_reference_revisions
|
|
@ -0,0 +1,20 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.paragraph.field_date
|
||||
- paragraphs.paragraphs_type.event
|
||||
module:
|
||||
- datetime
|
||||
id: paragraph.event.field_date
|
||||
field_name: field_date
|
||||
entity_type: paragraph
|
||||
bundle: event
|
||||
label: Date
|
||||
description: ''
|
||||
required: true
|
||||
translatable: false
|
||||
default_value: { }
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: datetime
|
|
@ -0,0 +1,20 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_reference_revisions
|
||||
- node
|
||||
- paragraphs
|
||||
id: node.field_events
|
||||
field_name: field_events
|
||||
entity_type: node
|
||||
type: entity_reference_revisions
|
||||
settings:
|
||||
target_type: paragraph
|
||||
module: entity_reference_revisions
|
||||
locked: false
|
||||
cardinality: -1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,19 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- datetime
|
||||
- paragraphs
|
||||
id: paragraph.field_date
|
||||
field_name: field_date
|
||||
entity_type: paragraph
|
||||
type: datetime
|
||||
settings:
|
||||
datetime_type: date
|
||||
module: datetime
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,10 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
name: Talk
|
||||
type: talk
|
||||
description: ''
|
||||
help: ''
|
||||
new_revision: true
|
||||
preview_mode: 1
|
||||
display_submitted: false
|
|
@ -0,0 +1,9 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: event
|
||||
label: Event
|
||||
icon_uuid: null
|
||||
icon_default: null
|
||||
description: ''
|
||||
behavior_plugins: { }
|
|
@ -0,0 +1,5 @@
|
|||
name: Custom Test
|
||||
type: module
|
||||
core: 8.x
|
||||
core_version_requirements: ^8 || ^9
|
||||
hidden: true
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Tests\custom\Kernel;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\paragraphs\Entity\Paragraph;
|
||||
use Drupal\paragraphs\ParagraphInterface;
|
||||
|
||||
final class UpdatesTalkCreatedDateTest extends EntityKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
// Core.
|
||||
'node',
|
||||
'file',
|
||||
'datetime',
|
||||
|
||||
// Contrib.
|
||||
'entity_reference_revisions',
|
||||
'paragraphs',
|
||||
'hook_event_dispatcher',
|
||||
|
||||
// Custom.
|
||||
'custom',
|
||||
'custom_test',
|
||||
];
|
||||
|
||||
public function testCreatingNode() {
|
||||
$eventDate = (new \DateTime('today'))->modify('+1 week');
|
||||
$eventDateToFormat = $eventDate->format(DateTimeItemInterface::DATE_STORAGE_FORMAT);
|
||||
$eventDateToTimestamp = $eventDate->getTimestamp();
|
||||
|
||||
$talk = $this->createTalk($eventDateToFormat);
|
||||
|
||||
$this->assertEqual($eventDateToTimestamp, $talk->get('created')
|
||||
->getString());
|
||||
}
|
||||
|
||||
public function testUpdatingNode() {
|
||||
$talk = $this->createTalk();
|
||||
|
||||
$eventDate = (new \DateTime('today'))->modify('+1 week');
|
||||
$eventDateToFormat = $eventDate->format(DateTimeItemInterface::DATE_STORAGE_FORMAT);
|
||||
$eventDateToTimestamp = $eventDate->getTimestamp();
|
||||
|
||||
$event = $this->createEvent($eventDateToFormat);
|
||||
$talk->set('field_events', [$event]);
|
||||
$talk->save();
|
||||
|
||||
$this->assertEqual($eventDateToTimestamp, $talk->get('created')
|
||||
->getString());
|
||||
}
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('paragraph');
|
||||
$this->installSchema('node', ['node_access']);
|
||||
|
||||
$this->installConfig(['custom_test']);
|
||||
}
|
||||
|
||||
private function createTalk(?string $eventDateToFormat = NULL): EntityInterface {
|
||||
if ($eventDateToFormat) {
|
||||
$event = $this->createEvent($eventDateToFormat);
|
||||
}
|
||||
|
||||
$talk = Node::create([
|
||||
'title' => 'TDD - Test Driven Drupal',
|
||||
'type' => 'talk',
|
||||
]);
|
||||
|
||||
if (isset($event)) {
|
||||
$talk->set('field_events', [$event]);
|
||||
}
|
||||
|
||||
$talk->save();
|
||||
|
||||
return $talk;
|
||||
}
|
||||
|
||||
private function createEvent(string $eventDateToFormat): ParagraphInterface {
|
||||
$event = Paragraph::create([
|
||||
'field_date' => $eventDateToFormat,
|
||||
'type' => 'event',
|
||||
]);
|
||||
|
||||
$event->save();
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue