brandfolder-8.x-1.x-dev/src/Plugin/ImageToolkit/BrandfolderToolkit.php

src/Plugin/ImageToolkit/BrandfolderToolkit.php
<?php

namespace Drupal\brandfolder\Plugin\ImageToolkit;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\ImageToolkit\ImageToolkitBase;
use Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Database\Connection;

/**
 * Defines the Brandfolder toolkit for image manipulation within Drupal.
 *
 * @ImageToolkit(
 *   id = "brandfolder",
 *   title = @Translation("Brandfolder image toolkit supporting CDN-based image transformations")
 * )
 */
class BrandfolderToolkit extends ImageToolkitBase {

  /**
   * DB connection.
   *
   * @var Connection
   */
  protected Connection $db;

  /**
   * A record of all image operations applied to the current image.
   *
   * @var array
   */
  protected array $operationsRecord = [];

  /**
   * Parameters to apply to the CDN URL for the source image.
   *
   * @var array
   */
  protected array $brandfolder_cdn_url_params = [];

  /**
   * Array with key file info.
   *
   * @var array
   */
  protected array $file_data = [];

  /**
   * A semi-immutable copy of the file data array, for reference.
   * This will only be set/reset when parseFile() is called.
   *
   * @var array
   */
  protected array $original_file_data = [];

  /**
   * Image type represented by a PHP IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG).
   *
   * @var int
   */
  protected int $type;

  /**
   * Constructs a BrandfolderToolkit object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param array $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\ImageToolkit\ImageToolkitOperationManagerInterface $operation_manager
   *   The toolkit operation manager.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Database\Connection $db_connection
   *   A database connection.
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImageToolkitOperationManagerInterface $operation_manager, LoggerInterface $logger, ConfigFactoryInterface $config_factory, Connection $db_connection) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $operation_manager, $logger, $config_factory);
    $this->db = $db_connection;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): BrandfolderToolkit {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('image.toolkit.operation.manager'),
      $container->get('logger.channel.image'),
      $container->get('config.factory'),
      $container->get('database')
    );
  }

  /**
   * Record an image processing operation in order to maintain a record of all
   * operations, in sequence. This context can be used to convert traditional
   * image manipulation sequences into a set of CDN URL parameters that will
   * achieve the same end result.
   *
   * @param string $operation_name The name of the operation, e.g. "resize."
   * @param array $operation_arguments All arguments passed to the operation.
   */
  public function recordOperation(string $operation_name, array $operation_arguments): void {
    $this->operationsRecord[] = [
      'operation' => $operation_name,
      'arguments' => $operation_arguments,
      'file_data' => $this->file_data,
      'bf_cdn_url_params' => $this->brandfolder_cdn_url_params,
    ];
  }

  /**
   * Get a record of all operations performed so far.
   *
   * @return array
   *   The operations record.
   */
  public function getOperationsRecord(): array {
    return $this->operationsRecord;
  }

  /**
   * Populate/overwrite the file_data array.
   *
   * @param array $file_data
   *
   * @return void
   */
  public function setFileData(array $file_data): void {
    $this->file_data = $file_data;
  }

  /**
   * Set an individual item in the file_data array.
   *
   * @param string $key
   * @param $value
   *
   * @return void
   */
  public function setFileDataItem(string $key, $value): void {
    $this->file_data[$key] = $value;
  }

  /**
   * Get the file_data array.
   *
   * @return array
   */
  public function getFileData(): array {
    return $this->file_data;
  }

  /**
   * Get an individual item from the file_data array.
   *
   * @param string $key
   *
   * @return mixed
   */
  public function getFileDataItem(string $key): mixed {
    return $this->file_data[$key] ?? NULL;
  }

  /**
   * Get the original_file_data array.
   *
   * @return array
   */
  public function getOriginalFileData(): array {
    return $this->original_file_data;
  }

  /**
   * Get an individual item from the original_file_data array.
   *
   * @param string $key
   *
   * @return mixed
   */
  public function getOriginalFileDataItem(string $key): mixed {
    return $this->original_file_data[$key] ?? NULL;
  }

  /**
   * Populate an array of Brandfolder CDN URL query parameters relevant to the
   * current image operation.
   *
   * @param array $params
   */
  public function setCdnUrlParams(array $params): void {
    $this->brandfolder_cdn_url_params = array_merge($this->brandfolder_cdn_url_params, $params);
  }

  /**
   * Retrieve an array of Brandfolder CDN URL query parameters relevant to the
   * current image operation.
   *
   * @return array
   */
  public function getCdnUrlParams(): array {
    return $this->brandfolder_cdn_url_params;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {

    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {}

  /**
   * {@inheritdoc}
   */
  public function isValid(): bool {
    // @todo
    return !empty($this->file_data);
  }

  /**
   * {@inheritdoc}
   */
  public function save($destination): bool {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function parseFile(): bool {
    $uri = $this->getSource();
    if (preg_match('/^bf:\/\/[^\/]+\/at\/([^\/]+)\/([^.]*\.([^?]+))?/', $uri, $matches)) {
      $bf_attachment_id = $matches[1];
      $query = $this->db->select('brandfolder_file', 'bf')
        ->fields('bf', ['filesize', 'width', 'height', 'mime_type', 'bf_attachment_id'])
        ->condition('bf_attachment_id', $bf_attachment_id);
      if ($query->countQuery()->execute()->fetchField() > 0) {
        $result = $query->execute();
        $file_data = $result->fetchAssoc();
        if (empty($this->original_file_data)) {
          $this->original_file_data = $file_data;
        }
        $this->file_data = $file_data;

        $extension = $matches[3] ?? '';
        $this->setType($this->extensionToImageType($extension));

        return TRUE;
      }
    }
    // @todo: Consider trying to (re)load the attachment from Brandfolder if no local record is found, and/or log, and/or perform cleanup operations.

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public static function isAvailable() : bool {
    // @todo: Perhaps check to ensure BF credentials/API are available.
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getWidth() {
    if (empty($this->file_data['width'])) {
      $this->parseFile();
    }

    return $this->file_data['width'];
  }

  /**
   * {@inheritdoc}
   */
  public function getHeight() {
    if (empty($this->file_data['height'])) {
      $this->parseFile();
    }

    return $this->file_data['height'];
  }

  /**
   * Get the file size of the image, in bytes.
   *
   * @return int
   */
  public function getFileSize(): int {
    if (empty($this->file_data['filesize'])) {
      $this->parseFile();
    }

    return $this->file_data['filesize'];
  }

  /**
   * Gets the PHP type of the image.
   *
   * @return int
   *   The image type represented by a PHP IMAGETYPE_* constant (e.g.
   *   IMAGETYPE_JPEG).
   */
  public function getType() : int {
    return $this->type;
  }

  /**
   * Sets the PHP type of the image.
   *
   * @param int $type
   *   The image type represented by a PHP IMAGETYPE_* constant (e.g.
   *   IMAGETYPE_JPEG).
   *
   * @return $this
   */
  public function setType(int $type) : BrandfolderToolkit {
    if (in_array($type, static::supportedTypes())) {
      $this->type = $type;
    }

    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getMimeType(): string {

    return $this->getType() ? image_type_to_mime_type($this->getType()) : '';
  }

  /**
   * {@inheritdoc}
   *
   * @todo: is this necessary? We want to serve a CDN URL regardless of apparent file extension.
   */
  public static function getSupportedExtensions(): array {
    $extensions = [];
    foreach (static::supportedTypes() as $image_type) {
      // @todo Automatically fetch possible extensions for each mime type.
      // @see https://www.drupal.org/node/2311679
      $extension = mb_strtolower(image_type_to_extension($image_type, FALSE));
      $extensions[] = $extension;
    }
    // Add some more variants.
    $extensions[] = 'jpg';
    $extensions[] = 'jpe';

    return $extensions;
  }

  /**
   * Returns the IMAGETYPE_xxx constant for the given extension.
   *
   * This is the reverse of the image_type_to_extension() function.
   *
   * @param string $extension
   *   The extension to get the IMAGETYPE_xxx constant for.
   *
   * @return int
   *   The IMAGETYPE_xxx constant for the given extension, or IMAGETYPE_UNKNOWN
   *   for unsupported extensions.
   *
   * @see image_type_to_extension()
   */
  public function extensionToImageType(string $extension): int {
    if (in_array($extension, ['jpe', 'jpg'])) {
      $extension = 'jpeg';
    }
    foreach ($this->supportedTypes() as $type) {
      if (image_type_to_extension($type, FALSE) === $extension) {

        return $type;
      }
    }

    return IMAGETYPE_UNKNOWN;
  }

  /**
   * Returns a list of image types supported by the toolkit.
   *
   * @return array
   *   An array of available image types. An image type is represented by a PHP
   *   IMAGETYPE_* constant (e.g. IMAGETYPE_JPEG, IMAGETYPE_PNG, etc.).
   */
  protected static function supportedTypes(): array {
    return [
      IMAGETYPE_UNKNOWN,
      IMAGETYPE_GIF,
      IMAGETYPE_JPEG,
      IMAGETYPE_PNG,
      IMAGETYPE_SWF,
      IMAGETYPE_PSD,
      IMAGETYPE_BMP,
      IMAGETYPE_TIFF_II,
      IMAGETYPE_TIFF_MM,
      IMAGETYPE_JPEG2000,
      IMAGETYPE_JPC,
      IMAGETYPE_JP2,
      IMAGETYPE_JPX,
      IMAGETYPE_JB2,
      IMAGETYPE_SWC,
      IMAGETYPE_IFF,
      IMAGETYPE_WBMP,
      IMAGETYPE_XBM,
      IMAGETYPE_ICO,
      IMAGETYPE_WEBP,
    ];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc