Commit 363bf966 authored by George's avatar George
Browse files

Issue #3102639 by vidorado: New Migrate plugin and new configurable behavior...

Issue #3102639 by vidorado: New Migrate plugin and new configurable behavior on flushing: unlink/regenerate.
parent a39da538
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -5,12 +5,17 @@ namespace Drupal\flush_single_image;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManager;
use Drupal\image\Entity\ImageStyle;

/**
 * Class FlushSingleImage.
 */
class FlushSingleImage implements FlushSingleImageInterface {

  const ACTION_UNLINK = 1;

  const ACTION_REGENERATE = 2;

  /**
   * Drupal\Core\Entity\EntityTypeManager definition.
   *
@@ -36,11 +41,22 @@ class FlushSingleImage implements FlushSingleImageInterface {
  /**
   * {inheritdoc}
   */
  public function flush($path) {
  public function flush($path, $action = self::ACTION_UNLINK) {
    if (!in_array($action, [self::ACTION_UNLINK, self::ACTION_REGENERATE])) {
      throw new \InvalidArgumentException("The argument \$action must be either " . get_class($this) . "::ACTION_UNLINK or " . get_class($this) . "::ACTION_REGENERATE");
    }

    $style_paths = $this->getStylePaths($path);
    foreach ($style_paths as $style_path) {
    foreach ($style_paths as $style_id => $style_path) {
      $this->fileSystem->unlink($style_path);
      if ($action == self::ACTION_UNLINK) {
        $this->fileSystem->unlink($style_path);
      }
      elseif ($action == self::ACTION_REGENERATE) {
        $imageStyle = ImageStyle::load($style_id);
        $imageStyle->createDerivative($path, $style_path);
      }
    }

    return $style_paths;
  }
@@ -52,17 +68,18 @@ class FlushSingleImage implements FlushSingleImageInterface {
    $path = $this->buildUri($path);
    $styles = $this->entityTypeManager->getStorage('image_style')
      ->loadMultiple();
    $style_paths = [];

    $style_paths = [];
    foreach ($styles as $style) {
      /** @var \Drupal\image\Entity\ImageStyle  $style */
      $style_path = $style->buildUri($path);
      if (is_file($style_path) && file_exists($style_path)) {
        $style_paths[] = $style_path;
        $style_paths[$style->id()] = $style_path;
      }
      $path_parts = pathinfo($style_path);
      $style_path_webp = $path_parts['dirname'] . '/' . $path_parts['filename'] . '.webp';
      if (is_file($style_path_webp) && file_exists($style_path_webp)) {
        $style_paths[] = $style_path_webp;
        $style_paths[$style->id()] = $style_path_webp;
      }
    }

+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ interface FlushSingleImageInterface {
  public function flush($path);

  /**
   * The the image styles currently cached for given image path.
   * The image styles currently cached for given image path.
   *
   * @param string $path
   *   The filename to flush from all styles. This can be a relative path which
+114 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\flush_single_image\Plugin\migrate\process;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\flush_single_image\FlushSingleImageInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Flushes (deleting or regenerating) existent image derivatives from a single
 * image
 *
 * The source value is the final destination of the file (usually the return
 * value from Migrate Download process plugin)
 *
 * Available configuration keys:
 * - action:
 *   - 'unlink' - (default) Deletes existent image derivatives.
 *   - 'regenerate' - Regenerates existent image derivatives.
 *
 * Examples:
 *
 * @code
 * process:
 *   path_to_file:
 *     -
 *       plugin: file_copy
 *       source:
 *         - /path/to/file.png
 *         - public://new/path/to/file.png
 *     -
 *       plugin: flush_single_image
 *       action: 'regenerate'
 *
 * @endcode
 *
 * This will download /path/to/file.png to public://new/path/to/file.png
 * (replacing it if it already exists (this is the default behavior of
 *   file_copy plugin) and flush all image derivatives previously created for
 *   image public://new/path/to/file.png
 *
 *
 * @MigrateProcessPlugin(
 *   id = "flush_single_image"
 * )
 */
class FlushSingleImage extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  /**
   * The flush_single_image service.
   *
   * @var \Drupal\flush_single_image\FlushSingleImage
   */
  protected $flushSingleImageService;

  /**
   * Constructs a flush single image process plugin.
   *
   * @param array $configuration
   *   The plugin configuration.
   * @param string $plugin_id
   *   The plugin ID.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\flush_single_image\FlushSingleImage $flushSingleImageService
   *   The flush single image service.
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, FlushSingleImageInterface $flushSingleImageService) {
    if (!empty($configuration['action'] && !in_array($configuration['action'], [
        'unlink',
        'regenerate',
      ]))) {
      throw new \InvalidArgumentException("The 'action' parameter must be empty, 'unlink' or 'regenerate'");
    }

    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->flushSingleImageService = $flushSingleImageService;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('flush_single_image')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $action = $this->flushSingleImageService::ACTION_UNLINK;
    if (!empty($this->configuration['action'])) {
      switch ($this->configuration['action']) {
        case 'regenerate':
          $action = $this->flushSingleImageService::ACTION_REGENERATE;
          break;
        case 'unlink':
          $action = $this->flushSingleImageService::ACTION_UNLINK;
          break;
      }
    }
    $this->flushSingleImageService->flush($value, $action);
    return $value;
  }

}