Verified Commit 603c21cb authored by Lee Rowlands's avatar Lee Rowlands Committed by Lee Rowlands
Browse files

Issue #3214915 by larowlan: Add a drush command

parent 751c4d16
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -10,9 +10,17 @@
        }
    ],
    "require": {
        "drupal/dynamic_entity_reference": "~1 || ~2"
        "drupal/dynamic_entity_reference": "~1 || ~2",
        "php": ">8"
    },
    "require-dev": {
        "drupal/paragraphs": "~1"
    },
    "extra": {
        "drush": {
            "services": {
                "drush.services.yml": "^9"
            }
        }
    }
}

drush.services.yml

0 → 100644
+9 −0
Original line number Diff line number Diff line
services:
  filter_format_audit.commands:
    class: Drupal\filter_format_audit\Commands\FilterFormatAuditCommands
    arguments:
      - '@entity_type.manager'
      - '@entity_field.manager'
      - '@plugin.manager.field.field_type'
    tags:
      - { name: drush.command }
+86 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\filter_format_audit;

use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\filter\FilterFormatInterface;
use Drupal\filter_format_audit\Form\RunAnalysisForm;
use Drupal\text\Plugin\Field\FieldType\TextItemBase;

/**
 * Defines a class for building the analysis batch task.
 */
final class AnalysisBatchBuilder {

  /**
   * Builds a batch task for analysis.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   Entity field manager.
   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $fieldTypePluginManager
   *   Field type plugin manager.
   *
   * @return array
   *   Batch jobs
   */
  public static function buildAnalysisBatch(EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, FieldTypePluginManagerInterface $fieldTypePluginManager): array {
    $ids = $entityTypeManager->getStorage('analysis_result')
      ->getQuery()
      ->accessCheck(FALSE)
      ->execute();
    $batch = [
      'title' => new TranslatableMarkup('Analysing content ...'),
      'operations' => [],
      'finished' => [RunAnalysisForm::class, 'finished'],
    ];
    foreach (array_chunk($ids, 50) as $chunk) {
      $batch['operations'][] = [[RunAnalysisForm::class, 'clear'], [$chunk]];
    }
    $formats = array_filter($entityTypeManager->getStorage('filter_format')->loadMultiple(), function (FilterFormatInterface $format) {
      return $format->filters('filter_html') && $format->filters('filter_html')->status;
    });
    foreach ($entityFieldManager->getFieldMap() as $entity_type_id => $fields) {
      if ($entity_type_id === 'analysis_result') {
        // Inception.
        continue;
      }
      $entity_type_storage = $entityTypeManager->getStorage($entity_type_id);
      foreach ($fields as $field_name => $details) {
        $type = $details['type'];
        $plugin = $fieldTypePluginManager->getDefinition($type, FALSE);
        if (!$plugin || !is_a($plugin['class'], TextItemBase::class, TRUE)) {
          continue;
        }
        try {
          $query = $entity_type_storage->getQuery()
            ->exists($field_name)
            ->accessCheck(FALSE)
            ->condition("$field_name.format", array_keys($formats), 'IN');
          $results = $query->execute();
        } catch (QueryException $e) {
          // Corrupt field map.
          continue;
        }
        if ($results) {
          foreach ($results as $entity_id) {
            $batch['operations'][] = [
              [RunAnalysisForm::class, 'analyse'],
              [$entity_type_id, $entity_id, $field_name],
            ];
          }
        }
      }

    }
    return $batch;
  }

}
+49 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\filter_format_audit\Commands;

use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\filter_format_audit\AnalysisBatchBuilder;
use Drush\Commands\DrushCommands;

/**
 * Defines a class for drush commands for the module.
 */
final class FilterFormatAuditCommands extends DrushCommands {

  /**
   * Constructs a new FilterFormatAuditCommands.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   Entity field manager.
   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $fieldTypePluginManager
   *   Field type plugin manager.
   */
  public function __construct(private EntityTypeManagerInterface $entityTypeManager, private EntityFieldManagerInterface $entityFieldManager, private FieldTypePluginManagerInterface $fieldTypePluginManager) {
    parent::__construct();
  }

  /**
   * Performs analysis tree.
   *
   * @usage drush filter-format-audit-analyse
   *   Regenerate analysis.
   *
   * @command filter-format-audit-analyse
   * @aliases filter-format-audit:analyse,ffaa
   */
  public function filterFormatAnalysis(): void {
    $tasks = AnalysisBatchBuilder::buildAnalysisBatch($this->entityTypeManager, $this->entityFieldManager, $this->fieldTypePluginManager);
    batch_set($tasks);
    $batch =& batch_get();
    $batch['progressive'] = FALSE;
    drush_backend_batch_process();
  }

}
+7 −52
Original line number Diff line number Diff line
@@ -2,14 +2,11 @@

namespace Drupal\filter_format_audit\Form;

use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\filter\FilterFormatInterface;
use Drupal\filter_format_audit\AnalysisBatchBuilder;
use Drupal\filter_format_audit\EntityHandlers\FilterFormatAuditHandlerInterface;
use Drupal\text\Plugin\Field\FieldType\TextItemBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
@@ -70,52 +67,10 @@ class RunAnalysisForm extends FormBase {
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $ids = $this->entityTypeManager->getStorage('analysis_result')->getQuery()->accessCheck(FALSE)->execute();
    $batch = [
      'title' => new TranslatableMarkup('Analysing content ...'),
      'operations' => [],
      'finished' => [static::class, 'finished'],
    ];
    foreach (array_chunk($ids, 20) as $chunk) {
      $batch['operations'][] = [[static::class, 'clear'], [$chunk]];
    }
    $formats = array_filter($this->entityTypeManager->getStorage('filter_format')->loadMultiple(), function (FilterFormatInterface $format) {
      return $format->filters('filter_html') && $format->filters('filter_html')->status;
    });
    foreach ($this->entityFieldManager->getFieldMap() as $entity_type_id => $fields) {
      if ($entity_type_id === 'analysis_result') {
        // Inception.
        continue;
      }
      $entity_type_storage = $this->entityTypeManager->getStorage($entity_type_id);
      foreach ($fields as $field_name => $details) {
        $type = $details['type'];
        $plugin = $this->fieldTypePluginManager->getDefinition($type, FALSE);
        if (!$plugin || !is_a($plugin['class'], TextItemBase::class, TRUE)) {
          continue;
        }
        try {
          $query = $entity_type_storage->getQuery()
            ->exists($field_name)
            ->accessCheck(FALSE)
            ->condition("$field_name.format", array_keys($formats), 'IN');
          $results = $query->execute();
        }
        catch (QueryException $e) {
          // Corrupt field map.
          continue;
        }
        if ($results) {
          foreach ($results as $entity_id) {
            $batch['operations'][] = [
              [static::class, 'analyse'],
              [$entity_type_id, $entity_id, $field_name],
            ];
          }
        }
      }

    }
    $entityTypeManager = $this->entityTypeManager;
    $entityFieldManager = $this->entityFieldManager;
    $fieldTypePluginManager = $this->fieldTypePluginManager;
    $batch = AnalysisBatchBuilder::buildAnalysisBatch($entityTypeManager, $entityFieldManager, $fieldTypePluginManager);
    batch_set($batch);
    $form_state->setRedirect('entity.analysis_result.collection');
  }
@@ -123,7 +78,7 @@ class RunAnalysisForm extends FormBase {
  /**
   * Batch callback.
   */
  public static function clear($ids, array &$context) {
  public static function clear($ids, array|\DrushBatchContext &$context) {
    $storage = \Drupal::entityTypeManager()->getStorage('analysis_result');
    $storage->delete($storage->loadMultiple($ids));
    $context['message'] = t('Deleting existing results');
@@ -132,7 +87,7 @@ class RunAnalysisForm extends FormBase {
  /**
   * Batch callback.
   */
  public static function analyse(string $entity_type_id, $entity_id, string $field_name, &$context) {
  public static function analyse(string $entity_type_id, $entity_id, string $field_name, array|\DrushBatchContext &$context) {
    $entity_type_manager = \Drupal::entityTypeManager();
    $entity_type_storage = $entity_type_manager->getStorage($entity_type_id);
    /** @var \Drupal\filter_format_audit\EntityHandlers\FilterFormatAuditHandlerInterface $handler */