diff --git a/.idea/oliverdavies-uk.iml b/.idea/oliverdavies-uk.iml
index 1664e077d..96482bc73 100644
--- a/.idea/oliverdavies-uk.iml
+++ b/.idea/oliverdavies-uk.iml
@@ -6,6 +6,7 @@
+
diff --git a/web/modules/custom/opdavies_blog/opdavies_blog.services.yml b/web/modules/custom/opdavies_blog/opdavies_blog.services.yml
index 2f627f8fc..e27a66f60 100644
--- a/web/modules/custom/opdavies_blog/opdavies_blog.services.yml
+++ b/web/modules/custom/opdavies_blog/opdavies_blog.services.yml
@@ -3,5 +3,9 @@ services:
tags:
- { name: event_subscriber }
+ Drupal\opdavies_blog\EventSubscriber\ReorderBlogTags:
+ tags:
+ - { name: event_subscriber }
+
Drupal\opdavies_blog\Repository\PostRepository:
autowire: true
diff --git a/web/modules/custom/opdavies_blog/src/Entity/Node/Post.php b/web/modules/custom/opdavies_blog/src/Entity/Node/Post.php
index 7744d179b..cda1c152e 100644
--- a/web/modules/custom/opdavies_blog/src/Entity/Node/Post.php
+++ b/web/modules/custom/opdavies_blog/src/Entity/Node/Post.php
@@ -6,6 +6,8 @@ namespace Drupal\opdavies_blog\Entity\Node;
use Drupal\discoverable_entity_bundle_classes\ContentEntityBundleInterface;
use Drupal\node\Entity\Node;
+use Drupal\taxonomy\Entity\Term;
+use Illuminate\Support\Collection;
/**
* Defines an blog post node class.
@@ -24,6 +26,13 @@ class Post extends Node implements ContentEntityBundleInterface {
: NULL;
}
+ /**
+ * @return Collection|Term[]
+ */
+ public function getTags(): Collection {
+ return new Collection($this->get('field_tags')->referencedEntities());
+ }
+
public function hasBeenSentToSocialMedia(): bool {
return (bool) $this->get('field_sent_to_social_media')->getString();
}
@@ -36,6 +45,10 @@ class Post extends Node implements ContentEntityBundleInterface {
return (bool) $this->getExternalLink();
}
+ public function setTags(array $tags): void {
+ $this->set('field_tags', $tags);
+ }
+
public function toTweet(): string {
// TODO: Add tags.
diff --git a/web/modules/custom/opdavies_blog/src/EventSubscriber/PushBlogPostToSocialMedia.php b/web/modules/custom/opdavies_blog/src/EventSubscriber/PushBlogPostToSocialMedia.php
index 70a4097f0..12b1e9fea 100644
--- a/web/modules/custom/opdavies_blog/src/EventSubscriber/PushBlogPostToSocialMedia.php
+++ b/web/modules/custom/opdavies_blog/src/EventSubscriber/PushBlogPostToSocialMedia.php
@@ -48,6 +48,10 @@ final class PushBlogPostToSocialMedia implements EventSubscriberInterface {
$url = \Drupal::configFactory()->get('opdavies_talks.config')
->get('zapier_post_tweet_url');
+ if (!$url) {
+ return;
+ }
+
\Drupal::httpClient()->post($url, [
'form_params' => [
'message' => $entity->toTweet(),
diff --git a/web/modules/custom/opdavies_blog/src/EventSubscriber/ReorderBlogTags.php b/web/modules/custom/opdavies_blog/src/EventSubscriber/ReorderBlogTags.php
new file mode 100644
index 000000000..8290550ed
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/src/EventSubscriber/ReorderBlogTags.php
@@ -0,0 +1,42 @@
+ '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());
+ }
+
+}
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_external_link.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_external_link.yml
new file mode 100644
index 000000000..153e1f888
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_external_link.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_sent_to_social_media.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_sent_to_social_media.yml
new file mode 100644
index 000000000..0a69f39b5
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_sent_to_social_media.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_tags.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_tags.yml
new file mode 100644
index 000000000..9f7092d17
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.field.node.post.field_tags.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_external_link.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_external_link.yml
new file mode 100644
index 000000000..1e6d9b34b
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_external_link.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_sent_to_social_media.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_sent_to_social_media.yml
new file mode 100644
index 000000000..2aa2631e6
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_sent_to_social_media.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_tags.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_tags.yml
new file mode 100644
index 000000000..73f821f2c
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/field.storage.node.field_tags.yml
@@ -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
diff --git a/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/taxonomy.vocabulary.tags.yml b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/taxonomy.vocabulary.tags.yml
new file mode 100644
index 000000000..f6cf44795
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/modules/opdavies_blog_test/config/install/taxonomy.vocabulary.tags.yml
@@ -0,0 +1,7 @@
+langcode: en
+status: true
+dependencies: { }
+name: Tags
+vid: tags
+description: 'Tags for categorising blog posts.'
+weight: 0
diff --git a/web/modules/custom/opdavies_blog/tests/src/Kernel/ReorderBlogTagsTest.php b/web/modules/custom/opdavies_blog/tests/src/Kernel/ReorderBlogTagsTest.php
new file mode 100644
index 000000000..2e1bb9907
--- /dev/null
+++ b/web/modules/custom/opdavies_blog/tests/src/Kernel/ReorderBlogTagsTest.php
@@ -0,0 +1,71 @@
+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');
+ }
+
+}