From 13ca099d4212d4dbcff76a7a9abd1986367fc57c Mon Sep 17 00:00:00 2001
From: Tim Rohaly <tr@202830.no-reply.drupal.org>
Date: Sat, 10 Aug 2024 10:35:06 -0700
Subject: [PATCH 1/8] Issue #3467356 by TR: Drop D9 support

---
 votingapi.info.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/votingapi.info.yml b/votingapi.info.yml
index 1dac996..399dea4 100644
--- a/votingapi.info.yml
+++ b/votingapi.info.yml
@@ -2,6 +2,6 @@ name: Voting API
 type: module
 description: 'Provides a voting API that other modules can make use of.'
 package: Voting
-core_version_requirement: ^9.2 || ^10
+core_version_requirement: ^10.3 || ^11
 
 configure: votingapi.admin_settings
-- 
GitLab


From 1a69bd340e2b768e7b7482671fddf7b97f4a75a4 Mon Sep 17 00:00:00 2001
From: Tim Rohaly <tr@202830.no-reply.drupal.org>
Date: Sat, 10 Aug 2024 17:28:01 -0700
Subject: [PATCH 2/8] Revert "Issue #3467356 by TR: Drop D9 support" I
 committed this to the wrong branch. This branch, 8-x-3.x, will not be
 dropping D9 support.

This reverts commit 13ca099d4212d4dbcff76a7a9abd1986367fc57c.
---
 votingapi.info.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/votingapi.info.yml b/votingapi.info.yml
index 399dea4..1dac996 100644
--- a/votingapi.info.yml
+++ b/votingapi.info.yml
@@ -2,6 +2,6 @@ name: Voting API
 type: module
 description: 'Provides a voting API that other modules can make use of.'
 package: Voting
-core_version_requirement: ^10.3 || ^11
+core_version_requirement: ^9.2 || ^10
 
 configure: votingapi.admin_settings
-- 
GitLab


From 10d69d21cb4d9dcd09cce804b30a9224d860ccbd Mon Sep 17 00:00:00 2001
From: Tim Rohaly <42475-tr@users.noreply.drupalcode.org>
Date: Sat, 10 Aug 2024 21:57:37 +0000
Subject: [PATCH 3/8] Issue #3467380 by TR: Don't use t() in tests

---
 tests/src/Functional/VoteDeletionTest.php | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/tests/src/Functional/VoteDeletionTest.php b/tests/src/Functional/VoteDeletionTest.php
index 0684320..a364611 100644
--- a/tests/src/Functional/VoteDeletionTest.php
+++ b/tests/src/Functional/VoteDeletionTest.php
@@ -89,19 +89,9 @@ class VoteDeletionTest extends BrowserTestBase {
 
     // Delete a vote.
     $this->drupalGet('admin/vote/' . reset($vote_id) . '/delete');
-    $session->pageTextContains(
-      t('You are about to delete a vote by @user on @entity-type @label. This action cannot be undone.', [
-        '@user' => $vote_owner,
-        '@entity-type' => $entity_type,
-        '@label' => $label,
-      ]));
+    $session->pageTextContains('You are about to delete a vote by ' . $vote_owner . ' on ' . $entity_type . ' ' . $label . '. This action cannot be undone.');
     $this->submitForm([], 'Delete');
-    $session->pageTextContains(
-      t('The vote by @user on @entity-type @label has been deleted.', [
-        '@user' => $vote_owner,
-        '@entity-type' => $entity_type,
-        '@label' => $label,
-      ]));
+    $session->pageTextContains('The vote by ' . $vote_owner . ' on ' . $entity_type . ' ' . $label . ' has been deleted.');
 
     // Assert that the vote got deleted and other votes remain.
     $source_1_votes = $vote_storage->getUserVotes(0, 'vote', 'node', 1, 'source_1');
-- 
GitLab


From cb6f0809b6830c4d7d4b2a92707e91707570e6a9 Mon Sep 17 00:00:00 2001
From: Tim Rohaly <tr@202830.no-reply.drupal.org>
Date: Sat, 10 Aug 2024 15:32:25 -0700
Subject: [PATCH 4/8] Issue #3467382 by TR: phpcs: list(...) is forbidden

---
 modules/votingapi_tokens/votingapi_tokens.tokens.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/votingapi_tokens/votingapi_tokens.tokens.inc b/modules/votingapi_tokens/votingapi_tokens.tokens.inc
index f0f52dc..2a09c01 100644
--- a/modules/votingapi_tokens/votingapi_tokens.tokens.inc
+++ b/modules/votingapi_tokens/votingapi_tokens.tokens.inc
@@ -64,7 +64,7 @@ function votingapi_tokens_tokens($type, $tokens, array $data, array $options, Bu
       $votes = \Drupal::service('plugin.manager.votingapi.resultfunction')
         ->getResults($entity_type, $data[$entity_type]->id());
       foreach ($tokens as $name => $original) {
-        list($token_name, $vote_type) = explode(':', $name);
+        [$token_name, $vote_type] = explode(':', $name);
         switch ($token_name) {
           case 'vote_count':
             $replacements[$original] = $votes[$vote_type]['vote_count'];
-- 
GitLab


From 35b7ff206ddac80e9409f992d3d2cf6f91d59b1f Mon Sep 17 00:00:00 2001
From: Tim Rohaly <42475-tr@users.noreply.drupalcode.org>
Date: Sat, 10 Aug 2024 22:24:52 +0000
Subject: [PATCH 5/8] Issue #3467381 by TR: cspell changes

---
 .gitlab-ci.yml               |  3 ++-
 API.txt                      | 13 ++++++-------
 src/VoteStorageInterface.php |  2 +-
 votingapi.api.php            | 14 +++++++-------
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a8671ab..561307e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -50,7 +50,8 @@ include:
 #   SKIP_ESLINT: '1'
 
 variables:
-  _CSPELL_IGNORE_PATHS: '"phpcs.xml.dist", "tests/fixtures/*.php"'
+  _CSPELL_IGNORE_PATHS: '"phpcs.xml.dist", "tests/fixtures/*.php", "README.txt"'
+  _CSPELL_WORDS: 'resultfunction'
   _SHOW_ENVIRONMENT_VARIABLES: 1
   _PHPUNIT_CONCURRENT: 1
   OPT_IN_TEST_MIN_PHP: 1
diff --git a/API.txt b/API.txt
index 5b8780d..ab4233e 100644
--- a/API.txt
+++ b/API.txt
@@ -30,7 +30,7 @@ How Data Is Stored
 VotingAPI manages a raw 'pool' of vote data -- it doesn't keep track of any
 content directly. Instead, it lets modules store each vote with a 'content type'
 and 'content id', so that the same APIs can be used to rate nodes, comments,
-users, aggregator items, or even other votes (in a Slashdot-esque
+users, aggregator items, or even other votes (in a Slashdot-like
 meta-moderation system). It can also be used by modules that need to store and
 calculate custom data like polling results -- using a custom entity_type ensures
 that other modules won't trample on your module's voting data.
@@ -175,7 +175,7 @@ comments. If your module casts other types of votes that should be made
 available via Views, it needs to implement hook_votingapi_relationships().
 
 
-function mymodule_votingapi_relationships() {
+function my_module_votingapi_relationships() {
   $relationships[] = [
     // 'description' is used to construct the field description in the Views UI.
     'description' => t('nodes'),
@@ -192,8 +192,7 @@ function mymodule_votingapi_relationships() {
     // VotingAPI constructs pseudo-tables so that multiple relationships can
     // point to the same base table (normal and translation-based votes nodes
     // for example. These two columns allow you to override the names of the
-    // pseudo-tables. You probably don't need to change this part unless you're
-    // nedjo.
+    // pseudo-tables. You probably don't need to change this part.
     'pseudo_vote' => 'votingapi_vote',
     'pseudo_cache' => 'votingapi_cache',
   ];
@@ -209,11 +208,11 @@ given VotingAPI view field. For the View field that's passed in, your hook
 should return an array of key => value pairs, where the key is a the name of a
 callback function that will format the values from the database.
 
-function mymodule_votingapi_views_formatters($field) {
+function my_module_votingapi_views_formatters($field) {
   if ($field->field == 'value') {
-    return ['mymodule_funky_formatter' => t('MyModule value formatter')];
+    return ['my_module_funky_formatter' => t('MyModule value formatter')];
   }
   if ($field->field == 'tag') {
-    return ['mymodule_funky_tags' => t('MyModule tag formatter')];
+    return ['my_module_funky_tags' => t('MyModule tag formatter')];
   }
 }
diff --git a/src/VoteStorageInterface.php b/src/VoteStorageInterface.php
index b9c43e4..a818d38 100644
--- a/src/VoteStorageInterface.php
+++ b/src/VoteStorageInterface.php
@@ -67,7 +67,7 @@ interface VoteStorageInterface extends EntityStorageInterface {
   public function getVotesSinceMoment();
 
   /**
-   * Delets votes for deleted entity everywhere in the database.
+   * Deletes votes for deleted entity everywhere in the database.
    *
    * @param string $entity_type_id
    *   The entity type ID.
diff --git a/votingapi.api.php b/votingapi.api.php
index 4be251c..9f85be0 100644
--- a/votingapi.api.php
+++ b/votingapi.api.php
@@ -68,7 +68,7 @@ function hook_votingapi_results_alter(array &$vote_results, $entity_type, $entit
  *
  * If your module uses custom tags or value_types, or calculates custom
  * aggregate functions, please implement this hook so other modules can properly
- * interperet and display your data.
+ * interpret and display your data.
  *
  * Three major bins of data are stored: tags, value_types, and aggregate result
  * functions. Each entry in these bins is keyed by the value stored in the
@@ -85,25 +85,25 @@ function hook_votingapi_metadata_alter(&$data) {
   $data['tags']['bread'] = [
     'name' => t('Bread'),
     'description' => t('The quality of the food at a restaurant.'),
-    'module' => 'mymodule',
+    'module' => 'my_module',
     // This is optional; we can add it for our own purposes.
   ];
   $data['tags']['circuses'] = [
     'name' => t('Circuses'),
     'description' => t('The quality of the presentation and atmosphere at a restaurant.'),
-    'module' => 'mymodule',
+    'module' => 'my_module',
   ];
 
   // Document two custom aggregate function.
   $data['functions']['standard_deviation'] = [
     'name' => t('Standard deviation'),
     'description' => t('The standard deviation of all votes cast on a given piece of content. Use this to find controversial content.'),
-    'module' => 'mymodule',
+    'module' => 'my_module',
   ];
   $data['functions']['median'] = [
     'name' => t('Median vote'),
     'description' => t('The median vote value cast on a given piece of content. More accurate than a pure average when there are a few outlying votes.'),
-    'module' => 'mymodule',
+    'module' => 'my_module',
   ];
 }
 
@@ -127,10 +127,10 @@ function hook_votingapi_metadata_alter(&$data) {
  */
 function hook_votingapi_views_formatters($field) {
   if ($field->field == 'value') {
-    return ['mymodule_funky_formatter' => t('MyModule value formatter')];
+    return ['my_module_funky_formatter' => t('MyModule value formatter')];
   }
   if ($field->field == 'tag') {
-    return ['mymodule_funky_tags' => t('MyModule tag formatter')];
+    return ['my_module_funky_tags' => t('MyModule tag formatter')];
   }
 }
 
-- 
GitLab


From 5f54fecbf02cb1207f8f70cfa7b0e20f28864ea4 Mon Sep 17 00:00:00 2001
From: Tim Rohaly <tr@202830.no-reply.drupal.org>
Date: Mon, 26 Aug 2024 15:36:14 -0700
Subject: [PATCH 6/8] Minor PHPCS fixes

---
 CHANGELOG.txt                     | 3 ++-
 src/Entity/VoteResult.php         | 1 -
 src/Entity/VoteType.php           | 2 +-
 src/VoteResultFunctionManager.php | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index d3b39c6..8341358 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -28,7 +28,8 @@ without using esoteric combinations of filters.
 --------
 A new setting has been introduced -- vote result calculation can be deferred
 until cron-time. This can be useful on heavy-load sites where MANY votes are
-being cast and complex, db-intensive calculations are used to weight the results.
+being cast and complex, db-intensive calculations are used to weight the
+results.
 
 05/01/06
 --------
diff --git a/src/Entity/VoteResult.php b/src/Entity/VoteResult.php
index a78eb31..2be9841 100644
--- a/src/Entity/VoteResult.php
+++ b/src/Entity/VoteResult.php
@@ -5,7 +5,6 @@ namespace Drupal\votingapi\Entity;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\user\UserInterface;
 use Drupal\votingapi\VoteResultInterface;
 
 /**
diff --git a/src/Entity/VoteType.php b/src/Entity/VoteType.php
index 799cbb2..17f9293 100644
--- a/src/Entity/VoteType.php
+++ b/src/Entity/VoteType.php
@@ -99,7 +99,7 @@ class VoteType extends ConfigEntityBundleBase implements VoteTypeInterface {
 
     // Clear the vote type cache to reflect the removal.
     $storage->resetCache(array_keys($entities));
-    // TODO: needed?
+    // @todo Is this needed?
   }
 
 }
diff --git a/src/VoteResultFunctionManager.php b/src/VoteResultFunctionManager.php
index 9b49f6a..110e4e7 100644
--- a/src/VoteResultFunctionManager.php
+++ b/src/VoteResultFunctionManager.php
@@ -176,7 +176,7 @@ class VoteResultFunctionManager extends DefaultPluginManager {
     // Give other modules a chance to act on the results of vote calculations.
     $this->moduleHandler->alter('votingapi_results', $vote_results, $entity_type_id, $entity_id);
 
-    foreach ($vote_results as $id => $vote_result) {
+    foreach ($vote_results as $vote_result) {
       if (!empty($vote_result)) {
         $this->database->insert('votingapi_result')->fields($vote_result)->execute();
       }
-- 
GitLab


From 40830e4fcc853463eeff3b19181d8a3661db5911 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabien=20Cl=C3=A9ment?= <goz@226961.no-reply.drupal.org>
Date: Thu, 12 Sep 2024 12:28:55 +0200
Subject: [PATCH 7/8] Issue #2965603 by jeffdavidgordon: Add support for UUID
 field to votingapi_result table

---
 src/Entity/VoteResult.php         |  8 +++++++-
 src/VoteResultFunctionManager.php | 12 +++++++++++-
 votingapi.install                 | 13 +++++++++++++
 votingapi.post_update.php         | 28 ++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 votingapi.post_update.php

diff --git a/src/Entity/VoteResult.php b/src/Entity/VoteResult.php
index e799912..6a48394 100644
--- a/src/Entity/VoteResult.php
+++ b/src/Entity/VoteResult.php
@@ -32,7 +32,8 @@ use Drupal\votingapi\VoteResultInterface;
  *   },
  *   base_table = "votingapi_result",
  *   entity_keys = {
- *     "id" = "id"
+ *     "id" = "id",
+ *     "uuid" = "uuid"
  *   }
  * )
  */
@@ -133,6 +134,11 @@ class VoteResult extends ContentEntityBase implements VoteResultInterface {
       ->setReadOnly(TRUE)
       ->setSetting('unsigned', TRUE);
 
+    $fields[$entity_type->getKey('uuid')] = BaseFieldDefinition::create('uuid')
+      ->setLabel(new TranslatableMarkup('UUID'))
+      ->setDescription(new TranslatableMarkup('The vote result UUID.'))
+      ->setReadOnly(TRUE);
+
     $fields['type'] = BaseFieldDefinition::create('entity_reference')
       ->setLabel(new TranslatableMarkup('Type'))
       ->setDescription(new TranslatableMarkup('The vote type.'))
diff --git a/src/VoteResultFunctionManager.php b/src/VoteResultFunctionManager.php
index 595ba2a..999a1a3 100644
--- a/src/VoteResultFunctionManager.php
+++ b/src/VoteResultFunctionManager.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace Drupal\votingapi;
 
 use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Component\Uuid\UuidInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -46,6 +47,11 @@ class VoteResultFunctionManager extends DefaultPluginManager implements VoteResu
    */
   protected $datetime;
 
+  /**
+   * @var \Drupal\Component\Uuid\UuidInterface
+   */
+  protected $uuid;
+
   /**
    * Constructs a new VoteResultFunctionManager.
    *
@@ -62,12 +68,15 @@ class VoteResultFunctionManager extends DefaultPluginManager implements VoteResu
    *   The entity_type.manager service.
    * @param \Drupal\Component\Datetime\TimeInterface $datetime
    *   The datetime.time service.
+   * @param \Drupal\Component\Uuid\UuidInterface $uuid
+   *   The UUID service.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, Connection $database, EntityTypeManagerInterface $entity_type_manager, TimeInterface $datetime) {
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, Connection $database, EntityTypeManagerInterface $entity_type_manager, TimeInterface $datetime, UuidInterface $uuid) {
     parent::__construct('Plugin/VoteResultFunction', $namespaces, $module_handler, VoteResultFunctionInterface::class, VoteResultFunction::class, 'Drupal\votingapi\Annotation\VoteResultFunction');
     $this->database = $database;
     $this->entityTypeManager = $entity_type_manager;
     $this->datetime = $datetime;
+    $this->uuid = $uuid;
     $this->alterInfo('vote_result_info');
     $this->setCacheBackend($cache_backend, 'vote_result_plugins');
   }
@@ -167,6 +176,7 @@ class VoteResultFunctionManager extends DefaultPluginManager implements VoteResu
       $plugin = $this->createInstance($plugin_id);
       $vote_results[] = [
         'entity_id' => $entity_id,
+        'uuid' => $this->uuid->generate(),
         'entity_type' => $entity_type_id,
         'type' => $vote_type,
         'function' => $plugin_id,
diff --git a/votingapi.install b/votingapi.install
index b27ebd6..a524721 100644
--- a/votingapi.install
+++ b/votingapi.install
@@ -11,3 +11,16 @@
 function votingapi_update_last_removed() {
   return 8304;
 }
+
+/**
+ * Install the definition of 'uuid' field Vote Result entity.
+ */
+function votingapi_update_8305(&$sandbox) {
+  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+  if ($vote_result_fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('vote_result')) {
+    /** @var \Drupal\Core\Field\BaseFieldDefinition $function_field_definition */
+    $function_field_definition = $vote_result_fields['uuid'];
+    $function_field_definition->getSchema();
+    $definition_update_manager->installFieldStorageDefinition('uuid', 'vote_result', 'votingapi', $function_field_definition);
+  }
+}
diff --git a/votingapi.post_update.php b/votingapi.post_update.php
new file mode 100644
index 0000000..6795717
--- /dev/null
+++ b/votingapi.post_update.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for votingapi.
+ */
+
+/**
+ * Generate uuids for existing vote_result entities with no uuids.
+ */
+function votingapi_post_update_generate_vote_result_uuids(&$sandbox) {
+  $table_name = 'votingapi_result';
+  $connection = \Drupal::service('database');
+  $rows = $connection->select($table_name, 'votingapi_result')
+    ->fields('votingapi_result', ['id'])
+    ->isNull('uuid')
+    ->execute()
+    ->fetchAll();
+
+  $uuidGenerator = \Drupal::service('uuid');
+
+  foreach ($rows as $row) {
+    $connection->update($table_name)
+      ->fields(['uuid' => $uuidGenerator->generate()])
+      ->condition('id', $row->id)
+      ->execute();
+  }
+}
-- 
GitLab


From 64d4ec4920e94bfc97e49683be762ade2ef7d6f9 Mon Sep 17 00:00:00 2001
From: Tim Rohaly <tr@202830.no-reply.drupal.org>
Date: Thu, 6 Mar 2025 22:48:23 -0800
Subject: [PATCH 8/8] Use BaseFieldDefinition from parent for id and uuid

---
 src/Entity/VoteResult.php | 16 +++++-----------
 votingapi.install         |  2 +-
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/src/Entity/VoteResult.php b/src/Entity/VoteResult.php
index 6a48394..1981604 100644
--- a/src/Entity/VoteResult.php
+++ b/src/Entity/VoteResult.php
@@ -33,7 +33,7 @@ use Drupal\votingapi\VoteResultInterface;
  *   base_table = "votingapi_result",
  *   entity_keys = {
  *     "id" = "id",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
  *   }
  * )
  */
@@ -128,16 +128,10 @@ class VoteResult extends ContentEntityBase implements VoteResultInterface {
    */
   public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {
     /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
-    $fields['id'] = BaseFieldDefinition::create('integer')
-      ->setLabel(new TranslatableMarkup('ID'))
-      ->setDescription(new TranslatableMarkup('The vote result ID.'))
-      ->setReadOnly(TRUE)
-      ->setSetting('unsigned', TRUE);
-
-    $fields[$entity_type->getKey('uuid')] = BaseFieldDefinition::create('uuid')
-      ->setLabel(new TranslatableMarkup('UUID'))
-      ->setDescription(new TranslatableMarkup('The vote result UUID.'))
-      ->setReadOnly(TRUE);
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    // Override parent id description.
+    $fields['id']->setDescription(new TranslatableMarkup('The vote result ID.'));
 
     $fields['type'] = BaseFieldDefinition::create('entity_reference')
       ->setLabel(new TranslatableMarkup('Type'))
diff --git a/votingapi.install b/votingapi.install
index a524721..e2915c6 100644
--- a/votingapi.install
+++ b/votingapi.install
@@ -15,7 +15,7 @@ function votingapi_update_last_removed() {
 /**
  * Install the definition of 'uuid' field Vote Result entity.
  */
-function votingapi_update_8305(&$sandbox) {
+function votingapi_update_10400(&$sandbox) {
   $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
   if ($vote_result_fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('vote_result')) {
     /** @var \Drupal\Core\Field\BaseFieldDefinition $function_field_definition */
-- 
GitLab