From 19dceed3b4f9610e69d339e45a6afe9fa06e0181 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 22 Apr 2025 14:39:43 +0200
Subject: [PATCH 01/46] Initial efforts for making ad content entities
 bundleable

---
 ad.routing.yml                                |  2 +-
 .../ad_content/ad_content.links.action.yml    |  6 ++
 modules/ad_content/ad_content.links.task.yml  |  5 ++
 modules/ad_content/ad_content.routing.yml     |  8 +++
 modules/ad_content/src/Entity/AdContent.php   |  1 +
 .../src/Entity/AdContentListBuilder.php       |  2 +
 .../ad_content/src/Entity/AdContentType.php   | 51 ++++++++++++++
 .../src/Entity/AdContentTypeInterface.php     | 15 ++++
 .../src/Entity/AdContentTypeListBuilder.php   | 39 +++++++++++
 .../src/Form/AdContentTypeEntityForm.php      | 68 +++++++++++++++++++
 10 files changed, 196 insertions(+), 1 deletion(-)
 create mode 100644 modules/ad_content/src/Entity/AdContentType.php
 create mode 100644 modules/ad_content/src/Entity/AdContentTypeInterface.php
 create mode 100644 modules/ad_content/src/Entity/AdContentTypeListBuilder.php
 create mode 100644 modules/ad_content/src/Form/AdContentTypeEntityForm.php

diff --git a/ad.routing.yml b/ad.routing.yml
index 1f7e692..4260b20 100644
--- a/ad.routing.yml
+++ b/ad.routing.yml
@@ -1,5 +1,5 @@
 ad.settings:
-  path: '/admin/ad/settings'
+  path: '/admin/ad'
   defaults:
     _form: '\Drupal\ad\Form\SettingsForm'
     _title: 'Settings'
diff --git a/modules/ad_content/ad_content.links.action.yml b/modules/ad_content/ad_content.links.action.yml
index 1aafc8e..dba5bfb 100644
--- a/modules/ad_content/ad_content.links.action.yml
+++ b/modules/ad_content/ad_content.links.action.yml
@@ -3,3 +3,9 @@ ad_content.add_form:
   title: 'Add content AD'
   appears_on:
     - entity.ad_content.collection
+
+ad_content_type.add_form:
+  route_name: entity.ad_content_type.add_form
+  title: 'Add content type'
+  appears_on:
+    - entity.ad_content_type.collection
diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
index 563bdde..7b4386b 100644
--- a/modules/ad_content/ad_content.links.task.yml
+++ b/modules/ad_content/ad_content.links.task.yml
@@ -8,3 +8,8 @@ ad.admin.settings:
   title: 'Settings'
   base_route: entity.ad_content.collection
   weight: 1
+
+entity.ad_content_type.collection:
+  route_name: entity.ad_content_type.collection
+  title: 'Content types'
+  base_route: entity.ad_content.collection
diff --git a/modules/ad_content/ad_content.routing.yml b/modules/ad_content/ad_content.routing.yml
index 971a1eb..a9ec48a 100644
--- a/modules/ad_content/ad_content.routing.yml
+++ b/modules/ad_content/ad_content.routing.yml
@@ -5,3 +5,11 @@ ad_content.render_ad:
     _title: 'Render AD'
   requirements:
     _permission: 'access content'
+
+entity.ad_content_type.collection:
+  path: '/admin/ad/content_type'
+  defaults:
+    _controller: '\Drupal\ad_content\Controller\ImpressionController::renderAds'
+    _title: 'Content types'
+  requirements:
+    _permission: 'administer ads'
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 62d7249..7123fe2 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -41,6 +41,7 @@ use Drupal\user\EntityOwnerTrait;
  *   base_table = "ad_content",
  *   revision_table = "ad_content_revision",
  *   admin_permission="administer ads",
+ *   bundle_entity_type = "ad_content_type",
  *   field_ui_base_route = "entity.ad_content.collection",
  *   links = {
  *     "add-form" = "/admin/ad/content/add",
diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index 271bb32..8eaed0b 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -18,6 +18,7 @@ class AdContentListBuilder extends EntityListBuilder {
       'id' => $this->t('ID'),
       'title' => $this->t('Title'),
       'size' => $this->t('Size'),
+      'bundle' => $this->t('Content type'),
       'status' => $this->t('Status'),
     ];
 
@@ -40,6 +41,7 @@ class AdContentListBuilder extends EntityListBuilder {
         ],
       ],
       'size' => $ad_content->getSizeId(),
+      'bundle' => $ad_content->bundle(),
       'status' => $ad_content->isPublished(),
     ];
 
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
new file mode 100644
index 0000000..24cc5e3
--- /dev/null
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\ad_content\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
+
+/**
+ * Defines the AD content type bundle class.
+ *
+ * @ConfigEntityType(
+ *   id = "ad_content_type",
+ *   label = @Translation("AD Content Type"),
+ *   label_singular = @Translation("AD content type"),
+ *   label_plural = @Translation("AD content types"),
+ *   label_count = @PluralTranslation(
+ *     singular = "@count AD content type",
+ *     plural = "@count AD content types",
+ *   ),
+ *   bundle_of = "ad_content",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid",
+ *   },
+ *   config_prefix = "ad_content_type",
+ *   config_export = {
+ *     "id",
+ *     "label",
+ *   },
+ *   handlers = {
+ *     "form" = {
+ *       "default" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
+ *       "add" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
+ *       "edit" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
+ *       "delete" = "Drupal\Core\Entity\EntityDeleteForm",
+ *     },
+ *     "route_provider" = {
+ *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
+ *     },
+ *   },
+ *   admin_permission = "administer ads",
+ *   links = {
+ *     "canonical" = "/admin/ad/content_type/{ad_content_type}",
+ *     "add-form" = "/admin/ad/content_type/add",
+ *     "edit-form" = "/admin/ad/content_type/{ad_content_type}/edit",
+ *     "delete-form" = "/admin/ad/content_type/{ad_content_type}/delete",
+ *     "collection" = "/admin/ad/content_type",
+ *   }
+ * )
+ */
+class AdContentType extends ConfigEntityBundleBase {}
diff --git a/modules/ad_content/src/Entity/AdContentTypeInterface.php b/modules/ad_content/src/Entity/AdContentTypeInterface.php
new file mode 100644
index 0000000..4aa4176
--- /dev/null
+++ b/modules/ad_content/src/Entity/AdContentTypeInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\ad_content\Entity;
+
+use Drupal\ad\AdInterface;
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Entity\EntityPublishedInterface;
+use Drupal\Core\Entity\RevisionLogInterface;
+use Drupal\user\EntityOwnerInterface;
+
+/**
+ * Common interface for AD content type bundle entities.
+ */
+interface AdContentTypeInterface extends AdInterface, ConfigEntityInterface, EntityOwnerInterface, EntityChangedInterface, EntityPublishedInterface, RevisionLogInterface {}
diff --git a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
new file mode 100644
index 0000000..b175f35
--- /dev/null
+++ b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\ad_content\Entity;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityListBuilder;
+
+/**
+ * AD content list builder.
+ */
+class AdContentTypeListBuilder extends EntityListBuilder {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildHeader() {
+    $header = [
+      'id' => $this->t('ID'),
+      'label' => $this->t('Title'),
+    ];
+
+    return $header + parent::buildHeader();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildRow(EntityInterface $ad_content_type) {
+    /** @var \Drupal\ad_content\Entity\AdContentTypeInterface $ad_content_type */
+
+    $row = [
+      'id' => $ad_content_type->id(),
+      'label' => $ad_content_type->label(),
+    ];
+
+    return $row + parent::buildRow($ad_content_type);
+  }
+
+}
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
new file mode 100644
index 0000000..abf891c
--- /dev/null
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Drupal\ad_content\Form;
+
+use Drupal\Core\Entity\BundleEntityFormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Entity form for the AD content type bundle.
+ */
+class AdContentTypeEntityForm extends BundleEntityFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    $entity_type = $this->entity;
+    $content_entity_id = $entity_type->getEntityType()->getBundleOf();
+
+    $form['label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Label'),
+      '#maxlength' => 255,
+      '#default_value' => $entity_type->label(),
+      '#description' => $this->t("Label for the %content_entity_id entity type (bundle).", ['%content_entity_id' => $content_entity_id]),
+      '#required' => TRUE,
+    ];
+
+    $form['id'] = [
+      '#type' => 'machine_name',
+      '#default_value' => $entity_type->id(),
+      '#machine_name' => [
+        'exists' => '\Drupal\ad_content\Entity\AdContentType::load',
+      ],
+      '#disabled' => !$entity_type->isNew(),
+    ];
+
+    return $this->protectBundleIdElement($form);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    $messenger = \Drupal::messenger();
+    $entity_type = $this->entity;
+    $status = $entity_type->save();
+    $message_params = [
+      '%label' => $entity_type->label(),
+      '%content_entity_id' => $entity_type->getEntityType()->getBundleOf(),
+    ];
+
+    // Provide a message for the user and redirect them back to the collection.
+    switch ($status) {
+      case SAVED_NEW:
+        $messenger->addMessage($this->t('Created the %label %content_entity_id entity type.', $message_params));
+        break;
+
+      default:
+        $messenger->addMessage($this->t('Saved the %label %content_entity_id entity type.', $message_params));
+    }
+
+    $form_state->setRedirectUrl($entity_type->toUrl('collection'));
+  }
+
+}
-- 
GitLab


From cd6a1ddf268596b715acbc4e82d5fdaa50418292 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 22 Apr 2025 15:00:52 +0200
Subject: [PATCH 02/46] Further development on ad content type bundles

---
 modules/ad_content/ad_content.routing.yml     |  8 ---
 .../ad_content/src/Entity/AdContentType.php   | 55 ++++++++++++++++++-
 .../src/Entity/AdContentTypeInterface.php     |  7 +--
 3 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/modules/ad_content/ad_content.routing.yml b/modules/ad_content/ad_content.routing.yml
index a9ec48a..971a1eb 100644
--- a/modules/ad_content/ad_content.routing.yml
+++ b/modules/ad_content/ad_content.routing.yml
@@ -5,11 +5,3 @@ ad_content.render_ad:
     _title: 'Render AD'
   requirements:
     _permission: 'access content'
-
-entity.ad_content_type.collection:
-  path: '/admin/ad/content_type'
-  defaults:
-    _controller: '\Drupal\ad_content\Controller\ImpressionController::renderAds'
-    _title: 'Content types'
-  requirements:
-    _permission: 'administer ads'
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 24cc5e3..48d8b59 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -28,6 +28,7 @@ use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
  *     "label",
  *   },
  *   handlers = {
+ *     "list_builder" = "Drupal\ad_content\Entity\AdContentTypeListBuilder",
  *     "form" = {
  *       "default" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
  *       "add" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
@@ -48,4 +49,56 @@ use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
  *   }
  * )
  */
-class AdContentType extends ConfigEntityBundleBase {}
+class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
+
+  /**
+   * Returns the UUID of the ad content type.
+   */
+  public function getUuid(): string {
+    return $this->uuid();
+  }
+
+  /**
+   * Returns the id of the ad content type.
+   */
+  public function getId(): string {
+    return $this->id();
+  }
+
+  /**
+   * Returns the label of the ad content type.
+   */
+  public function getLabel(): string {
+    return $this->label();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
+    $fields = parent::baseFieldDefinitions($entity_type);
+    $fields += static::ownerBaseFieldDefinitions($entity_type);
+
+    $fields['title'] = BaseFieldDefinition::create('string')
+      ->setLabel(new TranslatableMarkup('Title'))
+      ->setDescription(new TranslatableMarkup('A brief description of the AD.'))
+      ->setRevisionable(TRUE)
+      ->setRequired(TRUE)
+      ->addConstraint('UniqueField', [])
+      ->setDisplayOptions('form', [
+        'type' => 'string_textfield',
+        'weight' => -5,
+      ])
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'hidden',
+        'type' => 'string',
+        'weight' => -5,
+      ])
+      ->setDisplayConfigurable('view', TRUE);
+
+    return $fields;
+  }
+
+}
diff --git a/modules/ad_content/src/Entity/AdContentTypeInterface.php b/modules/ad_content/src/Entity/AdContentTypeInterface.php
index 4aa4176..0a0e088 100644
--- a/modules/ad_content/src/Entity/AdContentTypeInterface.php
+++ b/modules/ad_content/src/Entity/AdContentTypeInterface.php
@@ -2,14 +2,9 @@
 
 namespace Drupal\ad_content\Entity;
 
-use Drupal\ad\AdInterface;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Entity\EntityChangedInterface;
-use Drupal\Core\Entity\EntityPublishedInterface;
-use Drupal\Core\Entity\RevisionLogInterface;
-use Drupal\user\EntityOwnerInterface;
 
 /**
  * Common interface for AD content type bundle entities.
  */
-interface AdContentTypeInterface extends AdInterface, ConfigEntityInterface, EntityOwnerInterface, EntityChangedInterface, EntityPublishedInterface, RevisionLogInterface {}
+interface AdContentTypeInterface extends ConfigEntityInterface {}
-- 
GitLab


From 91741f7b40e35d05dfa1e79c26abf9b5c49feb3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 23 Apr 2025 10:23:08 +0200
Subject: [PATCH 03/46] Initial routing rewrite

---
 README.md                                     |  2 +-
 ad.links.menu.yml                             |  7 ++---
 ad.permissions.yml                            |  4 +--
 ad.routing.yml                                |  4 +--
 modules/ad_content/ad_content.links.menu.yml  |  4 +++
 modules/ad_content/ad_content.links.task.yml  | 15 ----------
 modules/ad_content/ad_content.module          |  7 -----
 modules/ad_content/ad_content.services.yml    |  5 ----
 modules/ad_content/src/Entity/AdContent.php   | 16 ++++++++--
 .../ad_content/src/Entity/AdContentType.php   | 29 -------------------
 .../src/Routing/RouteSubscriber.php           | 23 ---------------
 11 files changed, 25 insertions(+), 91 deletions(-)
 create mode 100644 modules/ad_content/ad_content.links.menu.yml
 delete mode 100644 modules/ad_content/ad_content.links.task.yml
 delete mode 100644 modules/ad_content/ad_content.services.yml
 delete mode 100644 modules/ad_content/src/Routing/RouteSubscriber.php

diff --git a/README.md b/README.md
index 881d156..dc1dbc2 100644
--- a/README.md
+++ b/README.md
@@ -26,5 +26,5 @@ tracker, typically the `AD Content` and `AD Tracker` modules.
 # Usage
 
 - After enabling all the required modules, configure a tracker for every enabled
-AD source at `/admin/ad/settings`.
+AD source at `/admin/config/ad`.
 - Place one or more AD blocks as needed.
diff --git a/ad.links.menu.yml b/ad.links.menu.yml
index 10f53fc..69c3453 100644
--- a/ad.links.menu.yml
+++ b/ad.links.menu.yml
@@ -1,6 +1,5 @@
-ad.admin:
+ad.settings:
   title: 'Advertisement'
-  description: 'Configure and manage all advertisement settings.'
+  description: 'Configure and manage advertisement settings.'
   route_name: ad.settings
-  parent: system.admin
-  weight: 4
+  parent: system.admin_config
diff --git a/ad.permissions.yml b/ad.permissions.yml
index d016025..9fa2fda 100644
--- a/ad.permissions.yml
+++ b/ad.permissions.yml
@@ -1,8 +1,8 @@
 administer ads:
   title: 'Administer ADs'
-  description: 'Manage all advertisements.'
+  description: 'Manage advertisements.'
   restrict access: true
 administer ad settings:
   title: 'Administer AD settings'
-  description: 'Configure and manage all advertisement settings.'
+  description: 'Configure and manage advertisement settings.'
   restrict access: true
diff --git a/ad.routing.yml b/ad.routing.yml
index 4260b20..93a7cc9 100644
--- a/ad.routing.yml
+++ b/ad.routing.yml
@@ -1,7 +1,7 @@
 ad.settings:
-  path: '/admin/ad'
+  path: '/admin/config/ad'
   defaults:
     _form: '\Drupal\ad\Form\SettingsForm'
-    _title: 'Settings'
+    _title: 'Advertisement Settings'
   requirements:
     _permission: 'administer ad settings'
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
new file mode 100644
index 0000000..234879c
--- /dev/null
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -0,0 +1,4 @@
+entity.ad_content.collection:
+  route_name: entity.ad_content.collection
+  title: 'Advertisements'
+  base_route: system.admin_content
diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
deleted file mode 100644
index 7b4386b..0000000
--- a/modules/ad_content/ad_content.links.task.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-entity.ad_content.collection:
-  route_name: entity.ad_content.collection
-  title: 'Content'
-  base_route: entity.ad_content.collection
-
-ad.admin.settings:
-  route_name: ad.settings
-  title: 'Settings'
-  base_route: entity.ad_content.collection
-  weight: 1
-
-entity.ad_content_type.collection:
-  route_name: entity.ad_content_type.collection
-  title: 'Content types'
-  base_route: entity.ad_content.collection
diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index 7f4fc55..2109d74 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -4,10 +4,3 @@
  * @file
  * Main file for the "AD Content" module.
  */
-
-/**
- * Implements hook_menu_links_discovered_alter().
- */
-function ad_content_menu_links_discovered_alter(&$links) {
-  $links['ad.admin']['route_name'] = 'entity.ad_content.collection';
-}
diff --git a/modules/ad_content/ad_content.services.yml b/modules/ad_content/ad_content.services.yml
deleted file mode 100644
index 8b1a26c..0000000
--- a/modules/ad_content/ad_content.services.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-services:
-  ad_content.route_subscriber:
-    class: Drupal\ad_content\Routing\RouteSubscriber
-    tags:
-      - { name: event_subscriber }
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 7123fe2..384f889 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -53,11 +53,12 @@ use Drupal\user\EntityOwnerTrait;
  *   },
  *   entity_keys = {
  *     "id" = "id",
+ *     "bundle" = "bundle",
  *     "revision" = "revision_id",
  *     "label" = "title",
  *     "uuid" = "uuid",
  *     "published" = "status",
- *     "owner" = "uid",
+ *     "owner" = "uid"
  *   },
  *   revision_metadata_keys = {
  *     "revision_user" = "revision_user",
@@ -112,8 +113,17 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
     $fields = parent::baseFieldDefinitions($entity_type);
     $fields += static::ownerBaseFieldDefinitions($entity_type);
 
-    // @todo Implement AD bundles.
-    // $fields['type']->setDescription(t('The AD Content type.'));
+    $fields['type'] = BaseFieldDefinition::create('list_string')
+      ->setLabel(new TranslatableMarkup('AD content type'))
+      ->setDescription(new TranslatableMarkup('The ad content type.'))
+      ->setRevisionable(TRUE)
+      ->setRequired(TRUE)
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayConfigurable('view', TRUE)
+      ->setSettings([
+        'allowed_values_function' => 'ad_content_get_content_types',
+      ]);
+
     $fields['status']
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 48d8b59..ec9af82 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -72,33 +72,4 @@ class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInter
     return $this->label();
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
-    /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
-    $fields = parent::baseFieldDefinitions($entity_type);
-    $fields += static::ownerBaseFieldDefinitions($entity_type);
-
-    $fields['title'] = BaseFieldDefinition::create('string')
-      ->setLabel(new TranslatableMarkup('Title'))
-      ->setDescription(new TranslatableMarkup('A brief description of the AD.'))
-      ->setRevisionable(TRUE)
-      ->setRequired(TRUE)
-      ->addConstraint('UniqueField', [])
-      ->setDisplayOptions('form', [
-        'type' => 'string_textfield',
-        'weight' => -5,
-      ])
-      ->setDisplayConfigurable('form', TRUE)
-      ->setDisplayOptions('view', [
-        'label' => 'hidden',
-        'type' => 'string',
-        'weight' => -5,
-      ])
-      ->setDisplayConfigurable('view', TRUE);
-
-    return $fields;
-  }
-
 }
diff --git a/modules/ad_content/src/Routing/RouteSubscriber.php b/modules/ad_content/src/Routing/RouteSubscriber.php
deleted file mode 100644
index 1daf545..0000000
--- a/modules/ad_content/src/Routing/RouteSubscriber.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-namespace Drupal\ad_content\Routing;
-
-use Drupal\Core\Routing\RouteSubscriberBase;
-use Symfony\Component\Routing\RouteCollection;
-
-/**
- * AD content route subscriber.
- */
-class RouteSubscriber extends RouteSubscriberBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterRoutes(RouteCollection $collection) {
-    // Move AD settings to a dedicated route to make room for the AD content
-    // listing.
-    $collection->get('ad.settings')
-      ->setPath('/admin/ad/settings');
-  }
-
-}
-- 
GitLab


From 0f49c38ee17ff9d24ae8465f26636fa9df84bfdb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 23 Apr 2025 11:15:56 +0200
Subject: [PATCH 04/46] Unifying the word 'ad' to correct english spelling

---
 README.md                                     | 24 ++++++++--------
 ad.info.yml                                   |  2 +-
 ad.module                                     |  4 +--
 ad.permissions.yml                            |  4 +--
 config/schema/ad.schema.yml                   |  4 +--
 modules/ad_content/ad_content.info.yml        |  4 +--
 .../ad_content/ad_content.links.action.yml    |  4 +--
 modules/ad_content/ad_content.links.menu.yml  |  7 +++++
 modules/ad_content/ad_content.module          |  2 +-
 modules/ad_content/ad_content.routing.yml     |  2 +-
 .../optional/views.view.ad_administration.yml |  2 +-
 .../optional/views.view.ad_statistics.yml     |  6 ++--
 .../src/Controller/ImpressionController.php   | 12 ++++----
 modules/ad_content/src/Entity/AdContent.php   | 28 +++++++++----------
 .../src/Entity/AdContentInterface.php         |  2 +-
 .../src/Entity/AdContentListBuilder.php       |  2 +-
 .../ad_content/src/Entity/AdContentType.php   | 12 ++++----
 .../src/Entity/AdContentTypeInterface.php     |  2 +-
 .../src/Entity/AdContentTypeListBuilder.php   |  2 +-
 .../src/Entity/AdContentViewController.php    |  4 +--
 .../src/Field/AdContentImageFormatterBase.php |  4 +--
 .../src/Form/AdContentTypeEntityForm.php      |  2 +-
 .../src/Plugin/Ad/Bucket/AdContentBucket.php  | 24 ++++++++--------
 .../AdContentImageFormatter.php               |  4 +--
 .../TrackAdContentImageFormatter.php          |  4 +--
 modules/ad_track/ad_track.info.yml            |  4 +--
 modules/ad_track/ad_track.install             |  8 +++---
 modules/ad_track/ad_track.module              |  2 +-
 modules/ad_track/ad_track.views.inc           | 14 +++++-----
 .../src/Controller/ClickTrackController.php   | 10 +++----
 modules/ad_track/src/Entity/AdTrackEvent.php  |  8 +++---
 .../src/Entity/AdTrackEventStorageSchema.php  |  2 +-
 .../src/Entity/AdTrackEventViewsData.php      |  4 +--
 .../Plugin/Ad/Track/DelayedLocalTracker.php   |  6 ++--
 .../src/Plugin/Ad/Track/LocalTracker.php      | 10 +++----
 .../DelayedLocalTrackQueueWorker.php          |  8 +++---
 modules/ad_track/src/TotalSqlStorage.php      |  4 +--
 .../ad_track/src/TotalStorageInterface.php    | 18 ++++++------
 src/AdFactoryBase.php                         |  4 +--
 src/AdFactoryInterface.php                    |  4 +--
 src/AdInterface.php                           | 12 ++++----
 src/Bucket/BucketFactory.php                  |  6 ++--
 src/Bucket/BucketFactoryInterface.php         |  6 ++--
 src/Bucket/BucketInterface.php                | 22 +++++++--------
 src/Bucket/BucketPluginManager.php            |  2 +-
 src/Form/SettingsForm.php                     | 14 +++++-----
 src/Plugin/Ad/Track/NullTracker.php           |  2 +-
 src/Plugin/Block/AdBlock.php                  |  6 ++--
 .../Block/Derivative/AdBlockDeriver.php       |  6 ++--
 src/Size/Size.php                             |  6 ++--
 src/Size/SizeFactory.php                      | 14 +++++-----
 src/Size/SizeInterface.php                    |  6 ++--
 src/Track/TrackerFactory.php                  |  4 +--
 src/Track/TrackerFactoryInterface.php         |  6 ++--
 src/Track/TrackerInterface.php                | 14 +++++-----
 src/Track/TrackerPluginManager.php            |  2 +-
 56 files changed, 204 insertions(+), 197 deletions(-)

diff --git a/README.md b/README.md
index dc1dbc2..9acbabc 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,30 @@
 # Summary
 
 This module provides a flexible and extensible advertising system allowing
-display ADs via blocks.
+display ads via blocks.
 
-This AD system supports enabling multiple AD sources and tracking systems: by
-default both AD data and AD tracking data are stored in the local database, but
-alternative AD sources or trackers can be provided via plugins. For instance a
-module could define a plugin to track AD events via Google Analytics.
+This ad system supports enabling multiple ad sources and tracking systems: by
+default both ad data and ad tracking data are stored in the local database, but
+alternative ad sources or trackers can be provided via plugins. For instance a
+module could define a plugin to track ad events via Google Analytics.
 
-The native `AD Tracker` module implements two trackers:
-- The `Local AD event tracker` tracks impressions/clicks immediately, which on
+The native `Ad Tracker` module implements two trackers:
+- The `Local ad event tracker` tracks impressions/clicks immediately, which on
   high traffic sites can result in significant additional load for the web
   servers.
-- The `Queue-based local AD event tracker` tracks data via a queue, so events
+- The `Queue-based local ad event tracker` tracks data via a queue, so events
   will only actually appear in the statistics display section after running
   cron or after manually processing `ad_track_queue`.
 
 
 # Installation
 
-Enable the main `AD` module, together with at least one AD source and one
-tracker, typically the `AD Content` and `AD Tracker` modules.
+Enable the main `Ad` module, together with at least one ad source and one
+tracker, typically the `Ad Content` and `Ad Tracker` modules.
 
 
 # Usage
 
 - After enabling all the required modules, configure a tracker for every enabled
-AD source at `/admin/config/ad`.
-- Place one or more AD blocks as needed.
+ad source at `/admin/config/ad`.
+- Place one or more ad blocks as needed.
diff --git a/ad.info.yml b/ad.info.yml
index d689954..353a165 100644
--- a/ad.info.yml
+++ b/ad.info.yml
@@ -1,4 +1,4 @@
-name: AD
+name: Ad
 type: module
 description: 'A flexible and extensible advertising system.'
 package: Advertisement
diff --git a/ad.module b/ad.module
index 4b13575..83895e4 100644
--- a/ad.module
+++ b/ad.module
@@ -2,13 +2,13 @@
 
 /**
  * @file
- * Main file for the "AD" module.
+ * Main file for the "Ad" module.
  */
 
 use Drupal\ad\Size\SizeInterface;
 
 /**
- * Returns the available AD sizes.
+ * Returns the available Ad sizes.
  *
  * @return string[]
  *   An array of array size IDs.
diff --git a/ad.permissions.yml b/ad.permissions.yml
index 9fa2fda..2c530ea 100644
--- a/ad.permissions.yml
+++ b/ad.permissions.yml
@@ -1,8 +1,8 @@
 administer ads:
-  title: 'Administer ADs'
+  title: 'Administer ads'
   description: 'Manage advertisements.'
   restrict access: true
 administer ad settings:
-  title: 'Administer AD settings'
+  title: 'Administer Ad settings'
   description: 'Configure and manage advertisement settings.'
   restrict access: true
diff --git a/config/schema/ad.schema.yml b/config/schema/ad.schema.yml
index a5d0fac..ff72ad2 100644
--- a/config/schema/ad.schema.yml
+++ b/config/schema/ad.schema.yml
@@ -1,8 +1,8 @@
-# Schema for the configuration files of the "AD" module.
+# Schema for the configuration files of the "Ad" module.
 
 ad.settings:
   type: config_object
-  label: 'AD Settings'
+  label: 'Ad Settings'
   mapping:
     trackers:
       type: sequence
diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 7e7df84..8218b86 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -1,5 +1,5 @@
-name: AD Content
-description: 'AD source allowing to create ADs via the administrative UI.'
+name: Ad Content
+description: 'Ad source allowing to create ads via the administrative UI.'
 type: module
 package: Advertisement
 core_version_requirement: ^10.3 || ^11
diff --git a/modules/ad_content/ad_content.links.action.yml b/modules/ad_content/ad_content.links.action.yml
index dba5bfb..3f2c5af 100644
--- a/modules/ad_content/ad_content.links.action.yml
+++ b/modules/ad_content/ad_content.links.action.yml
@@ -1,11 +1,11 @@
 ad_content.add_form:
   route_name: entity.ad_content.add_form
-  title: 'Add content AD'
+  title: 'Add ad content'
   appears_on:
     - entity.ad_content.collection
 
 ad_content_type.add_form:
   route_name: entity.ad_content_type.add_form
-  title: 'Add content type'
+  title: 'Add ad content type'
   appears_on:
     - entity.ad_content_type.collection
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
index 234879c..8c3de47 100644
--- a/modules/ad_content/ad_content.links.menu.yml
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -1,4 +1,11 @@
 entity.ad_content.collection:
   route_name: entity.ad_content.collection
   title: 'Advertisements'
+  description: 'Manage Advertisement content.'
   base_route: system.admin_content
+
+entity.media_type.collection:
+  title: 'Media types'
+  parent: system.admin_structure
+  description: 'Manage Advertisement types.'
+  route_name: entity.media_type.collection
diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index 2109d74..ffb2af6 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -2,5 +2,5 @@
 
 /**
  * @file
- * Main file for the "AD Content" module.
+ * Main file for the "Ad Content" module.
  */
diff --git a/modules/ad_content/ad_content.routing.yml b/modules/ad_content/ad_content.routing.yml
index 971a1eb..3dbf450 100644
--- a/modules/ad_content/ad_content.routing.yml
+++ b/modules/ad_content/ad_content.routing.yml
@@ -2,6 +2,6 @@ ad_content.render_ad:
   path: '/ad/content/render'
   defaults:
     _controller: '\Drupal\ad_content\Controller\ImpressionController::renderAds'
-    _title: 'Render AD'
+    _title: 'Render ad'
   requirements:
     _permission: 'access content'
diff --git a/modules/ad_content/config/optional/views.view.ad_administration.yml b/modules/ad_content/config/optional/views.view.ad_administration.yml
index c67734c..139ccd1 100644
--- a/modules/ad_content/config/optional/views.view.ad_administration.yml
+++ b/modules/ad_content/config/optional/views.view.ad_administration.yml
@@ -12,7 +12,7 @@ dependencies:
     - options
     - user
 id: ad_administration
-label: 'AD Administration'
+label: 'Ad Administration'
 module: views
 description: ''
 tag: ''
diff --git a/modules/ad_content/config/optional/views.view.ad_statistics.yml b/modules/ad_content/config/optional/views.view.ad_statistics.yml
index 496d3b1..b19d400 100644
--- a/modules/ad_content/config/optional/views.view.ad_statistics.yml
+++ b/modules/ad_content/config/optional/views.view.ad_statistics.yml
@@ -5,7 +5,7 @@ dependencies:
     - ad_content
     - ad_track
 id: ad_statistics
-label: 'AD Statistics'
+label: 'Ad Statistics'
 module: views
 description: ''
 tag: ''
@@ -430,7 +430,7 @@ display:
           relationship: ad_id
           group_type: group
           admin_label: ''
-          label: AD
+          label: Ad
           exclude: false
           alter:
             alter_text: false
@@ -1110,7 +1110,7 @@ display:
           field: ad_id
           relationship: none
           group_type: group
-          admin_label: 'Content AD'
+          admin_label: 'Content ad'
           required: false
           entity_type: ad_track_event
           plugin_id: standard
diff --git a/modules/ad_content/src/Controller/ImpressionController.php b/modules/ad_content/src/Controller/ImpressionController.php
index 79f3374..5e5112a 100644
--- a/modules/ad_content/src/Controller/ImpressionController.php
+++ b/modules/ad_content/src/Controller/ImpressionController.php
@@ -12,19 +12,19 @@ use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
- * AD impression controller.
+ * Ad impression controller.
  */
 class ImpressionController extends ControllerBase implements ContainerInjectionInterface {
 
   /**
-   * The AD size factory.
+   * The ad size factory.
    *
    * @var \Drupal\ad\Size\SizeFactory
    */
   protected SizeFactory $sizeFactory;
 
   /**
-   * The AD bucket factory.
+   * The ad bucket factory.
    *
    * @var \Drupal\ad\Bucket\BucketFactoryInterface
    */
@@ -41,9 +41,9 @@ class ImpressionController extends ControllerBase implements ContainerInjectionI
    * Impression constructor.
    *
    * @param \Drupal\ad\Size\SizeFactory $ad_size_factory
-   *   The AD size factory.
+   *   The ad size factory.
    * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
-   *   The AD bucket factory.
+   *   The ad bucket factory.
    * @param \Drupal\Core\Render\RendererInterface $renderer
    *   The renderer service.
    */
@@ -69,7 +69,7 @@ class ImpressionController extends ControllerBase implements ContainerInjectionI
   }
 
   /**
-   * Renders the specified ADs.
+   * Renders the specified ads.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The HTTP request.
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 384f889..3efe77a 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -10,17 +10,17 @@ use Drupal\Core\Url;
 use Drupal\user\EntityOwnerTrait;
 
 /**
- * Defines the AD content entity class.
+ * Defines the ad content entity class.
  *
  * @ContentEntityType(
  *   id = "ad_content",
- *   label = @Translation("AD Content"),
+ *   label = @Translation("Advertisement Content"),
  *   label_collection = @Translation("Advertisement"),
- *   label_singular = @Translation("content AD"),
- *   label_plural = @Translation("content ADs"),
+ *   label_singular = @Translation("Advertisement content"),
+ *   label_plural = @Translation("Advertisement contents"),
  *   label_count = @PluralTranslation(
- *     singular = "@count content AD",
- *     plural = "@count content ADs",
+ *     singular = "@count advertisement content",
+ *     plural = "@count advertisement contents",
  *   ),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
@@ -87,10 +87,10 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
   }
 
   /**
-   * Returns the AD size.
+   * Returns the ad size.
    *
    * @return string
-   *   The AD size ID.
+   *   The ad size ID.
    */
   public function getSizeId(): string {
     return $this->get('size')->value;
@@ -114,7 +114,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
     $fields += static::ownerBaseFieldDefinitions($entity_type);
 
     $fields['type'] = BaseFieldDefinition::create('list_string')
-      ->setLabel(new TranslatableMarkup('AD content type'))
+      ->setLabel(new TranslatableMarkup('Ad content type'))
       ->setDescription(new TranslatableMarkup('The ad content type.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
@@ -130,7 +130,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['title'] = BaseFieldDefinition::create('string')
       ->setLabel(new TranslatableMarkup('Title'))
-      ->setDescription(new TranslatableMarkup('A brief description of the AD.'))
+      ->setDescription(new TranslatableMarkup('A brief description of the ad.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->addConstraint('UniqueField', [])
@@ -170,7 +170,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['size'] = BaseFieldDefinition::create('list_string')
       ->setLabel(new TranslatableMarkup('Size'))
-      ->setDescription(new TranslatableMarkup('The AD size.'))
+      ->setDescription(new TranslatableMarkup('The ad size.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->setSettings([
@@ -189,7 +189,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['target_url'] = BaseFieldDefinition::create('link')
       ->setLabel(new TranslatableMarkup('Target URL'))
-      ->setDescription(new TranslatableMarkup('The URL to be taken to when clicking on the AD.'))
+      ->setDescription(new TranslatableMarkup('The URL to be taken to when clicking on the ad.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->setDisplayOptions('form', [
@@ -205,7 +205,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(new TranslatableMarkup('Authored on'))
-      ->setDescription(t('The time that the AD was created.'))
+      ->setDescription(t('The time that the ad was created.'))
       ->setRevisionable(TRUE)
       ->setDisplayOptions('form', [
         'type' => 'datetime_timestamp',
@@ -221,7 +221,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['changed'] = BaseFieldDefinition::create('changed')
       ->setLabel(t('Changed'))
-      ->setDescription(t('The time that the AD was last edited.'));
+      ->setDescription(t('The time that the ad was last edited.'));
 
     return $fields;
   }
diff --git a/modules/ad_content/src/Entity/AdContentInterface.php b/modules/ad_content/src/Entity/AdContentInterface.php
index 3253f77..8b73211 100644
--- a/modules/ad_content/src/Entity/AdContentInterface.php
+++ b/modules/ad_content/src/Entity/AdContentInterface.php
@@ -10,7 +10,7 @@ use Drupal\Core\Entity\RevisionLogInterface;
 use Drupal\user\EntityOwnerInterface;
 
 /**
- * Common interface for AD content entities.
+ * Common interface for ad content entities.
  */
 interface AdContentInterface extends AdInterface, ContentEntityInterface, EntityOwnerInterface, EntityChangedInterface, EntityPublishedInterface, RevisionLogInterface {
 
diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index 8eaed0b..89070c8 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
 
 /**
- * AD content list builder.
+ * Ad content list builder.
  */
 class AdContentListBuilder extends EntityListBuilder {
 
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index ec9af82..dcded58 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -5,16 +5,16 @@ namespace Drupal\ad_content\Entity;
 use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
 
 /**
- * Defines the AD content type bundle class.
+ * Defines the ad content type bundle class.
  *
  * @ConfigEntityType(
  *   id = "ad_content_type",
- *   label = @Translation("AD Content Type"),
- *   label_singular = @Translation("AD content type"),
- *   label_plural = @Translation("AD content types"),
+ *   label = @Translation("Ad Content Type"),
+ *   label_singular = @Translation("Ad content type"),
+ *   label_plural = @Translation("Ad content types"),
  *   label_count = @PluralTranslation(
- *     singular = "@count AD content type",
- *     plural = "@count AD content types",
+ *     singular = "@count ad content type",
+ *     plural = "@count ad content types",
  *   ),
  *   bundle_of = "ad_content",
  *   entity_keys = {
diff --git a/modules/ad_content/src/Entity/AdContentTypeInterface.php b/modules/ad_content/src/Entity/AdContentTypeInterface.php
index 0a0e088..e4ca67f 100644
--- a/modules/ad_content/src/Entity/AdContentTypeInterface.php
+++ b/modules/ad_content/src/Entity/AdContentTypeInterface.php
@@ -5,6 +5,6 @@ namespace Drupal\ad_content\Entity;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
 
 /**
- * Common interface for AD content type bundle entities.
+ * Common interface for ad content type bundle entities.
  */
 interface AdContentTypeInterface extends ConfigEntityInterface {}
diff --git a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
index b175f35..234e403 100644
--- a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
 
 /**
- * AD content list builder.
+ * Ad content list builder.
  */
 class AdContentTypeListBuilder extends EntityListBuilder {
 
diff --git a/modules/ad_content/src/Entity/AdContentViewController.php b/modules/ad_content/src/Entity/AdContentViewController.php
index 7134f8c..ab9d0a6 100644
--- a/modules/ad_content/src/Entity/AdContentViewController.php
+++ b/modules/ad_content/src/Entity/AdContentViewController.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\Controller\EntityViewController;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
- * AD content view controller.
+ * Ad content view controller.
  */
 class AdContentViewController extends EntityViewController {
 
@@ -14,7 +14,7 @@ class AdContentViewController extends EntityViewController {
    * The _title_callback for the page that renders a single node.
    *
    * @param \Drupal\Core\Entity\EntityInterface $ad_content
-   *   The current AD content.
+   *   The current ad content.
    *
    * @return string
    *   The page title.
diff --git a/modules/ad_content/src/Field/AdContentImageFormatterBase.php b/modules/ad_content/src/Field/AdContentImageFormatterBase.php
index 1145796..b07293e 100644
--- a/modules/ad_content/src/Field/AdContentImageFormatterBase.php
+++ b/modules/ad_content/src/Field/AdContentImageFormatterBase.php
@@ -8,7 +8,7 @@ use Drupal\Core\Url;
 use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;
 
 /**
- * Base class for AD image formatters.
+ * Base class for ad image formatters.
  */
 abstract class AdContentImageFormatterBase extends ImageFormatterBase {
 
@@ -53,7 +53,7 @@ abstract class AdContentImageFormatterBase extends ImageFormatterBase {
    * Returns the URL the image should be linked to.
    *
    * @param \Drupal\ad_content\Entity\AdContentInterface $ad_content
-   *   A content AD entity.
+   *   A content ad entity.
    *
    * @return \Drupal\Core\Url|null
    *   A URL object or NULL if none is available.
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
index abf891c..20e4034 100644
--- a/modules/ad_content/src/Form/AdContentTypeEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\BundleEntityFormBase;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
- * Entity form for the AD content type bundle.
+ * Entity form for the ad content type bundle.
  */
 class AdContentTypeEntityForm extends BundleEntityFormBase {
 
diff --git a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
index 4a9f890..71cf15b 100644
--- a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
+++ b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
@@ -25,11 +25,11 @@ use Psr\Log\LoggerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Basic AD content bucket.
+ * Basic ad content bucket.
  *
  * @Plugin(
  *   id = \Drupal\ad_content\Entity\AdContentInterface::BUCKET_ID,
- *   label = @Translation("AD Content"),
+ *   label = @Translation("Ad Content"),
  * )
  */
 class AdContentBucket extends PluginBase implements BucketInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface {
@@ -49,7 +49,7 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
   protected EntityRepositoryInterface $entityRepository;
 
   /**
-   * The AD tracker factory.
+   * The ad tracker factory.
    *
    * @var \Drupal\ad\Track\TrackerFactoryInterface
    */
@@ -83,7 +83,7 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
    * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
    *   The entity repository.
    * @param \Drupal\ad\Track\TrackerFactoryInterface $tracker_factory
-   *   The AD tracker factory.
+   *   The ad tracker factory.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current user.
    * @param \Psr\Log\LoggerInterface $logger
@@ -194,20 +194,20 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
   }
 
   /**
-   * Returns the AD to be rendered.
+   * Returns the ad to be rendered.
    *
    * @param \Drupal\ad\Size\SizeInterface $size
-   *   The AD size.
+   *   The ad size.
    *
    * @return \Drupal\ad_content\Entity\AdContentInterface
-   *   An AD content entity.
+   *   An ad content entity.
    */
   protected function getAdContent(SizeInterface $size): ?AdContentInterface {
     return $this->getRandomAd($size);
   }
 
   /**
-   * Post render callback for the AD view builder.
+   * Post render callback for the ad view builder.
    */
   public static function postAdRender($markup, array $build) {
     $output = str_replace(TrackerInterface::PLACEHOLDER_IMPRESSION, $build['#ad_impression_id'], $markup);
@@ -215,13 +215,13 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
   }
 
   /**
-   * Retrieves a random AD of the specified size.
+   * Retrieves a random ad of the specified size.
    *
    * @param \Drupal\ad\Size\SizeInterface $size
-   *   The AD size.
+   *   The ad size.
    *
    * @return \Drupal\ad_content\Entity\AdContentInterface|null
-   *   An AD entity or NULL if none could be found.
+   *   An ad entity or NULL if none could be found.
    */
   protected function getRandomAd(SizeInterface $size): ?AdContentInterface {
     $size_id = $size->getId();
@@ -255,7 +255,7 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
    * Get the base query for finding an ad by size.
    *
    * @param string $size_id
-   *   The AD size ID.
+   *   The ad size ID.
    *
    * @return \Drupal\Core\Entity\Query\QueryInterface
    *   Ad base query.
diff --git a/modules/ad_content/src/Plugin/Field/FieldFormatter/AdContentImageFormatter.php b/modules/ad_content/src/Plugin/Field/FieldFormatter/AdContentImageFormatter.php
index 4ef0f38..fd083ec 100644
--- a/modules/ad_content/src/Plugin/Field/FieldFormatter/AdContentImageFormatter.php
+++ b/modules/ad_content/src/Plugin/Field/FieldFormatter/AdContentImageFormatter.php
@@ -5,11 +5,11 @@ namespace Drupal\ad_content\Plugin\Field\FieldFormatter;
 use Drupal\ad_content\Field\AdContentImageFormatterBase;
 
 /**
- * Plugin implementation of the AD Image formatter.
+ * Plugin implementation of the ad Image formatter.
  *
  * @FieldFormatter(
  *   id = "ad_content_image",
- *   label = @Translation("AD Image"),
+ *   label = @Translation("Ad Image"),
  *   field_types = {
  *     "image"
  *   }
diff --git a/modules/ad_content/src/Plugin/Field/FieldFormatter/TrackAdContentImageFormatter.php b/modules/ad_content/src/Plugin/Field/FieldFormatter/TrackAdContentImageFormatter.php
index 16c38ce..05e1bf1 100644
--- a/modules/ad_content/src/Plugin/Field/FieldFormatter/TrackAdContentImageFormatter.php
+++ b/modules/ad_content/src/Plugin/Field/FieldFormatter/TrackAdContentImageFormatter.php
@@ -9,11 +9,11 @@ use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Url;
 
 /**
- * Plugin implementation of the AD image formatter with local tracking.
+ * Plugin implementation of the ad image formatter with local tracking.
  *
  * @FieldFormatter(
  *   id = "ad_content_image_click_track",
- *   label = @Translation("AD Image with local click tracking"),
+ *   label = @Translation("Ad Image with local click tracking"),
  *   field_types = {
  *     "image"
  *   }
diff --git a/modules/ad_track/ad_track.info.yml b/modules/ad_track/ad_track.info.yml
index 43cc5f3..e623555 100644
--- a/modules/ad_track/ad_track.info.yml
+++ b/modules/ad_track/ad_track.info.yml
@@ -1,5 +1,5 @@
-name: AD Track
-description: 'AD statistics tracker allowing to count AD impressions and clicks locally.'
+name: Ad Track
+description: 'Ad statistics tracker allowing to count ad impressions and clicks locally.'
 type: module
 package: Advertisement
 core_version_requirement: ^10.3 || ^11
diff --git a/modules/ad_track/ad_track.install b/modules/ad_track/ad_track.install
index c9556c1..baf601c 100644
--- a/modules/ad_track/ad_track.install
+++ b/modules/ad_track/ad_track.install
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Installation file for the "AD Track" module.
+ * Installation file for the "Ad Track" module.
  */
 
 /**
@@ -12,16 +12,16 @@ function ad_track_schema() {
   $schema = [];
 
   $schema['ad_track_total'] = [
-    'description' => 'Stores AD total event counts.',
+    'description' => 'Stores ad total event counts.',
     'fields' => [
       'ad_id' => [
-        'description' => 'The AD identifier.',
+        'description' => 'The ad identifier.',
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE,
       ],
       'bucket_id' => [
-        'description' => 'The identifier of the AD bucket.',
+        'description' => 'The identifier of the ad bucket.',
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
diff --git a/modules/ad_track/ad_track.module b/modules/ad_track/ad_track.module
index 8da0e09..202cf32 100644
--- a/modules/ad_track/ad_track.module
+++ b/modules/ad_track/ad_track.module
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Main module file for the "AD Track" module.
+ * Main module file for the "Ad Track" module.
  */
 
 use Drupal\ad\Track\TrackerInterface;
diff --git a/modules/ad_track/ad_track.views.inc b/modules/ad_track/ad_track.views.inc
index 4ebf5d4..a80fc17 100644
--- a/modules/ad_track/ad_track.views.inc
+++ b/modules/ad_track/ad_track.views.inc
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Views integration file for the "AD Track" module.
+ * Views integration file for the "Ad Track" module.
  */
 
 use Drupal\ad\Track\TrackerInterface;
@@ -14,17 +14,17 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 function ad_track_views_data() {
   $data = [];
 
-  $data['ad_track_total']['table']['group'] = new TranslatableMarkup('AD Track');
+  $data['ad_track_total']['table']['group'] = new TranslatableMarkup('Ad Track');
   $data['ad_track_total']['table']['provider'] = 'ad_track';
 
   $data['ad_track_total']['table']['base'] = [
     'field' => 'ad_id',
-    'title' => new TranslatableMarkup('AD Track Totals'),
-    'help' => new TranslatableMarkup('Stores AD total event counts.'),
+    'title' => new TranslatableMarkup('Ad Track Totals'),
+    'help' => new TranslatableMarkup('Stores Ad total event counts.'),
   ];
 
   $ids = [
-    'ad_id' => new TranslatableMarkup('AD ID'),
+    'ad_id' => new TranslatableMarkup('Ad ID'),
     'bucket_id' => new TranslatableMarkup('Bucket ID'),
   ];
 
@@ -78,7 +78,7 @@ function ad_track_views_data() {
 
   if (Drupal::moduleHandler()->moduleExists('ad_content')) {
     $data['ad_track_total']['ad_id']['relationship'] = [
-      'label' => new TranslatableMarkup('AD Content'),
+      'label' => new TranslatableMarkup('Ad Content'),
       'base' => 'ad_content',
       'base field' => 'uuid',
       'id' => 'standard',
@@ -94,7 +94,7 @@ function ad_track_views_data() {
 function ad_track_views_data_alter(array &$data) {
   if (Drupal::moduleHandler()->moduleExists('ad_content')) {
     $data['ad_content']['uuid']['relationship'] = [
-      'label' => new TranslatableMarkup('AD Track Totals'),
+      'label' => new TranslatableMarkup('Ad Track Totals'),
       'base' => 'ad_track_total',
       'base field' => 'ad_id',
       'id' => 'standard',
diff --git a/modules/ad_track/src/Controller/ClickTrackController.php b/modules/ad_track/src/Controller/ClickTrackController.php
index 401d0c8..0c275ad 100644
--- a/modules/ad_track/src/Controller/ClickTrackController.php
+++ b/modules/ad_track/src/Controller/ClickTrackController.php
@@ -17,7 +17,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 class ClickTrackController extends ControllerBase {
 
   /**
-   * The AD bucket factory.
+   * The ad bucket factory.
    *
    * @var \Drupal\ad\Bucket\BucketFactoryInterface
    */
@@ -27,7 +27,7 @@ class ClickTrackController extends ControllerBase {
    * ClickTrackController constructor.
    *
    * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
-   *   The AD tracker factory.
+   *   The ad tracker factory.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current user.
    */
@@ -47,17 +47,17 @@ class ClickTrackController extends ControllerBase {
   }
 
   /**
-   * Tracks an AD click event.
+   * Tracks an ad click event.
    *
    * @param string $bucket_id
    *   The bucket identifier.
    * @param string $ad_id
-   *   The AD identifier.
+   *   The ad identifier.
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The current request.
    *
    * @return \Symfony\Component\HttpFoundation\RedirectResponse
-   *   A redirect response pointing to the AD target URL.
+   *   A redirect response pointing to the ad target URL.
    */
   public function track(string $bucket_id, string $ad_id, Request $request): RedirectResponse {
     // @todo Add CSRF protection.
diff --git a/modules/ad_track/src/Entity/AdTrackEvent.php b/modules/ad_track/src/Entity/AdTrackEvent.php
index b1e62f4..576178f 100644
--- a/modules/ad_track/src/Entity/AdTrackEvent.php
+++ b/modules/ad_track/src/Entity/AdTrackEvent.php
@@ -8,11 +8,11 @@ use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 
 /**
- * Defines the AD track event entity class.
+ * Defines the ad track event entity class.
  *
  * @ContentEntityType(
  *   id = "ad_track_event",
- *   label = @Translation("AD Track Event"),
+ *   label = @Translation("ad Track Event"),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
  *     "storage_schema" = "Drupal\ad_track\Entity\AdTrackEventStorageSchema",
@@ -50,8 +50,8 @@ class AdTrackEvent extends ContentEntityBase {
       ->setDescription(t('The event timestamp.'));
 
     $fields['ad_id'] = BaseFieldDefinition::create('string')
-      ->setLabel(new TranslatableMarkup('AD'))
-      ->setDescription(t('The identifier of the AD the events refers to.'));
+      ->setLabel(new TranslatableMarkup('Ad'))
+      ->setDescription(t('The identifier of the ad the events refers to.'));
 
     $fields['ip_address'] = BaseFieldDefinition::create('string')
       ->setLabel(new TranslatableMarkup('IP address'))
diff --git a/modules/ad_track/src/Entity/AdTrackEventStorageSchema.php b/modules/ad_track/src/Entity/AdTrackEventStorageSchema.php
index 33b1660..fb6f295 100644
--- a/modules/ad_track/src/Entity/AdTrackEventStorageSchema.php
+++ b/modules/ad_track/src/Entity/AdTrackEventStorageSchema.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
 
 /**
- * Defines the AD track event schema handler.
+ * Defines the ad track event schema handler.
  */
 class AdTrackEventStorageSchema extends SqlContentEntityStorageSchema {
 
diff --git a/modules/ad_track/src/Entity/AdTrackEventViewsData.php b/modules/ad_track/src/Entity/AdTrackEventViewsData.php
index 7746608..ee09846 100644
--- a/modules/ad_track/src/Entity/AdTrackEventViewsData.php
+++ b/modules/ad_track/src/Entity/AdTrackEventViewsData.php
@@ -6,7 +6,7 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\views\EntityViewsData;
 
 /**
- * Entity views data for the AD Track Event entity type.
+ * Entity views data for the ad Track Event entity type.
  */
 class AdTrackEventViewsData extends EntityViewsData {
 
@@ -18,7 +18,7 @@ class AdTrackEventViewsData extends EntityViewsData {
 
     if ($this->moduleHandler->moduleExists('ad_content')) {
       $data['ad_track_event']['ad_id']['relationship'] = [
-        'label' => new TranslatableMarkup('Content AD'),
+        'label' => new TranslatableMarkup('Content ad'),
         'base' => 'ad_content',
         'base field' => 'uuid',
         'id' => 'standard',
diff --git a/modules/ad_track/src/Plugin/Ad/Track/DelayedLocalTracker.php b/modules/ad_track/src/Plugin/Ad/Track/DelayedLocalTracker.php
index e019ca3..fdef5cd 100644
--- a/modules/ad_track/src/Plugin/Ad/Track/DelayedLocalTracker.php
+++ b/modules/ad_track/src/Plugin/Ad/Track/DelayedLocalTracker.php
@@ -11,7 +11,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *
  * @Plugin(
  *   id = \Drupal\ad_track\Plugin\Ad\Track\DelayedLocalTracker::TRACKER_ID,
- *   label = @Translation("Queue-based local AD event tracker"),
+ *   label = @Translation("Queue-based local ad event tracker"),
  * )
  *
  * @internal
@@ -52,10 +52,10 @@ class DelayedLocalTracker extends LocalTracker {
   }
 
   /**
-   * Actually saves the specified AD event.
+   * Actually saves the specified ad event.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD to be tracked.
+   *   The ad to be tracked.
    * @param array $values
    *   The event values to be stored.
    *
diff --git a/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php b/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
index 1948d97..bfb2395 100644
--- a/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
+++ b/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
@@ -24,7 +24,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
  *
  * @Plugin(
  *   id = \Drupal\ad_track\Plugin\Ad\Track\LocalTracker::TRACKER_ID,
- *   label = @Translation("Local AD event tracker"),
+ *   label = @Translation("Local ad event tracker"),
  * )
  *
  * @internal
@@ -224,9 +224,9 @@ class LocalTracker implements TrackerInterface, ContainerFactoryPluginInterface
    * Tracks the specified event.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD to be tracked.
+   *   The ad to be tracked.
    * @param \Drupal\Core\Session\AccountInterface $user
-   *   The user triggering the AD event.
+   *   The user triggering the ad event.
    * @param array $values
    *   The event values to be stored.
    *
@@ -258,10 +258,10 @@ class LocalTracker implements TrackerInterface, ContainerFactoryPluginInterface
   }
 
   /**
-   * Saves the specified AD event.
+   * Saves the specified ad event.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD to be tracked.
+   *   The ad to be tracked.
    * @param array $values
    *   The event values to be stored.
    *
diff --git a/modules/ad_track/src/Plugin/QueueWorker/DelayedLocalTrackQueueWorker.php b/modules/ad_track/src/Plugin/QueueWorker/DelayedLocalTrackQueueWorker.php
index 2891812..e41f5ca 100644
--- a/modules/ad_track/src/Plugin/QueueWorker/DelayedLocalTrackQueueWorker.php
+++ b/modules/ad_track/src/Plugin/QueueWorker/DelayedLocalTrackQueueWorker.php
@@ -23,14 +23,14 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 class DelayedLocalTrackQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The AD bucket factory.
+   * The ad bucket factory.
    *
    * @var \Drupal\ad\Bucket\BucketFactoryInterface
    */
   protected BucketFactoryInterface $bucketFactory;
 
   /**
-   * The AD tracker factory.
+   * The ad tracker factory.
    *
    * @var \Drupal\ad\Track\TrackerFactoryInterface
    */
@@ -46,9 +46,9 @@ class DelayedLocalTrackQueueWorker extends QueueWorkerBase implements ContainerF
    * @param mixed $plugin_definition
    *   The plugin implementation definition.
    * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
-   *   The AD bucket factory.
+   *   The ad bucket factory.
    * @param \Drupal\ad\Track\TrackerFactoryInterface $tracker_factory
-   *   The AD tracker factory.
+   *   The ad tracker factory.
    */
   public function __construct(
     array $configuration,
diff --git a/modules/ad_track/src/TotalSqlStorage.php b/modules/ad_track/src/TotalSqlStorage.php
index b4f228d..15c022c 100644
--- a/modules/ad_track/src/TotalSqlStorage.php
+++ b/modules/ad_track/src/TotalSqlStorage.php
@@ -94,7 +94,7 @@ class TotalSqlStorage implements TotalStorageInterface {
    * Returns a transaction ID.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD being tracked.
+   *   The ad being tracked.
    *
    * @return string
    *   A transaction ID.
@@ -112,7 +112,7 @@ class TotalSqlStorage implements TotalStorageInterface {
       $this->transactions[$id] = $this->database->startTransaction($id);
     }
     else {
-      $message = sprintf('A transaction already exists for AD %s', $id);
+      $message = sprintf('A transaction already exists for ad %s', $id);
       throw new \InvalidArgumentException($message);
     }
   }
diff --git a/modules/ad_track/src/TotalStorageInterface.php b/modules/ad_track/src/TotalStorageInterface.php
index 04eb362..af64985 100644
--- a/modules/ad_track/src/TotalStorageInterface.php
+++ b/modules/ad_track/src/TotalStorageInterface.php
@@ -10,10 +10,10 @@ use Drupal\ad\AdInterface;
 interface TotalStorageInterface {
 
   /**
-   * Loads the totals for the specified AD.
+   * Loads the totals for the specified ad.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   An AD object.
+   *   An ad object.
    *
    * @return int[]
    *   An associative array of event totals keyed by event type.
@@ -21,14 +21,14 @@ interface TotalStorageInterface {
   public function loadTotals(AdInterface $ad): array;
 
   /**
-   * Increases the total impression count for the specified AD.
+   * Increases the total impression count for the specified ad.
    *
    * Always start a transaction before performing this.
    *
    * @param string $type
    *   The event type.
    * @param \Drupal\ad\AdInterface $ad
-   *   An AD object.
+   *   An ad object.
    *
    * @see TotalStorageInterface::startTransaction()
    * @see TotalStorageInterface::rollbackTransaction()
@@ -39,22 +39,22 @@ interface TotalStorageInterface {
   public function increaseTotal(string $type, AdInterface $ad): void;
 
   /**
-   * Starts a transaction before increasing totals for the specified AD.
+   * Starts a transaction before increasing totals for the specified ad.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   An AD object.
+   *   An ad object.
    *
    * @throws \InvalidArgumentException
-   *   If a transaction for the specified AD was already started, nested
+   *   If a transaction for the specified ad was already started, nested
    *   transactions are not supported.
    */
   public function startTransaction(AdInterface $ad): void;
 
   /**
-   * Rolls back a transaction the specified AD.
+   * Rolls back a transaction the specified ad.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   An AD object.
+   *   An ad object.
    */
   public function rollbackTransaction(AdInterface $ad): void;
 
diff --git a/src/AdFactoryBase.php b/src/AdFactoryBase.php
index 4191b16..00542a1 100644
--- a/src/AdFactoryBase.php
+++ b/src/AdFactoryBase.php
@@ -5,14 +5,14 @@ namespace Drupal\ad;
 use Drupal\Component\Plugin\PluginManagerInterface;
 
 /**
- * Base class for AD factories.
+ * Base class for ad factories.
  *
  * @internal
  */
 abstract class AdFactoryBase implements AdFactoryInterface {
 
   /**
-   * The AD bucket plugin manager.
+   * The ad bucket plugin manager.
    *
    * @var \Drupal\Component\Plugin\PluginManagerInterface
    */
diff --git a/src/AdFactoryInterface.php b/src/AdFactoryInterface.php
index 046b336..a996cc2 100644
--- a/src/AdFactoryInterface.php
+++ b/src/AdFactoryInterface.php
@@ -3,7 +3,7 @@
 namespace Drupal\ad;
 
 /**
- * Common interface for AD factories.
+ * Common interface for ad factories.
  */
 interface AdFactoryInterface {
 
@@ -11,7 +11,7 @@ interface AdFactoryInterface {
    * Returns a list of buckets.
    *
    * @return string[]
-   *   An associative array of AD bucket labels keyed by ID.
+   *   An associative array of ad bucket labels keyed by ID.
    */
   public function getList(): array;
 
diff --git a/src/AdInterface.php b/src/AdInterface.php
index feb20b7..c6c3db9 100644
--- a/src/AdInterface.php
+++ b/src/AdInterface.php
@@ -5,20 +5,20 @@ namespace Drupal\ad;
 use Drupal\Core\Url;
 
 /**
- * Common interface for AD domain objects.
+ * Common interface for ad domain objects.
  */
 interface AdInterface {
 
   /**
-   * Returns the AD identifier.
+   * Returns the ad identifier.
    *
    * @return string
-   *   An string uniquely identifying the AD.
+   *   An string uniquely identifying the ad.
    */
   public function getAdIdentifier(): string;
 
   /**
-   * Returns the ID of the bucket providing the AD.
+   * Returns the ID of the bucket providing the ad.
    *
    * @return string
    *   A bucket machine name.
@@ -26,10 +26,10 @@ interface AdInterface {
   public function getBucketId(): string;
 
   /**
-   * Returns the AD size.
+   * Returns the ad size.
    *
    * @return string
-   *   The AD size ID.
+   *   The ad size ID.
    */
   public function getSizeId(): string;
 
diff --git a/src/Bucket/BucketFactory.php b/src/Bucket/BucketFactory.php
index c1c59d2..20de670 100644
--- a/src/Bucket/BucketFactory.php
+++ b/src/Bucket/BucketFactory.php
@@ -9,7 +9,7 @@ use Drupal\Core\Config\ConfigFactoryInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
- * The AD bucket factory.
+ * The ad bucket factory.
  *
  * @internal
  */
@@ -33,7 +33,7 @@ class BucketFactory extends AdFactoryBase implements BucketFactoryInterface {
    * BucketFactory constructor.
    *
    * @param \Drupal\ad\Bucket\BucketPluginManager $plugin_manager
-   *   The AD bucket plugin manager.
+   *   The ad bucket plugin manager.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The config factory.
    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
@@ -67,7 +67,7 @@ class BucketFactory extends AdFactoryBase implements BucketFactoryInterface {
     }
     catch (PluginException $e) {
     }
-    throw new \LogicException('No valid AD bucket found.');
+    throw new \LogicException('No valid ad bucket found.');
   }
 
 }
diff --git a/src/Bucket/BucketFactoryInterface.php b/src/Bucket/BucketFactoryInterface.php
index e037f87..210331e 100644
--- a/src/Bucket/BucketFactoryInterface.php
+++ b/src/Bucket/BucketFactoryInterface.php
@@ -5,18 +5,18 @@ namespace Drupal\ad\Bucket;
 use Drupal\ad\AdFactoryInterface;
 
 /**
- * Common interface for AD bucket factories.
+ * Common interface for ad bucket factories.
  */
 interface BucketFactoryInterface extends AdFactoryInterface {
 
   /**
-   * Returns the specified AD bucket.
+   * Returns the specified ad bucket.
    *
    * @param string $id
    *   The bucket machine name.
    *
    * @return \Drupal\ad\Bucket\BucketInterface
-   *   An AD bucket instance.
+   *   An ad bucket instance.
    */
   public function get(string $id): BucketInterface;
 
diff --git a/src/Bucket/BucketInterface.php b/src/Bucket/BucketInterface.php
index d3a19ed..5e143ce 100644
--- a/src/Bucket/BucketInterface.php
+++ b/src/Bucket/BucketInterface.php
@@ -7,45 +7,45 @@ use Drupal\ad\Size\SizeInterface;
 use Drupal\ad\Track\TrackerInterface;
 
 /**
- * Common interface for AD buckets.
+ * Common interface for ad buckets.
  */
 interface BucketInterface {
 
   /**
-   * Builds an AD placeholder of the specified size.
+   * Builds an ad placeholder of the specified size.
    *
    * @param \Drupal\ad\Size\SizeInterface $size
-   *   An AD size.
+   *   An ad size.
    *
    * @return array
-   *   A renderable AD placeholder array.
+   *   A renderable ad placeholder array.
    */
   public function buildPlaceholder(SizeInterface $size): array;
 
   /**
-   * Builds an AD of the specified size.
+   * Builds an ad of the specified size.
    *
    * @param \Drupal\ad\Size\SizeInterface $size
-   *   An AD size.
+   *   An ad size.
    *
    * @return array
-   *   An AD render array.
+   *   An ad render array.
    */
   public function buildAd(SizeInterface $size): array;
 
   /**
-   * Returns the specified AD.
+   * Returns the specified ad.
    *
    * @param string $id
-   *   The AD identifier.
+   *   The ad identifier.
    *
    * @return \Drupal\ad\AdInterface|null
-   *   An AD instance or NULL if none could be found.
+   *   An ad instance or NULL if none could be found.
    */
   public function getAd(string $id): ?AdInterface;
 
   /**
-   * Returns the bucket's AD tracker.
+   * Returns the bucket's ad tracker.
    *
    * @return \Drupal\ad\Track\TrackerInterface
    *   A tracker instance.
diff --git a/src/Bucket/BucketPluginManager.php b/src/Bucket/BucketPluginManager.php
index 6f07c51..4d2a3ef 100644
--- a/src/Bucket/BucketPluginManager.php
+++ b/src/Bucket/BucketPluginManager.php
@@ -8,7 +8,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 
 /**
- * AD bucket plugin manager.
+ * Ad bucket plugin manager.
  *
  * @internal
  */
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index a70db47..b83aee8 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -14,19 +14,19 @@ use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * AD settings configuration form.
+ * Ad settings configuration form.
  */
 class SettingsForm extends ConfigFormBase {
 
   /**
-   * The AD bucket factory.
+   * The ad bucket factory.
    *
    * @var \Drupal\ad\Bucket\BucketFactoryInterface
    */
   protected BucketFactoryInterface $bucketFactory;
 
   /**
-   * The AD tracker factory.
+   * The ad tracker factory.
    *
    * @var \Drupal\ad\Track\TrackerFactoryInterface
    */
@@ -38,9 +38,9 @@ class SettingsForm extends ConfigFormBase {
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The factory for configuration objects.
    * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
-   *   The AD bucket factory.
+   *   The ad bucket factory.
    * @param \Drupal\ad\Track\TrackerFactoryInterface $tracker_factory
-   *   The AD tracker factory.
+   *   The ad tracker factory.
    * @param \Drupal\Core\Config\TypedConfigManagerInterface|null $typedConfigManager
    *   The typed config manager.
    */
@@ -93,7 +93,7 @@ class SettingsForm extends ConfigFormBase {
     $form['trackers'] = [
       '#type' => 'fieldset',
       '#title' => new TranslatableMarkup('Tracker configuration'),
-      '#description' => new TranslatableMarkup('Assign an AD statistics tracker for each AD source.'),
+      '#description' => new TranslatableMarkup('Assign an ad statistics tracker for each ad source.'),
       '#tree' => TRUE,
     ];
 
@@ -103,7 +103,7 @@ class SettingsForm extends ConfigFormBase {
           ->toString(TRUE)
           ->getGeneratedUrl(),
       ];
-      $form['trackers']['#description'] = new TranslatableMarkup('You need to <a href="@url">enable</a> at least one AD source and one AD statistics tracker engine.', $args);
+      $form['trackers']['#description'] = new TranslatableMarkup('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
 
       return $form;
     }
diff --git a/src/Plugin/Ad/Track/NullTracker.php b/src/Plugin/Ad/Track/NullTracker.php
index 2d06aa9..87ecb0f 100644
--- a/src/Plugin/Ad/Track/NullTracker.php
+++ b/src/Plugin/Ad/Track/NullTracker.php
@@ -7,7 +7,7 @@ use Drupal\ad\Track\TrackerInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
- * Null AD tracker, useful as a fallback if no actual tracker is available.
+ * Null ad tracker, useful as a fallback if no actual tracker is available.
  *
  * @Plugin(
  *   id = \Drupal\ad\Plugin\Ad\Track\NullTracker::TRACKER_ID,
diff --git a/src/Plugin/Block/AdBlock.php b/src/Plugin/Block/AdBlock.php
index 96d72f5..57aea24 100644
--- a/src/Plugin/Block/AdBlock.php
+++ b/src/Plugin/Block/AdBlock.php
@@ -11,7 +11,7 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Defines an AD block type.
+ * Defines an ad block type.
  *
  * @Block(
  *  id = "ad",
@@ -23,14 +23,14 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 class AdBlock extends BlockBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The AD size factory.
+   * The ad size factory.
    *
    * @var \Drupal\ad\Size\SizeFactory
    */
   protected SizeFactory $sizeFactory;
 
   /**
-   * The AD bucket factory.
+   * The ad bucket factory.
    *
    * @var \Drupal\ad\Bucket\BucketFactoryInterface
    */
diff --git a/src/Plugin/Block/Derivative/AdBlockDeriver.php b/src/Plugin/Block/Derivative/AdBlockDeriver.php
index 31aee66..9ab31cb 100644
--- a/src/Plugin/Block/Derivative/AdBlockDeriver.php
+++ b/src/Plugin/Block/Derivative/AdBlockDeriver.php
@@ -8,12 +8,12 @@ use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * AD block deriver creating a derivative for each AD size.
+ * Ad block deriver creating a derivative for each ad size.
  */
 class AdBlockDeriver extends DeriverBase implements ContainerDeriverInterface {
 
   /**
-   * The AD size factory.
+   * The ad size factory.
    *
    * @var \Drupal\ad\Size\SizeFactory
    */
@@ -23,7 +23,7 @@ class AdBlockDeriver extends DeriverBase implements ContainerDeriverInterface {
    * AdBlockDeriver constructor.
    *
    * @param \Drupal\ad\Size\SizeFactory $ad_size_factory
-   *   The AD size factory.
+   *   The ad size factory.
    */
   public function __construct(SizeFactory $ad_size_factory) {
     $this->sizeFactory = $ad_size_factory;
diff --git a/src/Size/Size.php b/src/Size/Size.php
index ca5d00e..c013dff 100644
--- a/src/Size/Size.php
+++ b/src/Size/Size.php
@@ -3,21 +3,21 @@
 namespace Drupal\ad\Size;
 
 /**
- * An AD size.
+ * An ad size.
  *
  * @internal
  */
 class Size implements SizeInterface {
 
   /**
-   * The AD size ID.
+   * The ad size ID.
    *
    * @var string
    */
   protected string $id;
 
   /**
-   * The AD size label.
+   * The ad size label.
    *
    * @var string
    */
diff --git a/src/Size/SizeFactory.php b/src/Size/SizeFactory.php
index afd9157..8693127 100644
--- a/src/Size/SizeFactory.php
+++ b/src/Size/SizeFactory.php
@@ -5,27 +5,27 @@ namespace Drupal\ad\Size;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 
 /**
- * The AD size factory.
+ * The ad size factory.
  *
  * @internal
  */
 class SizeFactory {
 
   /**
-   * All the available AD sizes.
+   * All the available ad sizes.
    *
    * @var \Drupal\ad\Size\SizeInterface[]
    */
   protected array $sizes;
 
   /**
-   * Returns the specified AD size.
+   * Returns the specified ad size.
    *
    * @param string $id
-   *   The AD size machine name.
+   *   The ad size machine name.
    *
    * @return \Drupal\ad\Size\SizeInterface
-   *   An AD size.
+   *   An ad size.
    */
   public function get(string $id): SizeInterface {
     $sizes = $this->getAll();
@@ -36,10 +36,10 @@ class SizeFactory {
   }
 
   /**
-   * Returns all available AD sizes.
+   * Returns all available ad sizes.
    *
    * @return \Drupal\ad\Size\SizeInterface[]
-   *   An array of AD sizes.
+   *   An array of ad sizes.
    */
   public function getAll(): array {
     if (!isset($this->sizes)) {
diff --git a/src/Size/SizeInterface.php b/src/Size/SizeInterface.php
index 35c3f78..f41f380 100644
--- a/src/Size/SizeInterface.php
+++ b/src/Size/SizeInterface.php
@@ -3,17 +3,17 @@
 namespace Drupal\ad\Size;
 
 /**
- * Common interface for AD sizes.
+ * Common interface for ad sizes.
  */
 interface SizeInterface {
 
   /**
-   * The AD size ID.
+   * The ad size ID.
    */
   public function getId(): string;
 
   /**
-   * The AD size human-readable label.
+   * The ad size human-readable label.
    */
   public function getLabel(): string;
 
diff --git a/src/Track/TrackerFactory.php b/src/Track/TrackerFactory.php
index 477a169..86bafd1 100644
--- a/src/Track/TrackerFactory.php
+++ b/src/Track/TrackerFactory.php
@@ -10,7 +10,7 @@ use Drupal\Core\Logger\LoggerChannelFactory;
 use Psr\Log\LoggerInterface;
 
 /**
- * The AD tracker factory.
+ * The ad tracker factory.
  *
  * @internal
  */
@@ -27,7 +27,7 @@ class TrackerFactory extends AdFactoryBase implements TrackerFactoryInterface {
    * TrackerFactory constructor.
    *
    * @param \Drupal\ad\Track\TrackerPluginManager $plugin_manager
-   *   The AD tracker plugin manager.
+   *   The ad tracker plugin manager.
    * @param \Drupal\Core\Logger\LoggerChannelFactory $loggerFactory
    *   The logger factory service.
    */
diff --git a/src/Track/TrackerFactoryInterface.php b/src/Track/TrackerFactoryInterface.php
index 9a587f9..a865ecc 100644
--- a/src/Track/TrackerFactoryInterface.php
+++ b/src/Track/TrackerFactoryInterface.php
@@ -5,18 +5,18 @@ namespace Drupal\ad\Track;
 use Drupal\ad\AdFactoryInterface;
 
 /**
- * Common interface for AD tracker factories.
+ * Common interface for ad tracker factories.
  */
 interface TrackerFactoryInterface extends AdFactoryInterface {
 
   /**
-   * Returns the specified AD tracker.
+   * Returns the specified ad tracker.
    *
    * @param string $name
    *   The tracker machine name.
    *
    * @return \Drupal\ad\Track\TrackerInterface
-   *   An AD tracker instance.
+   *   An ad tracker instance.
    */
   public function get(string $name): TrackerInterface;
 
diff --git a/src/Track/TrackerInterface.php b/src/Track/TrackerInterface.php
index 66e8502..853de79 100644
--- a/src/Track/TrackerInterface.php
+++ b/src/Track/TrackerInterface.php
@@ -6,7 +6,7 @@ use Drupal\ad\AdInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
- * Common interface for AD event trackers.
+ * Common interface for ad event trackers.
  */
 interface TrackerInterface {
 
@@ -24,12 +24,12 @@ interface TrackerInterface {
   public function id(): string;
 
   /**
-   * Tracks an AD impression.
+   * Tracks an ad impression.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD to be tracked.
+   *   The ad to be tracked.
    * @param \Drupal\Core\Session\AccountInterface $user
-   *   The user triggering the AD event.
+   *   The user triggering the ad event.
    * @param array $context
    *   The context.
    *
@@ -39,12 +39,12 @@ interface TrackerInterface {
   public function trackImpression(AdInterface $ad, AccountInterface $user, array $context = []): ?string;
 
   /**
-   * Tracks an AD click.
+   * Tracks an ad click.
    *
    * @param \Drupal\ad\AdInterface $ad
-   *   The AD to be tracked.
+   *   The ad to be tracked.
    * @param \Drupal\Core\Session\AccountInterface $user
-   *   The user triggering the AD event.
+   *   The user triggering the ad event.
    * @param array $context
    *   The context.
    *
diff --git a/src/Track/TrackerPluginManager.php b/src/Track/TrackerPluginManager.php
index 6ccd861..8a8861b 100644
--- a/src/Track/TrackerPluginManager.php
+++ b/src/Track/TrackerPluginManager.php
@@ -8,7 +8,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 
 /**
- * AD bucket plugin manager.
+ * Ad bucket plugin manager.
  *
  * @internal
  */
-- 
GitLab


From f53e9a6d00ecde30d0156487046ea0bbb41d69aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 23 Apr 2025 11:52:51 +0200
Subject: [PATCH 05/46] Finishing routing rewrite

---
 ad.routing.yml                                |  2 +-
 modules/ad_content/ad_content.links.menu.yml  | 14 +++++------
 modules/ad_content/src/Entity/AdContent.php   | 23 +++++--------------
 .../src/Entity/AdContentListBuilder.php       |  2 +-
 .../src/Entity/AdContentTypeListBuilder.php   |  6 ++---
 .../src/Form/AdContentTypeEntityForm.php      |  5 ++--
 6 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/ad.routing.yml b/ad.routing.yml
index 93a7cc9..42d3120 100644
--- a/ad.routing.yml
+++ b/ad.routing.yml
@@ -2,6 +2,6 @@ ad.settings:
   path: '/admin/config/ad'
   defaults:
     _form: '\Drupal\ad\Form\SettingsForm'
-    _title: 'Advertisement Settings'
+    _title: 'Ad Settings'
   requirements:
     _permission: 'administer ad settings'
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
index 8c3de47..d4a8cc1 100644
--- a/modules/ad_content/ad_content.links.menu.yml
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -1,11 +1,11 @@
 entity.ad_content.collection:
   route_name: entity.ad_content.collection
-  title: 'Advertisements'
-  description: 'Manage Advertisement content.'
-  base_route: system.admin_content
+  title: 'Ad content'
+  description: 'Manage ad content.'
+  parent: system.admin_content
 
-entity.media_type.collection:
-  title: 'Media types'
+entity.ad_content_type.collection:
+  title: 'Ad content types'
   parent: system.admin_structure
-  description: 'Manage Advertisement types.'
-  route_name: entity.media_type.collection
+  description: 'Manage ad content types.'
+  route_name: entity.ad_content_type.collection
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 3efe77a..a4bf0de 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -14,13 +14,13 @@ use Drupal\user\EntityOwnerTrait;
  *
  * @ContentEntityType(
  *   id = "ad_content",
- *   label = @Translation("Advertisement Content"),
- *   label_collection = @Translation("Advertisement"),
- *   label_singular = @Translation("Advertisement content"),
- *   label_plural = @Translation("Advertisement contents"),
+ *   label = @Translation("Ad Content"),
+ *   label_collection = @Translation("Ad content"),
+ *   label_singular = @Translation("Ad content"),
+ *   label_plural = @Translation("Ad contents"),
  *   label_count = @PluralTranslation(
- *     singular = "@count advertisement content",
- *     plural = "@count advertisement contents",
+ *     singular = "@count ad content",
+ *     plural = "@count ad contents",
  *   ),
  *   handlers = {
  *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
@@ -113,17 +113,6 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
     $fields = parent::baseFieldDefinitions($entity_type);
     $fields += static::ownerBaseFieldDefinitions($entity_type);
 
-    $fields['type'] = BaseFieldDefinition::create('list_string')
-      ->setLabel(new TranslatableMarkup('Ad content type'))
-      ->setDescription(new TranslatableMarkup('The ad content type.'))
-      ->setRevisionable(TRUE)
-      ->setRequired(TRUE)
-      ->setDisplayConfigurable('form', TRUE)
-      ->setDisplayConfigurable('view', TRUE)
-      ->setSettings([
-        'allowed_values_function' => 'ad_content_get_content_types',
-      ]);
-
     $fields['status']
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index 89070c8..52c198f 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -18,7 +18,7 @@ class AdContentListBuilder extends EntityListBuilder {
       'id' => $this->t('ID'),
       'title' => $this->t('Title'),
       'size' => $this->t('Size'),
-      'bundle' => $this->t('Content type'),
+      'bundle' => $this->t('Type'),
       'status' => $this->t('Status'),
     ];
 
diff --git a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
index 234e403..1d2d164 100644
--- a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
@@ -15,8 +15,7 @@ class AdContentTypeListBuilder extends EntityListBuilder {
    */
   public function buildHeader() {
     $header = [
-      'id' => $this->t('ID'),
-      'label' => $this->t('Title'),
+      'title' => $this->t('Title'),
     ];
 
     return $header + parent::buildHeader();
@@ -29,8 +28,7 @@ class AdContentTypeListBuilder extends EntityListBuilder {
     /** @var \Drupal\ad_content\Entity\AdContentTypeInterface $ad_content_type */
 
     $row = [
-      'id' => $ad_content_type->id(),
-      'label' => $ad_content_type->label(),
+      'title' => $ad_content_type->label(),
     ];
 
     return $row + parent::buildRow($ad_content_type);
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
index 20e4034..7646707 100644
--- a/modules/ad_content/src/Form/AdContentTypeEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -17,14 +17,13 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
     $form = parent::form($form, $form_state);
 
     $entity_type = $this->entity;
-    $content_entity_id = $entity_type->getEntityType()->getBundleOf();
 
     $form['label'] = [
       '#type' => 'textfield',
-      '#title' => $this->t('Label'),
+      '#title' => $this->t('Title'),
       '#maxlength' => 255,
       '#default_value' => $entity_type->label(),
-      '#description' => $this->t("Label for the %content_entity_id entity type (bundle).", ['%content_entity_id' => $content_entity_id]),
+      '#description' => $this->t("The title for the ad content type (bundle)."),
       '#required' => TRUE,
     ];
 
-- 
GitLab


From 182817a2108438baa7357564b61c31ae131cc4ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 23 Apr 2025 13:48:46 +0200
Subject: [PATCH 06/46] Updating entity annotations

---
 modules/ad_content/src/Entity/AdContent.php   | 128 ++++++++++--------
 .../ad_content/src/Entity/AdContentType.php   |  88 ++++++------
 2 files changed, 114 insertions(+), 102 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index a4bf0de..e9b18a6 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -2,72 +2,80 @@
 
 namespace Drupal\ad_content\Entity;
 
-use Drupal\Core\Entity\EditorialContentEntityBase;
-use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Url;
 use Drupal\user\EntityOwnerTrait;
+use Drupal\views\EntityViewsData;
+use Drupal\Core\Entity\ContentEntityForm;
+use Drupal\Core\Entity\EntityViewBuilder;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\ContentEntityDeleteForm;
+use Drupal\Core\Entity\Attribute\ContentEntityType;
+use Drupal\Core\Entity\EditorialContentEntityBase;
+use Drupal\Core\Entity\EntityAccessControlHandler;
+use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 
 /**
  * Defines the ad content entity class.
- *
- * @ContentEntityType(
- *   id = "ad_content",
- *   label = @Translation("Ad Content"),
- *   label_collection = @Translation("Ad content"),
- *   label_singular = @Translation("Ad content"),
- *   label_plural = @Translation("Ad contents"),
- *   label_count = @PluralTranslation(
- *     singular = "@count ad content",
- *     plural = "@count ad contents",
- *   ),
- *   handlers = {
- *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
- *     "access" = "Drupal\Core\Entity\EntityAccessControlHandler",
- *     "list_builder" = "Drupal\ad_content\Entity\AdContentListBuilder",
- *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
- *     "views_data" = "Drupal\views\EntityViewsData",
- *     "form" = {
- *       "add" = "Drupal\Core\Entity\ContentEntityForm",
- *       "edit" = "Drupal\Core\Entity\ContentEntityForm",
- *       "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
- *       "default" = "Drupal\Core\Entity\ContentEntityForm"
- *     },
- *    "route_provider" = {
- *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
- *     },
- *   },
- *   base_table = "ad_content",
- *   revision_table = "ad_content_revision",
- *   admin_permission="administer ads",
- *   bundle_entity_type = "ad_content_type",
- *   field_ui_base_route = "entity.ad_content.collection",
- *   links = {
- *     "add-form" = "/admin/ad/content/add",
- *     "create" = "/admin/ad/content/add",
- *     "canonical" = "/admin/ad/content/{ad_content}",
- *     "collection" = "/admin/ad",
- *     "delete-form" = "/admin/ad/content/{ad_content}/delete",
- *     "edit-form" = "/admin/ad/content/{ad_content}/edit",
- *   },
- *   entity_keys = {
- *     "id" = "id",
- *     "bundle" = "bundle",
- *     "revision" = "revision_id",
- *     "label" = "title",
- *     "uuid" = "uuid",
- *     "published" = "status",
- *     "owner" = "uid"
- *   },
- *   revision_metadata_keys = {
- *     "revision_user" = "revision_user",
- *     "revision_created" = "revision_created",
- *     "revision_log_message" = "revision_log"
- *   },
- *   render_cache = TRUE,
- * )
  */
+#[ContentEntityType(
+  id:'ad_content',
+  label: new TranslatableMarkup('Ad Content'),
+  label_collection: new TranslatableMarkup('Ad content'),
+  label_singular: new TranslatableMarkup('Ad content'),
+  label_plural: new TranslatableMarkup('Ad contents'),
+  label_count: [
+    'singular' => '@count ad content',
+    'plural' => '@count ad contents',
+  ],
+  handlers: [
+    'storage' => SqlContentEntityStorage::class,
+    'access' => EntityAccessControlHandler::class,
+    'list_builder' => AdContentListBuilder::class,
+    'view_builder' => EntityViewBuilder::class,
+    'views_data' => EntityViewsData::class,
+    'form' => [
+      'add' => ContentEntityForm::class,
+      'edit' => ContentEntityForm::class,
+      'delete' => ContentEntityDeleteForm::class,
+      'default' => ContentEntityForm::class,
+    ],
+    'route_provider' => [
+      'html' => AdminHtmlRouteProvider::class,
+    ],
+  ],
+  base_table: 'ad_content',
+  revision_table: 'ad_content_revision',
+  admin_permission: 'administer ads',
+  bundle_entity_type: 'ad_content_type',
+  bundle_label: new TranslatableMarkup('Ad content type'),
+  field_ui_base_route: 'entity.ad_content_type.edit_form',
+  links: [
+    'add-form' => '/admin/ad/content/add',
+    'create' => '/admin/ad/content/add',
+    'canonical' => '/admin/ad/content/{ad_content}',
+    'collection' => '/admin/ad',
+    'delete-form' => '/admin/ad/content/{ad_content}/delete',
+    'edit-form' => '/admin/ad/content/{ad_content}/edit',
+  ],
+  entity_keys: [
+    'id' => 'id',
+    'bundle' => 'bundle',
+    'revision' => 'revision_id',
+    'label' => 'title',
+    'uuid' => 'uuid',
+    'published' => 'status',
+    'owner' => 'uid',
+  ],
+  revision_metadata_keys: [
+    'revision_user' => 'revision_user',
+    'revision_created' => 'revision_created',
+    'revision_log_message' => 'revision_log',
+  ],
+  render_cache: TRUE
+)]
 class AdContent extends EditorialContentEntityBase implements AdContentInterface {
 
   use EntityOwnerTrait;
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index dcded58..99cc3ba 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -2,53 +2,57 @@
 
 namespace Drupal\ad_content\Entity;
 
+use Drupal\Core\Entity\EntityDeleteForm;
+use Drupal\Core\Entity\Attribute\ConfigEntityType;
+use Drupal\ad_content\Form\AdContentTypeEntityForm;
 use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 
 /**
  * Defines the ad content type bundle class.
- *
- * @ConfigEntityType(
- *   id = "ad_content_type",
- *   label = @Translation("Ad Content Type"),
- *   label_singular = @Translation("Ad content type"),
- *   label_plural = @Translation("Ad content types"),
- *   label_count = @PluralTranslation(
- *     singular = "@count ad content type",
- *     plural = "@count ad content types",
- *   ),
- *   bundle_of = "ad_content",
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "label",
- *     "uuid" = "uuid",
- *   },
- *   config_prefix = "ad_content_type",
- *   config_export = {
- *     "id",
- *     "label",
- *   },
- *   handlers = {
- *     "list_builder" = "Drupal\ad_content\Entity\AdContentTypeListBuilder",
- *     "form" = {
- *       "default" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
- *       "add" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
- *       "edit" = "Drupal\ad_content\Form\AdContentTypeEntityForm",
- *       "delete" = "Drupal\Core\Entity\EntityDeleteForm",
- *     },
- *     "route_provider" = {
- *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
- *     },
- *   },
- *   admin_permission = "administer ads",
- *   links = {
- *     "canonical" = "/admin/ad/content_type/{ad_content_type}",
- *     "add-form" = "/admin/ad/content_type/add",
- *     "edit-form" = "/admin/ad/content_type/{ad_content_type}/edit",
- *     "delete-form" = "/admin/ad/content_type/{ad_content_type}/delete",
- *     "collection" = "/admin/ad/content_type",
- *   }
- * )
  */
+#[ConfigEntityType(
+  id: 'ad_content_type',
+  label: new TranslatableMarkup('Ad Content Type'),
+  label_singular: new TranslatableMarkup('Ad content type'),
+  label_plural: new TranslatableMarkup('Ad content types'),
+  label_count: [
+    'singular' => '@count ad content type',
+    'plural' => '@count ad content types',
+  ],
+  bundle_of: 'ad_content',
+  entity_keys: [
+    'id' => 'id',
+    'label' => 'label',
+    'uuid' => 'uuid',
+  ],
+  config_prefix: 'ad_content_type',
+  config_export: [
+    'id',
+    'label',
+  ],
+  handlers: [
+    'list_builder' => AdContentTypeListBuilder::class,
+    'form' => [
+      'default' => AdContentTypeEntityForm::class,
+      'add' => AdContentTypeEntityForm::class,
+      'edit' => AdContentTypeEntityForm::class,
+      'delete' => EntityDeleteForm::class,
+    ],
+    'route_provider' => [
+      'html' => AdminHtmlRouteProvider::class,
+    ],
+  ],
+  admin_permission: 'administer ads',
+  links: [
+    'canonical' => '/admin/ad/content_type/{ad_content_type}',
+    'add-form' => '/admin/ad/content_type/add',
+    'edit-form' => '/admin/ad/content_type/{ad_content_type}/edit',
+    'delete-form' => '/admin/ad/content_type/{ad_content_type}/delete',
+    'collection' => '/admin/ad/content_type',
+  ]
+)]
 class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
 
   /**
-- 
GitLab


From b12b797118d402c12b51b57bdf8ef79189a5a76f Mon Sep 17 00:00:00 2001
From: Grevil <js@webks.de>
Date: Wed, 23 Apr 2025 14:26:24 +0200
Subject: [PATCH 07/46] Fixes

---
 ..._display.ad_content.ad_content.default.yml | 68 --------------
 ..._display.ad_content.ad_content.default.yml | 88 -------------------
 ...iew_display.ad_content.ad_content.full.yml | 46 ----------
 ...splay.ad_content.ad_content.impression.yml | 30 -------
 .../core.entity_view_mode.ad_content.full.yml |  9 --
 ...entity_view_mode.ad_content.impression.yml |  9 --
 ...ield.ad_content.ad_content.field_image.yml | 37 --------
 .../field.storage.ad_content.field_image.yml  | 29 ------
 modules/ad_content/src/Entity/AdContent.php   |  3 +-
 9 files changed, 1 insertion(+), 318 deletions(-)
 delete mode 100644 modules/ad_content/config/install/core.entity_form_display.ad_content.ad_content.default.yml
 delete mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.default.yml
 delete mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.full.yml
 delete mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.impression.yml
 delete mode 100644 modules/ad_content/config/install/core.entity_view_mode.ad_content.full.yml
 delete mode 100644 modules/ad_content/config/install/core.entity_view_mode.ad_content.impression.yml
 delete mode 100644 modules/ad_content/config/install/field.field.ad_content.ad_content.field_image.yml
 delete mode 100644 modules/ad_content/config/install/field.storage.ad_content.field_image.yml

diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.ad_content.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.ad_content.default.yml
deleted file mode 100644
index c02eb7d..0000000
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.ad_content.default.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.ad_content.ad_content.field_image
-    - image.style.thumbnail
-  module:
-    - ad_content
-    - image
-    - link
-id: ad_content.ad_content.default
-targetEntityType: ad_content
-bundle: ad_content
-mode: default
-content:
-  created:
-    type: datetime_timestamp
-    weight: 5
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-  field_image:
-    weight: 3
-    settings:
-      progress_indicator: throbber
-      preview_image_style: thumbnail
-    third_party_settings: {  }
-    type: image_image
-    region: content
-  size:
-    type: options_select
-    weight: 1
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-  target_url:
-    type: link_default
-    weight: 2
-    region: content
-    settings:
-      placeholder_url: ''
-      placeholder_title: ''
-    third_party_settings: {  }
-  title:
-    type: string_textfield
-    weight: 0
-    region: content
-    settings:
-      size: 60
-      placeholder: ''
-    third_party_settings: {  }
-  uid:
-    type: entity_reference_autocomplete
-    weight: 4
-    settings:
-      match_operator: CONTAINS
-      size: 60
-      placeholder: ''
-      match_limit: 10
-    region: content
-    third_party_settings: {  }
-  status:
-    type: boolean_checkbox
-    weight: 6
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.default.yml
deleted file mode 100644
index c700efe..0000000
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.default.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.ad_content.ad_content.field_image
-  module:
-    - ad_content
-    - link
-    - options
-id: ad_content.ad_content.default
-targetEntityType: ad_content
-bundle: ad_content
-mode: default
-content:
-  created:
-    type: timestamp
-    weight: 5
-    region: content
-    label: inline
-    settings:
-      date_format: medium
-      custom_date_format: ''
-      timezone: ''
-    third_party_settings: {  }
-  field_image:
-    weight: 7
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    type: ad_content_image
-    region: content
-  size:
-    type: list_default
-    weight: 1
-    region: content
-    label: inline
-    settings: {  }
-    third_party_settings: {  }
-  status:
-    type: boolean
-    weight: 0
-    region: content
-    label: inline
-    settings:
-      format: yes-no
-      format_custom_true: ''
-      format_custom_false: ''
-    third_party_settings: {  }
-  target_url:
-    type: link
-    weight: 2
-    region: content
-    label: inline
-    settings:
-      trim_length: 80
-      url_only: false
-      url_plain: false
-      rel: ''
-      target: ''
-    third_party_settings: {  }
-  total_click:
-    type: number_integer
-    weight: 4
-    region: content
-    label: inline
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-  total_impression:
-    type: number_integer
-    weight: 3
-    region: content
-    label: inline
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-  uid:
-    type: entity_reference_label
-    weight: 6
-    region: content
-    label: inline
-    settings:
-      link: true
-    third_party_settings: {  }
-hidden:
-  title: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.full.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.full.yml
deleted file mode 100644
index d4d0714..0000000
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.full.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-langcode: en
-status: false
-dependencies:
-  config:
-    - core.entity_view_mode.ad_content.full
-    - field.field.ad_content.ad_content.field_image
-  module:
-    - ad_content
-    - ad_track
-id: ad_content.ad_content.full
-targetEntityType: ad_content
-bundle: ad_content
-mode: full
-content:
-  field_image:
-    weight: 2
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    type: ad_content_image_click_track
-    region: content
-  total_click:
-    type: number_integer
-    weight: 10
-    region: content
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-  total_impression:
-    type: number_integer
-    weight: 10
-    region: content
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-hidden:
-  created: true
-  size: true
-  status: true
-  target_url: true
-  title: true
-  uid: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.impression.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.impression.yml
deleted file mode 100644
index 9e153a0..0000000
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.ad_content.impression.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - core.entity_view_mode.ad_content.impression
-    - field.field.ad_content.ad_content.field_image
-  module:
-    - ad_content
-    - ad_track
-id: ad_content.ad_content.impression
-targetEntityType: ad_content
-bundle: ad_content
-mode: impression
-content:
-  field_image:
-    weight: 0
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    type: ad_content_image_click_track
-    region: content
-hidden:
-  created: true
-  size: true
-  status: true
-  target_url: true
-  title: true
-  total_click: true
-  total_impression: true
-  uid: true
diff --git a/modules/ad_content/config/install/core.entity_view_mode.ad_content.full.yml b/modules/ad_content/config/install/core.entity_view_mode.ad_content.full.yml
deleted file mode 100644
index 3055461..0000000
--- a/modules/ad_content/config/install/core.entity_view_mode.ad_content.full.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - ad_content
-id: ad_content.full
-label: Preview
-targetEntityType: ad_content
-cache: true
diff --git a/modules/ad_content/config/install/core.entity_view_mode.ad_content.impression.yml b/modules/ad_content/config/install/core.entity_view_mode.ad_content.impression.yml
deleted file mode 100644
index ac111bf..0000000
--- a/modules/ad_content/config/install/core.entity_view_mode.ad_content.impression.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - ad_content
-id: ad_content.impression
-label: Impression
-targetEntityType: ad_content
-cache: true
diff --git a/modules/ad_content/config/install/field.field.ad_content.ad_content.field_image.yml b/modules/ad_content/config/install/field.field.ad_content.ad_content.field_image.yml
deleted file mode 100644
index e3f1000..0000000
--- a/modules/ad_content/config/install/field.field.ad_content.ad_content.field_image.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.ad_content.field_image
-  module:
-    - ad_content
-    - image
-id: ad_content.ad_content.field_image
-field_name: field_image
-entity_type: ad_content
-bundle: ad_content
-label: Image
-description: ''
-required: true
-translatable: false
-default_value: {  }
-default_value_callback: ''
-settings:
-  file_directory: 'ad/[date:custom:Y]-[date:custom:m]'
-  file_extensions: 'png gif jpg jpeg'
-  max_filesize: ''
-  max_resolution: ''
-  min_resolution: ''
-  alt_field: true
-  alt_field_required: false
-  title_field: false
-  title_field_required: false
-  default_image:
-    uuid: ''
-    alt: ''
-    title: ''
-    width: null
-    height: null
-  handler: 'default:file'
-  handler_settings: {  }
-field_type: image
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_image.yml
deleted file mode 100644
index 3473537..0000000
--- a/modules/ad_content/config/install/field.storage.ad_content.field_image.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - ad_content
-    - file
-    - image
-id: ad_content.field_image
-field_name: field_image
-entity_type: ad_content
-type: image
-settings:
-  uri_scheme: public
-  default_image:
-    uuid: ''
-    alt: ''
-    title: ''
-    width: null
-    height: null
-  target_type: file
-  display_field: false
-  display_default: false
-module: image
-locked: false
-cardinality: 1
-translatable: true
-indexes: {  }
-persist_with_no_fields: false
-custom_storage: false
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index e9b18a6..1b9492d 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -53,8 +53,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   bundle_label: new TranslatableMarkup('Ad content type'),
   field_ui_base_route: 'entity.ad_content_type.edit_form',
   links: [
-    'add-form' => '/admin/ad/content/add',
-    'create' => '/admin/ad/content/add',
+    'add-form' => '/admin/ad/content/add/{ad_content_type}',
     'canonical' => '/admin/ad/content/{ad_content}',
     'collection' => '/admin/ad',
     'delete-form' => '/admin/ad/content/{ad_content}/delete',
-- 
GitLab


From 88fa1d548fb659bdb9c39195f52a1a9799ff3355 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 10:24:42 +0200
Subject: [PATCH 08/46] Routing and path rewrites

---
 modules/ad_content/ad_content.info.yml          |  2 +-
 modules/ad_content/ad_content.links.action.yml  |  2 +-
 modules/ad_content/src/Entity/AdContent.php     | 11 ++++++-----
 modules/ad_content/src/Entity/AdContentType.php | 10 +++++-----
 modules/ad_track/ad_track.routing.yml           |  2 +-
 5 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 8218b86..94b8299 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -8,4 +8,4 @@ dependencies:
   - ad:ad_track
   - drupal:options
   - drupal:text
-configure: 'entity.ad_content.collection'
+configure: 'ad.settings'
diff --git a/modules/ad_content/ad_content.links.action.yml b/modules/ad_content/ad_content.links.action.yml
index 3f2c5af..93cb394 100644
--- a/modules/ad_content/ad_content.links.action.yml
+++ b/modules/ad_content/ad_content.links.action.yml
@@ -1,5 +1,5 @@
 ad_content.add_form:
-  route_name: entity.ad_content.add_form
+  route_name: entity.ad_content.add_page
   title: 'Add ad content'
   appears_on:
     - entity.ad_content.collection
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 1b9492d..6531033 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -53,11 +53,12 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   bundle_label: new TranslatableMarkup('Ad content type'),
   field_ui_base_route: 'entity.ad_content_type.edit_form',
   links: [
-    'add-form' => '/admin/ad/content/add/{ad_content_type}',
-    'canonical' => '/admin/ad/content/{ad_content}',
-    'collection' => '/admin/ad',
-    'delete-form' => '/admin/ad/content/{ad_content}/delete',
-    'edit-form' => '/admin/ad/content/{ad_content}/edit',
+    'add-page' => '/admin/content/ad/add',
+    'add-form' => '/admin/content/ad/add/{ad_content_type}',
+    'canonical' => '/admin/content/ad/{ad_content}',
+    'collection' => '/admin/content/ad',
+    'delete-form' => '/admin/content/ad/{ad_content}/delete',
+    'edit-form' => '/admin/content/ad/{ad_content}/edit',
   ],
   entity_keys: [
     'id' => 'id',
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 99cc3ba..315603e 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -46,11 +46,11 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   ],
   admin_permission: 'administer ads',
   links: [
-    'canonical' => '/admin/ad/content_type/{ad_content_type}',
-    'add-form' => '/admin/ad/content_type/add',
-    'edit-form' => '/admin/ad/content_type/{ad_content_type}/edit',
-    'delete-form' => '/admin/ad/content_type/{ad_content_type}/delete',
-    'collection' => '/admin/ad/content_type',
+    'canonical' => '/admin/structure/ad_content_type/{ad_content_type}',
+    'add-form' => '/admin/structure/ad_content_type/add',
+    'edit-form' => '/admin/structure/ad_content_type/{ad_content_type}/edit',
+    'delete-form' => '/admin/structure/ad_content_type/{ad_content_type}/delete',
+    'collection' => '/admin/structure/ad_content_type',
   ]
 )]
 class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
diff --git a/modules/ad_track/ad_track.routing.yml b/modules/ad_track/ad_track.routing.yml
index a7f6dca..88d0dc8 100644
--- a/modules/ad_track/ad_track.routing.yml
+++ b/modules/ad_track/ad_track.routing.yml
@@ -1,5 +1,5 @@
 ad_track.track:
-  path: '/ad/track/{bucket_id}/{ad_id}'
+  path: '/content/ad/track/{bucket_id}/{ad_id}'
   defaults:
     _controller: '\Drupal\ad_track\Controller\ClickTrackController::track'
     _title: 'Click Tracking'
-- 
GitLab


From fbefcbb4ef78617c1188729d84e917ac3e731575 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 12:03:56 +0200
Subject: [PATCH 09/46] Miscellaneous fixes

---
 .../src/Entity/AdContentListBuilder.php       | 43 ++++++++++++++++++-
 .../src/Form/AdContentTypeEntityForm.php      |  6 +--
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index 52c198f..75e8ada 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -4,12 +4,39 @@ namespace Drupal\ad_content\Entity;
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Ad content list builder.
  */
 class AdContentListBuilder extends EntityListBuilder {
 
+  /**
+   * The entity type manager service.
+   *
+   * @var Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, EntityTypeManagerInterface $entity_type_manager) {
+    parent::__construct($entity_type, $storage);
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+    return new static(
+      $entity_type,
+      $container->get('entity_type.manager')->getStorage($entity_type->id()),
+      $container->get('entity_type.manager'),
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -41,11 +68,25 @@ class AdContentListBuilder extends EntityListBuilder {
         ],
       ],
       'size' => $ad_content->getSizeId(),
-      'bundle' => $ad_content->bundle(),
+      'bundle' => $this->getBundleName($ad_content->bundle()),
       'status' => $ad_content->isPublished(),
     ];
 
     return $row + parent::buildRow($ad_content);
   }
 
+  /**
+   * Returns the name of the bundle with the given ID.
+   *
+   * @param string $bundleId
+   *   The ID of the bundle.
+   *
+   * @return string
+   *   The name of the bundle.
+   */
+  private function getBundleName($bundleId): string {
+    $bundle = $this->entityTypeManager->getStorage('ad_content_type')->load($bundleId);
+    return $bundle !== NULL ? $bundle->label() : $this->t('@bundleId (Not found)', ['@bundleId' => $bundleId]);
+  }
+
 }
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
index 7646707..1d61274 100644
--- a/modules/ad_content/src/Form/AdContentTypeEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -43,7 +43,6 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
    * {@inheritdoc}
    */
   public function save(array $form, FormStateInterface $form_state) {
-    $messenger = \Drupal::messenger();
     $entity_type = $this->entity;
     $status = $entity_type->save();
     $message_params = [
@@ -54,14 +53,15 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
     // Provide a message for the user and redirect them back to the collection.
     switch ($status) {
       case SAVED_NEW:
-        $messenger->addMessage($this->t('Created the %label %content_entity_id entity type.', $message_params));
+        $this->messenger()->addMessage($this->t('Created the %label %content_entity_id entity type.', $message_params));
         break;
 
       default:
-        $messenger->addMessage($this->t('Saved the %label %content_entity_id entity type.', $message_params));
+        $this->messenger()->addMessage($this->t('Saved the %label %content_entity_id entity type.', $message_params));
     }
 
     $form_state->setRedirectUrl($entity_type->toUrl('collection'));
+    return $status;
   }
 
 }
-- 
GitLab


From b47e0fef07b975606c47d46ef6425a2213560c45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 12:40:02 +0200
Subject: [PATCH 10/46] Adding description to ad content types

---
 .../ad_content/src/Entity/AdContentType.php   | 28 +++++++++++++++++++
 .../src/Entity/AdContentTypeInterface.php     | 20 ++++++++++++-
 .../src/Entity/AdContentTypeListBuilder.php   |  2 ++
 .../src/Form/AdContentTypeEntityForm.php      | 15 ++++++++--
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 315603e..27f7a8f 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -31,6 +31,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   config_export: [
     'id',
     'label',
+    'description',
   ],
   handlers: [
     'list_builder' => AdContentTypeListBuilder::class,
@@ -55,6 +56,33 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 )]
 class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
 
+  /**
+   * A brief description of the ad content type.
+   *
+   * @var string
+   */
+  protected $description;
+
+  /**
+   * Returns the description of the ad content type.
+   *
+   * @return string
+   *   The description of the ad content type.
+   */
+  public function getDescription(): string {
+    return $this->description ?? '';
+  }
+
+  /**
+   * Sets the description of the ad content type.
+   *
+   * @param string $description
+   *   The description of the ad content type.
+   */
+  public function setDescription($description) {
+    return $this->set('description', $description);
+  }
+
   /**
    * Returns the UUID of the ad content type.
    */
diff --git a/modules/ad_content/src/Entity/AdContentTypeInterface.php b/modules/ad_content/src/Entity/AdContentTypeInterface.php
index e4ca67f..f75a4eb 100644
--- a/modules/ad_content/src/Entity/AdContentTypeInterface.php
+++ b/modules/ad_content/src/Entity/AdContentTypeInterface.php
@@ -7,4 +7,22 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface;
 /**
  * Common interface for ad content type bundle entities.
  */
-interface AdContentTypeInterface extends ConfigEntityInterface {}
+interface AdContentTypeInterface extends ConfigEntityInterface {
+
+  /**
+   * Returns the description of the ad content type.
+   *
+   * @return string
+   *   The description of the ad content type.
+   */
+  public function getDescription(): string;
+
+  /**
+   * Sets the description of the ad content type.
+   *
+   * @param string $description
+   *   The description of the ad content type.
+   */
+  public function setDescription($description);
+
+}
diff --git a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
index 1d2d164..59d02b5 100644
--- a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
@@ -16,6 +16,7 @@ class AdContentTypeListBuilder extends EntityListBuilder {
   public function buildHeader() {
     $header = [
       'title' => $this->t('Title'),
+      'description' => $this->t('Description'),
     ];
 
     return $header + parent::buildHeader();
@@ -29,6 +30,7 @@ class AdContentTypeListBuilder extends EntityListBuilder {
 
     $row = [
       'title' => $ad_content_type->label(),
+      'description' => $ad_content_type->getDescription(),
     ];
 
     return $row + parent::buildRow($ad_content_type);
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
index 1d61274..c0470d3 100644
--- a/modules/ad_content/src/Form/AdContentTypeEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -16,6 +16,7 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
   public function form(array $form, FormStateInterface $form_state) {
     $form = parent::form($form, $form_state);
 
+    /** @var \Drupal\ad_content\Entity\AdContentTypeInterface $entity_type */
     $entity_type = $this->entity;
 
     $form['label'] = [
@@ -23,7 +24,7 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
       '#title' => $this->t('Title'),
       '#maxlength' => 255,
       '#default_value' => $entity_type->label(),
-      '#description' => $this->t("The title for the ad content type (bundle)."),
+      '#description' => $this->t('The title for the ad content type (bundle).'),
       '#required' => TRUE,
     ];
 
@@ -36,6 +37,14 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
       '#disabled' => !$entity_type->isNew(),
     ];
 
+    $form['description'] = [
+      '#type' => 'textarea',
+      '#title' => $this->t('Description'),
+      '#default_value' => $entity_type->getDescription() ?? '',
+      '#description' => $this->t('A short description of the ad content type.'),
+      '#required' => FALSE,
+    ];
+
     return $this->protectBundleIdElement($form);
   }
 
@@ -53,11 +62,11 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
     // Provide a message for the user and redirect them back to the collection.
     switch ($status) {
       case SAVED_NEW:
-        $this->messenger()->addMessage($this->t('Created the %label %content_entity_id entity type.', $message_params));
+        $this->messenger()->addMessage($this->t('Created the %label ad content type..', $message_params));
         break;
 
       default:
-        $this->messenger()->addMessage($this->t('Saved the %label %content_entity_id entity type.', $message_params));
+        $this->messenger()->addMessage($this->t('Saved the %label ad content type.', $message_params));
     }
 
     $form_state->setRedirectUrl($entity_type->toUrl('collection'));
-- 
GitLab


From 7ccf69e035f33f1290912acd7815e5dc4ee28beb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 14:57:10 +0200
Subject: [PATCH 11/46] Making ad content translatable

---
 modules/ad_content/src/Entity/AdContent.php     | 17 +++++++++++++----
 modules/ad_content/src/Entity/AdContentType.php | 10 ++--------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 6531033..f88c834 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -47,6 +47,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
     ],
   ],
   base_table: 'ad_content',
+  data_table: 'ad_content_field_data',
   revision_table: 'ad_content_revision',
   admin_permission: 'administer ads',
   bundle_entity_type: 'ad_content_type',
@@ -68,13 +69,15 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
     'uuid' => 'uuid',
     'published' => 'status',
     'owner' => 'uid',
+    'langcode' => 'langcode',
   ],
   revision_metadata_keys: [
     'revision_user' => 'revision_user',
     'revision_created' => 'revision_created',
     'revision_log_message' => 'revision_log',
   ],
-  render_cache: TRUE
+  render_cache: TRUE,
+  translatable: TRUE,
 )]
 class AdContent extends EditorialContentEntityBase implements AdContentInterface {
 
@@ -123,7 +126,11 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['status']
       ->setDisplayConfigurable('form', TRUE)
-      ->setDisplayConfigurable('view', TRUE);
+      ->setDisplayConfigurable('view', TRUE)
+      ->setDisplayOptions('form', [
+        'type' => 'boolean_checkbox',
+        'weight' => 15,
+      ]);
 
     $fields['title'] = BaseFieldDefinition::create('string')
       ->setLabel(new TranslatableMarkup('Title'))
@@ -141,7 +148,8 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
         'type' => 'string',
         'weight' => -5,
       ])
-      ->setDisplayConfigurable('view', TRUE);
+      ->setDisplayConfigurable('view', TRUE)
+      ->setTranslatable(TRUE);
 
     $fields['uid']
       ->setLabel(new TranslatableMarkup('Authored by'))
@@ -198,7 +206,8 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
         'type' => 'link',
         'weight' => -3,
       ])
-      ->setDisplayConfigurable('view', TRUE);
+      ->setDisplayConfigurable('view', TRUE)
+      ->setTranslatable(TRUE);
 
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(new TranslatableMarkup('Authored on'))
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 27f7a8f..d31c46b 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -64,20 +64,14 @@ class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInter
   protected $description;
 
   /**
-   * Returns the description of the ad content type.
-   *
-   * @return string
-   *   The description of the ad content type.
+   * {@inheritDoc}
    */
   public function getDescription(): string {
     return $this->description ?? '';
   }
 
   /**
-   * Sets the description of the ad content type.
-   *
-   * @param string $description
-   *   The description of the ad content type.
+   * {@inheritDoc}
    */
   public function setDescription($description) {
     return $this->set('description', $description);
-- 
GitLab


From f8fccbc830d0b396b129928430c2a2148d5329f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 15:24:38 +0200
Subject: [PATCH 12/46] Workaround for form redirect

---
 .../src/Form/AdContentEntityForm.php          | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 modules/ad_content/src/Form/AdContentEntityForm.php

diff --git a/modules/ad_content/src/Form/AdContentEntityForm.php b/modules/ad_content/src/Form/AdContentEntityForm.php
new file mode 100644
index 0000000..c53ba47
--- /dev/null
+++ b/modules/ad_content/src/Form/AdContentEntityForm.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\ad_content\Form;
+
+use Drupal\Core\Entity\ContentEntityForm;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Entity form for ad content.
+ */
+class AdContentEntityForm extends ContentEntityForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    parent::save($form, $form_state);
+    $form_state->setRedirectUrl($this->entity->toUrl('collection'));
+  }
+
+}
-- 
GitLab


From d18c5bb4c701440217a0193fe1941d13566b99d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 30 Apr 2025 15:25:03 +0200
Subject: [PATCH 13/46] Workaround for form redirect

---
 modules/ad_content/src/Entity/AdContent.php | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index f88c834..e904231 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -2,10 +2,10 @@
 
 namespace Drupal\ad_content\Entity;
 
+use Drupal\ad_content\Form\AdContentEntityForm;
 use Drupal\Core\Url;
 use Drupal\user\EntityOwnerTrait;
 use Drupal\views\EntityViewsData;
-use Drupal\Core\Entity\ContentEntityForm;
 use Drupal\Core\Entity\EntityViewBuilder;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Entity\EntityTypeInterface;
@@ -37,10 +37,10 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
     'view_builder' => EntityViewBuilder::class,
     'views_data' => EntityViewsData::class,
     'form' => [
-      'add' => ContentEntityForm::class,
-      'edit' => ContentEntityForm::class,
+      'add' => AdContentEntityForm::class,
+      'edit' => AdContentEntityForm::class,
       'delete' => ContentEntityDeleteForm::class,
-      'default' => ContentEntityForm::class,
+      'default' => AdContentEntityForm::class,
     ],
     'route_provider' => [
       'html' => AdminHtmlRouteProvider::class,
-- 
GitLab


From b4173e92297db5f57a0ab0d9db01a1084c0628f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 6 May 2025 17:16:46 +0200
Subject: [PATCH 14/46] Adding default ad types via install config

---
 .../ad_content.ad_content_type.image_ad.yml   |   6 ++
 ..._content.ad_content_type.javascript_ad.yml |   6 ++
 .../ad_content.ad_content_type.text_ad.yml    |   6 ++
 ...rm_display.ad_content.image_ad.default.yml |  76 +++++++++++++
 ...splay.ad_content.javascript_ad.default.yml |  75 +++++++++++++
 ...orm_display.ad_content.text_ad.default.yml |  77 +++++++++++++
 ...ew_display.ad_content.image_ad.default.yml | 101 ++++++++++++++++++
 ...splay.ad_content.javascript_ad.default.yml |  90 ++++++++++++++++
 ...iew_display.ad_content.text_ad.default.yml |  97 +++++++++++++++++
 ...eld.ad_content.image_ad.field_ad_image.yml |  37 +++++++
 ...content.javascript_ad.field_javascript.yml |  21 ++++
 ...field.ad_content.text_ad.field_ad_text.yml |  23 ++++
 ...ield.storage.ad_content.field_ad_image.yml |  29 +++++
 ...field.storage.ad_content.field_ad_text.yml |  18 ++++
 ...ld.storage.ad_content.field_javascript.yml |  18 ++++
 15 files changed, 680 insertions(+)
 create mode 100644 modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
 create mode 100644 modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
 create mode 100644 modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
 create mode 100644 modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
 create mode 100644 modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
 create mode 100644 modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
 create mode 100644 modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
 create mode 100644 modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
 create mode 100644 modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
 create mode 100644 modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
 create mode 100644 modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
 create mode 100644 modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml

diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
new file mode 100644
index 0000000..b1176e8
--- /dev/null
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
@@ -0,0 +1,6 @@
+langcode: en
+status: true
+dependencies: {  }
+id: image_ad
+label: 'Image Ad'
+description: 'An ad that contains an image.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
new file mode 100644
index 0000000..382df32
--- /dev/null
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
@@ -0,0 +1,6 @@
+langcode: en
+status: true
+dependencies: {  }
+id: javascript_ad
+label: 'JavaScript Ad'
+description: 'An ad that contains JavaScript.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
new file mode 100644
index 0000000..80ae1e6
--- /dev/null
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
@@ -0,0 +1,6 @@
+langcode: en
+status: true
+dependencies: {  }
+id: text_ad
+label: 'Text Ad'
+description: 'An ad that contains text.'
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
new file mode 100644
index 0000000..17b81bc
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
@@ -0,0 +1,76 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.image_ad
+    - field.field.ad_content.image_ad.field_ad_image
+    - image.style.thumbnail
+  module:
+    - image
+    - link
+id: ad_content.image_ad.default
+targetEntityType: ad_content
+bundle: image_ad
+mode: default
+content:
+  created:
+    type: datetime_timestamp
+    weight: 6
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  field_ad_image:
+    type: image_image
+    weight: 2
+    region: content
+    settings:
+      progress_indicator: throbber
+      preview_image_style: thumbnail
+    third_party_settings: {  }
+  langcode:
+    type: language_select
+    weight: 4
+    region: content
+    settings:
+      include_locked: true
+    third_party_settings: {  }
+  size:
+    type: options_select
+    weight: 1
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    weight: 7
+    region: content
+    settings:
+      display_label: true
+    third_party_settings: {  }
+  target_url:
+    type: link_default
+    weight: 3
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: 0
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
new file mode 100644
index 0000000..290c56e
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
@@ -0,0 +1,75 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.javascript_ad
+    - field.field.ad_content.javascript_ad.field_javascript
+  module:
+    - link
+    - text
+id: ad_content.javascript_ad.default
+targetEntityType: ad_content
+bundle: javascript_ad
+mode: default
+content:
+  created:
+    type: datetime_timestamp
+    weight: 6
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  field_javascript:
+    type: text_textarea
+    weight: 2
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  langcode:
+    type: language_select
+    weight: 4
+    region: content
+    settings:
+      include_locked: true
+    third_party_settings: {  }
+  size:
+    type: options_select
+    weight: 1
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    weight: 7
+    region: content
+    settings:
+      display_label: true
+    third_party_settings: {  }
+  target_url:
+    type: link_default
+    weight: 3
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: 0
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
new file mode 100644
index 0000000..07dc9b2
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
@@ -0,0 +1,77 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.text_ad
+    - field.field.ad_content.text_ad.field_ad_text
+  module:
+    - link
+    - text
+id: ad_content.text_ad.default
+targetEntityType: ad_content
+bundle: text_ad
+mode: default
+content:
+  created:
+    type: datetime_timestamp
+    weight: 6
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  field_ad_text:
+    type: text_textarea_with_summary
+    weight: 2
+    region: content
+    settings:
+      rows: 9
+      summary_rows: 3
+      placeholder: ''
+      show_summary: false
+    third_party_settings: {  }
+  langcode:
+    type: language_select
+    weight: 4
+    region: content
+    settings:
+      include_locked: true
+    third_party_settings: {  }
+  size:
+    type: options_select
+    weight: 1
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    weight: 7
+    region: content
+    settings:
+      display_label: true
+    third_party_settings: {  }
+  target_url:
+    type: link_default
+    weight: 3
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: 0
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  uid:
+    type: entity_reference_autocomplete
+    weight: 5
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
new file mode 100644
index 0000000..134d27c
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
@@ -0,0 +1,101 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.image_ad
+    - field.field.ad_content.image_ad.field_ad_image
+  module:
+    - image
+    - link
+    - options
+    - user
+id: ad_content.image_ad.default
+targetEntityType: ad_content
+bundle: image_ad
+mode: default
+content:
+  created:
+    type: timestamp
+    label: hidden
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  field_ad_image:
+    type: image
+    label: hidden
+    settings:
+      image_link: ''
+      image_style: ''
+      image_loading:
+        attribute: lazy
+    third_party_settings: {  }
+    weight: 11
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: -4
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: -3
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: -5
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  uid:
+    type: author
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 5
+    region: content
+hidden:
+  langcode: true
+  status: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
new file mode 100644
index 0000000..8b618d8
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
@@ -0,0 +1,90 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.javascript_ad
+    - field.field.ad_content.javascript_ad.field_javascript
+  module:
+    - link
+    - options
+    - user
+id: ad_content.javascript_ad.default
+targetEntityType: ad_content
+bundle: javascript_ad
+mode: default
+content:
+  created:
+    type: timestamp
+    label: hidden
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 3
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 6
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  uid:
+    type: author
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 4
+    region: content
+hidden:
+  field_javascript: true
+  langcode: true
+  status: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
new file mode 100644
index 0000000..d4ace17
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
@@ -0,0 +1,97 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.text_ad
+    - field.field.ad_content.text_ad.field_ad_text
+  module:
+    - link
+    - options
+    - text
+    - user
+id: ad_content.text_ad.default
+targetEntityType: ad_content
+bundle: text_ad
+mode: default
+content:
+  created:
+    type: timestamp
+    label: hidden
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  field_ad_text:
+    type: text_default
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 11
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: -4
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: -3
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: -5
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 10
+    region: content
+  uid:
+    type: author
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 5
+    region: content
+hidden:
+  langcode: true
+  status: true
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
new file mode 100644
index 0000000..e43b867
--- /dev/null
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -0,0 +1,37 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.image_ad
+    - field.storage.ad_content.field_ad_image
+  module:
+    - image
+id: ad_content.image_ad.field_ad_image
+field_name: field_ad_image
+entity_type: ad_content
+bundle: image_ad
+label: 'Ad image'
+description: 'The image that the ad should display.'
+required: true
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:file'
+  handler_settings: {  }
+  file_directory: '[date:custom:Y]-[date:custom:m]'
+  file_extensions: 'png gif jpg jpeg webp'
+  max_filesize: ''
+  max_resolution: ''
+  min_resolution: ''
+  alt_field: true
+  alt_field_required: true
+  title_field: true
+  title_field_required: false
+  default_image:
+    uuid: ''
+    alt: ''
+    title: ''
+    width: null
+    height: null
+field_type: image
diff --git a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
new file mode 100644
index 0000000..3977d39
--- /dev/null
+++ b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
@@ -0,0 +1,21 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.javascript_ad
+    - field.storage.ad_content.field_javascript
+  module:
+    - text
+id: ad_content.javascript_ad.field_javascript
+field_name: field_javascript
+entity_type: ad_content
+bundle: javascript_ad
+label: 'JavaScript code'
+description: 'The JavaScript code that the ad should run in order to display.'
+required: true
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  allowed_formats: {  }
+field_type: text_long
diff --git a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
new file mode 100644
index 0000000..476d4ef
--- /dev/null
+++ b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
@@ -0,0 +1,23 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.text_ad
+    - field.storage.ad_content.field_ad_text
+  module:
+    - text
+id: ad_content.text_ad.field_ad_text
+field_name: field_ad_text
+entity_type: ad_content
+bundle: text_ad
+label: 'Ad text'
+description: 'The text that the ad should display.'
+required: true
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  display_summary: true
+  required_summary: false
+  allowed_formats: {  }
+field_type: text_with_summary
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
new file mode 100644
index 0000000..8ae34c9
--- /dev/null
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
@@ -0,0 +1,29 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - ad_content
+    - file
+    - image
+id: ad_content.field_ad_image
+field_name: field_ad_image
+entity_type: ad_content
+type: image
+settings:
+  target_type: file
+  display_field: false
+  display_default: true
+  uri_scheme: public
+  default_image:
+    uuid: ''
+    alt: ''
+    title: ''
+    width: null
+    height: null
+module: image
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
new file mode 100644
index 0000000..c2fed7c
--- /dev/null
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - ad_content
+    - text
+id: ad_content.field_ad_text
+field_name: field_ad_text
+entity_type: ad_content
+type: text_with_summary
+settings: {  }
+module: text
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
new file mode 100644
index 0000000..f88394a
--- /dev/null
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
@@ -0,0 +1,18 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - ad_content
+    - text
+id: ad_content.field_javascript
+field_name: field_javascript
+entity_type: ad_content
+type: text_long
+settings: {  }
+module: text
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
-- 
GitLab


From 7d50d48a2c87a8180f7da98faf219b6a6d7a7109 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 6 May 2025 17:32:41 +0200
Subject: [PATCH 15/46] Removing outdated view and updating statistics view
 config

---
 .../optional/views.view.ad_administration.yml | 1172 -----------------
 .../optional/views.view.ad_statistics.yml     |    6 +-
 2 files changed, 3 insertions(+), 1175 deletions(-)
 delete mode 100644 modules/ad_content/config/optional/views.view.ad_administration.yml

diff --git a/modules/ad_content/config/optional/views.view.ad_administration.yml b/modules/ad_content/config/optional/views.view.ad_administration.yml
deleted file mode 100644
index 139ccd1..0000000
--- a/modules/ad_content/config/optional/views.view.ad_administration.yml
+++ /dev/null
@@ -1,1172 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.ad_content.field_image
-    - image.style.mini_thumbnail
-  module:
-    - ad_content
-    - ad_track
-    - image
-    - link
-    - options
-    - user
-id: ad_administration
-label: 'Ad Administration'
-module: views
-description: ''
-tag: ''
-base_table: ad_content
-base_field: id
-display:
-  default:
-    id: default
-    display_title: Master
-    display_plugin: default
-    position: 0
-    display_options:
-      title: Advertisement
-      fields:
-        id:
-          id: id
-          table: ad_content
-          field: id
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: id
-          plugin_id: field
-          label: ID
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: number_integer
-          settings:
-            thousand_separator: ''
-            prefix_suffix: true
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        field_image:
-          id: field_image
-          table: ad_content__field_image
-          field: field_image
-          relationship: none
-          group_type: group
-          admin_label: ''
-          plugin_id: field
-          label: Preview
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: false
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: target_id
-          type: image
-          settings:
-            image_link: content
-            image_style: mini_thumbnail
-            image_loading:
-              attribute: lazy
-          group_column: ''
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        title:
-          id: title
-          table: ad_content
-          field: title
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: title
-          plugin_id: field
-          label: Title
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: string
-          settings:
-            link_to_entity: true
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        status:
-          id: status
-          table: ad_content
-          field: status
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: status
-          plugin_id: field
-          label: Status
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: boolean
-          settings:
-            format: custom
-            format_custom_false: Unpublished
-            format_custom_true: Published
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        size:
-          id: size
-          table: ad_content
-          field: size
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: size
-          plugin_id: field
-          label: Size
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: list_default
-          settings: {  }
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        target_url__uri:
-          id: target_url__uri
-          table: ad_content
-          field: target_url__uri
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: target_url
-          plugin_id: field
-          label: 'Target URL'
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: uri
-          type: link
-          settings:
-            trim_length: 80
-            url_only: false
-            url_plain: false
-            rel: '0'
-            target: _blank
-          group_column: ''
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        impression:
-          id: impression
-          table: ad_track_total
-          field: impression
-          relationship: uuid
-          group_type: group
-          admin_label: ''
-          plugin_id: numeric
-          label: Impressions
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: true
-            path: '/admin/ad/statistics/{{ id }}'
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          set_precision: false
-          precision: 0
-          decimal: .
-          separator: ','
-          format_plural: false
-          format_plural_string: !!binary MQNAY291bnQ=
-          prefix: ''
-          suffix: ''
-        click:
-          id: click
-          table: ad_track_total
-          field: click
-          relationship: uuid
-          group_type: group
-          admin_label: ''
-          plugin_id: numeric
-          label: Clicks
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: true
-            path: '/admin/ad/statistics/{{ id }}'
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          set_precision: false
-          precision: 0
-          decimal: .
-          separator: ','
-          format_plural: false
-          format_plural_string: !!binary MQNAY291bnQ=
-          prefix: ''
-          suffix: ''
-        click_through:
-          id: click_through
-          table: ad_track_total
-          field: click_through
-          relationship: uuid
-          group_type: group
-          admin_label: ''
-          plugin_id: ad_track_click_through
-          label: 'Click through'
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: true
-            path: '/admin/ad/statistics/{{ id }}'
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-        created:
-          id: created
-          table: ad_content
-          field: created
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: created
-          plugin_id: field
-          label: Created
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: timestamp
-          settings:
-            date_format: short
-            custom_date_format: ''
-            timezone: ''
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        changed:
-          id: changed
-          table: ad_content
-          field: changed
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: changed
-          plugin_id: field
-          label: Updated
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: timestamp
-          settings:
-            date_format: short
-            custom_date_format: ''
-            timezone: ''
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        operations:
-          id: operations
-          table: ad_content
-          field: operations
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          plugin_id: entity_operations
-          label: Operations
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          destination: true
-      pager:
-        type: full
-        options:
-          offset: 0
-          items_per_page: 15
-          total_pages: null
-          id: 0
-          tags:
-            next: ››
-            previous: ‹‹
-            first: '« First'
-            last: 'Last »'
-          expose:
-            items_per_page: false
-            items_per_page_label: 'Items per page'
-            items_per_page_options: '5, 10, 25, 50'
-            items_per_page_options_all: false
-            items_per_page_options_all_label: '- All -'
-            offset: false
-            offset_label: Offset
-          quantity: 9
-      exposed_form:
-        type: basic
-        options:
-          submit_button: Apply
-          reset_button: false
-          reset_button_label: Reset
-          exposed_sorts_label: 'Sort by'
-          expose_sort_order: true
-          sort_asc_label: Asc
-          sort_desc_label: Desc
-      access:
-        type: perm
-        options:
-          perm: 'administer ads'
-      cache:
-        type: none
-        options: {  }
-      empty: {  }
-      sorts: {  }
-      arguments: {  }
-      filters:
-        status:
-          id: status
-          table: ad_content
-          field: status
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: status
-          plugin_id: boolean
-          operator: '='
-          value: '1'
-          group: 1
-          exposed: true
-          expose:
-            operator_id: ''
-            label: Published
-            description: ''
-            use_operator: false
-            operator: status_op
-            operator_limit_selection: false
-            operator_list: {  }
-            identifier: status
-            required: true
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              verified: '0'
-              administrator: '0'
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-        size:
-          id: size
-          table: ad_content
-          field: size
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: size
-          plugin_id: string
-          operator: contains
-          value: ''
-          group: 1
-          exposed: true
-          expose:
-            operator_id: size_op
-            label: Size
-            description: ''
-            use_operator: false
-            operator: size_op
-            operator_limit_selection: false
-            operator_list: {  }
-            identifier: size
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              verified: '0'
-              administrator: '0'
-            placeholder: ''
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-        title:
-          id: title
-          table: ad_content
-          field: title
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: title
-          plugin_id: string
-          operator: contains
-          value: ''
-          group: 1
-          exposed: true
-          expose:
-            operator_id: title_op
-            label: Title
-            description: ''
-            use_operator: false
-            operator: title_op
-            operator_limit_selection: false
-            operator_list: {  }
-            identifier: title
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              verified: '0'
-              administrator: '0'
-            placeholder: ''
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-        target_url__uri:
-          id: target_url__uri
-          table: ad_content
-          field: target_url__uri
-          relationship: none
-          group_type: group
-          admin_label: ''
-          entity_type: ad_content
-          entity_field: target_url
-          plugin_id: string
-          operator: contains
-          value: ''
-          group: 1
-          exposed: true
-          expose:
-            operator_id: target_url__uri_op
-            label: 'Target URL'
-            description: ''
-            use_operator: false
-            operator: target_url__uri_op
-            operator_limit_selection: false
-            operator_list: {  }
-            identifier: target_url__uri
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              verified: '0'
-              administrator: '0'
-            placeholder: ''
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-      filter_groups:
-        operator: AND
-        groups:
-          1: AND
-      style:
-        type: table
-        options:
-          grouping: {  }
-          row_class: ''
-          default_row_class: true
-          columns:
-            id: id
-            title: title
-            size: size
-            field_image: field_image
-            target_url__uri: target_url__uri
-            impression: impression
-            click: click
-            click_through: click_through
-            status: status
-            created: created
-            changed: changed
-            operations: operations
-          default: created
-          info:
-            id:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            title:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            size:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            field_image:
-              sortable: false
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            target_url__uri:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            impression:
-              sortable: true
-              default_sort_order: asc
-              align: views-align-center
-              separator: ''
-              empty_column: false
-              responsive: ''
-            click:
-              sortable: true
-              default_sort_order: asc
-              align: views-align-center
-              separator: ''
-              empty_column: false
-              responsive: ''
-            click_through:
-              sortable: false
-              default_sort_order: asc
-              align: views-align-center
-              separator: ''
-              empty_column: false
-              responsive: ''
-            status:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            created:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            changed:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            operations:
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-          override: true
-          sticky: false
-          summary: ''
-          empty_table: false
-          caption: ''
-          description: ''
-      row:
-        type: fields
-      query:
-        type: views_query
-        options:
-          query_comment: ''
-          disable_sql_rewrite: false
-          distinct: false
-          replica: false
-          query_tags: {  }
-      relationships:
-        uuid:
-          id: uuid
-          table: ad_content
-          field: uuid
-          relationship: none
-          group_type: group
-          admin_label: Totals
-          entity_type: ad_content
-          entity_field: uuid
-          plugin_id: standard
-          required: false
-      use_ajax: true
-      header: {  }
-      footer: {  }
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - user.permissions
-      tags:
-        - 'config:field.storage.ad_content.field_image'
-  page:
-    id: page
-    display_title: Page
-    display_plugin: page
-    position: 1
-    display_options:
-      display_extenders: {  }
-      path: admin/ad
-      menu:
-        type: none
-        title: List
-        description: ''
-        weight: 0
-        expanded: false
-        menu_name: main
-        parent: ''
-        context: '0'
-      tab_options:
-        type: normal
-        title: Content
-        description: ''
-        weight: 0
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - user.permissions
-      tags:
-        - 'config:field.storage.ad_content.field_image'
diff --git a/modules/ad_content/config/optional/views.view.ad_statistics.yml b/modules/ad_content/config/optional/views.view.ad_statistics.yml
index b19d400..de60cd1 100644
--- a/modules/ad_content/config/optional/views.view.ad_statistics.yml
+++ b/modules/ad_content/config/optional/views.view.ad_statistics.yml
@@ -436,7 +436,7 @@ display:
             alter_text: false
             text: ''
             make_link: true
-            path: '/admin/ad/statistics/{{ id_1 }}'
+            path: '/admin/content/ad/statistics/{{ id_1 }}'
             absolute: false
             external: false
             replace_spaces: false
@@ -1110,7 +1110,7 @@ display:
           field: ad_id
           relationship: none
           group_type: group
-          admin_label: 'Content ad'
+          admin_label: 'Ad content'
           required: false
           entity_type: ad_track_event
           plugin_id: standard
@@ -1172,7 +1172,7 @@ display:
     position: 1
     display_options:
       display_extenders: {  }
-      path: admin/ad/statistics
+      path: admin/content/ad/statistics
     cache_metadata:
       max-age: -1
       contexts:
-- 
GitLab


From 534362fe4001b91685fe050df2310cce677b1346 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 09:39:07 +0200
Subject: [PATCH 16/46] Miscellaneous fixes

---
 .../src/Entity/AdContentListBuilder.php       |  2 +-
 .../src/Form/AdContentEntityForm.php          |  3 ++-
 modules/ad_track/ad_track.services.yml        |  2 +-
 .../src/Plugin/Ad/Track/LocalTracker.php      |  2 +-
 modules/ad_track/src/TotalSqlStorage.php      | 27 ++++++-------------
 5 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index 75e8ada..e2d797f 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -69,7 +69,7 @@ class AdContentListBuilder extends EntityListBuilder {
       ],
       'size' => $ad_content->getSizeId(),
       'bundle' => $this->getBundleName($ad_content->bundle()),
-      'status' => $ad_content->isPublished(),
+      'status' => $ad_content->isPublished() ? $this->t('Published') : $this->t('Not published'),
     ];
 
     return $row + parent::buildRow($ad_content);
diff --git a/modules/ad_content/src/Form/AdContentEntityForm.php b/modules/ad_content/src/Form/AdContentEntityForm.php
index c53ba47..5f456c8 100644
--- a/modules/ad_content/src/Form/AdContentEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentEntityForm.php
@@ -14,8 +14,9 @@ class AdContentEntityForm extends ContentEntityForm {
    * {@inheritdoc}
    */
   public function save(array $form, FormStateInterface $form_state) {
-    parent::save($form, $form_state);
+    $status = parent::save($form, $form_state);
     $form_state->setRedirectUrl($this->entity->toUrl('collection'));
+    return $status;
   }
 
 }
diff --git a/modules/ad_track/ad_track.services.yml b/modules/ad_track/ad_track.services.yml
index ed55ac4..dc1a350 100644
--- a/modules/ad_track/ad_track.services.yml
+++ b/modules/ad_track/ad_track.services.yml
@@ -1,4 +1,4 @@
 services:
   ad_track.total_storage:
     class: Drupal\ad_track\TotalSqlStorage
-    arguments: ['@database']
+    arguments: ['@database', '@logger.factory']
diff --git a/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php b/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
index bfb2395..42ab409 100644
--- a/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
+++ b/modules/ad_track/src/Plugin/Ad/Track/LocalTracker.php
@@ -139,7 +139,7 @@ class LocalTracker implements TrackerInterface, ContainerFactoryPluginInterface
       $container->get('entity.repository'),
       $container->get('ad_track.total_storage'),
       $container->get('uuid'),
-      $container->get('logger.factory')->get('ad_content')
+      $container->get('logger.factory')->get('ad_track')
     );
   }
 
diff --git a/modules/ad_track/src/TotalSqlStorage.php b/modules/ad_track/src/TotalSqlStorage.php
index 15c022c..25d53d6 100644
--- a/modules/ad_track/src/TotalSqlStorage.php
+++ b/modules/ad_track/src/TotalSqlStorage.php
@@ -7,8 +7,7 @@ use Drupal\ad\AdInterface;
 use Drupal\ad\Track\TrackerInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\DatabaseExceptionWrapper;
-use Psr\Log\LoggerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Logger\LoggerChannelFactoryInterface;
 
 /**
  * Track totals SQL storage backend.
@@ -32,33 +31,23 @@ class TotalSqlStorage implements TotalStorageInterface {
   protected array $transactions = [];
 
   /**
-   * The logger service.
+   * The logger factory service.
    *
-   * @var \Psr\Log\LoggerInterface
+   * @var \Psr\Log\LoggerChannelFactoryInterface
    */
-  protected LoggerInterface $logger;
+  protected LoggerChannelFactoryInterface $loggerFactory;
 
   /**
    * AdTrackTotalSqlStorage constructor.
    *
    * @param \Drupal\Core\Database\Connection $database
    *   The database connection.
-   * @param \Psr\Log\LoggerInterface $logger
+   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
    *   The logger service.
    */
-  public function __construct(Connection $database, LoggerInterface $logger) {
+  public function __construct(Connection $database, LoggerChannelFactoryInterface $loggerFactory) {
     $this->database = $database;
-    $this->logger = $logger;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, Connection $database) {
-    return new static(
-      $database,
-      $container->get('logger.factory')->get('ad_content'),
-    );
+    $this->loggerFactory = $loggerFactory;
   }
 
   /**
@@ -84,7 +73,7 @@ class TotalSqlStorage implements TotalStorageInterface {
       }
     }
     catch (DatabaseExceptionWrapper $e) {
-      Error::logException($this->logger, $e);
+      Error::logException($this->loggerFactory->get('ad_track'), $e);
     }
 
     return $result;
-- 
GitLab


From 2a49945232da5e6f1e93c4fe6789231ffa383b93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 11:08:50 +0200
Subject: [PATCH 17/46] Basic framework for ad_scheduler submodule

---
 modules/ad_scheduler/ad_scheduler.info.yml    |  9 +++++++++
 .../Plugin/Scheduler/AdContentScheduler.php   | 20 +++++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 modules/ad_scheduler/ad_scheduler.info.yml
 create mode 100644 modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php

diff --git a/modules/ad_scheduler/ad_scheduler.info.yml b/modules/ad_scheduler/ad_scheduler.info.yml
new file mode 100644
index 0000000..2fa91bb
--- /dev/null
+++ b/modules/ad_scheduler/ad_scheduler.info.yml
@@ -0,0 +1,9 @@
+name: Ad Scheduler
+description: 'Integrates ad contents with the scheduler module.'
+type: module
+package: Advertisement
+core_version_requirement: ^10.3 || ^11
+dependencies:
+  - ad:ad
+  - ad:ad_content
+  - scheduler:scheduler
diff --git a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
new file mode 100644
index 0000000..b10d332
--- /dev/null
+++ b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\ad_scheduler\Plugin\Scheduler;
+
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\scheduler\Annotation\SchedulerPlugin;
+use Drupal\scheduler\SchedulerPluginBase;
+
+/**
+ * Ad content plugin for the scheduler module.
+ */
+#[SchedulerPlugin(
+  id: 'ad_content_scheduler',
+  label: new TranslatableMarkup('Ad content scheduler plugin'),
+  description: new TranslatableMarkup('Support for scheduling ad content entities'),
+  entityType: 'ad_content',
+  dependency: 'ad_content',
+)]
+class AdContentScheduler extends SchedulerPluginBase implements ContainerFactoryPluginInterface {}
-- 
GitLab


From 18fb483b28c62ee0cd71d96bec67801c253772d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 12:26:40 +0200
Subject: [PATCH 18/46] Adding ad label setting in form

---
 src/Form/SettingsForm.php | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index b83aee8..882f2a2 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -9,7 +9,6 @@ use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -86,14 +85,14 @@ class SettingsForm extends ConfigFormBase {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $config = $this->config('ad.settings');
-    $settings = $config->get('trackers');
+    $trackerSettings = $config->get('trackers');
     $trackers = $this->trackerFactory->getList();
     $buckets = $this->bucketFactory->getList();
 
     $form['trackers'] = [
       '#type' => 'fieldset',
-      '#title' => new TranslatableMarkup('Tracker configuration'),
-      '#description' => new TranslatableMarkup('Assign an ad statistics tracker for each ad source.'),
+      '#title' => $this->t('Tracker configuration'),
+      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
       '#tree' => TRUE,
     ];
 
@@ -103,9 +102,7 @@ class SettingsForm extends ConfigFormBase {
           ->toString(TRUE)
           ->getGeneratedUrl(),
       ];
-      $form['trackers']['#description'] = new TranslatableMarkup('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
-
-      return $form;
+      $form['trackers']['#description'] = $this->t('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
     }
 
     foreach ($buckets as $id => $label) {
@@ -114,10 +111,17 @@ class SettingsForm extends ConfigFormBase {
         '#title' => $label,
         '#required' => TRUE,
         '#options' => $trackers,
-        '#default_value' => $settings[$id] ?? key($trackers),
+        '#default_value' => $trackerSettings[$id] ?? key($trackers),
       ];
     }
 
+    $form['ad_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Ad label'),
+      '#description' => $this->t('In many countries it is mandatory to label ads ad being such. This setting adds a small print (e.g. "ADVERTISEMENT") to all ad blocks.'),
+      '#default_value' => $config->get('ad_label') ?? '',
+    ];
+
     return parent::buildForm($form, $form_state);
   }
 
@@ -127,6 +131,7 @@ class SettingsForm extends ConfigFormBase {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->config('ad.settings')
       ->set('trackers', $form_state->getValue('trackers'))
+      ->set('ad_label', $form_state->getValue('ad_label'))
       ->save();
 
     parent::submitForm($form, $form_state);
-- 
GitLab


From ca6970607c7adc3ba49c6f7cf3953b574033ce4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 12:43:06 +0200
Subject: [PATCH 19/46] Updating install config to include view modes for admin
 and impression

---
 .../config/install/SettingsForm.php           | 140 ++++++++++++++++++
 .../ad_content.ad_content_type.image_ad.yml   |   3 +
 ..._content.ad_content_type.javascript_ad.yml |   3 +
 .../ad_content.ad_content_type.text_ad.yml    |   3 +
 ...rm_display.ad_content.image_ad.default.yml |   3 +
 ...splay.ad_content.javascript_ad.default.yml |   3 +
 ...orm_display.ad_content.text_ad.default.yml |   3 +
 ...view_display.ad_content.image_ad.admin.yml | 122 +++++++++++++++
 ...ew_display.ad_content.image_ad.default.yml |  94 ++----------
 ...display.ad_content.javascript_ad.admin.yml | 118 +++++++++++++++
 ...splay.ad_content.javascript_ad.default.yml |  87 ++---------
 ..._view_display.ad_content.text_ad.admin.yml | 118 +++++++++++++++
 ...iew_display.ad_content.text_ad.default.yml |  86 ++---------
 ...core.entity_view_mode.ad_content.admin.yml |  11 ++
 ...eld.ad_content.image_ad.field_ad_image.yml |   3 +
 ...content.javascript_ad.field_javascript.yml |   3 +
 ...field.ad_content.text_ad.field_ad_text.yml |   3 +
 ...ield.storage.ad_content.field_ad_image.yml |   3 +
 ...field.storage.ad_content.field_ad_text.yml |   3 +
 ...ld.storage.ad_content.field_javascript.yml |   3 +
 20 files changed, 580 insertions(+), 232 deletions(-)
 create mode 100644 modules/ad_content/config/install/SettingsForm.php
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
 create mode 100644 modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml

diff --git a/modules/ad_content/config/install/SettingsForm.php b/modules/ad_content/config/install/SettingsForm.php
new file mode 100644
index 0000000..882f2a2
--- /dev/null
+++ b/modules/ad_content/config/install/SettingsForm.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Drupal\ad\Form;
+
+use Drupal\ad\Bucket\BucketFactoryInterface;
+use Drupal\ad\Plugin\Ad\Track\NullTracker;
+use Drupal\ad\Track\TrackerFactoryInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\Form\ConfigFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Ad settings configuration form.
+ */
+class SettingsForm extends ConfigFormBase {
+
+  /**
+   * The ad bucket factory.
+   *
+   * @var \Drupal\ad\Bucket\BucketFactoryInterface
+   */
+  protected BucketFactoryInterface $bucketFactory;
+
+  /**
+   * The ad tracker factory.
+   *
+   * @var \Drupal\ad\Track\TrackerFactoryInterface
+   */
+  protected TrackerFactoryInterface $trackerFactory;
+
+  /**
+   * AdSettingsForm constructor.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The factory for configuration objects.
+   * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
+   *   The ad bucket factory.
+   * @param \Drupal\ad\Track\TrackerFactoryInterface $tracker_factory
+   *   The ad tracker factory.
+   * @param \Drupal\Core\Config\TypedConfigManagerInterface|null $typedConfigManager
+   *   The typed config manager.
+   */
+  public function __construct(
+    ConfigFactoryInterface $config_factory,
+    BucketFactoryInterface $bucket_factory,
+    TrackerFactoryInterface $tracker_factory,
+    ?TypedConfigManagerInterface $typedConfigManager,
+  ) {
+    parent::__construct($config_factory, $typedConfigManager);
+    $this->bucketFactory = $bucket_factory;
+    $this->trackerFactory = $tracker_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('config.factory'),
+      $container->get('ad.bucket_factory'),
+      $container->get('ad.tracker_factory'),
+      $container->get('config.typed') ?? NULL
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'ad_settings_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEditableConfigNames() {
+    return ['ad.settings'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $config = $this->config('ad.settings');
+    $trackerSettings = $config->get('trackers');
+    $trackers = $this->trackerFactory->getList();
+    $buckets = $this->bucketFactory->getList();
+
+    $form['trackers'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Tracker configuration'),
+      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
+      '#tree' => TRUE,
+    ];
+
+    if (!$buckets || !array_diff_key($trackers, [NullTracker::TRACKER_ID => TRUE])) {
+      $args = [
+        '@url' => Url::fromRoute('system.modules_list')
+          ->toString(TRUE)
+          ->getGeneratedUrl(),
+      ];
+      $form['trackers']['#description'] = $this->t('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
+    }
+
+    foreach ($buckets as $id => $label) {
+      $form['trackers'][$id] = [
+        '#type' => 'select',
+        '#title' => $label,
+        '#required' => TRUE,
+        '#options' => $trackers,
+        '#default_value' => $trackerSettings[$id] ?? key($trackers),
+      ];
+    }
+
+    $form['ad_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Ad label'),
+      '#description' => $this->t('In many countries it is mandatory to label ads ad being such. This setting adds a small print (e.g. "ADVERTISEMENT") to all ad blocks.'),
+      '#default_value' => $config->get('ad_label') ?? '',
+    ];
+
+    return parent::buildForm($form, $form_state);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $this->config('ad.settings')
+      ->set('trackers', $form_state->getValue('trackers'))
+      ->set('ad_label', $form_state->getValue('ad_label'))
+      ->save();
+
+    parent::submitForm($form, $form_state);
+  }
+
+}
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
index b1176e8..9eedc1c 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
@@ -1,6 +1,9 @@
+uuid: 2c8b2aba-398f-4b50-8d0a-fdea2e58ef3b
 langcode: en
 status: true
 dependencies: {  }
+_core:
+  default_config_hash: 70w6Ey7LXY-E3lhw9mF66135CtguOmLgGOPMOsBTYgw
 id: image_ad
 label: 'Image Ad'
 description: 'An ad that contains an image.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
index 382df32..128eca9 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
@@ -1,6 +1,9 @@
+uuid: eb61fc19-3a2a-45a7-b671-91710554ad67
 langcode: en
 status: true
 dependencies: {  }
+_core:
+  default_config_hash: 3-b7VmbRg6wr3mdfEfQFXRA0g3jjJKfhfd-i4Vkt-Xo
 id: javascript_ad
 label: 'JavaScript Ad'
 description: 'An ad that contains JavaScript.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
index 80ae1e6..adb65e0 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
@@ -1,6 +1,9 @@
+uuid: d8dd7e3e-82a7-497f-bd91-e63482d68bf2
 langcode: en
 status: true
 dependencies: {  }
+_core:
+  default_config_hash: tywPIk8H6-iFrXx1yJscqDfaGgP80RVqhRiFsUkGkug
 id: text_ad
 label: 'Text Ad'
 description: 'An ad that contains text.'
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
index 17b81bc..14386a2 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
@@ -1,3 +1,4 @@
+uuid: e584489b-4cbe-4327-9750-bbe622f4df03
 langcode: en
 status: true
 dependencies:
@@ -8,6 +9,8 @@ dependencies:
   module:
     - image
     - link
+_core:
+  default_config_hash: 3Vgj7vgvPaHcUo1rb2XsF-stFcWNBIBB8weDoTaa9Yo
 id: ad_content.image_ad.default
 targetEntityType: ad_content
 bundle: image_ad
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
index 290c56e..389c89f 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
@@ -1,3 +1,4 @@
+uuid: fcf564f8-618e-4854-b12e-c0bfa0dffe73
 langcode: en
 status: true
 dependencies:
@@ -7,6 +8,8 @@ dependencies:
   module:
     - link
     - text
+_core:
+  default_config_hash: IR_j39aOu9b6Gjyo9l07mjcR71S1qIJ-8upeMWZZhCk
 id: ad_content.javascript_ad.default
 targetEntityType: ad_content
 bundle: javascript_ad
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
index 07dc9b2..50a1a8f 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
@@ -1,3 +1,4 @@
+uuid: a3d0de6a-96cc-4b6c-9737-b68ee7659bc7
 langcode: en
 status: true
 dependencies:
@@ -7,6 +8,8 @@ dependencies:
   module:
     - link
     - text
+_core:
+  default_config_hash: RlfmVxm3ZRSmCvAnCR6CZARtR2Pui1CjfMe9P0RMwD4
 id: ad_content.text_ad.default
 targetEntityType: ad_content
 bundle: text_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
new file mode 100644
index 0000000..379ceee
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
@@ -0,0 +1,122 @@
+uuid: e068172a-0315-46e3-bc83-0ac39f9de3bc
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.image_ad
+    - core.entity_view_mode.ad_content.admin
+    - field.field.ad_content.image_ad.field_ad_image
+  module:
+    - image
+    - link
+    - options
+_core:
+  default_config_hash: rZ1V9xOYYZfo5Sg4vJ1ODvpwDdk6VgUU-5-Mwx2CC0c
+id: ad_content.image_ad.admin
+targetEntityType: ad_content
+bundle: image_ad
+mode: admin
+content:
+  created:
+    type: timestamp
+    label: above
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 4
+    region: content
+  field_ad_image:
+    type: image
+    label: above
+    settings:
+      image_link: ''
+      image_style: ''
+      image_loading:
+        attribute: lazy
+    third_party_settings: {  }
+    weight: 9
+    region: content
+  langcode:
+    type: language
+    label: above
+    settings:
+      link_to_entity: false
+      native_language: false
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  status:
+    type: boolean
+    label: above
+    settings:
+      format: default
+      format_custom_false: ''
+      format_custom_true: ''
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 8
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 7
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 6
+    region: content
+  uid:
+    type: entity_reference_label
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    weight: 3
+    region: content
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
index 134d27c..4dec0e0 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
@@ -1,3 +1,4 @@
+uuid: 5e71d5c6-7a99-4240-a90f-970903c52fb0
 langcode: en
 status: true
 dependencies:
@@ -5,97 +6,28 @@ dependencies:
     - ad_content.ad_content_type.image_ad
     - field.field.ad_content.image_ad.field_ad_image
   module:
-    - image
-    - link
-    - options
-    - user
+    - ad_content
+_core:
+  default_config_hash: rZ1V9xOYYZfo5Sg4vJ1ODvpwDdk6VgUU-5-Mwx2CC0c
 id: ad_content.image_ad.default
 targetEntityType: ad_content
 bundle: image_ad
 mode: default
 content:
-  created:
-    type: timestamp
-    label: hidden
-    settings:
-      date_format: medium
-      custom_date_format: ''
-      timezone: ''
-      tooltip:
-        date_format: long
-        custom_date_format: ''
-      time_diff:
-        enabled: false
-        future_format: '@interval hence'
-        past_format: '@interval ago'
-        granularity: 2
-        refresh: 60
-    third_party_settings: {  }
-    weight: 0
-    region: content
   field_ad_image:
-    type: image
-    label: hidden
-    settings:
-      image_link: ''
-      image_style: ''
-      image_loading:
-        attribute: lazy
-    third_party_settings: {  }
-    weight: 11
-    region: content
-  size:
-    type: list_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: -4
-    region: content
-  target_url:
-    type: link
-    label: above
-    settings:
-      trim_length: 80
-      url_only: false
-      url_plain: false
-      rel: ''
-      target: ''
-    third_party_settings: {  }
-    weight: -3
-    region: content
-  title:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: -5
-    region: content
-  total_click:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 10
-    region: content
-  total_impression:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 10
-    region: content
-  uid:
-    type: author
+    type: ad_content_image
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 0
     region: content
 hidden:
+  created: true
   langcode: true
+  size: true
   status: true
+  target_url: true
+  title: true
+  total_click: true
+  total_impression: true
+  uid: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
new file mode 100644
index 0000000..5105bda
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
@@ -0,0 +1,118 @@
+uuid: dc5c7d76-38c7-4043-95b9-39d83302f7f8
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.javascript_ad
+    - core.entity_view_mode.ad_content.admin
+    - field.field.ad_content.javascript_ad.field_javascript
+  module:
+    - link
+    - options
+    - text
+_core:
+  default_config_hash: xgxqAudqdE6Rr4GdMtkCgr9xKTQFUUhyvg3b1S3tCLo
+id: ad_content.javascript_ad.admin
+targetEntityType: ad_content
+bundle: javascript_ad
+mode: admin
+content:
+  created:
+    type: timestamp
+    label: above
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 4
+    region: content
+  field_javascript:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 9
+    region: content
+  langcode:
+    type: language
+    label: above
+    settings:
+      link_to_entity: false
+      native_language: false
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  status:
+    type: boolean
+    label: above
+    settings:
+      format: default
+      format_custom_false: ''
+      format_custom_true: ''
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 8
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 7
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 6
+    region: content
+  uid:
+    type: entity_reference_label
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    weight: 3
+    region: content
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
index 8b618d8..2039cd6 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
@@ -1,90 +1,25 @@
+uuid: 1e45d17b-dbba-48b6-a562-bc59f7a4759b
 langcode: en
 status: true
 dependencies:
   config:
     - ad_content.ad_content_type.javascript_ad
     - field.field.ad_content.javascript_ad.field_javascript
-  module:
-    - link
-    - options
-    - user
+_core:
+  default_config_hash: xgxqAudqdE6Rr4GdMtkCgr9xKTQFUUhyvg3b1S3tCLo
 id: ad_content.javascript_ad.default
 targetEntityType: ad_content
 bundle: javascript_ad
 mode: default
-content:
-  created:
-    type: timestamp
-    label: hidden
-    settings:
-      date_format: medium
-      custom_date_format: ''
-      timezone: ''
-      tooltip:
-        date_format: long
-        custom_date_format: ''
-      time_diff:
-        enabled: false
-        future_format: '@interval hence'
-        past_format: '@interval ago'
-        granularity: 2
-        refresh: 60
-    third_party_settings: {  }
-    weight: 3
-    region: content
-  size:
-    type: list_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 1
-    region: content
-  target_url:
-    type: link
-    label: above
-    settings:
-      trim_length: 80
-      url_only: false
-      url_plain: false
-      rel: ''
-      target: ''
-    third_party_settings: {  }
-    weight: 2
-    region: content
-  title:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: 0
-    region: content
-  total_click:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 6
-    region: content
-  total_impression:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 5
-    region: content
-  uid:
-    type: author
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    weight: 4
-    region: content
+content: {  }
 hidden:
+  created: true
   field_javascript: true
   langcode: true
+  size: true
   status: true
+  target_url: true
+  title: true
+  total_click: true
+  total_impression: true
+  uid: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
new file mode 100644
index 0000000..36e9486
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
@@ -0,0 +1,118 @@
+uuid: c84bb4c0-07f5-4e93-b921-f3d260508751
+langcode: en
+status: true
+dependencies:
+  config:
+    - ad_content.ad_content_type.text_ad
+    - core.entity_view_mode.ad_content.admin
+    - field.field.ad_content.text_ad.field_ad_text
+  module:
+    - link
+    - options
+    - text
+_core:
+  default_config_hash: Lkuw-5Wpg0peD-7sqvvW-2p8fAQagB2Ky_3vcs3Pbu0
+id: ad_content.text_ad.admin
+targetEntityType: ad_content
+bundle: text_ad
+mode: admin
+content:
+  created:
+    type: timestamp
+    label: above
+    settings:
+      date_format: medium
+      custom_date_format: ''
+      timezone: ''
+      tooltip:
+        date_format: long
+        custom_date_format: ''
+      time_diff:
+        enabled: false
+        future_format: '@interval hence'
+        past_format: '@interval ago'
+        granularity: 2
+        refresh: 60
+    third_party_settings: {  }
+    weight: 4
+    region: content
+  field_ad_text:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 9
+    region: content
+  langcode:
+    type: language
+    label: above
+    settings:
+      link_to_entity: false
+      native_language: false
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  size:
+    type: list_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  status:
+    type: boolean
+    label: above
+    settings:
+      format: default
+      format_custom_false: ''
+      format_custom_true: ''
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  target_url:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 8
+    region: content
+  title:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  total_click:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 7
+    region: content
+  total_impression:
+    type: number_integer
+    label: above
+    settings:
+      thousand_separator: ''
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 6
+    region: content
+  uid:
+    type: entity_reference_label
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    weight: 3
+    region: content
+hidden: {  }
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
index d4ace17..ce6fc8f 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
@@ -1,3 +1,4 @@
+uuid: 53d30e50-ea49-49ad-88ef-2042cce2f105
 langcode: en
 status: true
 dependencies:
@@ -5,93 +6,28 @@ dependencies:
     - ad_content.ad_content_type.text_ad
     - field.field.ad_content.text_ad.field_ad_text
   module:
-    - link
-    - options
     - text
-    - user
+_core:
+  default_config_hash: Lkuw-5Wpg0peD-7sqvvW-2p8fAQagB2Ky_3vcs3Pbu0
 id: ad_content.text_ad.default
 targetEntityType: ad_content
 bundle: text_ad
 mode: default
 content:
-  created:
-    type: timestamp
-    label: hidden
-    settings:
-      date_format: medium
-      custom_date_format: ''
-      timezone: ''
-      tooltip:
-        date_format: long
-        custom_date_format: ''
-      time_diff:
-        enabled: false
-        future_format: '@interval hence'
-        past_format: '@interval ago'
-        granularity: 2
-        refresh: 60
-    third_party_settings: {  }
-    weight: 0
-    region: content
   field_ad_text:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 11
-    region: content
-  size:
-    type: list_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: -4
-    region: content
-  target_url:
-    type: link
-    label: above
-    settings:
-      trim_length: 80
-      url_only: false
-      url_plain: false
-      rel: ''
-      target: ''
-    third_party_settings: {  }
-    weight: -3
-    region: content
-  title:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: -5
-    region: content
-  total_click:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 10
-    region: content
-  total_impression:
-    type: number_integer
-    label: above
-    settings:
-      thousand_separator: ''
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 10
-    region: content
-  uid:
-    type: author
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    weight: 5
+    weight: 0
     region: content
 hidden:
+  created: true
   langcode: true
+  size: true
   status: true
+  target_url: true
+  title: true
+  total_click: true
+  total_impression: true
+  uid: true
diff --git a/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
new file mode 100644
index 0000000..4205029
--- /dev/null
+++ b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
@@ -0,0 +1,11 @@
+uuid: 5db452dc-2c2f-4316-858e-ca4b354dfc6f
+langcode: en
+status: true
+dependencies:
+  module:
+    - ad_content
+id: ad_content.admin
+label: Admin
+description: 'The way that this ad is displayed on admin pages (showing additional info about the ad).'
+targetEntityType: ad_content
+cache: true
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
index e43b867..f3ecd61 100644
--- a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -1,3 +1,4 @@
+uuid: 5bf729a3-a24f-4ac1-a93a-2ebab680c2dc
 langcode: en
 status: true
 dependencies:
@@ -6,6 +7,8 @@ dependencies:
     - field.storage.ad_content.field_ad_image
   module:
     - image
+_core:
+  default_config_hash: OhX6mHef7ZJyP0MxkCuYE_onTJY7bhx5Irxfl997iKU
 id: ad_content.image_ad.field_ad_image
 field_name: field_ad_image
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
index 3977d39..ca74e68 100644
--- a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
@@ -1,3 +1,4 @@
+uuid: aea8003c-27ac-4f39-880e-1be4fc275067
 langcode: en
 status: true
 dependencies:
@@ -6,6 +7,8 @@ dependencies:
     - field.storage.ad_content.field_javascript
   module:
     - text
+_core:
+  default_config_hash: znZ5h92wvcQKRdiCuAVex0g4GOkilLdYzaiMif9Uuak
 id: ad_content.javascript_ad.field_javascript
 field_name: field_javascript
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
index 476d4ef..b2a093a 100644
--- a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
@@ -1,3 +1,4 @@
+uuid: cabacf0a-85a6-4ba0-b7f5-aa47c04c07e4
 langcode: en
 status: true
 dependencies:
@@ -6,6 +7,8 @@ dependencies:
     - field.storage.ad_content.field_ad_text
   module:
     - text
+_core:
+  default_config_hash: Q1XCe6j_Z3tRVISSAHmlQ7E2qLIg9g9S_kErmHnP8L8
 id: ad_content.text_ad.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
index 8ae34c9..578b57a 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
@@ -1,3 +1,4 @@
+uuid: 1e578b95-c5fd-4137-ab06-eb3e14cff3d7
 langcode: en
 status: true
 dependencies:
@@ -5,6 +6,8 @@ dependencies:
     - ad_content
     - file
     - image
+_core:
+  default_config_hash: s8tKIBj8EjjaPBF8u3GR4Xiv5VyTFiTijp2w-5M2fqs
 id: ad_content.field_ad_image
 field_name: field_ad_image
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
index c2fed7c..d2c8acf 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
@@ -1,9 +1,12 @@
+uuid: b2db0052-ae43-45b3-86b5-d6c7b883fe75
 langcode: en
 status: true
 dependencies:
   module:
     - ad_content
     - text
+_core:
+  default_config_hash: PZYPOAQh2ZjoRN0bajlJ8M2uC2RlSSBEBZMfaxVvuLI
 id: ad_content.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
index f88394a..e53afe9 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
@@ -1,9 +1,12 @@
+uuid: 6744dcc3-6fe8-46c6-b825-b076114b7520
 langcode: en
 status: true
 dependencies:
   module:
     - ad_content
     - text
+_core:
+  default_config_hash: DHDjLh0Aa464lSCXZNuuLETmZ7cFZKW3wWy-bUVCw7Y
 id: ad_content.field_javascript
 field_name: field_javascript
 entity_type: ad_content
-- 
GitLab


From 33425e7f39eda5369a202092f558b07e6b7de9fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 12:44:22 +0200
Subject: [PATCH 20/46] Removing accidental file copy

---
 .../config/install/SettingsForm.php           | 140 ------------------
 1 file changed, 140 deletions(-)
 delete mode 100644 modules/ad_content/config/install/SettingsForm.php

diff --git a/modules/ad_content/config/install/SettingsForm.php b/modules/ad_content/config/install/SettingsForm.php
deleted file mode 100644
index 882f2a2..0000000
--- a/modules/ad_content/config/install/SettingsForm.php
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-
-namespace Drupal\ad\Form;
-
-use Drupal\ad\Bucket\BucketFactoryInterface;
-use Drupal\ad\Plugin\Ad\Track\NullTracker;
-use Drupal\ad\Track\TrackerFactoryInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\Form\ConfigFormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Ad settings configuration form.
- */
-class SettingsForm extends ConfigFormBase {
-
-  /**
-   * The ad bucket factory.
-   *
-   * @var \Drupal\ad\Bucket\BucketFactoryInterface
-   */
-  protected BucketFactoryInterface $bucketFactory;
-
-  /**
-   * The ad tracker factory.
-   *
-   * @var \Drupal\ad\Track\TrackerFactoryInterface
-   */
-  protected TrackerFactoryInterface $trackerFactory;
-
-  /**
-   * AdSettingsForm constructor.
-   *
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The factory for configuration objects.
-   * @param \Drupal\ad\Bucket\BucketFactoryInterface $bucket_factory
-   *   The ad bucket factory.
-   * @param \Drupal\ad\Track\TrackerFactoryInterface $tracker_factory
-   *   The ad tracker factory.
-   * @param \Drupal\Core\Config\TypedConfigManagerInterface|null $typedConfigManager
-   *   The typed config manager.
-   */
-  public function __construct(
-    ConfigFactoryInterface $config_factory,
-    BucketFactoryInterface $bucket_factory,
-    TrackerFactoryInterface $tracker_factory,
-    ?TypedConfigManagerInterface $typedConfigManager,
-  ) {
-    parent::__construct($config_factory, $typedConfigManager);
-    $this->bucketFactory = $bucket_factory;
-    $this->trackerFactory = $tracker_factory;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('config.factory'),
-      $container->get('ad.bucket_factory'),
-      $container->get('ad.tracker_factory'),
-      $container->get('config.typed') ?? NULL
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'ad_settings_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getEditableConfigNames() {
-    return ['ad.settings'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $config = $this->config('ad.settings');
-    $trackerSettings = $config->get('trackers');
-    $trackers = $this->trackerFactory->getList();
-    $buckets = $this->bucketFactory->getList();
-
-    $form['trackers'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Tracker configuration'),
-      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
-      '#tree' => TRUE,
-    ];
-
-    if (!$buckets || !array_diff_key($trackers, [NullTracker::TRACKER_ID => TRUE])) {
-      $args = [
-        '@url' => Url::fromRoute('system.modules_list')
-          ->toString(TRUE)
-          ->getGeneratedUrl(),
-      ];
-      $form['trackers']['#description'] = $this->t('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
-    }
-
-    foreach ($buckets as $id => $label) {
-      $form['trackers'][$id] = [
-        '#type' => 'select',
-        '#title' => $label,
-        '#required' => TRUE,
-        '#options' => $trackers,
-        '#default_value' => $trackerSettings[$id] ?? key($trackers),
-      ];
-    }
-
-    $form['ad_label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Ad label'),
-      '#description' => $this->t('In many countries it is mandatory to label ads ad being such. This setting adds a small print (e.g. "ADVERTISEMENT") to all ad blocks.'),
-      '#default_value' => $config->get('ad_label') ?? '',
-    ];
-
-    return parent::buildForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->config('ad.settings')
-      ->set('trackers', $form_state->getValue('trackers'))
-      ->set('ad_label', $form_state->getValue('ad_label'))
-      ->save();
-
-    parent::submitForm($form, $form_state);
-  }
-
-}
-- 
GitLab


From 685da90022b21b668dd16e04f374411d329298e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 14:37:38 +0200
Subject: [PATCH 21/46] Adding admin view mode to admin page rendering of ads

---
 modules/ad_content/ad_content.routing.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/modules/ad_content/ad_content.routing.yml b/modules/ad_content/ad_content.routing.yml
index 3dbf450..7b7a5d3 100644
--- a/modules/ad_content/ad_content.routing.yml
+++ b/modules/ad_content/ad_content.routing.yml
@@ -5,3 +5,10 @@ ad_content.render_ad:
     _title: 'Render ad'
   requirements:
     _permission: 'access content'
+
+entity.ad_content.canonical:
+  path: '/admin/content/ad/{ad_content}'
+  defaults:
+    _entity_view: 'ad_content.admin'
+  requirements:
+    _permission: 'administer ads'
-- 
GitLab


From 84b0772ebc183f9bf0f43df4aecded98db5b9f29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 14:45:15 +0200
Subject: [PATCH 22/46] Fixing random ad provider not actually providing a
 random ad

---
 modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
index 71cf15b..6d62433 100644
--- a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
+++ b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
@@ -235,13 +235,13 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
         ->accessCheck(TRUE);
 
       $result = $query
-        ->range(0, 1)
         ->sort('id')
         ->execute();
 
       if ($result) {
+        $randomAdId = mt_rand(1, count($result));
         /** @var \Drupal\ad_content\Entity\AdContentInterface $ad_content */
-        $ad_content = $storage->load(reset($result));
+        $ad_content = $storage->load($result[$randomAdId]);
       }
     }
     catch (PluginException $e) {
-- 
GitLab


From debc3b0e0889c4a3bb190bf3d13e52f575e5c347 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 14:48:39 +0200
Subject: [PATCH 23/46] Integrating ad content into content menu via tabs

---
 modules/ad_content/ad_content.links.task.yml | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 modules/ad_content/ad_content.links.task.yml

diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
new file mode 100644
index 0000000..6d37afe
--- /dev/null
+++ b/modules/ad_content/ad_content.links.task.yml
@@ -0,0 +1,4 @@
+ad_content.admin:
+  title: 'Ad content'
+  route_name: entity.ad_content.collection
+  base_route: system.admin_content
-- 
GitLab


From c5ac127a9c7eaf31a561989df1a8e00a8d24eb87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 7 May 2025 14:59:17 +0200
Subject: [PATCH 24/46] Random algorithm update

---
 .../ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php    | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
index 6d62433..315fc37 100644
--- a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
+++ b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
@@ -235,13 +235,14 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
         ->accessCheck(TRUE);
 
       $result = $query
-        ->sort('id')
+      // @todo Continue here
+        ->orderRandom()
+        ->range(0, 1)
         ->execute();
 
       if ($result) {
-        $randomAdId = mt_rand(1, count($result));
         /** @var \Drupal\ad_content\Entity\AdContentInterface $ad_content */
-        $ad_content = $storage->load($result[$randomAdId]);
+        $ad_content = $storage->load(reset($result));
       }
     }
     catch (PluginException $e) {
-- 
GitLab


From ac3dca065d0853eb41d95aabaff9d627f9deaa8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 13 May 2025 16:04:54 +0200
Subject: [PATCH 25/46] Fixing random ad query

---
 modules/ad_content/ad_content.module                   | 10 ++++++++++
 .../src/Plugin/Ad/Bucket/AdContentBucket.php           |  3 +--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index ffb2af6..23ace8c 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -4,3 +4,13 @@
  * @file
  * Main file for the "Ad Content" module.
  */
+
+use Drupal\Core\Database\Query\AlterableInterface;
+
+/**
+ * Implements hook_query_alter().
+ */
+function ad_content_query_order_random_alter(AlterableInterface $query) {
+  /** @var \Drupal\Core\Database\Query\Select $query */
+  $query->orderRandom();
+}
diff --git a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
index 315fc37..dca537c 100644
--- a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
+++ b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
@@ -235,8 +235,7 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
         ->accessCheck(TRUE);
 
       $result = $query
-      // @todo Continue here
-        ->orderRandom()
+        ->addTag('order_random')
         ->range(0, 1)
         ->execute();
 
-- 
GitLab


From 1f61730afb1c007a5ea84488adc14821d785393e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 13 May 2025 16:52:10 +0200
Subject: [PATCH 26/46] Adding generic module tests and missing ad content type
 schema

---
 modules/ad_content/ad_content.info.yml        |  2 ++
 .../config/schema/ad_content.schema.yml       | 15 +++++++++++++++
 .../src/Functional/AdContentGenericTest.php   | 19 +++++++++++++++++++
 .../src/Functional/AdSchedulerGenericTest.php | 19 +++++++++++++++++++
 .../src/Functional/AdTrackGenericTest.php     | 19 +++++++++++++++++++
 tests/src/Functional/AdGenericTest.php        | 19 +++++++++++++++++++
 6 files changed, 93 insertions(+)
 create mode 100644 modules/ad_content/config/schema/ad_content.schema.yml
 create mode 100644 modules/ad_content/tests/src/Functional/AdContentGenericTest.php
 create mode 100644 modules/ad_scheduler/tests/src/Functional/AdSchedulerGenericTest.php
 create mode 100644 modules/ad_track/tests/src/Functional/AdTrackGenericTest.php
 create mode 100644 tests/src/Functional/AdGenericTest.php

diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 94b8299..6b81dd6 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -6,6 +6,8 @@ core_version_requirement: ^10.3 || ^11
 dependencies:
   - ad:ad
   - ad:ad_track
+  - drupal:image
+  - drupal:link
   - drupal:options
   - drupal:text
 configure: 'ad.settings'
diff --git a/modules/ad_content/config/schema/ad_content.schema.yml b/modules/ad_content/config/schema/ad_content.schema.yml
new file mode 100644
index 0000000..2523fae
--- /dev/null
+++ b/modules/ad_content/config/schema/ad_content.schema.yml
@@ -0,0 +1,15 @@
+# Schema for the configuration files of the ad_content module.
+
+ad_content.ad_content_type.*:
+  type: config_entity
+  label: 'Ad content type'
+  mapping:
+    id:
+      type: string
+      label: 'ID'
+    label:
+      type: label
+      label: 'Name'
+    description:
+      type: text
+      label: 'Description'
diff --git a/modules/ad_content/tests/src/Functional/AdContentGenericTest.php b/modules/ad_content/tests/src/Functional/AdContentGenericTest.php
new file mode 100644
index 0000000..a4f8213
--- /dev/null
+++ b/modules/ad_content/tests/src/Functional/AdContentGenericTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\ad_content\Functional;
+
+use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
+
+/**
+ * Generic module test for ad_content.
+ *
+ * @group ad_content
+ */
+class AdContentGenericTest extends GenericModuleTestBase {
+
+  /**
+   * {@inheritDoc}
+   */
+  protected function assertHookHelp(string $module): void {}
+
+}
diff --git a/modules/ad_scheduler/tests/src/Functional/AdSchedulerGenericTest.php b/modules/ad_scheduler/tests/src/Functional/AdSchedulerGenericTest.php
new file mode 100644
index 0000000..7ddf410
--- /dev/null
+++ b/modules/ad_scheduler/tests/src/Functional/AdSchedulerGenericTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\ad_scheduler\Functional;
+
+use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
+
+/**
+ * Generic module test for ad_scheduler.
+ *
+ * @group ad_scheduler
+ */
+class AdSchedulerGenericTest extends GenericModuleTestBase {
+
+  /**
+   * {@inheritDoc}
+   */
+  protected function assertHookHelp(string $module): void {}
+
+}
diff --git a/modules/ad_track/tests/src/Functional/AdTrackGenericTest.php b/modules/ad_track/tests/src/Functional/AdTrackGenericTest.php
new file mode 100644
index 0000000..2b4a0a9
--- /dev/null
+++ b/modules/ad_track/tests/src/Functional/AdTrackGenericTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\ad_track\Functional;
+
+use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
+
+/**
+ * Generic module test for ad_track.
+ *
+ * @group ad_track
+ */
+class AdTrackGenericTest extends GenericModuleTestBase {
+
+  /**
+   * {@inheritDoc}
+   */
+  protected function assertHookHelp(string $module): void {}
+
+}
diff --git a/tests/src/Functional/AdGenericTest.php b/tests/src/Functional/AdGenericTest.php
new file mode 100644
index 0000000..12a57d1
--- /dev/null
+++ b/tests/src/Functional/AdGenericTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\ad\Functional;
+
+use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
+
+/**
+ * Generic module test for ad.
+ *
+ * @group ad
+ */
+class AdGenericTest extends GenericModuleTestBase {
+
+  /**
+   * {@inheritDoc}
+   */
+  protected function assertHookHelp(string $module): void {}
+
+}
-- 
GitLab


From fc1cbd86f86680b990aa551a88202057d054108e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 13 May 2025 17:03:55 +0200
Subject: [PATCH 27/46] Removing uuid and default_config_hash from all install
 config files

---
 .../config/install/ad_content.ad_content_type.image_ad.yml    | 3 ---
 .../install/ad_content.ad_content_type.javascript_ad.yml      | 3 ---
 .../config/install/ad_content.ad_content_type.text_ad.yml     | 3 ---
 .../core.entity_form_display.ad_content.image_ad.default.yml  | 3 ---
 ...e.entity_form_display.ad_content.javascript_ad.default.yml | 3 ---
 .../core.entity_form_display.ad_content.text_ad.default.yml   | 3 ---
 .../core.entity_view_display.ad_content.image_ad.admin.yml    | 3 ---
 .../core.entity_view_display.ad_content.image_ad.default.yml  | 3 ---
 ...ore.entity_view_display.ad_content.javascript_ad.admin.yml | 3 ---
 ...e.entity_view_display.ad_content.javascript_ad.default.yml | 3 ---
 .../core.entity_view_display.ad_content.text_ad.admin.yml     | 3 ---
 .../core.entity_view_display.ad_content.text_ad.default.yml   | 3 ---
 .../config/install/core.entity_view_mode.ad_content.admin.yml | 1 -
 .../field.field.ad_content.image_ad.field_ad_image.yml        | 4 ----
 .../field.field.ad_content.javascript_ad.field_javascript.yml | 3 ---
 .../install/field.field.ad_content.text_ad.field_ad_text.yml  | 3 ---
 .../install/field.storage.ad_content.field_ad_image.yml       | 4 ----
 .../config/install/field.storage.ad_content.field_ad_text.yml | 3 ---
 .../install/field.storage.ad_content.field_javascript.yml     | 3 ---
 19 files changed, 57 deletions(-)

diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
index 9eedc1c..b1176e8 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
@@ -1,9 +1,6 @@
-uuid: 2c8b2aba-398f-4b50-8d0a-fdea2e58ef3b
 langcode: en
 status: true
 dependencies: {  }
-_core:
-  default_config_hash: 70w6Ey7LXY-E3lhw9mF66135CtguOmLgGOPMOsBTYgw
 id: image_ad
 label: 'Image Ad'
 description: 'An ad that contains an image.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
index 128eca9..382df32 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
@@ -1,9 +1,6 @@
-uuid: eb61fc19-3a2a-45a7-b671-91710554ad67
 langcode: en
 status: true
 dependencies: {  }
-_core:
-  default_config_hash: 3-b7VmbRg6wr3mdfEfQFXRA0g3jjJKfhfd-i4Vkt-Xo
 id: javascript_ad
 label: 'JavaScript Ad'
 description: 'An ad that contains JavaScript.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
index adb65e0..80ae1e6 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
@@ -1,9 +1,6 @@
-uuid: d8dd7e3e-82a7-497f-bd91-e63482d68bf2
 langcode: en
 status: true
 dependencies: {  }
-_core:
-  default_config_hash: tywPIk8H6-iFrXx1yJscqDfaGgP80RVqhRiFsUkGkug
 id: text_ad
 label: 'Text Ad'
 description: 'An ad that contains text.'
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
index 14386a2..17b81bc 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
@@ -1,4 +1,3 @@
-uuid: e584489b-4cbe-4327-9750-bbe622f4df03
 langcode: en
 status: true
 dependencies:
@@ -9,8 +8,6 @@ dependencies:
   module:
     - image
     - link
-_core:
-  default_config_hash: 3Vgj7vgvPaHcUo1rb2XsF-stFcWNBIBB8weDoTaa9Yo
 id: ad_content.image_ad.default
 targetEntityType: ad_content
 bundle: image_ad
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
index 389c89f..290c56e 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
@@ -1,4 +1,3 @@
-uuid: fcf564f8-618e-4854-b12e-c0bfa0dffe73
 langcode: en
 status: true
 dependencies:
@@ -8,8 +7,6 @@ dependencies:
   module:
     - link
     - text
-_core:
-  default_config_hash: IR_j39aOu9b6Gjyo9l07mjcR71S1qIJ-8upeMWZZhCk
 id: ad_content.javascript_ad.default
 targetEntityType: ad_content
 bundle: javascript_ad
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
index 50a1a8f..07dc9b2 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
@@ -1,4 +1,3 @@
-uuid: a3d0de6a-96cc-4b6c-9737-b68ee7659bc7
 langcode: en
 status: true
 dependencies:
@@ -8,8 +7,6 @@ dependencies:
   module:
     - link
     - text
-_core:
-  default_config_hash: RlfmVxm3ZRSmCvAnCR6CZARtR2Pui1CjfMe9P0RMwD4
 id: ad_content.text_ad.default
 targetEntityType: ad_content
 bundle: text_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
index 379ceee..e49d393 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
@@ -1,4 +1,3 @@
-uuid: e068172a-0315-46e3-bc83-0ac39f9de3bc
 langcode: en
 status: true
 dependencies:
@@ -10,8 +9,6 @@ dependencies:
     - image
     - link
     - options
-_core:
-  default_config_hash: rZ1V9xOYYZfo5Sg4vJ1ODvpwDdk6VgUU-5-Mwx2CC0c
 id: ad_content.image_ad.admin
 targetEntityType: ad_content
 bundle: image_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
index 4dec0e0..430ad02 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
@@ -1,4 +1,3 @@
-uuid: 5e71d5c6-7a99-4240-a90f-970903c52fb0
 langcode: en
 status: true
 dependencies:
@@ -7,8 +6,6 @@ dependencies:
     - field.field.ad_content.image_ad.field_ad_image
   module:
     - ad_content
-_core:
-  default_config_hash: rZ1V9xOYYZfo5Sg4vJ1ODvpwDdk6VgUU-5-Mwx2CC0c
 id: ad_content.image_ad.default
 targetEntityType: ad_content
 bundle: image_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
index 5105bda..7138b65 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
@@ -1,4 +1,3 @@
-uuid: dc5c7d76-38c7-4043-95b9-39d83302f7f8
 langcode: en
 status: true
 dependencies:
@@ -10,8 +9,6 @@ dependencies:
     - link
     - options
     - text
-_core:
-  default_config_hash: xgxqAudqdE6Rr4GdMtkCgr9xKTQFUUhyvg3b1S3tCLo
 id: ad_content.javascript_ad.admin
 targetEntityType: ad_content
 bundle: javascript_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
index 2039cd6..57c9bde 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
@@ -1,12 +1,9 @@
-uuid: 1e45d17b-dbba-48b6-a562-bc59f7a4759b
 langcode: en
 status: true
 dependencies:
   config:
     - ad_content.ad_content_type.javascript_ad
     - field.field.ad_content.javascript_ad.field_javascript
-_core:
-  default_config_hash: xgxqAudqdE6Rr4GdMtkCgr9xKTQFUUhyvg3b1S3tCLo
 id: ad_content.javascript_ad.default
 targetEntityType: ad_content
 bundle: javascript_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
index 36e9486..322123b 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
@@ -1,4 +1,3 @@
-uuid: c84bb4c0-07f5-4e93-b921-f3d260508751
 langcode: en
 status: true
 dependencies:
@@ -10,8 +9,6 @@ dependencies:
     - link
     - options
     - text
-_core:
-  default_config_hash: Lkuw-5Wpg0peD-7sqvvW-2p8fAQagB2Ky_3vcs3Pbu0
 id: ad_content.text_ad.admin
 targetEntityType: ad_content
 bundle: text_ad
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
index ce6fc8f..69cf536 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
@@ -1,4 +1,3 @@
-uuid: 53d30e50-ea49-49ad-88ef-2042cce2f105
 langcode: en
 status: true
 dependencies:
@@ -7,8 +6,6 @@ dependencies:
     - field.field.ad_content.text_ad.field_ad_text
   module:
     - text
-_core:
-  default_config_hash: Lkuw-5Wpg0peD-7sqvvW-2p8fAQagB2Ky_3vcs3Pbu0
 id: ad_content.text_ad.default
 targetEntityType: ad_content
 bundle: text_ad
diff --git a/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
index 4205029..7844b15 100644
--- a/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
@@ -1,4 +1,3 @@
-uuid: 5db452dc-2c2f-4316-858e-ca4b354dfc6f
 langcode: en
 status: true
 dependencies:
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
index f3ecd61..db24619 100644
--- a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -1,4 +1,3 @@
-uuid: 5bf729a3-a24f-4ac1-a93a-2ebab680c2dc
 langcode: en
 status: true
 dependencies:
@@ -7,8 +6,6 @@ dependencies:
     - field.storage.ad_content.field_ad_image
   module:
     - image
-_core:
-  default_config_hash: OhX6mHef7ZJyP0MxkCuYE_onTJY7bhx5Irxfl997iKU
 id: ad_content.image_ad.field_ad_image
 field_name: field_ad_image
 entity_type: ad_content
@@ -32,7 +29,6 @@ settings:
   title_field: true
   title_field_required: false
   default_image:
-    uuid: ''
     alt: ''
     title: ''
     width: null
diff --git a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
index ca74e68..3977d39 100644
--- a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
@@ -1,4 +1,3 @@
-uuid: aea8003c-27ac-4f39-880e-1be4fc275067
 langcode: en
 status: true
 dependencies:
@@ -7,8 +6,6 @@ dependencies:
     - field.storage.ad_content.field_javascript
   module:
     - text
-_core:
-  default_config_hash: znZ5h92wvcQKRdiCuAVex0g4GOkilLdYzaiMif9Uuak
 id: ad_content.javascript_ad.field_javascript
 field_name: field_javascript
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
index b2a093a..476d4ef 100644
--- a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
@@ -1,4 +1,3 @@
-uuid: cabacf0a-85a6-4ba0-b7f5-aa47c04c07e4
 langcode: en
 status: true
 dependencies:
@@ -7,8 +6,6 @@ dependencies:
     - field.storage.ad_content.field_ad_text
   module:
     - text
-_core:
-  default_config_hash: Q1XCe6j_Z3tRVISSAHmlQ7E2qLIg9g9S_kErmHnP8L8
 id: ad_content.text_ad.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
index 578b57a..4b2e056 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
@@ -1,4 +1,3 @@
-uuid: 1e578b95-c5fd-4137-ab06-eb3e14cff3d7
 langcode: en
 status: true
 dependencies:
@@ -6,8 +5,6 @@ dependencies:
     - ad_content
     - file
     - image
-_core:
-  default_config_hash: s8tKIBj8EjjaPBF8u3GR4Xiv5VyTFiTijp2w-5M2fqs
 id: ad_content.field_ad_image
 field_name: field_ad_image
 entity_type: ad_content
@@ -18,7 +15,6 @@ settings:
   display_default: true
   uri_scheme: public
   default_image:
-    uuid: ''
     alt: ''
     title: ''
     width: null
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
index d2c8acf..c2fed7c 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
@@ -1,12 +1,9 @@
-uuid: b2db0052-ae43-45b3-86b5-d6c7b883fe75
 langcode: en
 status: true
 dependencies:
   module:
     - ad_content
     - text
-_core:
-  default_config_hash: PZYPOAQh2ZjoRN0bajlJ8M2uC2RlSSBEBZMfaxVvuLI
 id: ad_content.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
index e53afe9..f88394a 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
@@ -1,12 +1,9 @@
-uuid: 6744dcc3-6fe8-46c6-b825-b076114b7520
 langcode: en
 status: true
 dependencies:
   module:
     - ad_content
     - text
-_core:
-  default_config_hash: DHDjLh0Aa464lSCXZNuuLETmZ7cFZKW3wWy-bUVCw7Y
 id: ad_content.field_javascript
 field_name: field_javascript
 entity_type: ad_content
-- 
GitLab


From 10733de004ea12f2ba6ec89e85cdc44719bbe71d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 10:14:41 +0200
Subject: [PATCH 28/46] Adding hooks for ad label field and re-adding uuid in
 install config

---
 modules/ad_content/ad_content.module          | 33 +++++++++++++++++++
 ...eld.ad_content.image_ad.field_ad_image.yml |  1 +
 ...ield.storage.ad_content.field_ad_image.yml |  1 +
 3 files changed, 35 insertions(+)

diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index 23ace8c..0a21169 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -5,7 +5,10 @@
  * Main file for the "Ad Content" module.
  */
 
+use Drupal\ad_content\Entity\AdContentType;
 use Drupal\Core\Database\Query\AlterableInterface;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Implements hook_query_alter().
@@ -14,3 +17,33 @@ function ad_content_query_order_random_alter(AlterableInterface $query) {
   /** @var \Drupal\Core\Database\Query\Select $query */
   $query->orderRandom();
 }
+
+/**
+ * Implements hook_entity_extra_field_info().
+ */
+function ad_content_entity_extra_field_info() {
+  $extra = [];
+  foreach (AdContentType::loadMultiple() as $bundle) {
+    $extra['ad_content_type'][$bundle->id()]['display']['field_ad_label'] = [
+      'label' => t('Ad label'),
+      'description' => t('Displays the ad label configurable in the ad settings.'),
+      'weight' => 0,
+      'visible' => TRUE,
+      'translatable' => TRUE,
+    ];
+  }
+  return $extra;
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_view().
+ */
+function ad_content_ad_content_type_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
+  if ($display->getComponent('field_ad_label')) {
+    $adLabel = \Drupal::config('ad.settings')->get('ad_label');
+    $build['field_ad_label'] = [
+      '#type' => 'markup',
+      '#markup' => $adLabel,
+    ];
+  }
+}
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
index db24619..e43b867 100644
--- a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -29,6 +29,7 @@ settings:
   title_field: true
   title_field_required: false
   default_image:
+    uuid: ''
     alt: ''
     title: ''
     width: null
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
index 4b2e056..8ae34c9 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
@@ -15,6 +15,7 @@ settings:
   display_default: true
   uri_scheme: public
   default_image:
+    uuid: ''
     alt: ''
     title: ''
     width: null
-- 
GitLab


From bea0092f98cd5eeb9962df13bef8ddc036f165fd Mon Sep 17 00:00:00 2001
From: DDEV User <nobody@example.com>
Date: Wed, 14 May 2025 10:45:12 +0200
Subject: [PATCH 29/46] Renamed Ad content to Advertisements for clarification

---
 README.md                                     |  2 +-
 modules/ad_content/ad_content.info.yml        |  2 +-
 .../ad_content/ad_content.links.action.yml    |  4 ++--
 modules/ad_content/ad_content.links.menu.yml  |  8 ++++----
 modules/ad_content/ad_content.links.task.yml  |  2 +-
 modules/ad_content/ad_content.module          | 16 +++++++--------
 .../optional/views.view.ad_statistics.yml     |  2 +-
 .../config/schema/ad_content.schema.yml       |  2 +-
 modules/ad_content/src/Entity/AdContent.php   | 16 +++++++--------
 .../src/Entity/AdContentInterface.php         |  2 +-
 .../src/Entity/AdContentListBuilder.php       |  2 +-
 .../ad_content/src/Entity/AdContentType.php   | 20 +++++++++----------
 .../src/Entity/AdContentTypeInterface.php     | 10 +++++-----
 .../src/Entity/AdContentTypeListBuilder.php   |  2 +-
 .../src/Entity/AdContentViewController.php    |  4 ++--
 .../src/Form/AdContentEntityForm.php          |  2 +-
 .../src/Form/AdContentTypeEntityForm.php      | 10 +++++-----
 .../src/Plugin/Ad/Bucket/AdContentBucket.php  |  6 +++---
 modules/ad_scheduler/ad_scheduler.info.yml    |  2 +-
 .../Plugin/Scheduler/AdContentScheduler.php   |  6 +++---
 modules/ad_track/ad_track.views.inc           |  2 +-
 21 files changed, 61 insertions(+), 61 deletions(-)

diff --git a/README.md b/README.md
index 9acbabc..fcf838d 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ The native `Ad Tracker` module implements two trackers:
 # Installation
 
 Enable the main `Ad` module, together with at least one ad source and one
-tracker, typically the `Ad Content` and `Ad Tracker` modules.
+tracker, typically the `Advertisement` and `Ad Tracker` modules.
 
 
 # Usage
diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 6b81dd6..651f625 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -1,4 +1,4 @@
-name: Ad Content
+name: Advertisement
 description: 'Ad source allowing to create ads via the administrative UI.'
 type: module
 package: Advertisement
diff --git a/modules/ad_content/ad_content.links.action.yml b/modules/ad_content/ad_content.links.action.yml
index 93cb394..ce4c0eb 100644
--- a/modules/ad_content/ad_content.links.action.yml
+++ b/modules/ad_content/ad_content.links.action.yml
@@ -1,11 +1,11 @@
 ad_content.add_form:
   route_name: entity.ad_content.add_page
-  title: 'Add ad content'
+  title: 'Add advertisement'
   appears_on:
     - entity.ad_content.collection
 
 ad_content_type.add_form:
   route_name: entity.ad_content_type.add_form
-  title: 'Add ad content type'
+  title: 'Add advertisement type'
   appears_on:
     - entity.ad_content_type.collection
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
index d4a8cc1..f2c12ea 100644
--- a/modules/ad_content/ad_content.links.menu.yml
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -1,11 +1,11 @@
 entity.ad_content.collection:
   route_name: entity.ad_content.collection
-  title: 'Ad content'
-  description: 'Manage ad content.'
+  title: 'Advertisements'
+  description: 'Manage advertisements.'
   parent: system.admin_content
 
 entity.ad_content_type.collection:
-  title: 'Ad content types'
+  title: 'Advertisement types'
   parent: system.admin_structure
-  description: 'Manage ad content types.'
+  description: 'Manage advertisements types.'
   route_name: entity.ad_content_type.collection
diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
index 6d37afe..ffa140b 100644
--- a/modules/ad_content/ad_content.links.task.yml
+++ b/modules/ad_content/ad_content.links.task.yml
@@ -1,4 +1,4 @@
 ad_content.admin:
-  title: 'Ad content'
+  title: 'Advertisement'
   route_name: entity.ad_content.collection
   base_route: system.admin_content
diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index 0a21169..fdace8b 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Main file for the "Ad Content" module.
+ * Main file for the "Advertisement" module.
  */
 
 use Drupal\ad_content\Entity\AdContentType;
@@ -24,10 +24,10 @@ function ad_content_query_order_random_alter(AlterableInterface $query) {
 function ad_content_entity_extra_field_info() {
   $extra = [];
   foreach (AdContentType::loadMultiple() as $bundle) {
-    $extra['ad_content_type'][$bundle->id()]['display']['field_ad_label'] = [
-      'label' => t('Ad label'),
-      'description' => t('Displays the ad label configurable in the ad settings.'),
-      'weight' => 0,
+    $extra['ad_content'][$bundle->id()]['display']['ad_content_advertisement_indicator'] = [
+      'label' => t('"Advertisement" indicator'),
+      'description' => t('Displays the "advertisement" indicator, configurable in the ad settings.'),
+      'weight' => 99,
       'visible' => TRUE,
       'translatable' => TRUE,
     ];
@@ -39,9 +39,9 @@ function ad_content_entity_extra_field_info() {
  * Implements hook_ENTITY_TYPE_view().
  */
 function ad_content_ad_content_type_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
-  if ($display->getComponent('field_ad_label')) {
-    $adLabel = \Drupal::config('ad.settings')->get('ad_label');
-    $build['field_ad_label'] = [
+  if ($display->getComponent('ad_content_advertisement_indicator')) {
+    $adLabel = \Drupal::config('ad.settings')->get('advertisement_indicator');
+    $build['ad_content_advertisement_indicator'] = [
       '#type' => 'markup',
       '#markup' => $adLabel,
     ];
diff --git a/modules/ad_content/config/optional/views.view.ad_statistics.yml b/modules/ad_content/config/optional/views.view.ad_statistics.yml
index de60cd1..b6a7657 100644
--- a/modules/ad_content/config/optional/views.view.ad_statistics.yml
+++ b/modules/ad_content/config/optional/views.view.ad_statistics.yml
@@ -1110,7 +1110,7 @@ display:
           field: ad_id
           relationship: none
           group_type: group
-          admin_label: 'Ad content'
+          admin_label: 'Advertisement'
           required: false
           entity_type: ad_track_event
           plugin_id: standard
diff --git a/modules/ad_content/config/schema/ad_content.schema.yml b/modules/ad_content/config/schema/ad_content.schema.yml
index 2523fae..67f0e52 100644
--- a/modules/ad_content/config/schema/ad_content.schema.yml
+++ b/modules/ad_content/config/schema/ad_content.schema.yml
@@ -2,7 +2,7 @@
 
 ad_content.ad_content_type.*:
   type: config_entity
-  label: 'Ad content type'
+  label: 'Advertisement type'
   mapping:
     id:
       type: string
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index e904231..fc60a82 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -18,17 +18,17 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 
 /**
- * Defines the ad content entity class.
+ * Defines the advertisement entity class.
  */
 #[ContentEntityType(
   id:'ad_content',
-  label: new TranslatableMarkup('Ad Content'),
-  label_collection: new TranslatableMarkup('Ad content'),
-  label_singular: new TranslatableMarkup('Ad content'),
-  label_plural: new TranslatableMarkup('Ad contents'),
+  label: new TranslatableMarkup('Advertisement'),
+  label_collection: new TranslatableMarkup('Advertisement'),
+  label_singular: new TranslatableMarkup('Advertisement'),
+  label_plural: new TranslatableMarkup('Advertisements'),
   label_count: [
-    'singular' => '@count ad content',
-    'plural' => '@count ad contents',
+    'singular' => '@count advertisement',
+    'plural' => '@count advertisements',
   ],
   handlers: [
     'storage' => SqlContentEntityStorage::class,
@@ -51,7 +51,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   revision_table: 'ad_content_revision',
   admin_permission: 'administer ads',
   bundle_entity_type: 'ad_content_type',
-  bundle_label: new TranslatableMarkup('Ad content type'),
+  bundle_label: new TranslatableMarkup('Advertisement type'),
   field_ui_base_route: 'entity.ad_content_type.edit_form',
   links: [
     'add-page' => '/admin/content/ad/add',
diff --git a/modules/ad_content/src/Entity/AdContentInterface.php b/modules/ad_content/src/Entity/AdContentInterface.php
index 8b73211..dafd5db 100644
--- a/modules/ad_content/src/Entity/AdContentInterface.php
+++ b/modules/ad_content/src/Entity/AdContentInterface.php
@@ -10,7 +10,7 @@ use Drupal\Core\Entity\RevisionLogInterface;
 use Drupal\user\EntityOwnerInterface;
 
 /**
- * Common interface for ad content entities.
+ * Common interface for advertisement entities.
  */
 interface AdContentInterface extends AdInterface, ContentEntityInterface, EntityOwnerInterface, EntityChangedInterface, EntityPublishedInterface, RevisionLogInterface {
 
diff --git a/modules/ad_content/src/Entity/AdContentListBuilder.php b/modules/ad_content/src/Entity/AdContentListBuilder.php
index e2d797f..b5109a3 100644
--- a/modules/ad_content/src/Entity/AdContentListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentListBuilder.php
@@ -10,7 +10,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Ad content list builder.
+ * Advertisement list builder.
  */
 class AdContentListBuilder extends EntityListBuilder {
 
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index d31c46b..88bc18d 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -10,16 +10,16 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 
 /**
- * Defines the ad content type bundle class.
+ * Defines the advertisement type bundle class.
  */
 #[ConfigEntityType(
   id: 'ad_content_type',
-  label: new TranslatableMarkup('Ad Content Type'),
-  label_singular: new TranslatableMarkup('Ad content type'),
-  label_plural: new TranslatableMarkup('Ad content types'),
+  label: new TranslatableMarkup('Advertisement Type'),
+  label_singular: new TranslatableMarkup('Advertisement type'),
+  label_plural: new TranslatableMarkup('Advertisement types'),
   label_count: [
-    'singular' => '@count ad content type',
-    'plural' => '@count ad content types',
+    'singular' => '@count advertisement type',
+    'plural' => '@count advertisement types',
   ],
   bundle_of: 'ad_content',
   entity_keys: [
@@ -57,7 +57,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
 
   /**
-   * A brief description of the ad content type.
+   * A brief description of the advertisement type.
    *
    * @var string
    */
@@ -78,21 +78,21 @@ class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInter
   }
 
   /**
-   * Returns the UUID of the ad content type.
+   * Returns the UUID of the advertisement type.
    */
   public function getUuid(): string {
     return $this->uuid();
   }
 
   /**
-   * Returns the id of the ad content type.
+   * Returns the id of the advertisement type.
    */
   public function getId(): string {
     return $this->id();
   }
 
   /**
-   * Returns the label of the ad content type.
+   * Returns the label of the advertisement type.
    */
   public function getLabel(): string {
     return $this->label();
diff --git a/modules/ad_content/src/Entity/AdContentTypeInterface.php b/modules/ad_content/src/Entity/AdContentTypeInterface.php
index f75a4eb..864ae7a 100644
--- a/modules/ad_content/src/Entity/AdContentTypeInterface.php
+++ b/modules/ad_content/src/Entity/AdContentTypeInterface.php
@@ -5,23 +5,23 @@ namespace Drupal\ad_content\Entity;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
 
 /**
- * Common interface for ad content type bundle entities.
+ * Common interface for advertisement type bundle entities.
  */
 interface AdContentTypeInterface extends ConfigEntityInterface {
 
   /**
-   * Returns the description of the ad content type.
+   * Returns the description of the advertisement type.
    *
    * @return string
-   *   The description of the ad content type.
+   *   The description of the advertisement type.
    */
   public function getDescription(): string;
 
   /**
-   * Sets the description of the ad content type.
+   * Sets the description of the advertisement type.
    *
    * @param string $description
-   *   The description of the ad content type.
+   *   The description of the advertisement type.
    */
   public function setDescription($description);
 
diff --git a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
index 59d02b5..ecb5384 100644
--- a/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
+++ b/modules/ad_content/src/Entity/AdContentTypeListBuilder.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
 
 /**
- * Ad content list builder.
+ * Advertisement list builder.
  */
 class AdContentTypeListBuilder extends EntityListBuilder {
 
diff --git a/modules/ad_content/src/Entity/AdContentViewController.php b/modules/ad_content/src/Entity/AdContentViewController.php
index ab9d0a6..71a44f0 100644
--- a/modules/ad_content/src/Entity/AdContentViewController.php
+++ b/modules/ad_content/src/Entity/AdContentViewController.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\Controller\EntityViewController;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
- * Ad content view controller.
+ * Advertisement view controller.
  */
 class AdContentViewController extends EntityViewController {
 
@@ -14,7 +14,7 @@ class AdContentViewController extends EntityViewController {
    * The _title_callback for the page that renders a single node.
    *
    * @param \Drupal\Core\Entity\EntityInterface $ad_content
-   *   The current ad content.
+   *   The current advertisement.
    *
    * @return string
    *   The page title.
diff --git a/modules/ad_content/src/Form/AdContentEntityForm.php b/modules/ad_content/src/Form/AdContentEntityForm.php
index 5f456c8..90d31eb 100644
--- a/modules/ad_content/src/Form/AdContentEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentEntityForm.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\ContentEntityForm;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
- * Entity form for ad content.
+ * Entity form for advertisement.
  */
 class AdContentEntityForm extends ContentEntityForm {
 
diff --git a/modules/ad_content/src/Form/AdContentTypeEntityForm.php b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
index c0470d3..3abf2f6 100644
--- a/modules/ad_content/src/Form/AdContentTypeEntityForm.php
+++ b/modules/ad_content/src/Form/AdContentTypeEntityForm.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\BundleEntityFormBase;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
- * Entity form for the ad content type bundle.
+ * Entity form for the advertisement type bundle.
  */
 class AdContentTypeEntityForm extends BundleEntityFormBase {
 
@@ -24,7 +24,7 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
       '#title' => $this->t('Title'),
       '#maxlength' => 255,
       '#default_value' => $entity_type->label(),
-      '#description' => $this->t('The title for the ad content type (bundle).'),
+      '#description' => $this->t('The title for the advertisement type (bundle).'),
       '#required' => TRUE,
     ];
 
@@ -41,7 +41,7 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
       '#type' => 'textarea',
       '#title' => $this->t('Description'),
       '#default_value' => $entity_type->getDescription() ?? '',
-      '#description' => $this->t('A short description of the ad content type.'),
+      '#description' => $this->t('A short description of the advertisement type.'),
       '#required' => FALSE,
     ];
 
@@ -62,11 +62,11 @@ class AdContentTypeEntityForm extends BundleEntityFormBase {
     // Provide a message for the user and redirect them back to the collection.
     switch ($status) {
       case SAVED_NEW:
-        $this->messenger()->addMessage($this->t('Created the %label ad content type..', $message_params));
+        $this->messenger()->addMessage($this->t('Created the %label advertisement type..', $message_params));
         break;
 
       default:
-        $this->messenger()->addMessage($this->t('Saved the %label ad content type.', $message_params));
+        $this->messenger()->addMessage($this->t('Saved the %label advertisement type.', $message_params));
     }
 
     $form_state->setRedirectUrl($entity_type->toUrl('collection'));
diff --git a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
index dca537c..4d67cfc 100644
--- a/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
+++ b/modules/ad_content/src/Plugin/Ad/Bucket/AdContentBucket.php
@@ -25,11 +25,11 @@ use Psr\Log\LoggerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Basic ad content bucket.
+ * Basic advertisement bucket.
  *
  * @Plugin(
  *   id = \Drupal\ad_content\Entity\AdContentInterface::BUCKET_ID,
- *   label = @Translation("Ad Content"),
+ *   label = @Translation("Advertisement"),
  * )
  */
 class AdContentBucket extends PluginBase implements BucketInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface {
@@ -200,7 +200,7 @@ class AdContentBucket extends PluginBase implements BucketInterface, ContainerFa
    *   The ad size.
    *
    * @return \Drupal\ad_content\Entity\AdContentInterface
-   *   An ad content entity.
+   *   An advertisement entity.
    */
   protected function getAdContent(SizeInterface $size): ?AdContentInterface {
     return $this->getRandomAd($size);
diff --git a/modules/ad_scheduler/ad_scheduler.info.yml b/modules/ad_scheduler/ad_scheduler.info.yml
index 2fa91bb..83ed409 100644
--- a/modules/ad_scheduler/ad_scheduler.info.yml
+++ b/modules/ad_scheduler/ad_scheduler.info.yml
@@ -1,5 +1,5 @@
 name: Ad Scheduler
-description: 'Integrates ad contents with the scheduler module.'
+description: 'Integrates advertisements with the scheduler module.'
 type: module
 package: Advertisement
 core_version_requirement: ^10.3 || ^11
diff --git a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
index b10d332..26dfcfe 100644
--- a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
+++ b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
@@ -8,12 +8,12 @@ use Drupal\scheduler\Annotation\SchedulerPlugin;
 use Drupal\scheduler\SchedulerPluginBase;
 
 /**
- * Ad content plugin for the scheduler module.
+ * Advertisement plugin for the scheduler module.
  */
 #[SchedulerPlugin(
   id: 'ad_content_scheduler',
-  label: new TranslatableMarkup('Ad content scheduler plugin'),
-  description: new TranslatableMarkup('Support for scheduling ad content entities'),
+  label: new TranslatableMarkup('Advertisement scheduler plugin'),
+  description: new TranslatableMarkup('Support for scheduling advertisement entities'),
   entityType: 'ad_content',
   dependency: 'ad_content',
 )]
diff --git a/modules/ad_track/ad_track.views.inc b/modules/ad_track/ad_track.views.inc
index a80fc17..2ba4970 100644
--- a/modules/ad_track/ad_track.views.inc
+++ b/modules/ad_track/ad_track.views.inc
@@ -78,7 +78,7 @@ function ad_track_views_data() {
 
   if (Drupal::moduleHandler()->moduleExists('ad_content')) {
     $data['ad_track_total']['ad_id']['relationship'] = [
-      'label' => new TranslatableMarkup('Ad Content'),
+      'label' => new TranslatableMarkup('Advertisement'),
       'base' => 'ad_content',
       'base field' => 'uuid',
       'id' => 'standard',
-- 
GitLab


From ddd7a2b31da3ff97e8cac6d08e5033adf0ebea1b Mon Sep 17 00:00:00 2001
From: DDEV User <nobody@example.com>
Date: Wed, 14 May 2025 10:58:50 +0200
Subject: [PATCH 30/46] Fixed menu structure, namings etc.

---
 ad.links.menu.yml                               |  4 ++--
 ad.routing.yml                                  |  2 +-
 modules/ad_content/ad_content.links.menu.yml    |  2 ++
 modules/ad_content/ad_content.links.task.yml    |  2 +-
 modules/ad_content/ad_content.routing.yml       |  2 +-
 modules/ad_content/src/Entity/AdContent.php     |  2 +-
 modules/ad_content/src/Entity/AdContentType.php | 10 +++++-----
 src/Form/SettingsForm.php                       | 10 +++++-----
 8 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/ad.links.menu.yml b/ad.links.menu.yml
index 69c3453..f1ad362 100644
--- a/ad.links.menu.yml
+++ b/ad.links.menu.yml
@@ -1,5 +1,5 @@
 ad.settings:
-  title: 'Advertisement'
+  title: 'Advertisement settings'
   description: 'Configure and manage advertisement settings.'
   route_name: ad.settings
-  parent: system.admin_config
+  parent: system.admin_config_content
diff --git a/ad.routing.yml b/ad.routing.yml
index 42d3120..551e418 100644
--- a/ad.routing.yml
+++ b/ad.routing.yml
@@ -1,5 +1,5 @@
 ad.settings:
-  path: '/admin/config/ad'
+  path: '/admin/config/content/ad'
   defaults:
     _form: '\Drupal\ad\Form\SettingsForm'
     _title: 'Ad Settings'
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
index f2c12ea..cdce110 100644
--- a/modules/ad_content/ad_content.links.menu.yml
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -3,6 +3,8 @@ entity.ad_content.collection:
   title: 'Advertisements'
   description: 'Manage advertisements.'
   parent: system.admin_content
+  # Place at bottom in the menu by default:
+  weight: 100
 
 entity.ad_content_type.collection:
   title: 'Advertisement types'
diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
index ffa140b..d7ccdcd 100644
--- a/modules/ad_content/ad_content.links.task.yml
+++ b/modules/ad_content/ad_content.links.task.yml
@@ -1,4 +1,4 @@
 ad_content.admin:
-  title: 'Advertisement'
+  title: 'Advertisements'
   route_name: entity.ad_content.collection
   base_route: system.admin_content
diff --git a/modules/ad_content/ad_content.routing.yml b/modules/ad_content/ad_content.routing.yml
index 7b7a5d3..dab8ed6 100644
--- a/modules/ad_content/ad_content.routing.yml
+++ b/modules/ad_content/ad_content.routing.yml
@@ -2,7 +2,7 @@ ad_content.render_ad:
   path: '/ad/content/render'
   defaults:
     _controller: '\Drupal\ad_content\Controller\ImpressionController::renderAds'
-    _title: 'Render ad'
+    _title: 'Render advertisement'
   requirements:
     _permission: 'access content'
 
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index fc60a82..8ad8bb6 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -23,7 +23,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
 #[ContentEntityType(
   id:'ad_content',
   label: new TranslatableMarkup('Advertisement'),
-  label_collection: new TranslatableMarkup('Advertisement'),
+  label_collection: new TranslatableMarkup('Advertisements'),
   label_singular: new TranslatableMarkup('Advertisement'),
   label_plural: new TranslatableMarkup('Advertisements'),
   label_count: [
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 88bc18d..955998b 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -47,11 +47,11 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   ],
   admin_permission: 'administer ads',
   links: [
-    'canonical' => '/admin/structure/ad_content_type/{ad_content_type}',
-    'add-form' => '/admin/structure/ad_content_type/add',
-    'edit-form' => '/admin/structure/ad_content_type/{ad_content_type}/edit',
-    'delete-form' => '/admin/structure/ad_content_type/{ad_content_type}/delete',
-    'collection' => '/admin/structure/ad_content_type',
+    'canonical' => '/admin/structure/ad-content/{ad_content_type}',
+    'add-form' => '/admin/structure/ad-content/add',
+    'edit-form' => '/admin/structure/ad-content/{ad_content_type}/edit',
+    'delete-form' => '/admin/structure/ad-content/{ad_content_type}/delete',
+    'collection' => '/admin/structure/ad-content',
   ]
 )]
 class AdContentType extends ConfigEntityBundleBase implements AdContentTypeInterface {
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index 882f2a2..355c699 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -115,11 +115,11 @@ class SettingsForm extends ConfigFormBase {
       ];
     }
 
-    $form['ad_label'] = [
+    $form['advertisement_indicator'] = [
       '#type' => 'textfield',
-      '#title' => $this->t('Ad label'),
-      '#description' => $this->t('In many countries it is mandatory to label ads ad being such. This setting adds a small print (e.g. "ADVERTISEMENT") to all ad blocks.'),
-      '#default_value' => $config->get('ad_label') ?? '',
+      '#title' => $this->t('Advertisement indicator'),
+      '#description' => $this->t('In many countries it is mandatory to label ads as being such. This setting adds a small print (e.g. "Advertisement") to all ad blocks.'),
+      '#default_value' => $config->get('advertisement_indicator') ?? '',
     ];
 
     return parent::buildForm($form, $form_state);
@@ -131,7 +131,7 @@ class SettingsForm extends ConfigFormBase {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->config('ad.settings')
       ->set('trackers', $form_state->getValue('trackers'))
-      ->set('ad_label', $form_state->getValue('ad_label'))
+      ->set('advertisement_indicator', $form_state->getValue('advertisement_indicator'))
       ->save();
 
     parent::submitForm($form, $form_state);
-- 
GitLab


From fd480528d6bd978c18d34320bcab39add358396d Mon Sep 17 00:00:00 2001
From: DDEV User <nobody@example.com>
Date: Wed, 14 May 2025 11:05:53 +0200
Subject: [PATCH 31/46] Ad track improvements

---
 modules/ad_content/ad_content.module | 6 +++---
 modules/ad_track/ad_track.module     | 7 +++++++
 src/Form/SettingsForm.php            | 2 +-
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index fdace8b..c7f064f 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -29,7 +29,6 @@ function ad_content_entity_extra_field_info() {
       'description' => t('Displays the "advertisement" indicator, configurable in the ad settings.'),
       'weight' => 99,
       'visible' => TRUE,
-      'translatable' => TRUE,
     ];
   }
   return $extra;
@@ -40,10 +39,11 @@ function ad_content_entity_extra_field_info() {
  */
 function ad_content_ad_content_type_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
   if ($display->getComponent('ad_content_advertisement_indicator')) {
-    $adLabel = \Drupal::config('ad.settings')->get('advertisement_indicator');
+    // @todo: Get config value in interface language:
+    $advertisementIndicator = \Drupal::config('ad.settings')->get('advertisement_indicator');
     $build['ad_content_advertisement_indicator'] = [
       '#type' => 'markup',
-      '#markup' => $adLabel,
+      '#markup' => $advertisementIndicator,
     ];
   }
 }
diff --git a/modules/ad_track/ad_track.module b/modules/ad_track/ad_track.module
index 202cf32..90a9e89 100644
--- a/modules/ad_track/ad_track.module
+++ b/modules/ad_track/ad_track.module
@@ -71,3 +71,10 @@ function ad_track_ad_content_view_alter(array &$build, AdContentInterface $ad_co
     }
   }
 }
+
+/**
+ * Implements hook_install().
+ */
+function hook_install($is_syncing) : void {
+    // @todo: Set tracker to "local" in config, if not set yet.
+}
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index 355c699..af1002a 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -92,7 +92,7 @@ class SettingsForm extends ConfigFormBase {
     $form['trackers'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Tracker configuration'),
-      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
+      '#description' => $this->t('Assign an ad statistics tracker for each ad source. Note: You may need to enable the "Ad track" submodule or a custom ad tracking module.'),
       '#tree' => TRUE,
     ];
 
-- 
GitLab


From 8d2e882bc0f4532006aa94a335cfc9bf31c3260f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 12:43:48 +0200
Subject: [PATCH 32/46] Updates and translation feature for ad indicator
 setting

---
 ad.config_translation.yml            |  5 +++++
 ad.links.task.yml                    |  4 ++++
 config/schema/ad.schema.yml          |  3 +++
 modules/ad_content/ad_content.module | 19 ++++++++++++-------
 4 files changed, 24 insertions(+), 7 deletions(-)
 create mode 100644 ad.config_translation.yml
 create mode 100644 ad.links.task.yml

diff --git a/ad.config_translation.yml b/ad.config_translation.yml
new file mode 100644
index 0000000..24856bb
--- /dev/null
+++ b/ad.config_translation.yml
@@ -0,0 +1,5 @@
+ad.settings:
+  title: 'Ad settings'
+  base_route_name: ad.settings
+  names:
+    - ad.settings
diff --git a/ad.links.task.yml b/ad.links.task.yml
new file mode 100644
index 0000000..632ea59
--- /dev/null
+++ b/ad.links.task.yml
@@ -0,0 +1,4 @@
+ad.settings:
+  route_name: ad.settings
+  title: 'Ad settings'
+  base_route: ad.settings
diff --git a/config/schema/ad.schema.yml b/config/schema/ad.schema.yml
index ff72ad2..802de9f 100644
--- a/config/schema/ad.schema.yml
+++ b/config/schema/ad.schema.yml
@@ -10,3 +10,6 @@ ad.settings:
       sequence:
         type: string
         label: 'Tracker'
+    advertisement_indicator:
+      type: label
+      label: 'Advertisement indicator'
diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index c7f064f..4dc64a9 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -37,13 +37,18 @@ function ad_content_entity_extra_field_info() {
 /**
  * Implements hook_ENTITY_TYPE_view().
  */
-function ad_content_ad_content_type_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
+function ad_content_ad_content_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
   if ($display->getComponent('ad_content_advertisement_indicator')) {
-    // @todo: Get config value in interface language:
-    $advertisementIndicator = \Drupal::config('ad.settings')->get('advertisement_indicator');
-    $build['ad_content_advertisement_indicator'] = [
-      '#type' => 'markup',
-      '#markup' => $advertisementIndicator,
-    ];
+    // @todo Get config value in interface language:
+    $advertisementIndicator = trim(\Drupal::config('ad.settings')->get('advertisement_indicator'));
+    if (!empty($advertisementIndicator)) {
+      $build['ad_content_advertisement_indicator'] = [
+        '#type' => 'inline_template',
+        '#template' => '<small class="ad-indicator">{{ indicator_text }}</small>',
+        '#context' => [
+          'indicator_text' => $advertisementIndicator,
+        ],
+      ];
+    }
   }
 }
-- 
GitLab


From 4e196fb638c4b37d31304d0235c275f6582720b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 13:09:10 +0200
Subject: [PATCH 33/46] Make translated ad indicator actually appear on
 localized pages

---
 modules/ad_content/ad_content.module | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index 4dc64a9..caa6a87 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -9,6 +9,7 @@ use Drupal\ad_content\Entity\AdContentType;
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Language\Language;
 
 /**
  * Implements hook_query_alter().
@@ -39,8 +40,12 @@ function ad_content_entity_extra_field_info() {
  */
 function ad_content_ad_content_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
   if ($display->getComponent('ad_content_advertisement_indicator')) {
-    // @todo Get config value in interface language:
+    // This hack is still needed to retrieve the translated config string:
+    $languageManager = \Drupal::languageManager();
+    $originalLanguage = $languageManager->getConfigOverrideLanguage();
+    $languageManager->setConfigOverrideLanguage(new Language(['id' => $languageManager->getCurrentLanguage()->getId()]));
     $advertisementIndicator = trim(\Drupal::config('ad.settings')->get('advertisement_indicator'));
+    $languageManager->setConfigOverrideLanguage($originalLanguage);
     if (!empty($advertisementIndicator)) {
       $build['ad_content_advertisement_indicator'] = [
         '#type' => 'inline_template',
-- 
GitLab


From 030e5b97791d1fd5885671ebc52d2786f733dce8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 13:14:01 +0200
Subject: [PATCH 34/46] Add default setting for ad indicator setting

---
 config/install/ad.settings.yml         | 1 +
 modules/ad_content/ad_content.info.yml | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 config/install/ad.settings.yml

diff --git a/config/install/ad.settings.yml b/config/install/ad.settings.yml
new file mode 100644
index 0000000..bfa9358
--- /dev/null
+++ b/config/install/ad.settings.yml
@@ -0,0 +1 @@
+advertisement_indicator: 'Advertisement'
diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 651f625..6460616 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -1,4 +1,4 @@
-name: Advertisement
+name: 'Ad Content'
 description: 'Ad source allowing to create ads via the administrative UI.'
 type: module
 package: Advertisement
-- 
GitLab


From cde7a7302014ea93ec82e67f45813e6bfd8abcbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 14:11:50 +0200
Subject: [PATCH 35/46] Adding install hook that sets ad_track tracker on empty
 tracker setting fields

---
 modules/ad_track/ad_track.install | 14 ++++++++++++++
 modules/ad_track/ad_track.module  |  7 -------
 src/Form/SettingsForm.php         |  2 +-
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/modules/ad_track/ad_track.install b/modules/ad_track/ad_track.install
index baf601c..4d651ee 100644
--- a/modules/ad_track/ad_track.install
+++ b/modules/ad_track/ad_track.install
@@ -46,3 +46,17 @@ function ad_track_schema() {
 
   return $schema;
 }
+
+/**
+ * Implements hook_install().
+ */
+function ad_track_install($is_syncing) : void {
+  $config = \Drupal::configFactory()->getEditable('ad.settings');
+  $trackerSettings = $config->get('trackers');
+  foreach ($trackerSettings as &$trackerSetting) {
+    if ($trackerSetting === 'null') {
+      $trackerSetting = 'local';
+    }
+  }
+  $config->set('trackers', $trackerSettings)->save();
+}
diff --git a/modules/ad_track/ad_track.module b/modules/ad_track/ad_track.module
index 90a9e89..202cf32 100644
--- a/modules/ad_track/ad_track.module
+++ b/modules/ad_track/ad_track.module
@@ -71,10 +71,3 @@ function ad_track_ad_content_view_alter(array &$build, AdContentInterface $ad_co
     }
   }
 }
-
-/**
- * Implements hook_install().
- */
-function hook_install($is_syncing) : void {
-    // @todo: Set tracker to "local" in config, if not set yet.
-}
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index af1002a..355c699 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -92,7 +92,7 @@ class SettingsForm extends ConfigFormBase {
     $form['trackers'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Tracker configuration'),
-      '#description' => $this->t('Assign an ad statistics tracker for each ad source. Note: You may need to enable the "Ad track" submodule or a custom ad tracking module.'),
+      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
       '#tree' => TRUE,
     ];
 
-- 
GitLab


From b620cd0ce6f5ca566a1a55b450c355d5f847274f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 14:28:14 +0200
Subject: [PATCH 36/46] Merging edit and manage tabs for ad content type
 entities

---
 modules/ad_content/ad_content.links.task.yml    | 5 +++++
 modules/ad_content/src/Entity/AdContentType.php | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/modules/ad_content/ad_content.links.task.yml b/modules/ad_content/ad_content.links.task.yml
index d7ccdcd..b83a730 100644
--- a/modules/ad_content/ad_content.links.task.yml
+++ b/modules/ad_content/ad_content.links.task.yml
@@ -2,3 +2,8 @@ ad_content.admin:
   title: 'Advertisements'
   route_name: entity.ad_content.collection
   base_route: system.admin_content
+
+entity.ad_content_type.edit_form:
+  title: 'Edit'
+  route_name: entity.ad_content_type.edit_form
+  base_route: entity.ad_content_type.edit_form
diff --git a/modules/ad_content/src/Entity/AdContentType.php b/modules/ad_content/src/Entity/AdContentType.php
index 955998b..d73a659 100644
--- a/modules/ad_content/src/Entity/AdContentType.php
+++ b/modules/ad_content/src/Entity/AdContentType.php
@@ -49,8 +49,8 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   links: [
     'canonical' => '/admin/structure/ad-content/{ad_content_type}',
     'add-form' => '/admin/structure/ad-content/add',
-    'edit-form' => '/admin/structure/ad-content/{ad_content_type}/edit',
-    'delete-form' => '/admin/structure/ad-content/{ad_content_type}/delete',
+    'edit-form' => '/admin/structure/ad-content/manage/{ad_content_type}',
+    'delete-form' => '/admin/structure/ad-content/manage/{ad_content_type}/delete',
     'collection' => '/admin/structure/ad-content',
   ]
 )]
-- 
GitLab


From 8d26b0ecdcaaffd04594595762886d7c92d1c048 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 14:49:51 +0200
Subject: [PATCH 37/46] Changing all frontend spellings of ad to advertisement

---
 ad.config_translation.yml                              |  2 +-
 ad.info.yml                                            |  2 +-
 ad.links.task.yml                                      |  2 +-
 ad.module                                              |  4 ++--
 ad.permissions.yml                                     |  4 ++--
 ad.routing.yml                                         |  2 +-
 config/schema/ad.schema.yml                            |  4 ++--
 modules/ad_content/ad_content.info.yml                 |  4 ++--
 modules/ad_content/ad_content.links.menu.yml           |  2 +-
 modules/ad_content/ad_content.module                   |  6 +++---
 .../install/ad_content.ad_content_type.image_ad.yml    |  4 ++--
 .../ad_content.ad_content_type.javascript_ad.yml       |  4 ++--
 .../install/ad_content.ad_content_type.text_ad.yml     |  4 ++--
 .../install/core.entity_view_mode.ad_content.admin.yml |  2 +-
 .../field.field.ad_content.image_ad.field_ad_image.yml |  4 ++--
 ...field.ad_content.javascript_ad.field_javascript.yml |  2 +-
 .../field.field.ad_content.text_ad.field_ad_text.yml   |  4 ++--
 .../config/optional/views.view.ad_statistics.yml       |  6 +++---
 modules/ad_content/src/Entity/AdContent.php            | 10 +++++-----
 modules/ad_scheduler/ad_scheduler.info.yml             |  2 +-
 modules/ad_track/ad_track.info.yml                     |  4 ++--
 modules/ad_track/ad_track.install                      | 10 +++++-----
 modules/ad_track/ad_track.views.inc                    | 10 +++++-----
 modules/ad_track/src/Entity/AdTrackEvent.php           |  4 ++--
 modules/ad_track/src/Entity/AdTrackEventViewsData.php  |  2 +-
 modules/ad_track/src/TotalSqlStorage.php               |  2 +-
 src/Bucket/BucketFactory.php                           |  2 +-
 src/Form/SettingsForm.php                              |  6 +++---
 28 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/ad.config_translation.yml b/ad.config_translation.yml
index 24856bb..64cb123 100644
--- a/ad.config_translation.yml
+++ b/ad.config_translation.yml
@@ -1,5 +1,5 @@
 ad.settings:
-  title: 'Ad settings'
+  title: 'Advertisement settings'
   base_route_name: ad.settings
   names:
     - ad.settings
diff --git a/ad.info.yml b/ad.info.yml
index 353a165..0206c51 100644
--- a/ad.info.yml
+++ b/ad.info.yml
@@ -1,4 +1,4 @@
-name: Ad
+name: Advertisement
 type: module
 description: 'A flexible and extensible advertising system.'
 package: Advertisement
diff --git a/ad.links.task.yml b/ad.links.task.yml
index 632ea59..042be81 100644
--- a/ad.links.task.yml
+++ b/ad.links.task.yml
@@ -1,4 +1,4 @@
 ad.settings:
   route_name: ad.settings
-  title: 'Ad settings'
+  title: 'Advertisement settings'
   base_route: ad.settings
diff --git a/ad.module b/ad.module
index 83895e4..3a49052 100644
--- a/ad.module
+++ b/ad.module
@@ -2,13 +2,13 @@
 
 /**
  * @file
- * Main file for the "Ad" module.
+ * Main file for the ad module.
  */
 
 use Drupal\ad\Size\SizeInterface;
 
 /**
- * Returns the available Ad sizes.
+ * Returns the available ad sizes.
  *
  * @return string[]
  *   An array of array size IDs.
diff --git a/ad.permissions.yml b/ad.permissions.yml
index 2c530ea..8fb4c06 100644
--- a/ad.permissions.yml
+++ b/ad.permissions.yml
@@ -1,8 +1,8 @@
 administer ads:
-  title: 'Administer ads'
+  title: 'Administer advertisements'
   description: 'Manage advertisements.'
   restrict access: true
 administer ad settings:
-  title: 'Administer Ad settings'
+  title: 'Administer advertisement settings'
   description: 'Configure and manage advertisement settings.'
   restrict access: true
diff --git a/ad.routing.yml b/ad.routing.yml
index 551e418..13985c5 100644
--- a/ad.routing.yml
+++ b/ad.routing.yml
@@ -2,6 +2,6 @@ ad.settings:
   path: '/admin/config/content/ad'
   defaults:
     _form: '\Drupal\ad\Form\SettingsForm'
-    _title: 'Ad Settings'
+    _title: 'Advertisement settings'
   requirements:
     _permission: 'administer ad settings'
diff --git a/config/schema/ad.schema.yml b/config/schema/ad.schema.yml
index 802de9f..6a54e28 100644
--- a/config/schema/ad.schema.yml
+++ b/config/schema/ad.schema.yml
@@ -1,8 +1,8 @@
-# Schema for the configuration files of the "Ad" module.
+# Schema for the configuration files of the ad module.
 
 ad.settings:
   type: config_object
-  label: 'Ad Settings'
+  label: 'Advertisement settings'
   mapping:
     trackers:
       type: sequence
diff --git a/modules/ad_content/ad_content.info.yml b/modules/ad_content/ad_content.info.yml
index 6460616..bd76d67 100644
--- a/modules/ad_content/ad_content.info.yml
+++ b/modules/ad_content/ad_content.info.yml
@@ -1,5 +1,5 @@
-name: 'Ad Content'
-description: 'Ad source allowing to create ads via the administrative UI.'
+name: 'Advertisement content'
+description: 'Advertisement source allowing to create advertisements via the administrative UI.'
 type: module
 package: Advertisement
 core_version_requirement: ^10.3 || ^11
diff --git a/modules/ad_content/ad_content.links.menu.yml b/modules/ad_content/ad_content.links.menu.yml
index cdce110..8a73308 100644
--- a/modules/ad_content/ad_content.links.menu.yml
+++ b/modules/ad_content/ad_content.links.menu.yml
@@ -9,5 +9,5 @@ entity.ad_content.collection:
 entity.ad_content_type.collection:
   title: 'Advertisement types'
   parent: system.admin_structure
-  description: 'Manage advertisements types.'
+  description: 'Manage advertisement types.'
   route_name: entity.ad_content_type.collection
diff --git a/modules/ad_content/ad_content.module b/modules/ad_content/ad_content.module
index caa6a87..d397259 100644
--- a/modules/ad_content/ad_content.module
+++ b/modules/ad_content/ad_content.module
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Main file for the "Advertisement" module.
+ * Main file for the ad module.
  */
 
 use Drupal\ad_content\Entity\AdContentType;
@@ -26,8 +26,8 @@ function ad_content_entity_extra_field_info() {
   $extra = [];
   foreach (AdContentType::loadMultiple() as $bundle) {
     $extra['ad_content'][$bundle->id()]['display']['ad_content_advertisement_indicator'] = [
-      'label' => t('"Advertisement" indicator'),
-      'description' => t('Displays the "advertisement" indicator, configurable in the ad settings.'),
+      'label' => t('Advertisement indicator'),
+      'description' => t('Displays the advertisement indicator, configurable in the ad settings.'),
       'weight' => 99,
       'visible' => TRUE,
     ];
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
index b1176e8..19283d6 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
@@ -2,5 +2,5 @@ langcode: en
 status: true
 dependencies: {  }
 id: image_ad
-label: 'Image Ad'
-description: 'An ad that contains an image.'
+label: 'Image advertisement'
+description: 'An advertisement that contains an image.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
index 382df32..a482cb5 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
@@ -2,5 +2,5 @@ langcode: en
 status: true
 dependencies: {  }
 id: javascript_ad
-label: 'JavaScript Ad'
-description: 'An ad that contains JavaScript.'
+label: 'JavaScript advertisement'
+description: 'An advertisement that contains JavaScript.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
index 80ae1e6..da02515 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
@@ -2,5 +2,5 @@ langcode: en
 status: true
 dependencies: {  }
 id: text_ad
-label: 'Text Ad'
-description: 'An ad that contains text.'
+label: 'Text advertisement'
+description: 'An advertisement that contains text.'
diff --git a/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
index 7844b15..f6658b5 100644
--- a/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_mode.ad_content.admin.yml
@@ -5,6 +5,6 @@ dependencies:
     - ad_content
 id: ad_content.admin
 label: Admin
-description: 'The way that this ad is displayed on admin pages (showing additional info about the ad).'
+description: 'The way that this advertisement is displayed on admin pages (showing additional info about the advertisement).'
 targetEntityType: ad_content
 cache: true
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
index e43b867..fda7c6d 100644
--- a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -10,8 +10,8 @@ id: ad_content.image_ad.field_ad_image
 field_name: field_ad_image
 entity_type: ad_content
 bundle: image_ad
-label: 'Ad image'
-description: 'The image that the ad should display.'
+label: 'Advertisement image'
+description: 'The image that the advertisement should display.'
 required: true
 translatable: false
 default_value: {  }
diff --git a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
index 3977d39..8111be2 100644
--- a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
@@ -11,7 +11,7 @@ field_name: field_javascript
 entity_type: ad_content
 bundle: javascript_ad
 label: 'JavaScript code'
-description: 'The JavaScript code that the ad should run in order to display.'
+description: 'The JavaScript code that the advertisement should run in order to display.'
 required: true
 translatable: false
 default_value: {  }
diff --git a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
index 476d4ef..cd88f8e 100644
--- a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
@@ -10,8 +10,8 @@ id: ad_content.text_ad.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
 bundle: text_ad
-label: 'Ad text'
-description: 'The text that the ad should display.'
+label: 'Advertisement text'
+description: 'The text that the advertisement should display.'
 required: true
 translatable: false
 default_value: {  }
diff --git a/modules/ad_content/config/optional/views.view.ad_statistics.yml b/modules/ad_content/config/optional/views.view.ad_statistics.yml
index b6a7657..4857626 100644
--- a/modules/ad_content/config/optional/views.view.ad_statistics.yml
+++ b/modules/ad_content/config/optional/views.view.ad_statistics.yml
@@ -5,7 +5,7 @@ dependencies:
     - ad_content
     - ad_track
 id: ad_statistics
-label: 'Ad Statistics'
+label: 'Advertisement Statistics'
 module: views
 description: ''
 tag: ''
@@ -430,7 +430,7 @@ display:
           relationship: ad_id
           group_type: group
           admin_label: ''
-          label: Ad
+          label: Advertisement
           exclude: false
           alter:
             alter_text: false
@@ -1099,7 +1099,7 @@ display:
           entity_field: url
           plugin_id: string
       sorts: {  }
-      title: 'Advertisement Statistics'
+      title: 'Advertisement statistics'
       header: {  }
       footer: {  }
       empty: {  }
diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index 8ad8bb6..e2d67d6 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -134,7 +134,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['title'] = BaseFieldDefinition::create('string')
       ->setLabel(new TranslatableMarkup('Title'))
-      ->setDescription(new TranslatableMarkup('A brief description of the ad.'))
+      ->setDescription(new TranslatableMarkup('A brief description of the advertisement.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->addConstraint('UniqueField', [])
@@ -175,7 +175,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['size'] = BaseFieldDefinition::create('list_string')
       ->setLabel(new TranslatableMarkup('Size'))
-      ->setDescription(new TranslatableMarkup('The ad size.'))
+      ->setDescription(new TranslatableMarkup("The advertisement's size."))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->setSettings([
@@ -194,7 +194,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['target_url'] = BaseFieldDefinition::create('link')
       ->setLabel(new TranslatableMarkup('Target URL'))
-      ->setDescription(new TranslatableMarkup('The URL to be taken to when clicking on the ad.'))
+      ->setDescription(new TranslatableMarkup('The URL to be taken to when clicking on the advertisement.'))
       ->setRevisionable(TRUE)
       ->setRequired(TRUE)
       ->setDisplayOptions('form', [
@@ -211,7 +211,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(new TranslatableMarkup('Authored on'))
-      ->setDescription(t('The time that the ad was created.'))
+      ->setDescription(t('The time that the advertisement was created.'))
       ->setRevisionable(TRUE)
       ->setDisplayOptions('form', [
         'type' => 'datetime_timestamp',
@@ -227,7 +227,7 @@ class AdContent extends EditorialContentEntityBase implements AdContentInterface
 
     $fields['changed'] = BaseFieldDefinition::create('changed')
       ->setLabel(t('Changed'))
-      ->setDescription(t('The time that the ad was last edited.'));
+      ->setDescription(t('The time that the advertisement was last edited.'));
 
     return $fields;
   }
diff --git a/modules/ad_scheduler/ad_scheduler.info.yml b/modules/ad_scheduler/ad_scheduler.info.yml
index 83ed409..0002899 100644
--- a/modules/ad_scheduler/ad_scheduler.info.yml
+++ b/modules/ad_scheduler/ad_scheduler.info.yml
@@ -1,4 +1,4 @@
-name: Ad Scheduler
+name: Advertisement scheduler
 description: 'Integrates advertisements with the scheduler module.'
 type: module
 package: Advertisement
diff --git a/modules/ad_track/ad_track.info.yml b/modules/ad_track/ad_track.info.yml
index e623555..7a64dfa 100644
--- a/modules/ad_track/ad_track.info.yml
+++ b/modules/ad_track/ad_track.info.yml
@@ -1,5 +1,5 @@
-name: Ad Track
-description: 'Ad statistics tracker allowing to count ad impressions and clicks locally.'
+name: Advertisement track
+description: 'Advertisement statistics tracker allowing to count advertisement impressions and clicks locally.'
 type: module
 package: Advertisement
 core_version_requirement: ^10.3 || ^11
diff --git a/modules/ad_track/ad_track.install b/modules/ad_track/ad_track.install
index 4d651ee..89c6349 100644
--- a/modules/ad_track/ad_track.install
+++ b/modules/ad_track/ad_track.install
@@ -12,29 +12,29 @@ function ad_track_schema() {
   $schema = [];
 
   $schema['ad_track_total'] = [
-    'description' => 'Stores ad total event counts.',
+    'description' => 'Stores advertisement total event counts.',
     'fields' => [
       'ad_id' => [
-        'description' => 'The ad identifier.',
+        'description' => 'The advertisement identifier.',
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE,
       ],
       'bucket_id' => [
-        'description' => 'The identifier of the ad bucket.',
+        'description' => 'The identifier of the advertisement bucket.',
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
       ],
       'click' => [
-        'description' => 'Total clicks of an ad.',
+        'description' => 'Total clicks of an advertisement.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
       ],
       'impression' => [
-        'description' => 'Total impressions of an ad.',
+        'description' => 'Total impressions of an advertisement.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
diff --git a/modules/ad_track/ad_track.views.inc b/modules/ad_track/ad_track.views.inc
index 2ba4970..6ddbff3 100644
--- a/modules/ad_track/ad_track.views.inc
+++ b/modules/ad_track/ad_track.views.inc
@@ -14,17 +14,17 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
 function ad_track_views_data() {
   $data = [];
 
-  $data['ad_track_total']['table']['group'] = new TranslatableMarkup('Ad Track');
+  $data['ad_track_total']['table']['group'] = new TranslatableMarkup('Advertisement track');
   $data['ad_track_total']['table']['provider'] = 'ad_track';
 
   $data['ad_track_total']['table']['base'] = [
     'field' => 'ad_id',
-    'title' => new TranslatableMarkup('Ad Track Totals'),
-    'help' => new TranslatableMarkup('Stores Ad total event counts.'),
+    'title' => new TranslatableMarkup('Advertisement Track Totals'),
+    'help' => new TranslatableMarkup('Stores advertisement total event counts.'),
   ];
 
   $ids = [
-    'ad_id' => new TranslatableMarkup('Ad ID'),
+    'ad_id' => new TranslatableMarkup('Advertisement ID'),
     'bucket_id' => new TranslatableMarkup('Bucket ID'),
   ];
 
@@ -94,7 +94,7 @@ function ad_track_views_data() {
 function ad_track_views_data_alter(array &$data) {
   if (Drupal::moduleHandler()->moduleExists('ad_content')) {
     $data['ad_content']['uuid']['relationship'] = [
-      'label' => new TranslatableMarkup('Ad Track Totals'),
+      'label' => new TranslatableMarkup('Advertisement Track Totals'),
       'base' => 'ad_track_total',
       'base field' => 'ad_id',
       'id' => 'standard',
diff --git a/modules/ad_track/src/Entity/AdTrackEvent.php b/modules/ad_track/src/Entity/AdTrackEvent.php
index 576178f..093f8c0 100644
--- a/modules/ad_track/src/Entity/AdTrackEvent.php
+++ b/modules/ad_track/src/Entity/AdTrackEvent.php
@@ -50,8 +50,8 @@ class AdTrackEvent extends ContentEntityBase {
       ->setDescription(t('The event timestamp.'));
 
     $fields['ad_id'] = BaseFieldDefinition::create('string')
-      ->setLabel(new TranslatableMarkup('Ad'))
-      ->setDescription(t('The identifier of the ad the events refers to.'));
+      ->setLabel(new TranslatableMarkup('Advertisement'))
+      ->setDescription(t('The identifier of the advertisement the events refers to.'));
 
     $fields['ip_address'] = BaseFieldDefinition::create('string')
       ->setLabel(new TranslatableMarkup('IP address'))
diff --git a/modules/ad_track/src/Entity/AdTrackEventViewsData.php b/modules/ad_track/src/Entity/AdTrackEventViewsData.php
index ee09846..40231fa 100644
--- a/modules/ad_track/src/Entity/AdTrackEventViewsData.php
+++ b/modules/ad_track/src/Entity/AdTrackEventViewsData.php
@@ -18,7 +18,7 @@ class AdTrackEventViewsData extends EntityViewsData {
 
     if ($this->moduleHandler->moduleExists('ad_content')) {
       $data['ad_track_event']['ad_id']['relationship'] = [
-        'label' => new TranslatableMarkup('Content ad'),
+        'label' => new TranslatableMarkup('Advertisement'),
         'base' => 'ad_content',
         'base field' => 'uuid',
         'id' => 'standard',
diff --git a/modules/ad_track/src/TotalSqlStorage.php b/modules/ad_track/src/TotalSqlStorage.php
index 25d53d6..f9a41ad 100644
--- a/modules/ad_track/src/TotalSqlStorage.php
+++ b/modules/ad_track/src/TotalSqlStorage.php
@@ -101,7 +101,7 @@ class TotalSqlStorage implements TotalStorageInterface {
       $this->transactions[$id] = $this->database->startTransaction($id);
     }
     else {
-      $message = sprintf('A transaction already exists for ad %s', $id);
+      $message = sprintf('A transaction already exists for advertisement %s', $id);
       throw new \InvalidArgumentException($message);
     }
   }
diff --git a/src/Bucket/BucketFactory.php b/src/Bucket/BucketFactory.php
index 20de670..d39a7bd 100644
--- a/src/Bucket/BucketFactory.php
+++ b/src/Bucket/BucketFactory.php
@@ -67,7 +67,7 @@ class BucketFactory extends AdFactoryBase implements BucketFactoryInterface {
     }
     catch (PluginException $e) {
     }
-    throw new \LogicException('No valid ad bucket found.');
+    throw new \LogicException('No valid advertisement bucket found.');
   }
 
 }
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index 355c699..2c09347 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -92,7 +92,7 @@ class SettingsForm extends ConfigFormBase {
     $form['trackers'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Tracker configuration'),
-      '#description' => $this->t('Assign an ad statistics tracker for each ad source.'),
+      '#description' => $this->t('Assign an advertisement statistics tracker for each advertisement source.'),
       '#tree' => TRUE,
     ];
 
@@ -102,7 +102,7 @@ class SettingsForm extends ConfigFormBase {
           ->toString(TRUE)
           ->getGeneratedUrl(),
       ];
-      $form['trackers']['#description'] = $this->t('You need to <a href="@url">enable</a> at least one ad source and one ad statistics tracker engine.', $args);
+      $form['trackers']['#description'] = $this->t('You need to <a href="@url">enable</a> at least one advertisement source and one advertisement statistics tracker engine.', $args);
     }
 
     foreach ($buckets as $id => $label) {
@@ -118,7 +118,7 @@ class SettingsForm extends ConfigFormBase {
     $form['advertisement_indicator'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Advertisement indicator'),
-      '#description' => $this->t('In many countries it is mandatory to label ads as being such. This setting adds a small print (e.g. "Advertisement") to all ad blocks.'),
+      '#description' => $this->t('In many countries it is mandatory to label advertisements as being such. This setting adds a small print (e.g. "Advertisement") to all advertisement blocks.'),
       '#default_value' => $config->get('advertisement_indicator') ?? '',
     ];
 
-- 
GitLab


From 9571293b9e350baec7a853a53baf6f39b2ba5ce2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Wed, 14 May 2025 15:15:42 +0200
Subject: [PATCH 38/46] Updating README according to Drupal template

---
 README.md | 69 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 48 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index fcf838d..6c2e2b0 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,57 @@
-# Summary
+# Advertisement
 
-This module provides a flexible and extensible advertising system allowing
-display ads via blocks.
+The Advertisement module provides a flexible and extensible advertising system
+allowing to display ads via the block layout.
 
-This ad system supports enabling multiple ad sources and tracking systems: by
-default both ad data and ad tracking data are stored in the local database, but
-alternative ad sources or trackers can be provided via plugins. For instance a
-module could define a plugin to track ad events via Google Analytics.
+The advertisement system is built dynamically so that both content providers
+(advertisement buckets) and statistics trackers can be extended by custom
+modules via the plugin API. A native provider and tracker are also provided as
+submodules.
 
-The native `Ad Tracker` module implements two trackers:
-- The `Local ad event tracker` tracks impressions/clicks immediately, which on
-  high traffic sites can result in significant additional load for the web
-  servers.
-- The `Queue-based local ad event tracker` tracks data via a queue, so events
-  will only actually appear in the statistics display section after running
-  cron or after manually processing `ad_track_queue`.
+The native tracker module implements two trackers:
+- The *"Local advertisement event tracker"* tracks impressions/clicks
+immediately, which on high traffic sites can result in significant additional
+load for the web servers.
+- The *"Queue-based local advertisement event tracker"* tracks data via a queue,
+so events will only actually appear in the statistics display section after
+running cron or after manually processing `ad_track_queue`.
 
+For a full description of the module, visit the
+[project page](https://www.drupal.org/project/ad).
 
-# Installation
+Submit bug reports and feature suggestions, or track changes in the
+[issue queue](https://www.drupal.org/project/issues/ad).
 
-Enable the main `Ad` module, together with at least one ad source and one
-tracker, typically the `Advertisement` and `Ad Tracker` modules.
 
+## Requirements
 
-# Usage
+This module requires the following modules:
 
-- After enabling all the required modules, configure a tracker for every enabled
-ad source at `/admin/config/ad`.
-- Place one or more ad blocks as needed.
+- [**Scheduler**](https://www.drupal.org/project/scheduler) - Required when
+using the *"Advertisement scheduler"* submodule.
+
+
+## Installation
+
+Install as you would normally install a contributed Drupal module. For further
+information, see
+[Installing Drupal Modules](https://www.drupal.org/docs/extending-drupal/installing-drupal-modules).
+
+
+## Configuration
+
+After the installation, you need to install an advertisement content provider
+(e.g., the *"Advertisement content"* submodule) in order for the system to work.
+
+If you install the native *"Advertisement track"* tracker module, the tracker
+will work out of the box. In case you want to install a custom statistics
+tracker, perform the following steps to enable it:
+
+1. Go to *Configuration » Content authoring » Advertisement settings*.
+1. Select the tracker that you want to use for each advertisement content
+provider that you installed (the native tracker module will enable itself
+automatically here).
+
+After that, you can place one or more advertisement blocks in your block layout,
+which will then display the randomly chosen ads. *In order for ads to be shown
+in a block, their selected size must match that of the block!*
-- 
GitLab


From 252c696f51bd4e4033237035b04c80d8e93b88a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 16:15:10 +0200
Subject: [PATCH 39/46] Continuing work on scheduler submodule

---
 ...ystem.action.ad_content_publish_action.yml |   9 ++
 ...tem.action.ad_content_unpublish_action.yml |   9 ++
 .../src/Event/SchedulerAdContentEvents.php    | 100 ++++++++++++++++++
 3 files changed, 118 insertions(+)
 create mode 100644 modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
 create mode 100644 modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml
 create mode 100644 modules/ad_scheduler/src/Event/SchedulerAdContentEvents.php

diff --git a/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml b/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
new file mode 100644
index 0000000..ad0f0af
--- /dev/null
+++ b/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
@@ -0,0 +1,9 @@
+status: true
+dependencies:
+  module:
+    - ad_scheduler
+id: ad_content_publish_action
+label: 'Publish advertisement'
+type: ad_content
+plugin: entity:publish_action:ad_content
+configuration: {  }
diff --git a/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml b/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml
new file mode 100644
index 0000000..209105a
--- /dev/null
+++ b/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml
@@ -0,0 +1,9 @@
+status: true
+dependencies:
+  module:
+    - ad_scheduler
+id: ad_content_unpublish_action
+label: 'Unpublish advertisement'
+type: ad_content
+plugin: entity:unpublish_action:ad_content
+configuration: {  }
diff --git a/modules/ad_scheduler/src/Event/SchedulerAdContentEvents.php b/modules/ad_scheduler/src/Event/SchedulerAdContentEvents.php
new file mode 100644
index 0000000..679f518
--- /dev/null
+++ b/modules/ad_scheduler/src/Event/SchedulerAdContentEvents.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Drupal\ad_scheduler\Event;
+
+/**
+ * Lists the six events dispatched by Scheduler relating to ad content entities.
+ *
+ * The event names here are the original six, when only ad contents were
+ * supported. See SchedulerTaxonomyTermEvents for the generic naming convention
+ * to follow for any new entity plugin implementations.
+ */
+final class SchedulerAdContentEvents {
+
+  /**
+   * The event triggered after an ad content is published immediately.
+   *
+   * This event allows modules to react after an entity is published
+   * immediately when being saved after editing. The event listener method
+   * receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const PUBLISH_IMMEDIATELY = 'scheduler.publish_immediately';
+
+  /**
+   * The event triggered after an ad content is published by cron.
+   *
+   * This event allows modules to react after an entity is published by Cron.
+   * The event listener receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const PUBLISH = 'scheduler.publish';
+
+  /**
+   * The event triggered before an ad content is published immediately.
+   *
+   * This event allows modules to react before an entity is published
+   * immediately when being saved after editing. The event listener method
+   * receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const PRE_PUBLISH_IMMEDIATELY = 'scheduler.pre_publish_immediately';
+
+  /**
+   * The event triggered before an ad content is published by cron.
+   *
+   * This event allows modules to react before an entity is published by Cron.
+   * The event listener receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const PRE_PUBLISH = 'scheduler.pre_publish';
+
+  /**
+   * The event triggered before an ad content is unpublished by cron.
+   *
+   * This event allows modules to react before an entity is unpublished by Cron.
+   * The event listener receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const PRE_UNPUBLISH = 'scheduler.pre_unpublish';
+
+  /**
+   * The event triggered after an ad content is unpublished by cron.
+   *
+   * This event allows modules to react after an entity is unpublished by Cron.
+   * The event listener receives a \Drupal\Core\Entity\EntityInterface instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\scheduler\Event\SchedulerEvent
+   *
+   * @var string
+   */
+  const UNPUBLISH = 'scheduler.unpublish';
+
+}
-- 
GitLab


From 890d3106e97e716b30e059587f2e30fdbe9590cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 17:03:29 +0200
Subject: [PATCH 40/46] Fixing pipeline

---
 ad.services.yml                               |  3 +-
 config/install/ad.settings.yml                |  1 +
 .../ad_content.ad_content_type.image_ad.yml   |  2 +-
 ..._content.ad_content_type.javascript_ad.yml |  2 +-
 .../ad_content.ad_content_type.text_ad.yml    |  2 +-
 ...rm_display.ad_content.image_ad.default.yml | 22 ++---
 ...splay.ad_content.javascript_ad.default.yml | 22 ++---
 ...orm_display.ad_content.text_ad.default.yml | 22 ++---
 ...view_display.ad_content.image_ad.admin.yml | 24 +++---
 ...ew_display.ad_content.image_ad.default.yml |  4 +-
 ...display.ad_content.javascript_ad.admin.yml | 26 +++---
 ...splay.ad_content.javascript_ad.default.yml |  2 +-
 ..._view_display.ad_content.text_ad.admin.yml | 26 +++---
 ...iew_display.ad_content.text_ad.default.yml |  4 +-
 ...eld.ad_content.image_ad.field_ad_image.yml |  4 +-
 ...content.javascript_ad.field_javascript.yml |  4 +-
 ...field.ad_content.text_ad.field_ad_text.yml |  4 +-
 ...ield.storage.ad_content.field_ad_image.yml |  2 +-
 ...field.storage.ad_content.field_ad_text.yml |  4 +-
 ...ld.storage.ad_content.field_javascript.yml |  4 +-
 .../optional/image.style.mini_thumbnail.yml   |  2 +-
 .../optional/views.view.ad_statistics.yml     | 84 +++++++++----------
 modules/ad_content/js/ad-content.render.js    | 37 ++++----
 ...ystem.action.ad_content_publish_action.yml |  9 --
 ...tem.action.ad_content_unpublish_action.yml |  9 --
 25 files changed, 152 insertions(+), 173 deletions(-)
 delete mode 100644 modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
 delete mode 100644 modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml

diff --git a/ad.services.yml b/ad.services.yml
index 8aaab9e..2a92575 100644
--- a/ad.services.yml
+++ b/ad.services.yml
@@ -1,7 +1,8 @@
 services:
   ad.bucket_factory:
     class: Drupal\ad\Bucket\BucketFactory
-    arguments: ['@ad.bucket_plugin_manager', '@config.factory', '@request_stack']
+    arguments:
+      ['@ad.bucket_plugin_manager', '@config.factory', '@request_stack']
   ad.bucket_plugin_manager:
     class: Drupal\ad\Bucket\BucketPluginManager
     arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
diff --git a/config/install/ad.settings.yml b/config/install/ad.settings.yml
index bfa9358..c7b13c5 100644
--- a/config/install/ad.settings.yml
+++ b/config/install/ad.settings.yml
@@ -1 +1,2 @@
+trackers: {}
 advertisement_indicator: 'Advertisement'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
index 19283d6..bc11c00 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.image_ad.yml
@@ -1,6 +1,6 @@
 langcode: en
 status: true
-dependencies: {  }
+dependencies: {}
 id: image_ad
 label: 'Image advertisement'
 description: 'An advertisement that contains an image.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
index a482cb5..e1b2916 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.javascript_ad.yml
@@ -1,6 +1,6 @@
 langcode: en
 status: true
-dependencies: {  }
+dependencies: {}
 id: javascript_ad
 label: 'JavaScript advertisement'
 description: 'An advertisement that contains JavaScript.'
diff --git a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
index da02515..5fab9f6 100644
--- a/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
+++ b/modules/ad_content/config/install/ad_content.ad_content_type.text_ad.yml
@@ -1,6 +1,6 @@
 langcode: en
 status: true
-dependencies: {  }
+dependencies: {}
 id: text_ad
 label: 'Text advertisement'
 description: 'An advertisement that contains text.'
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
index 17b81bc..9e61761 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.image_ad.default.yml
@@ -17,8 +17,8 @@ content:
     type: datetime_timestamp
     weight: 6
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   field_ad_image:
     type: image_image
     weight: 2
@@ -26,27 +26,27 @@ content:
     settings:
       progress_indicator: throbber
       preview_image_style: thumbnail
-    third_party_settings: {  }
+    third_party_settings: {}
   langcode:
     type: language_select
     weight: 4
     region: content
     settings:
       include_locked: true
-    third_party_settings: {  }
+    third_party_settings: {}
   size:
     type: options_select
     weight: 1
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   status:
     type: boolean_checkbox
     weight: 7
     region: content
     settings:
       display_label: true
-    third_party_settings: {  }
+    third_party_settings: {}
   target_url:
     type: link_default
     weight: 3
@@ -54,7 +54,7 @@ content:
     settings:
       placeholder_url: ''
       placeholder_title: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   title:
     type: string_textfield
     weight: 0
@@ -62,7 +62,7 @@ content:
     settings:
       size: 60
       placeholder: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   uid:
     type: entity_reference_autocomplete
     weight: 5
@@ -72,5 +72,5 @@ content:
       match_limit: 10
       size: 60
       placeholder: ''
-    third_party_settings: {  }
-hidden: {  }
+    third_party_settings: {}
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
index 290c56e..c4a23dd 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.javascript_ad.default.yml
@@ -16,8 +16,8 @@ content:
     type: datetime_timestamp
     weight: 6
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   field_javascript:
     type: text_textarea
     weight: 2
@@ -25,27 +25,27 @@ content:
     settings:
       rows: 5
       placeholder: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   langcode:
     type: language_select
     weight: 4
     region: content
     settings:
       include_locked: true
-    third_party_settings: {  }
+    third_party_settings: {}
   size:
     type: options_select
     weight: 1
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   status:
     type: boolean_checkbox
     weight: 7
     region: content
     settings:
       display_label: true
-    third_party_settings: {  }
+    third_party_settings: {}
   target_url:
     type: link_default
     weight: 3
@@ -53,7 +53,7 @@ content:
     settings:
       placeholder_url: ''
       placeholder_title: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   title:
     type: string_textfield
     weight: 0
@@ -61,7 +61,7 @@ content:
     settings:
       size: 60
       placeholder: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   uid:
     type: entity_reference_autocomplete
     weight: 5
@@ -71,5 +71,5 @@ content:
       match_limit: 10
       size: 60
       placeholder: ''
-    third_party_settings: {  }
-hidden: {  }
+    third_party_settings: {}
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
index 07dc9b2..c5bb8bc 100644
--- a/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_form_display.ad_content.text_ad.default.yml
@@ -16,8 +16,8 @@ content:
     type: datetime_timestamp
     weight: 6
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   field_ad_text:
     type: text_textarea_with_summary
     weight: 2
@@ -27,27 +27,27 @@ content:
       summary_rows: 3
       placeholder: ''
       show_summary: false
-    third_party_settings: {  }
+    third_party_settings: {}
   langcode:
     type: language_select
     weight: 4
     region: content
     settings:
       include_locked: true
-    third_party_settings: {  }
+    third_party_settings: {}
   size:
     type: options_select
     weight: 1
     region: content
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
   status:
     type: boolean_checkbox
     weight: 7
     region: content
     settings:
       display_label: true
-    third_party_settings: {  }
+    third_party_settings: {}
   target_url:
     type: link_default
     weight: 3
@@ -55,7 +55,7 @@ content:
     settings:
       placeholder_url: ''
       placeholder_title: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   title:
     type: string_textfield
     weight: 0
@@ -63,7 +63,7 @@ content:
     settings:
       size: 60
       placeholder: ''
-    third_party_settings: {  }
+    third_party_settings: {}
   uid:
     type: entity_reference_autocomplete
     weight: 5
@@ -73,5 +73,5 @@ content:
       match_limit: 10
       size: 60
       placeholder: ''
-    third_party_settings: {  }
-hidden: {  }
+    third_party_settings: {}
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
index e49d393..5d72257 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.admin.yml
@@ -30,7 +30,7 @@ content:
         past_format: '@interval ago'
         granularity: 2
         refresh: 60
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 4
     region: content
   field_ad_image:
@@ -41,7 +41,7 @@ content:
       image_style: ''
       image_loading:
         attribute: lazy
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 9
     region: content
   langcode:
@@ -50,14 +50,14 @@ content:
     settings:
       link_to_entity: false
       native_language: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 1
     region: content
   size:
     type: list_default
     label: above
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 2
     region: content
   status:
@@ -67,7 +67,7 @@ content:
       format: default
       format_custom_false: ''
       format_custom_true: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 5
     region: content
   target_url:
@@ -79,7 +79,7 @@ content:
       url_plain: false
       rel: ''
       target: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 8
     region: content
   title:
@@ -87,7 +87,7 @@ content:
     label: hidden
     settings:
       link_to_entity: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 0
     region: content
   total_click:
@@ -96,7 +96,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 7
     region: content
   total_impression:
@@ -105,7 +105,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 6
     region: content
   uid:
@@ -113,7 +113,7 @@ content:
     label: above
     settings:
       link: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 3
     region: content
-hidden: {  }
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
index 430ad02..3fe9319 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.image_ad.default.yml
@@ -14,8 +14,8 @@ content:
   field_ad_image:
     type: ad_content_image
     label: hidden
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 0
     region: content
 hidden:
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
index 7138b65..89fea2c 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.admin.yml
@@ -30,14 +30,14 @@ content:
         past_format: '@interval ago'
         granularity: 2
         refresh: 60
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 4
     region: content
   field_javascript:
     type: text_default
     label: above
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 9
     region: content
   langcode:
@@ -46,14 +46,14 @@ content:
     settings:
       link_to_entity: false
       native_language: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 1
     region: content
   size:
     type: list_default
     label: above
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 2
     region: content
   status:
@@ -63,7 +63,7 @@ content:
       format: default
       format_custom_false: ''
       format_custom_true: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 5
     region: content
   target_url:
@@ -75,7 +75,7 @@ content:
       url_plain: false
       rel: ''
       target: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 8
     region: content
   title:
@@ -83,7 +83,7 @@ content:
     label: hidden
     settings:
       link_to_entity: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 0
     region: content
   total_click:
@@ -92,7 +92,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 7
     region: content
   total_impression:
@@ -101,7 +101,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 6
     region: content
   uid:
@@ -109,7 +109,7 @@ content:
     label: above
     settings:
       link: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 3
     region: content
-hidden: {  }
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
index 57c9bde..afeb2f1 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.javascript_ad.default.yml
@@ -8,7 +8,7 @@ id: ad_content.javascript_ad.default
 targetEntityType: ad_content
 bundle: javascript_ad
 mode: default
-content: {  }
+content: {}
 hidden:
   created: true
   field_javascript: true
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
index 322123b..bbf9c5d 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.admin.yml
@@ -30,14 +30,14 @@ content:
         past_format: '@interval ago'
         granularity: 2
         refresh: 60
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 4
     region: content
   field_ad_text:
     type: text_default
     label: above
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 9
     region: content
   langcode:
@@ -46,14 +46,14 @@ content:
     settings:
       link_to_entity: false
       native_language: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 1
     region: content
   size:
     type: list_default
     label: above
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 2
     region: content
   status:
@@ -63,7 +63,7 @@ content:
       format: default
       format_custom_false: ''
       format_custom_true: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 5
     region: content
   target_url:
@@ -75,7 +75,7 @@ content:
       url_plain: false
       rel: ''
       target: ''
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 8
     region: content
   title:
@@ -83,7 +83,7 @@ content:
     label: hidden
     settings:
       link_to_entity: false
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 0
     region: content
   total_click:
@@ -92,7 +92,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 7
     region: content
   total_impression:
@@ -101,7 +101,7 @@ content:
     settings:
       thousand_separator: ''
       prefix_suffix: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 6
     region: content
   uid:
@@ -109,7 +109,7 @@ content:
     label: above
     settings:
       link: true
-    third_party_settings: {  }
+    third_party_settings: {}
     weight: 3
     region: content
-hidden: {  }
+hidden: {}
diff --git a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
index 69cf536..a0b8998 100644
--- a/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
+++ b/modules/ad_content/config/install/core.entity_view_display.ad_content.text_ad.default.yml
@@ -14,8 +14,8 @@ content:
   field_ad_text:
     type: text_default
     label: hidden
-    settings: {  }
-    third_party_settings: {  }
+    settings: {}
+    third_party_settings: {}
     weight: 0
     region: content
 hidden:
diff --git a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
index fda7c6d..d1a6952 100644
--- a/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.image_ad.field_ad_image.yml
@@ -14,11 +14,11 @@ label: 'Advertisement image'
 description: 'The image that the advertisement should display.'
 required: true
 translatable: false
-default_value: {  }
+default_value: {}
 default_value_callback: ''
 settings:
   handler: 'default:file'
-  handler_settings: {  }
+  handler_settings: {}
   file_directory: '[date:custom:Y]-[date:custom:m]'
   file_extensions: 'png gif jpg jpeg webp'
   max_filesize: ''
diff --git a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
index 8111be2..5097be2 100644
--- a/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.javascript_ad.field_javascript.yml
@@ -14,8 +14,8 @@ label: 'JavaScript code'
 description: 'The JavaScript code that the advertisement should run in order to display.'
 required: true
 translatable: false
-default_value: {  }
+default_value: {}
 default_value_callback: ''
 settings:
-  allowed_formats: {  }
+  allowed_formats: {}
 field_type: text_long
diff --git a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
index cd88f8e..b96a63d 100644
--- a/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.field.ad_content.text_ad.field_ad_text.yml
@@ -14,10 +14,10 @@ label: 'Advertisement text'
 description: 'The text that the advertisement should display.'
 required: true
 translatable: false
-default_value: {  }
+default_value: {}
 default_value_callback: ''
 settings:
   display_summary: true
   required_summary: false
-  allowed_formats: {  }
+  allowed_formats: {}
 field_type: text_with_summary
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
index 8ae34c9..062d74f 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_image.yml
@@ -24,6 +24,6 @@ module: image
 locked: false
 cardinality: 1
 translatable: true
-indexes: {  }
+indexes: {}
 persist_with_no_fields: false
 custom_storage: false
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
index c2fed7c..3ba0fe6 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_ad_text.yml
@@ -8,11 +8,11 @@ id: ad_content.field_ad_text
 field_name: field_ad_text
 entity_type: ad_content
 type: text_with_summary
-settings: {  }
+settings: {}
 module: text
 locked: false
 cardinality: 1
 translatable: true
-indexes: {  }
+indexes: {}
 persist_with_no_fields: false
 custom_storage: false
diff --git a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
index f88394a..63da3f8 100644
--- a/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
+++ b/modules/ad_content/config/install/field.storage.ad_content.field_javascript.yml
@@ -8,11 +8,11 @@ id: ad_content.field_javascript
 field_name: field_javascript
 entity_type: ad_content
 type: text_long
-settings: {  }
+settings: {}
 module: text
 locked: false
 cardinality: 1
 translatable: true
-indexes: {  }
+indexes: {}
 persist_with_no_fields: false
 custom_storage: false
diff --git a/modules/ad_content/config/optional/image.style.mini_thumbnail.yml b/modules/ad_content/config/optional/image.style.mini_thumbnail.yml
index 4b9334c..035d947 100644
--- a/modules/ad_content/config/optional/image.style.mini_thumbnail.yml
+++ b/modules/ad_content/config/optional/image.style.mini_thumbnail.yml
@@ -1,6 +1,6 @@
 langcode: en
 status: true
-dependencies: {  }
+dependencies: {}
 name: mini_thumbnail
 label: 'Mini thumbnail'
 effects:
diff --git a/modules/ad_content/config/optional/views.view.ad_statistics.yml b/modules/ad_content/config/optional/views.view.ad_statistics.yml
index 4857626..5f438f4 100644
--- a/modules/ad_content/config/optional/views.view.ad_statistics.yml
+++ b/modules/ad_content/config/optional/views.view.ad_statistics.yml
@@ -20,10 +20,10 @@ display:
     display_options:
       access:
         type: none
-        options: {  }
+        options: {}
       cache:
         type: tag
-        options: {  }
+        options: {}
       query:
         type: views_query
         options:
@@ -31,7 +31,7 @@ display:
           distinct: false
           replica: false
           query_comment: ''
-          query_tags: {  }
+          query_tags: {}
       exposed_form:
         type: basic
         options:
@@ -66,7 +66,7 @@ display:
       style:
         type: table
         options:
-          grouping: {  }
+          grouping: {}
           row_class: ''
           default_row_class: true
           override: true
@@ -215,7 +215,7 @@ display:
             thousand_separator: ''
             prefix_suffix: true
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -280,7 +280,7 @@ display:
           settings:
             link_to_entity: false
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -345,7 +345,7 @@ display:
           settings:
             link_to_entity: false
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -411,7 +411,7 @@ display:
             thousand_separator: ''
             prefix_suffix: true
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -476,7 +476,7 @@ display:
           settings:
             link_to_entity: false
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -541,7 +541,7 @@ display:
           settings:
             link: true
           group_column: target_id
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -603,9 +603,9 @@ display:
           hide_alter_empty: true
           click_sort_column: value
           type: basic_string
-          settings: {  }
+          settings: {}
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -670,7 +670,7 @@ display:
           settings:
             link_to_entity: false
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -732,9 +732,9 @@ display:
           hide_alter_empty: true
           click_sort_column: value
           type: basic_string
-          settings: {  }
+          settings: {}
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -796,9 +796,9 @@ display:
           hide_alter_empty: true
           click_sort_column: value
           type: basic_string
-          settings: {  }
+          settings: {}
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -865,7 +865,7 @@ display:
             custom_date_format: ''
             timezone: ''
           group_column: value
-          group_columns: {  }
+          group_columns: {}
           group_rows: true
           delta_limit: 0
           delta_offset: 0
@@ -896,7 +896,7 @@ display:
             use_operator: false
             operator: type_op
             operator_limit_selection: false
-            operator_list: {  }
+            operator_list: {}
             identifier: type
             required: false
             remember: false
@@ -917,8 +917,8 @@ display:
             multiple: false
             remember: false
             default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
+            default_group_multiple: {}
+            group_items: {}
           entity_type: ad_track_event
           entity_field: type
           plugin_id: string
@@ -940,7 +940,7 @@ display:
             use_operator: false
             operator: user_agent_op
             operator_limit_selection: false
-            operator_list: {  }
+            operator_list: {}
             identifier: user_agent
             required: false
             remember: false
@@ -961,8 +961,8 @@ display:
             multiple: false
             remember: false
             default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
+            default_group_multiple: {}
+            group_items: {}
           entity_type: ad_track_event
           entity_field: user_agent
           plugin_id: string
@@ -984,7 +984,7 @@ display:
             use_operator: false
             operator: ip_address_op
             operator_limit_selection: false
-            operator_list: {  }
+            operator_list: {}
             identifier: ip_address
             required: false
             remember: false
@@ -1005,8 +1005,8 @@ display:
             multiple: false
             remember: false
             default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
+            default_group_multiple: {}
+            group_items: {}
           entity_type: ad_track_event
           entity_field: ip_address
           plugin_id: string
@@ -1028,7 +1028,7 @@ display:
             use_operator: false
             operator: page_title_op
             operator_limit_selection: false
-            operator_list: {  }
+            operator_list: {}
             identifier: page_title
             required: false
             remember: false
@@ -1049,8 +1049,8 @@ display:
             multiple: false
             remember: false
             default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
+            default_group_multiple: {}
+            group_items: {}
           entity_type: ad_track_event
           entity_field: page_title
           plugin_id: string
@@ -1072,7 +1072,7 @@ display:
             use_operator: false
             operator: url_op
             operator_limit_selection: false
-            operator_list: {  }
+            operator_list: {}
             identifier: url
             required: false
             remember: false
@@ -1093,16 +1093,16 @@ display:
             multiple: false
             remember: false
             default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
+            default_group_multiple: {}
+            group_items: {}
           entity_type: ad_track_event
           entity_field: url
           plugin_id: string
-      sorts: {  }
+      sorts: {}
       title: 'Advertisement statistics'
-      header: {  }
-      footer: {  }
-      empty: {  }
+      header: {}
+      footer: {}
+      empty: {}
       relationships:
         ad_id:
           id: ad_id
@@ -1149,13 +1149,13 @@ display:
             access: true
             operation: update
             multiple: 0
-            bundles: {  }
+            bundles: {}
           break_phrase: false
           not: false
           entity_type: ad_content
           entity_field: id
           plugin_id: numeric
-      display_extenders: {  }
+      display_extenders: {}
       use_ajax: true
     cache_metadata:
       max-age: -1
@@ -1164,14 +1164,14 @@ display:
         - 'languages:language_interface'
         - url
         - url.query_args
-      tags: {  }
+      tags: {}
   page:
     display_plugin: page
     id: page
     display_title: Page
     position: 1
     display_options:
-      display_extenders: {  }
+      display_extenders: {}
       path: admin/content/ad/statistics
     cache_metadata:
       max-age: -1
@@ -1180,4 +1180,4 @@ display:
         - 'languages:language_interface'
         - url
         - url.query_args
-      tags: {  }
+      tags: {}
diff --git a/modules/ad_content/js/ad-content.render.js b/modules/ad_content/js/ad-content.render.js
index 3d7903a..2c55e09 100644
--- a/modules/ad_content/js/ad-content.render.js
+++ b/modules/ad_content/js/ad-content.render.js
@@ -1,19 +1,16 @@
 (function (document, $, Drupal, once) {
-
   Drupal.behaviors.ad = {
+    attach(context, settings) {
+      const query = { ads: {} };
 
-    attach: function (context, settings) {
-      var query = { ads: {} };
-
-      $(once('ad-content', 'ad-content', context))
-        .each(function () {
-          var $placeholder = $(this);
-          query.ads[$placeholder.attr('id')] = {
-            size: $placeholder.attr('size'),
-            bucket: $placeholder.attr('bucket'),
-            arguments: $placeholder.attr('arguments') || {}
-          };
-        });
+      $(once('ad-content', 'ad-content', context)).each(function () {
+        const $placeholder = $(this);
+        query.ads[$placeholder.attr('id')] = {
+          size: $placeholder.attr('size'),
+          bucket: $placeholder.attr('bucket'),
+          arguments: $placeholder.attr('arguments') || {},
+        };
+      });
 
       if (Object.keys(query.ads).length > 0) {
         query.uid = settings.user.uid;
@@ -21,22 +18,20 @@
         query.page_title = document.title;
         query.referrer = document.referrer;
 
-        var url = Drupal.url('ad/content/render');
+        const url = Drupal.url('ad/content/render');
         $.get(
           url,
           query,
           function (responseData) {
-            for (var id in responseData) {
+            Object.values(responseData).forEach((id) => {
               if (responseData.hasOwnProperty(id)) {
-                $('#' + id).html(responseData[id]);
+                $(`#${id}`).html(responseData[id]);
               }
-            }
+            });
           },
-          'json'
+          'json',
         );
       }
-    }
-
+    },
   };
-
 })(document, jQuery, Drupal, once);
diff --git a/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml b/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
deleted file mode 100644
index ad0f0af..0000000
--- a/modules/ad_scheduler/config/install/system.action.ad_content_publish_action.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-status: true
-dependencies:
-  module:
-    - ad_scheduler
-id: ad_content_publish_action
-label: 'Publish advertisement'
-type: ad_content
-plugin: entity:publish_action:ad_content
-configuration: {  }
diff --git a/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml b/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml
deleted file mode 100644
index 209105a..0000000
--- a/modules/ad_scheduler/config/install/system.action.ad_content_unpublish_action.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-status: true
-dependencies:
-  module:
-    - ad_scheduler
-id: ad_content_unpublish_action
-label: 'Unpublish advertisement'
-type: ad_content
-plugin: entity:unpublish_action:ad_content
-configuration: {  }
-- 
GitLab


From 9e257f33d7d6c730aad10386c732b28b8d7c4c4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 17:08:19 +0200
Subject: [PATCH 41/46] Adding composer.json

---
 composer.json | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 composer.json

diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..5184aba
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,16 @@
+{
+  "name": "drupal/ad",
+  "type": "drupal-module",
+  "description": "A flexible and extensible advertising system.",
+  "keywords": ["Drupal"],
+  "license": "GPL-2.0-or-later",
+  "homepage": "https://www.drupal.org/project/ad",
+  "support": {
+      "issues": "https://www.drupal.org/project/issues/ad",
+      "source": "http://cgit.drupalcode.org/ad"
+  },
+  "require": {
+    "drupal/ad": "*",
+    "drupal/scheduler": "*"
+  }
+}
-- 
GitLab


From c845f3e25f1861bc1c9fd58409b18597c14722b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 17:19:20 +0200
Subject: [PATCH 42/46] Updating composer.json

---
 composer.json | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/composer.json b/composer.json
index 5184aba..7602010 100644
--- a/composer.json
+++ b/composer.json
@@ -7,10 +7,9 @@
   "homepage": "https://www.drupal.org/project/ad",
   "support": {
       "issues": "https://www.drupal.org/project/issues/ad",
-      "source": "http://cgit.drupalcode.org/ad"
+      "source": "https://cgit.drupalcode.org/ad"
   },
   "require": {
-    "drupal/ad": "*",
     "drupal/scheduler": "*"
   }
 }
-- 
GitLab


From 1ffe7891cd7547024ca3d49a3bb9527a9c385cc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 17:28:03 +0200
Subject: [PATCH 43/46] Changing ad_scheduler plugin attribute to annotation

---
 .../Plugin/Scheduler/AdContentScheduler.php   | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
index 26dfcfe..3f0d6ba 100644
--- a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
+++ b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
@@ -3,18 +3,19 @@
 namespace Drupal\ad_scheduler\Plugin\Scheduler;
 
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
-use Drupal\scheduler\Annotation\SchedulerPlugin;
 use Drupal\scheduler\SchedulerPluginBase;
 
 /**
  * Advertisement plugin for the scheduler module.
+ *
+ * @package Drupal\ad_scheduler\Plugin\Scheduler
+ *
+ * @SchedulerPlugin(
+ *  id = 'ad_content_scheduler',
+ *  label = @Translation('Advertisement scheduler plugin'),
+ *  description = @Translation('Support for scheduling advertisement entities'),
+ *  entityType = 'ad_content',
+ *  dependency = 'ad_content',
+ * )
  */
-#[SchedulerPlugin(
-  id: 'ad_content_scheduler',
-  label: new TranslatableMarkup('Advertisement scheduler plugin'),
-  description: new TranslatableMarkup('Support for scheduling advertisement entities'),
-  entityType: 'ad_content',
-  dependency: 'ad_content',
-)]
 class AdContentScheduler extends SchedulerPluginBase implements ContainerFactoryPluginInterface {}
-- 
GitLab


From e9ea1ecc857fcc3b132f6ff1f77126e6a260e6b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leon=20R=C3=B6themeyer?= <lr@webks.de>
Date: Tue, 20 May 2025 17:32:07 +0200
Subject: [PATCH 44/46] Fixes

---
 .../src/Plugin/Scheduler/AdContentScheduler.php        | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
index 3f0d6ba..919f838 100644
--- a/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
+++ b/modules/ad_scheduler/src/Plugin/Scheduler/AdContentScheduler.php
@@ -11,11 +11,11 @@ use Drupal\scheduler\SchedulerPluginBase;
  * @package Drupal\ad_scheduler\Plugin\Scheduler
  *
  * @SchedulerPlugin(
- *  id = 'ad_content_scheduler',
- *  label = @Translation('Advertisement scheduler plugin'),
- *  description = @Translation('Support for scheduling advertisement entities'),
- *  entityType = 'ad_content',
- *  dependency = 'ad_content',
+ *  id = "ad_content_scheduler",
+ *  label = @Translation("Advertisement scheduler plugin"),
+ *  description = @Translation("Support for scheduling advertisement entities"),
+ *  entityType = "ad_content",
+ *  dependency = "ad_content",
  * )
  */
 class AdContentScheduler extends SchedulerPluginBase implements ContainerFactoryPluginInterface {}
-- 
GitLab


From 6b172d8229f3f348ac91c63473152dce76348391 Mon Sep 17 00:00:00 2001
From: Grevil <js@webks.de>
Date: Wed, 21 May 2025 12:22:26 +0200
Subject: [PATCH 45/46] Add permission granularity

---
 modules/ad_content/src/Entity/AdContent.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/ad_content/src/Entity/AdContent.php b/modules/ad_content/src/Entity/AdContent.php
index e2d67d6..0862289 100644
--- a/modules/ad_content/src/Entity/AdContent.php
+++ b/modules/ad_content/src/Entity/AdContent.php
@@ -49,6 +49,7 @@ use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
   base_table: 'ad_content',
   data_table: 'ad_content_field_data',
   revision_table: 'ad_content_revision',
+  permission_granularity: 'bundle',
   admin_permission: 'administer ads',
   bundle_entity_type: 'ad_content_type',
   bundle_label: new TranslatableMarkup('Advertisement type'),
-- 
GitLab


From 0152613203e9812bdcc47e799dac7cace753cf06 Mon Sep 17 00:00:00 2001
From: Grevil <js@webks.de>
Date: Wed, 21 May 2025 13:03:40 +0200
Subject: [PATCH 46/46] remove composer.json

---
 composer.json | 15 ---------------
 1 file changed, 15 deletions(-)
 delete mode 100644 composer.json

diff --git a/composer.json b/composer.json
deleted file mode 100644
index 7602010..0000000
--- a/composer.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "drupal/ad",
-  "type": "drupal-module",
-  "description": "A flexible and extensible advertising system.",
-  "keywords": ["Drupal"],
-  "license": "GPL-2.0-or-later",
-  "homepage": "https://www.drupal.org/project/ad",
-  "support": {
-      "issues": "https://www.drupal.org/project/issues/ad",
-      "source": "https://cgit.drupalcode.org/ad"
-  },
-  "require": {
-    "drupal/scheduler": "*"
-  }
-}
-- 
GitLab