From 20d8630910242b920ae196fadc54182f3fcf2057 Mon Sep 17 00:00:00 2001 From: Tim Rohaly <tr@202830.no-reply.drupal.org> Date: Fri, 14 Feb 2025 01:06:36 -0800 Subject: [PATCH 1/5] Issue #3502021 by tr: Support for object oriented hook implementations using autowired services --- src/Hook/VotingApiWidgetsEntityHooks.php | 63 ++++++++++++++++++++++++ src/Hook/VotingApiWidgetsFormHooks.php | 43 ++++++++++++++++ src/Hook/VotingApiWidgetsHelpHooks.php | 47 ++++++++++++++++++ votingapi_widgets.module | 52 +++++++------------ votingapi_widgets.services.yml | 18 ++++++- 5 files changed, 186 insertions(+), 37 deletions(-) create mode 100644 src/Hook/VotingApiWidgetsEntityHooks.php create mode 100644 src/Hook/VotingApiWidgetsFormHooks.php create mode 100644 src/Hook/VotingApiWidgetsHelpHooks.php diff --git a/src/Hook/VotingApiWidgetsEntityHooks.php b/src/Hook/VotingApiWidgetsEntityHooks.php new file mode 100644 index 0000000..54b5d0f --- /dev/null +++ b/src/Hook/VotingApiWidgetsEntityHooks.php @@ -0,0 +1,63 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\votingapi_widgets\Hook; + +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager; + +/** + * Hook implementations used to create and dispatch Entity Events. + */ +final class VotingApiWidgetsEntityHooks { + + /** + * Constructs a new VotingApiWidgetsEntityHooks service. + * + * @param \Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager $widgetManager + * The entity_type.manager service. + */ + public function __construct( + protected VotingApiWidgetManager $widgetManager, + ) {} + + /** + * Implements hook_entity_base_field_info(). + */ + #[Hook('entity_base_field_info')] + public function entityBaseFieldInfo(EntityTypeInterface $entity_type): array { + $fields = []; + + // Add the field_name as a base field. + if ($entity_type->id() != 'vote') { + return $fields; + } + + $fields['field_name'] = BaseFieldDefinition::create('string') + ->setLabel(new TranslatableMarkup('Field name')) + ->setName('field_name') + ->setRevisionable(FALSE) + ->setRequired(FALSE) + ->setDescription(new TranslatableMarkup('Holds the field name.')) + ->setPropertyConstraints('value', ['Length' => ['max' => FieldStorageConfig::NAME_MAX_LENGTH]]); + + return $fields; + } + + /** + * Implements hook_entity_type_build(). + */ + #[Hook('entity_type_build')] + public function entityTypeBuild(array &$entity_types): void { + $plugins = $this->widgetManager->getDefinitions(); + foreach ($plugins as $plugin_id => $definition) { + $entity_types['vote']->setFormClass('votingapi_' . $plugin_id, 'Drupal\votingapi_widgets\Form\BaseRatingForm'); + } + } + +} diff --git a/src/Hook/VotingApiWidgetsFormHooks.php b/src/Hook/VotingApiWidgetsFormHooks.php new file mode 100644 index 0000000..4fb7ebe --- /dev/null +++ b/src/Hook/VotingApiWidgetsFormHooks.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\votingapi_widgets\Hook; + +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; + +/** + * Hook implementations used to alter and enhance forms. + */ +final class VotingApiWidgetsFormHooks { + use StringTranslationTrait; + + /** + * Constructs a new VotingApiWidgetsFormHooks service. + * + * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation + * The string translation service. + */ + public function __construct( + TranslationInterface $string_translation, + ) { + $this->stringTranslation = $string_translation; + } + + /** + * Implements hook_form_FORM_ID_alter() for field_config_edit_form. + */ + #[Hook('form_field_config_edit_form_alter')] + public function fieldConfigEditFormAlter(array &$form, FormStateInterface $form_state): void { + if ($form_state->getFormObject()->getEntity()->bundle() == 'voting_api_field') { + // We only support posting one comment at the time so it doesn't make sense + // to let the site builder choose anything else. + $form['field_storage']['subform']['cardinality_container']['cardinality']['#default_value'] = 1; + $form['field_storage']['subform']['cardinality_container']['#access'] = FALSE; + } + } + +} diff --git a/src/Hook/VotingApiWidgetsHelpHooks.php b/src/Hook/VotingApiWidgetsHelpHooks.php new file mode 100644 index 0000000..7c32f45 --- /dev/null +++ b/src/Hook/VotingApiWidgetsHelpHooks.php @@ -0,0 +1,47 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\votingapi_widgets\Hook; + +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; + +/** + * Hook implementations used to provide help. + */ +final class VotingApiWidgetsHelpHooks { + use StringTranslationTrait; + + /** + * Constructs a new VotingApiWidgetsHelpHooks service. + * + * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation + * The string translation service. + */ + public function __construct( + TranslationInterface $string_translation, + ) { + $this->stringTranslation = $string_translation; + } + + /** + * Implements hook_help(). + */ + #[Hook('help')] + public function help(string $route_name, RouteMatchInterface $route_match): ?string { + switch ($route_name) { + // Main module help for the votingapi_widgets module. + case 'help.page.votingapi_widgets': + $output = '<h3>' . $this->t('About') . '</h3>'; + $output .= '<p>' . $this->t('Voting API Widgets') . '</p>'; + return $output; + + default: + } + return NULL; + } + +} diff --git a/votingapi_widgets.module b/votingapi_widgets.module index 55e2efc..f88aa97 100644 --- a/votingapi_widgets.module +++ b/votingapi_widgets.module @@ -2,56 +2,48 @@ /** * @file - * Contains votingapi_widgets.module.. + * Contains votingapi_widgets.module. */ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Hook\Attribute\LegacyHook; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; +use Drupal\votingapi_widgets\Hook\VotingApiWidgetsEntityHooks; +use Drupal\votingapi_widgets\Hook\VotingApiWidgetsFormHooks; +use Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks; /** * Implements hook_help(). */ +#[LegacyHook] function votingapi_widgets_help($route_name, RouteMatchInterface $route_match) { - switch ($route_name) { - // Main module help for the votingapi_widgets module. - case 'help.page.votingapi_widgets': - $output = ''; - $output .= '<h3>' . t('About') . '</h3>'; - $output .= '<p>' . t('Voting API Widgets') . '</p>'; - return $output; - - default: - } + return \Drupal::service(VotingApiWidgetsHelpHooks::class)->help($route_name, $route_match); } /** * Implements hook_entity_base_field_info(). */ +#[LegacyHook] function votingapi_widgets_entity_base_field_info(EntityTypeInterface $entity_type) { - // Add the field_name as a base field. - if ($entity_type->id() != 'vote') { - return; - } - $fields = []; - - $fields['field_name'] = BaseFieldDefinition::create('string') - ->setLabel(t('Field name')) - ->setName('field_name') - ->setRevisionable(FALSE) - ->setRequired(FALSE) - ->setDescription(t('Holds the field name.')) - ->setPropertyConstraints('value', ['Length' => ['max' => FieldStorageConfig::NAME_MAX_LENGTH]]); + return \Drupal::service(VotingApiWidgetsEntityHooks::class)->entityBaseFieldInfo($entity_type); +} - return $fields; +/** + * Implements hook_entity_type_build(). + */ +#[LegacyHook] +function votingapi_widgets_entity_type_build(array &$entity_types) { + \Drupal::service(VotingApiWidgetsEntityHooks::class)->entityTypeBuild($entity_types); } /** * Implements hook_form_FORM_ID_alter() for field_config_edit_form. */ +#[LegacyHook] function votingapi_widgets_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) { if ($form_state->getFormObject()->getEntity()->bundle() == 'voting_api_field') { // We only support posting one comment at the time so it doesn't make sense @@ -61,16 +53,6 @@ function votingapi_widgets_form_field_config_edit_form_alter(&$form, FormStateIn } } -/** - * Implements hook_entity_type_build(). - */ -function votingapi_widgets_entity_type_build(array &$entity_types) { - $plugins = \Drupal::service('plugin.manager.voting_api_widget.processor')->getDefinitions(); - foreach ($plugins as $plugin_id => $definition) { - $entity_types['vote']->setFormClass('votingapi_' . $plugin_id, 'Drupal\votingapi_widgets\Form\BaseRatingForm'); - } -} - /** * Implements hook_theme_suggestions_alter(). */ diff --git a/votingapi_widgets.services.yml b/votingapi_widgets.services.yml index 5741534..d38a498 100644 --- a/votingapi_widgets.services.yml +++ b/votingapi_widgets.services.yml @@ -1,7 +1,21 @@ services: plugin.manager.voting_api_widget.processor: - class: Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager + class: \Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager parent: default_plugin_manager + Drupal\votingapi_widgets\Plugin\VotingApiWidgetManager: '@plugin.manager.voting_api_widget.processor' + voting_api.lazy_loader: - class: Drupal\votingapi_widgets\VotingApiLoader + class: \Drupal\votingapi_widgets\VotingApiLoader + autowire: true arguments: ['@plugin.manager.voting_api_widget.processor', '@entity_type.manager'] + Drupal\votingapi_widgets\VotingApiLoader: '@voting_api.lazy_loader' + + Drupal\votingapi_widgets\Hook\VotingApiWidgetsEntityHooks: + class: \Drupal\votingapi_widgets\Hook\VotingApiWidgetsEntityHooks + autowire: true + Drupal\votingapi_widgets\Hook\VotingApiWidgetsFormHooks: + class: \Drupal\votingapi_widgets\Hook\VotingApiWidgetsFormHooks + autowire: true + Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks: + class: \Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks + autowire: true -- GitLab From d06cb4a624a0937c1a16ddfec6b9d3e845523885 Mon Sep 17 00:00:00 2001 From: Tim Rohaly <tr@202830.no-reply.drupal.org> Date: Fri, 14 Feb 2025 01:11:05 -0800 Subject: [PATCH 2/5] missed one --- votingapi_widgets.module | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/votingapi_widgets.module b/votingapi_widgets.module index f88aa97..66cb247 100644 --- a/votingapi_widgets.module +++ b/votingapi_widgets.module @@ -45,12 +45,7 @@ function votingapi_widgets_entity_type_build(array &$entity_types) { */ #[LegacyHook] function votingapi_widgets_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) { - if ($form_state->getFormObject()->getEntity()->bundle() == 'voting_api_field') { - // We only support posting one comment at the time so it doesn't make sense - // to let the site builder choose anything else. - $form['field_storage']['subform']['cardinality_container']['cardinality']['#default_value'] = 1; - $form['field_storage']['subform']['cardinality_container']['#access'] = FALSE; - } + \Drupal::service(VotingApiWidgetsFormHooks::class)->fieldConfigEditFormAlter($form, $form_state, $form_id); } /** -- GitLab From b1724721ebcc7794c940246becb5b8fcfdb80d28 Mon Sep 17 00:00:00 2001 From: Tim Rohaly <tr@202830.no-reply.drupal.org> Date: Fri, 14 Feb 2025 10:36:52 -0800 Subject: [PATCH 3/5] unused use --- votingapi_widgets.module | 2 -- 1 file changed, 2 deletions(-) diff --git a/votingapi_widgets.module b/votingapi_widgets.module index 66cb247..5c39408 100644 --- a/votingapi_widgets.module +++ b/votingapi_widgets.module @@ -6,12 +6,10 @@ */ use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Hook\Attribute\LegacyHook; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\field\Entity\FieldConfig; -use Drupal\field\Entity\FieldStorageConfig; use Drupal\votingapi_widgets\Hook\VotingApiWidgetsEntityHooks; use Drupal\votingapi_widgets\Hook\VotingApiWidgetsFormHooks; use Drupal\votingapi_widgets\Hook\VotingApiWidgetsHelpHooks; -- GitLab From 2a66859068565238da8de3ea4276744dbf01de30 Mon Sep 17 00:00:00 2001 From: Tim Rohaly <tr@202830.no-reply.drupal.org> Date: Fri, 14 Feb 2025 14:45:30 -0800 Subject: [PATCH 4/5] remove extra parameter --- votingapi_widgets.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/votingapi_widgets.module b/votingapi_widgets.module index 5c39408..83be818 100644 --- a/votingapi_widgets.module +++ b/votingapi_widgets.module @@ -43,7 +43,7 @@ function votingapi_widgets_entity_type_build(array &$entity_types) { */ #[LegacyHook] function votingapi_widgets_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) { - \Drupal::service(VotingApiWidgetsFormHooks::class)->fieldConfigEditFormAlter($form, $form_state, $form_id); + \Drupal::service(VotingApiWidgetsFormHooks::class)->fieldConfigEditFormAlter($form, $form_state); } /** -- GitLab From f7f3ec8a44a1bb167fa7a86faded8f3b561bbabb Mon Sep 17 00:00:00 2001 From: Tim Rohaly <tr@202830.no-reply.drupal.org> Date: Sat, 15 Feb 2025 00:36:35 -0800 Subject: [PATCH 5/5] phpcs - comment line length. --- src/Hook/VotingApiWidgetsFormHooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Hook/VotingApiWidgetsFormHooks.php b/src/Hook/VotingApiWidgetsFormHooks.php index 4fb7ebe..6d23e8b 100644 --- a/src/Hook/VotingApiWidgetsFormHooks.php +++ b/src/Hook/VotingApiWidgetsFormHooks.php @@ -33,8 +33,8 @@ final class VotingApiWidgetsFormHooks { #[Hook('form_field_config_edit_form_alter')] public function fieldConfigEditFormAlter(array &$form, FormStateInterface $form_state): void { if ($form_state->getFormObject()->getEntity()->bundle() == 'voting_api_field') { - // We only support posting one comment at the time so it doesn't make sense - // to let the site builder choose anything else. + // We only support posting one comment at the time so it doesn't make + // sense to let the site builder choose anything else. $form['field_storage']['subform']['cardinality_container']['cardinality']['#default_value'] = 1; $form['field_storage']['subform']['cardinality_container']['#access'] = FALSE; } -- GitLab