From e7af13971736f1b7fc64f6b449e13e2f19472f22 Mon Sep 17 00:00:00 2001
From: Randal V <56416-RandalV@users.noreply.drupalcode.org>
Date: Thu, 24 Apr 2025 13:37:00 +0000
Subject: [PATCH] Resolve #3519844 "Support oop hooks"

---
 composer.json          |  2 +-
 fileslog.info.yml      |  2 +-
 fileslog.module        | 65 ++++++++++--------------------------------
 fileslog.services.yml  | 17 +++++++++--
 src/Hook/Cron.php      | 43 ++++++++++++++++++++++++++++
 src/Hook/FormAlter.php | 49 +++++++++++++++++++++++++++++++
 src/Hook/Help.php      | 26 +++++++++++++++++
 7 files changed, 150 insertions(+), 54 deletions(-)
 create mode 100644 src/Hook/Cron.php
 create mode 100644 src/Hook/FormAlter.php
 create mode 100644 src/Hook/Help.php

diff --git a/composer.json b/composer.json
index edc650a..294bee8 100644
--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,7 @@
     "source": "https://git.drupalcode.org/project/fileslog"
   },
   "require": {
-    "drupal/core": "^10 || ^11",
+    "drupal/core": "^10.1 || ^11",
     "php": ">=8.1"
   }
 }
diff --git a/fileslog.info.yml b/fileslog.info.yml
index e5cb55b..101d54f 100644
--- a/fileslog.info.yml
+++ b/fileslog.info.yml
@@ -1,6 +1,6 @@
 name: Private Files Logging
 type: module
 package: Logging
-core_version_requirement: ^10 || ^11
+core_version_requirement: ^10.1 || ^11
 description: 'Logs and records system events to the private filesystem.'
 configure: system.logging_settings
diff --git a/fileslog.module b/fileslog.module
index e9ec439..dc4a497 100644
--- a/fileslog.module
+++ b/fileslog.module
@@ -5,68 +5,33 @@
  * Redirects logging messages to the private filesystem.
  */
 
-use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Hook\Attribute\LegacyHook;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\fileslog\FilesLogInterface;
+use Drupal\fileslog\Hook\Cron;
+use Drupal\fileslog\Hook\FormAlter;
+use Drupal\fileslog\Hook\Help;
 
 /**
  * Implements hook_help().
  */
-function fileslog_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.fileslog':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The fileslog module saves logs to the private filesystem.') . '</p>';
-      return $output;
-  }
+#[LegacyHook]
+function fileslog_help($route_name, RouteMatchInterface $route_match): ?string {
+  return \Drupal::service(Help::class)->help($route_match, $route_match);
 }
 
 /**
- * Implements hook_cron().
- */
-function fileslog_cron() {
-  /** @var \Drupal\Core\File\FileSystemInterface $filesystem */
-  $filesystem = \Drupal::service('file_system');
-  /** @var \Drupal\fileslog\FilesLogManagerInterface $files_log_manager */
-  $files_log_manager = \Drupal::service('fileslog.manager');
-  $dir = FilesLogInterface::DIRECTORY;
-  $max_items = (int) \Drupal::config('fileslog.settings')->get('max_items') ?: 1000;
-
-  $filesystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
-  $files = $files_log_manager->getLogFiles([], 0);
-  if (count($files) > $max_items) {
-    $to_delete = array_slice($files, $max_items, (count($files) - $max_items));
-    foreach ($to_delete as $uri => $file) {
-      $filesystem->unlink($uri);
-    }
-  }
+* Implements hook_cron().
+*/
+#[LegacyHook]
+function fileslog_cron(): void {
+  \Drupal::service(Cron::class)->cron();
 }
 
 /**
  * Implements hook_form_FORM_ID_alter().
  */
-function fileslog_form_system_logging_settings_alter(&$form, FormStateInterface $form_state) {
-  $config = \Drupal::configFactory()->getEditable('fileslog.settings');
-  $form['max_items'] = [
-    '#type' => 'number',
-    '#title' => t('Maximum logs'),
-    '#default_value' => $config->get('max_items'),
-    '#required' => TRUE,
-    '#description' => t('The maximum log items to keep in the private filesystem before deleting the oldest ones.'),
-  ];
-
-  $form['#submit'][] = 'fileslog_logging_settings_submit';
-}
-
-/**
- * Form submission handler for system_logging_settings().
- *
- * @see fileslog_form_system_logging_settings_alter()
- */
-function fileslog_logging_settings_submit($form, FormStateInterface $form_state) {
-  \Drupal::configFactory()->getEditable('fileslog.settings')
-    ->set('max_items', $form_state->getValue('max_items'))
-    ->save();
+#[LegacyHook]
+function fileslog_form_system_logging_settings_alter(&$form, FormStateInterface $form_state): void {
+  \Drupal::service(FormAlter::class)->alterSystemLoggingSettingsForm($form, $form_state);
 }
diff --git a/fileslog.services.yml b/fileslog.services.yml
index 770b96f..f26e674 100644
--- a/fileslog.services.yml
+++ b/fileslog.services.yml
@@ -1,12 +1,25 @@
+parameters:
+  fileslog.hooks_converted: true
+
 services:
+  _defaults:
+    autowire: true
+
   # The fileslog manager.
   fileslog.manager:
     class: Drupal\fileslog\FilesLogManager
-    arguments: ['@file_system', '@request_stack']
+  Drupal\fileslog\FilesLogManagerInterface: '@fileslog.manager'
 
   # The logger service.
   logger.fileslog:
     class: Drupal\fileslog\Logger\FilesLog
-    arguments: ['@logger.log_message_parser']
     tags:
       - { name: logger }
+
+  # Hook services.
+  Drupal\fileslog\Hook\Help:
+    class: Drupal\fileslog\Hook\Help
+  Drupal\fileslog\Hook\Cron:
+    class: Drupal\fileslog\Hook\Cron
+  Drupal\fileslog\Hook\FormSystemLoggingSettingsAlter:
+    class: Drupal\fileslog\Hook\FormSystemLoggingSettingsAlter
diff --git a/src/Hook/Cron.php b/src/Hook/Cron.php
new file mode 100644
index 0000000..4acb826
--- /dev/null
+++ b/src/Hook/Cron.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\fileslog\Hook;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\File\FileSystemInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\fileslog\FilesLogInterface;
+use Drupal\fileslog\FilesLogManagerInterface;
+
+/**
+ * Hooks onto cron events.
+ */
+class Cron {
+
+  /**
+   * Constructs the cron hook class.
+   */
+  public function __construct(
+    protected FileSystemInterface $fileSystem,
+    protected ConfigFactoryInterface $configFactory,
+    protected FilesLogManagerInterface $filesLogManager,
+  ) {}
+
+  /**
+   * Executes the 'cron'-hook.
+   */
+  #[Hook('cron')]
+  public function cron(): void {
+    $max_items = (int) ($this->configFactory->get('fileslog.settings')->get('max_items') ?: 1000);
+    $dir = FilesLogInterface::DIRECTORY;
+
+    $this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
+    $files = $this->filesLogManager->getLogFiles([], 0);
+    if (count($files) > $max_items) {
+      $to_delete = array_slice($files, $max_items, (count($files) - $max_items));
+      foreach ($to_delete as $uri => $file) {
+        $this->fileSystem->unlink($uri);
+      }
+    }
+  }
+
+}
diff --git a/src/Hook/FormAlter.php b/src/Hook/FormAlter.php
new file mode 100644
index 0000000..1d92475
--- /dev/null
+++ b/src/Hook/FormAlter.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\fileslog\Hook;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hooks onto form alter events.
+ */
+class FormAlter {
+
+  /**
+   * Constructs the form_system_logging_settings_alter hook class.
+   */
+  public function __construct(
+    protected ConfigFactoryInterface $configFactory,
+  ) {}
+
+  /**
+   * Executes the 'form_system_logging_settings_alter'-hook.
+   */
+  #[Hook('form_system_logging_settings_alter')]
+  public function alterSystemLoggingSettingsForm(&$form, FormStateInterface $form_state): void {
+    $config = $this->configFactory->getEditable('fileslog.settings');
+    $form['max_items'] = [
+      '#type' => 'number',
+      '#title' => t('Maximum logs'),
+      '#default_value' => $config->get('max_items'),
+      '#required' => TRUE,
+      '#description' => t('The maximum log items to keep in the private filesystem before deleting the oldest ones.'),
+    ];
+
+    $form['#submit'][] = [$this, 'submitForm'];
+  }
+
+  /**
+   * Form submission handler for system_logging_settings().
+   *
+   * @see static::alterForm()
+   */
+  public function submitForm($form, FormStateInterface $form_state) {
+    $this->configFactory->getEditable('fileslog.settings')
+      ->set('max_items', $form_state->getValue('max_items'))
+      ->save();
+  }
+
+}
diff --git a/src/Hook/Help.php b/src/Hook/Help.php
new file mode 100644
index 0000000..277c121
--- /dev/null
+++ b/src/Hook/Help.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\fileslog\Hook;
+
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Hooks onto help events.
+ */
+class Help {
+
+  /**
+   * Executes the 'help'-hook.
+   */
+  #[Hook('help')]
+  public function help($route_name, RouteMatchInterface $route_match): ?string {
+    if ($route_name === 'help.page.fileslog') {
+      return '<h3>' . t('About') . '</h3>'
+        . '<p>' . t('The fileslog module saves logs to the private filesystem.') . '</p>';
+    }
+
+    return NULL;
+  }
+
+}
-- 
GitLab