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
|
@ -73,6 +73,14 @@
|
|||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<groups>
|
||||
<group>
|
||||
<type>GETTERS_AND_SETTERS</type>
|
||||
<order>KEEP</order>
|
||||
</group>
|
||||
</groups>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
|
@ -9,10 +9,14 @@ symfony php vendor/bin/phpcs -n \
|
|||
--exclude="Drupal.Commenting.ClassComment,Drupal.Commenting.FunctionComment" \
|
||||
web/modules/custom
|
||||
|
||||
# symfony php vendor/bin/phpcs -ns \
|
||||
# --standard="Drupal,DrupalPractice" \
|
||||
# --extensions="php,module,inc,install,test,profile,theme" \
|
||||
# --exclude="Drupal.Commenting.ClassComment,Drupal.Commenting.DocComment,Drupal.Commenting.FunctionComment,Drupal.NamingConventions.ValidFunctionName" \
|
||||
# web/modules/custom/**/tests
|
||||
symfony php vendor/bin/phpcs -n \
|
||||
--standard="Drupal,DrupalPractice" \
|
||||
--extensions="php,module,inc,install,test,profile,theme" \
|
||||
--exclude="Drupal.Commenting.ClassComment,Drupal.Commenting.DocComment,Drupal.Commenting.FunctionComment,Drupal.NamingConventions.ValidFunctionName" \
|
||||
web/modules/custom/**/tests
|
||||
|
||||
vendor/bin/phpstan analyze
|
||||
|
||||
symfony php vendor/bin/phpunit \
|
||||
-c web/core \
|
||||
"$@"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"drupal/config_ignore": "^2.2",
|
||||
"drupal/core-composer-scaffold": "^8.8",
|
||||
"drupal/core-recommended": "^8.8",
|
||||
"drupal/hook_event_dispatcher": "^1.28",
|
||||
"drupal/markdown": "^1.3",
|
||||
"drupal/metatag": "^1.11",
|
||||
"drupal/migrate_plus": "^5.0",
|
||||
|
|
104
composer.lock
generated
104
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "48b1c5f01bc8e5486f59462cb6b68de4",
|
||||
"content-hash": "2800d415e7b235b84c6922ceaa045ed8",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
|
@ -2177,6 +2177,108 @@
|
|||
"source": "https://git.drupalcode.org/project/entity_reference_revisions"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "drupal/hook_event_dispatcher",
|
||||
"version": "1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://git.drupalcode.org/project/hook_event_dispatcher.git",
|
||||
"reference": "8.x-1.28"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://ftp.drupal.org/files/projects/hook_event_dispatcher-8.x-1.28.zip",
|
||||
"reference": "8.x-1.28",
|
||||
"shasum": "a8e836015f27c87ad0584452cea3bfb02f0e4f2b"
|
||||
},
|
||||
"require": {
|
||||
"drupal/core": "^8 || ^9"
|
||||
},
|
||||
"require-dev": {
|
||||
"drupal/coder": "8.3.1",
|
||||
"drupal/core": "^8.8",
|
||||
"drupal/eck": "^1.0@alpha",
|
||||
"drupal/paragraphs": "^1.10",
|
||||
"drupal/webform": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.0",
|
||||
"phpmd/phpmd": "2.7.0",
|
||||
"phpunit/phpunit": "^7",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"suggest": {
|
||||
"drupal/paragraphs": "Enables the creation of paragraphs entities.",
|
||||
"drupal/token": "Provides additional tokens not supported by core (most notably fields), as well as a UI for browsing tokens."
|
||||
},
|
||||
"type": "drupal-module",
|
||||
"extra": {
|
||||
"drupal": {
|
||||
"version": "8.x-1.28",
|
||||
"datestamp": "1588695401",
|
||||
"security-coverage": {
|
||||
"status": "covered",
|
||||
"message": "Covered by Drupal's security advisory policy"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Drupal\\hook_event_dispatcher\\": "src/",
|
||||
"Drupal\\webform_event_dispatcher\\": "modules/webform_event_dispatcher/src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Drupal\\Tests\\hook_event_dispatcher\\": "tests/src/",
|
||||
"Drupal\\Tests\\webform_event_dispatcher\\": "modules/webform_event_dispatcher/tests/src/",
|
||||
"Drupal\\Tests\\": "vendor/drupal/core/tests/Drupal/Tests",
|
||||
"Drupal\\TestTools\\": "vendor/drupal/core/tests/Drupal/TestTools",
|
||||
"Drupal\\views\\": "vendor/drupal/core/modules/views/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packages.drupal.org/8/downloads",
|
||||
"scripts": {
|
||||
"test": [
|
||||
"@phplint",
|
||||
"@phpunit",
|
||||
"@phpcs",
|
||||
"@phpmd"
|
||||
],
|
||||
"phplint": [
|
||||
"vendor/bin/parallel-lint --exclude vendor/ --exclude .idea/ -e php,module,inc,install,profile,theme ."
|
||||
],
|
||||
"phpunit": [
|
||||
"vendor/bin/phpunit --configuration=phpunit.xml"
|
||||
],
|
||||
"phpcs": [
|
||||
"vendor/bin/phpcs --ignore=vendor/,.idea/ --standard=vendor/drupal/coder/coder_sniffer/Drupal/ruleset.xml --extensions=php,module,inc,install,profile,theme --report=full --warning-severity=0 ."
|
||||
],
|
||||
"phpcbf": [
|
||||
"vendor/bin/phpcbf --ignore=vendor/,.idea/ --standard=vendor/drupal/coder/coder_sniffer/Drupal/ruleset.xml --extensions=php,module,inc,install,profile,theme ."
|
||||
],
|
||||
"phpmd": [
|
||||
"vendor/bin/phpmd --exclude vendor/,.idea/ --suffixes php,module,inc,install,profile,theme . text phpmd.xml"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"GPL-2.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "pdenooijer",
|
||||
"homepage": "https://www.drupal.org/user/3175437"
|
||||
},
|
||||
{
|
||||
"name": "robin.ingelbrecht",
|
||||
"homepage": "https://www.drupal.org/user/2339074"
|
||||
}
|
||||
],
|
||||
"description": "Dispatches events for several drupal core hooks.",
|
||||
"homepage": "https://www.drupal.org/project/hook_event_dispatcher",
|
||||
"support": {
|
||||
"source": "https://git.drupalcode.org/project/hook_event_dispatcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "drupal/markdown",
|
||||
"version": "1.3.0",
|
||||
|
|
|
@ -17,6 +17,7 @@ module:
|
|||
field_ui: 0
|
||||
file: 0
|
||||
filter: 0
|
||||
hook_event_dispatcher: 0
|
||||
image: 0
|
||||
link: 0
|
||||
markdown: 0
|
||||
|
|
|
@ -7,6 +7,9 @@ parameters:
|
|||
- *Test.php
|
||||
- *TestBase.php
|
||||
checkMissingIterableValueType: false
|
||||
ignoreErrors:
|
||||
- '#Call to an undefined method Drupal\\Core\\Entity\\EntityInterface::get()#'
|
||||
- '#Call to an undefined method Drupal\\Core\\Entity\\EntityInterface::set()#'
|
||||
includes:
|
||||
- vendor/mglaman/phpstan-drupal/extension.neon
|
||||
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
|
||||
|
|
|
@ -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…
Reference in a new issue