parent
5e107b48d6
commit
59a98b8d78
|
@ -6,6 +6,7 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/custom/tests/src" isTestSource="true" packagePrefix="Drupal\Tests\custom" />
|
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/custom/tests/src" isTestSource="true" packagePrefix="Drupal\Tests\custom" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/opd_talks/tests/src" isTestSource="true" packagePrefix="Drupal\Tests\opd_talks" />
|
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/opd_talks/tests/src" isTestSource="true" packagePrefix="Drupal\Tests\opd_talks" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/opd_talks/src" isTestSource="false" packagePrefix="Drupal\opd_talks" />
|
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/opd_talks/src" isTestSource="false" packagePrefix="Drupal\opd_talks" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/web/modules/custom/opdavies_blog/tests/src" isTestSource="true" packagePrefix="Drupal\Tests\opdavies_blog" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/mink" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/mink" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/mink-browserkit-driver" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/mink-browserkit-driver" />
|
||||||
|
|
|
@ -3,5 +3,9 @@ services:
|
||||||
tags:
|
tags:
|
||||||
- { name: event_subscriber }
|
- { name: event_subscriber }
|
||||||
|
|
||||||
|
Drupal\opdavies_blog\EventSubscriber\ReorderBlogTags:
|
||||||
|
tags:
|
||||||
|
- { name: event_subscriber }
|
||||||
|
|
||||||
Drupal\opdavies_blog\Repository\PostRepository:
|
Drupal\opdavies_blog\Repository\PostRepository:
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace Drupal\opdavies_blog\Entity\Node;
|
||||||
|
|
||||||
use Drupal\discoverable_entity_bundle_classes\ContentEntityBundleInterface;
|
use Drupal\discoverable_entity_bundle_classes\ContentEntityBundleInterface;
|
||||||
use Drupal\node\Entity\Node;
|
use Drupal\node\Entity\Node;
|
||||||
|
use Drupal\taxonomy\Entity\Term;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an blog post node class.
|
* Defines an blog post node class.
|
||||||
|
@ -24,6 +26,13 @@ class Post extends Node implements ContentEntityBundleInterface {
|
||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Term[]
|
||||||
|
*/
|
||||||
|
public function getTags(): Collection {
|
||||||
|
return new Collection($this->get('field_tags')->referencedEntities());
|
||||||
|
}
|
||||||
|
|
||||||
public function hasBeenSentToSocialMedia(): bool {
|
public function hasBeenSentToSocialMedia(): bool {
|
||||||
return (bool) $this->get('field_sent_to_social_media')->getString();
|
return (bool) $this->get('field_sent_to_social_media')->getString();
|
||||||
}
|
}
|
||||||
|
@ -36,6 +45,10 @@ class Post extends Node implements ContentEntityBundleInterface {
|
||||||
return (bool) $this->getExternalLink();
|
return (bool) $this->getExternalLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setTags(array $tags): void {
|
||||||
|
$this->set('field_tags', $tags);
|
||||||
|
}
|
||||||
|
|
||||||
public function toTweet(): string {
|
public function toTweet(): string {
|
||||||
// TODO: Add tags.
|
// TODO: Add tags.
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,10 @@ final class PushBlogPostToSocialMedia implements EventSubscriberInterface {
|
||||||
$url = \Drupal::configFactory()->get('opdavies_talks.config')
|
$url = \Drupal::configFactory()->get('opdavies_talks.config')
|
||||||
->get('zapier_post_tweet_url');
|
->get('zapier_post_tweet_url');
|
||||||
|
|
||||||
|
if (!$url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
\Drupal::httpClient()->post($url, [
|
\Drupal::httpClient()->post($url, [
|
||||||
'form_params' => [
|
'form_params' => [
|
||||||
'message' => $entity->toTweet(),
|
'message' => $entity->toTweet(),
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Drupal\opdavies_blog\EventSubscriber;
|
||||||
|
|
||||||
|
use Drupal\hook_event_dispatcher\Event\Entity\BaseEntityEvent;
|
||||||
|
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
|
||||||
|
use Drupal\opdavies_blog\Entity\Node\Post;
|
||||||
|
use Drupal\taxonomy\TermInterface;
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
|
final class ReorderBlogTags implements EventSubscriberInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public static function getSubscribedEvents() {
|
||||||
|
return [
|
||||||
|
HookEventDispatcherInterface::ENTITY_PRE_SAVE => 'onEntityPreSave',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEntityPresave(BaseEntityEvent $event): void {
|
||||||
|
$entity = $event->getEntity();
|
||||||
|
|
||||||
|
if ($entity->getEntityTypeId() != 'node') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Post $entity */
|
||||||
|
if ($entity->bundle() != 'post') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sortedTags = $entity->getTags()
|
||||||
|
->sortBy(fn(TermInterface $tag) => $tag->label());
|
||||||
|
|
||||||
|
$entity->setTags($sortedTags->toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.storage.node.field_external_link
|
||||||
|
- node.type.post
|
||||||
|
module:
|
||||||
|
- link
|
||||||
|
id: node.post.field_external_link
|
||||||
|
field_name: field_external_link
|
||||||
|
entity_type: node
|
||||||
|
bundle: post
|
||||||
|
label: 'External link'
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
translatable: false
|
||||||
|
default_value: { }
|
||||||
|
default_value_callback: ''
|
||||||
|
settings:
|
||||||
|
link_type: 16
|
||||||
|
title: 2
|
||||||
|
field_type: link
|
|
@ -0,0 +1,22 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.storage.node.field_sent_to_social_media
|
||||||
|
- node.type.post
|
||||||
|
id: node.post.field_sent_to_social_media
|
||||||
|
field_name: field_sent_to_social_media
|
||||||
|
entity_type: node
|
||||||
|
bundle: post
|
||||||
|
label: 'Sent to social media'
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
translatable: false
|
||||||
|
default_value:
|
||||||
|
-
|
||||||
|
value: 0
|
||||||
|
default_value_callback: ''
|
||||||
|
settings:
|
||||||
|
on_label: 'On'
|
||||||
|
off_label: 'Off'
|
||||||
|
field_type: boolean
|
|
@ -0,0 +1,28 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- field.storage.node.field_tags
|
||||||
|
- node.type.post
|
||||||
|
- taxonomy.vocabulary.tags
|
||||||
|
id: node.post.field_tags
|
||||||
|
field_name: field_tags
|
||||||
|
entity_type: node
|
||||||
|
bundle: post
|
||||||
|
label: Tags
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
translatable: false
|
||||||
|
default_value: { }
|
||||||
|
default_value_callback: ''
|
||||||
|
settings:
|
||||||
|
handler: 'default:taxonomy_term'
|
||||||
|
handler_settings:
|
||||||
|
target_bundles:
|
||||||
|
tags: tags
|
||||||
|
sort:
|
||||||
|
field: name
|
||||||
|
direction: asc
|
||||||
|
auto_create: true
|
||||||
|
auto_create_bundle: ''
|
||||||
|
field_type: entity_reference
|
|
@ -0,0 +1,18 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
module:
|
||||||
|
- link
|
||||||
|
- node
|
||||||
|
id: node.field_external_link
|
||||||
|
field_name: field_external_link
|
||||||
|
entity_type: node
|
||||||
|
type: link
|
||||||
|
settings: { }
|
||||||
|
module: link
|
||||||
|
locked: false
|
||||||
|
cardinality: 1
|
||||||
|
translatable: true
|
||||||
|
indexes: { }
|
||||||
|
persist_with_no_fields: false
|
||||||
|
custom_storage: false
|
|
@ -0,0 +1,17 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
module:
|
||||||
|
- node
|
||||||
|
id: node.field_sent_to_social_media
|
||||||
|
field_name: field_sent_to_social_media
|
||||||
|
entity_type: node
|
||||||
|
type: boolean
|
||||||
|
settings: { }
|
||||||
|
module: core
|
||||||
|
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:
|
||||||
|
- node
|
||||||
|
- taxonomy
|
||||||
|
id: node.field_tags
|
||||||
|
field_name: field_tags
|
||||||
|
entity_type: node
|
||||||
|
type: entity_reference
|
||||||
|
settings:
|
||||||
|
target_type: taxonomy_term
|
||||||
|
module: core
|
||||||
|
locked: false
|
||||||
|
cardinality: -1
|
||||||
|
translatable: true
|
||||||
|
indexes: { }
|
||||||
|
persist_with_no_fields: false
|
||||||
|
custom_storage: false
|
|
@ -0,0 +1,7 @@
|
||||||
|
langcode: en
|
||||||
|
status: true
|
||||||
|
dependencies: { }
|
||||||
|
name: Tags
|
||||||
|
vid: tags
|
||||||
|
description: 'Tags for categorising blog posts.'
|
||||||
|
weight: 0
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\opdavies_blog\Kernel;
|
||||||
|
|
||||||
|
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||||
|
use Drupal\node\Entity\Node;
|
||||||
|
use Drupal\opdavies_blog\Entity\Node\Post;
|
||||||
|
use Drupal\taxonomy\Entity\Vocabulary;
|
||||||
|
use Drupal\taxonomy\TermInterface;
|
||||||
|
use Drupal\taxonomy\VocabularyInterface;
|
||||||
|
use Drupal\Tests\node\Traits\NodeCreationTrait;
|
||||||
|
use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
|
||||||
|
|
||||||
|
final class ReorderBlogTagsTest extends EntityKernelTestBase {
|
||||||
|
|
||||||
|
use NodeCreationTrait;
|
||||||
|
use TaxonomyTestTrait;
|
||||||
|
|
||||||
|
public static $modules = [
|
||||||
|
// Core.
|
||||||
|
'node',
|
||||||
|
'taxonomy',
|
||||||
|
'link',
|
||||||
|
|
||||||
|
// Contrib.
|
||||||
|
'discoverable_entity_bundle_classes',
|
||||||
|
'hook_event_dispatcher',
|
||||||
|
|
||||||
|
// Custom.
|
||||||
|
'opdavies_blog_test',
|
||||||
|
'opdavies_blog',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function it_reorders_tags_on_blog_posts_to_be_arranged_alphabetically(): void {
|
||||||
|
/** @var VocabularyInterface $vocabulary */
|
||||||
|
$vocabulary = Vocabulary::load('tags');
|
||||||
|
|
||||||
|
$this->createTerm($vocabulary, ['name' => 'Drupal']); // 1
|
||||||
|
$this->createTerm($vocabulary, ['name' => 'PHP']); // 2
|
||||||
|
$this->createTerm($vocabulary, ['name' => 'Symfony']); // 3
|
||||||
|
|
||||||
|
$post = $this->createNode([
|
||||||
|
'field_tags' => [3, 1, 2],
|
||||||
|
'type' => 'post',
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** @var Post $post */
|
||||||
|
$post = Node::load($post->id());
|
||||||
|
|
||||||
|
$this->assertSame(
|
||||||
|
['Drupal', 'PHP', 'Symfony'],
|
||||||
|
$post->getTags()
|
||||||
|
->map(fn(TermInterface $tag) => $tag->label())
|
||||||
|
->toArray()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->installConfig([
|
||||||
|
'filter',
|
||||||
|
'opdavies_blog_test',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->installEntitySchema('taxonomy_vocabulary');
|
||||||
|
$this->installEntitySchema('taxonomy_term');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue