Ver código fonte

images styles generation custom module

bach 4 anos atrás
pai
commit
8964b94b9f

+ 1 - 0
config/sync/core.extension.yml

@@ -92,6 +92,7 @@ module:
   image_delta_formatter: 0
   image_effects: 0
   imagemagick: 0
+  images_styles_gen: 0
   inline_entity_form: 0
   interval: 0
   jquery_ui: 0

+ 8 - 0
web/modules/custom/images_styles_gen/images_styles_gen.info.yml

@@ -0,0 +1,8 @@
+name: 'images_styles_cron_gen'
+type: module
+description: 'helpers for progressive decoupling'
+core: 8.x
+package: 'custom'
+# https://www.flocondetoile.fr/blog/generate-programmatically-image-styles-drupal-8
+# https://www.flocondetoile.fr/blog/using-drupal-8-cron-api-generate-image-styles
+# https://www.sitepoint.com/drupal-8-queue-api-powerful-manual-and-cron-queueing/

+ 95 - 0
web/modules/custom/images_styles_gen/images_styles_gen.module

@@ -0,0 +1,95 @@
+<?php
+
+use Drupal\image\Entity\ImageStyle;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\file\FileInterface;
+
+// /**
+//  * Implements hook_entity_insert().
+//  * Generate all image styles once an Image is uploaded.
+//  */
+// function images_styles_gen_entity_insert(EntityInterface $entity) {
+//   /** @var \Drupal\file\Entity\File $entity */
+//   if ($entity instanceof FileInterface) {
+//     $image = \Drupal::service('image.factory')->get($entity->getFileUri());
+//     /** @var \Drupal\Core\Image\Image $image */
+//     if ($image->isValid()) {
+//       $styles = ImageStyle::loadMultiple();
+//       $image_uri = $entity->getFileUri();
+//       /** @var \Drupal\image\Entity\ImageStyle $style */
+//       foreach ($styles as $style) {
+//         $destination = $style->buildUri($image_uri);
+//         $style->createDerivative($image_uri, $destination);
+//       }
+//     }
+//   }
+// }
+
+/**
+ * Implements hook_entity_insert().
+ * Queue generation of all image styles once an Image is uploaded.
+ */
+// function images_styles_gen_entity_insert(EntityInterface $entity) {
+//   // TODO: IS THIS EVEN WORKING ????
+//   /** @var \Drupal\file\Entity\File $entity */
+//   if ($entity instanceof FileInterface) {
+//     $image = \Drupal::service('image.factory')->get($entity->getFileUri());
+//     /** @var \Drupal\Core\Image\Image $image */
+//     if ($image->isValid()) {
+//       $queue = \Drupal::queue('img_styles_gen');
+//       $item = new \stdClass();
+//       $item->fid = $entity->id();
+//       $queue->createItem($item);
+//       // $data = ['entity' => $entity];
+//       // $queue->createItem($data);
+//     }
+//   }
+// }
+
+// function images_styles_gen_cron_DISABLED(){
+//   $file_storage = \Drupal::entityTypeManager()->getStorage('file');
+//   $query = $file_storage->getQuery()
+//     ->condition('filemime', 'image/%', 'LIKE')
+//     ->accessCheck(TRUE);
+//   $results = $query->execute();
+//
+//   // $styles_storage = \Drupal::entityTypeManager()->getStorage('image_style');
+//   // $styles = $styles_storage->loadMultiple();
+//
+//   /** @var QueueFactory $queue_factory */
+//   $queue_factory = \Drupal::service('queue');
+//   /** @var QueueInterface $queue */
+//   $queue = $queue_factory->get('img_styles_gen');
+//
+//   foreach ($results as $fid) {
+//     $item = new \stdClass();
+//     $item->fid = $fid;
+//     $queue->createItem($item);
+//
+//     // $queue->createItem(["fid" => $fid]);
+//
+//
+//     // /** @var \Drupal\file\FileInterface|null $file*/
+//     // $file_entity = \Drupal::entityTypeManager()->getStorage('file')->load($fid);
+//     // $image = \Drupal::service('image.factory')->get($file_entity->getFileUri());
+//     //
+//     // if ($image->isValid()) {
+//     //   $image_uri = $file_entity->getFileUri();
+//     //   /** @var \Drupal\image\Entity\ImageStyle $style */
+//     //   foreach ($styles as $style) {
+//     //     $destination = $style->buildUri($image_uri);
+//     //     // if destination exists skip
+//     //     if (file_exists($destination)) continue; // skip existing files
+//     //
+//     //     $data = [
+//     //       'style' => $style,
+//     //       'image_uri' => $image_uri,
+//     //       'destination' => $destination
+//     //     ];
+//     //     $queue->createItem($data);
+//     //     \Drupal::logger('images_styles_gen')->notice("created queue from $image_uri to $destination");
+//     //   }
+//
+//     // }
+//   }
+// }

+ 7 - 0
web/modules/custom/images_styles_gen/images_styles_gen.routing.yml

@@ -0,0 +1,7 @@
+images_styles_gen.form:
+  path: '/admin/config/media/imgstylesgen'
+  defaults:
+    _form: '\Drupal\images_styles_gen\Form\ImgStylesGenQueueForm'
+    _title: 'Images Styles Generator'
+  requirements:
+    _permission: 'administer site configuration'

+ 64 - 0
web/modules/custom/images_styles_gen/src/CreateImagesStyles.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace Drupal\images_styles_gen;
+
+
+// use Drupal\node\Entity\Node;
+
+class CreateImagesStyles {
+
+  public static function createStyles($item, &$context){
+    $context['sandbox']['progress']++;
+    $context['sandbox']['current_file'] = $item->uri;
+    // $message = 'Creating Styles ...';
+    $results = array();
+
+    // foreach ($items as $item) {
+      $results[] = $item->style->createDerivative($item->uri, $item->destination);
+    // }
+    // $styles_storage = \Drupal::entityTypeManager()->getStorage('image_style');
+    // $styles = $styles_storage->loadMultiple();
+    //
+    // foreach ($fids as $fid) {
+    //   /** @var \Drupal\file\FileInterface|null $file*/
+    //   $file_entity = \Drupal::entityTypeManager()->getStorage('file')->load($fid);
+    //   $file_uri = $file_entity->getFileUri();
+    //   $image = \Drupal::service('image.factory')->get($file_uri);
+    //   // \Drupal::logger('images_styles_gen')->notice("file_uri is $file_uri");
+    //
+    //   if ($image->isValid()) {
+    //     /** @var \Drupal\image\Entity\ImageStyle $style */
+    //     foreach ($styles as $style) {
+    //       $destination = $style->buildUri($file_uri);
+    //       // if destination exists skip
+    //       if (file_exists($destination)) continue; // skip existing files
+    //
+    //       $results[] = $style->createDerivative($file_uri, $destination);
+    //       // \Drupal::logger('images_styles_gen')->notice("Generated style $file_uri to $destination");
+    //     }
+    //
+    //   }
+    //
+    //
+    // }
+    // $context['message'] = $message;
+    // $context['results'] = $results;
+    $context['message'] = $item->uri . ' processed.';
+    $context['results'][] = $item->destination;
+  }
+
+  public static function createStylesFinishedCallback($success, $results, $operations) {
+    // The 'success' parameter means no fatal PHP errors were detected. All
+    // other error management should be handled using 'results'.
+    if ($success) {
+      $message = \Drupal::translation()->formatPlural(
+        count($results),
+        'One image processed.', '@count image processed.'
+      );
+    }
+    else {
+      $message = t('Finished with an error.');
+    }
+    drupal_set_message($message);
+  }
+}

+ 274 - 0
web/modules/custom/images_styles_gen/src/Form/ImgStylesGenQueueForm.php

@@ -0,0 +1,274 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\npq\Form\NodePublisherQueueForm.
+ */
+
+namespace Drupal\images_styles_gen\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Queue\QueueFactory;
+use Drupal\Core\Queue\QueueInterface;
+use Drupal\Core\Queue\QueueWorkerInterface;
+use Drupal\Core\Queue\QueueWorkerManagerInterface;
+use Drupal\Core\Queue\SuspendQueueException;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+class ImgStylesGenQueueForm extends FormBase {
+
+  /**
+   * @var QueueFactory
+   */
+  protected $queueFactory;
+
+  /**
+   * @var QueueWorkerManagerInterface
+   */
+  protected $queueManager;
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(QueueFactory $queue, QueueWorkerManagerInterface $queue_manager) {
+    $this->queueFactory = $queue;
+    $this->queueManager = $queue_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('queue'),
+      $container->get('plugin.manager.queue_worker')
+    );
+  }
+
+  /**
+   * {@inheritdoc}.
+   */
+  public function getFormId() {
+    return 'images_styles_gen_form';
+  }
+
+  /**
+   * {@inheritdoc}.
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+
+    $styles_storage = \Drupal::entityTypeManager()->getStorage('image_style');
+
+    $content_type_id = $form_state->getValue('node_type');
+    $style_id = $form_state->getValue('style');
+    $batch_size = (int)$form_state->getValue('batch_size');
+
+    $num_rows = 0;
+    if ( $content_type_id && $style_id ) {
+
+      $database = \Drupal::database();
+      $query = $database->select('file_managed', 'fm');
+      $query->join('file_usage', 'fu', 'fm.fid = fu.fid');
+      $query->join('node', 'n', 'fu.id = n.nid');
+      $query
+        ->condition('fm.filemime', 'image/%', 'LIKE')
+        ->condition('fu.type', 'node')
+        ->condition('n.type', $content_type_id)
+        ->fields('fm', ['fid', 'uri'])
+        ->fields('fu', ['id']);
+
+      $results = $query->execute();
+
+      /** @var \Drupal\image\Entity\ImageStyle $style */
+      $style = $styles_storage->load($style_id);
+
+      foreach ($results as $file) {
+        $destination = $style->buildUri($file->uri);
+        if (file_exists($destination)) continue; // if destination exists skip
+        $num_rows++;
+      }
+    }
+
+
+    // select from content type we'll generate derivatives
+    $contentTypes = \Drupal::service('entity.manager')->
+    getStorage('node_type')->loadMultiple();
+    $contentTypesList = [0 => "please choose a content type"];
+    foreach ($contentTypes as $contentType) {
+        $contentTypesList[$contentType->id()] = $contentType->label();
+    }
+    $form['node_type'] = array(
+      "#type" => "select",
+      "#title" => "Content type",
+      '#options' => $contentTypesList,
+      '#ajax' => [
+        'callback' => '::countAjaxCallback', // don't forget :: when calling a class method.
+        //'callback' => [$this, 'myAjaxCallback'], //alternative notation
+        'disable-refocus' => FALSE, // Or TRUE to prevent re-focusing on the triggering element.
+        'event' => 'change',
+        'wrapper' => 'edit-help-wrapper', // This element is updated with this AJAX callback.
+        'progress' => [
+          'type' => 'throbber',
+          'message' => $this->t('counting entries...'),
+        ],
+      ]
+    );
+
+    // select for which style will generate derivatives
+    $styles = $styles_storage->loadMultiple(); //, 'card_full', 'linkedmaterial_card'
+    $stylesList = [0 => "please choose a style"];
+    foreach ($styles as $style) {
+        $stylesList[$style->id()] = $style->label();
+    }
+    $form['style'] = array(
+      "#type" => "select",
+      "#title" => "Images Styles",
+      '#options' => $stylesList,
+      '#ajax' => [
+        'callback' => '::countAjaxCallback', // don't forget :: when calling a class method.
+        //'callback' => [$this, 'myAjaxCallback'], //alternative notation
+        'disable-refocus' => FALSE, // Or TRUE to prevent re-focusing on the triggering element.
+        'event' => 'change',
+        'wrapper' => 'edit-help-wrapper', // This element is updated with this AJAX callback.
+        'progress' => [
+          'type' => 'throbber',
+          'message' => $this->t('counting entries...'),
+        ],
+      ]
+    );
+
+    $form['batch_size'] = array(
+      '#type' => 'select',
+      '#title' => 'Batch size',
+      '#options' => array(
+        10 => '10',
+        100 => '100',
+        500 => '500',
+        1000 => '1000',
+        50000 => '5000',
+        10000 => '10000',
+        0 => 'no limit'
+      ),
+      '#ajax' => [
+        'callback' => '::countAjaxCallback', // don't forget :: when calling a class method.
+        //'callback' => [$this, 'myAjaxCallback'], //alternative notation
+        'disable-refocus' => FALSE, // Or TRUE to prevent re-focusing on the triggering element.
+        'event' => 'change',
+        'wrapper' => 'edit-help-wrapper', // This element is updated with this AJAX callback.
+        'progress' => [
+          'type' => 'throbber',
+          'message' => $this->t('counting entries...'),
+        ],
+      ]
+    );
+
+    $form['help-wrapper'] = array(
+      '#type' => 'container'
+    );
+
+    $form['help-wrapper']['help'] = array(
+      '#type' => 'markup',
+      // '#prefix' => '<div>',
+      '#markup' => $this->t('Please choose a content type and a style.'),
+      // '#suffix' => '</div>',
+      '#attributes' => array(
+        'id' => 'help'
+      )
+    );
+
+    if ($num_rows) {
+      if($batch_size == 0){
+        $batch_size = $num_rows;
+      }
+      $form['help-wrapper']['help']['#markup'] = $this->t('Submitting this form will process @batch_size of @number images.', array('@batch_size' => $batch_size, '@number' => $num_rows));
+      // $form['actions']['submit']['#disabled'] = FALSE;
+      // unset($form['actions']['submit']['#attributes']['disabled']);
+    }
+
+    $form['help-wrapper']['num_rows'] = array(
+      '#type' => 'hidden',
+      '#value' => $num_rows,
+    );
+
+    // Actions
+    $form['actions']['#type'] = 'actions';
+
+    $form['actions']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => $this->t('Create image derivatives'),
+      '#button_type' => 'primary',
+      // '#disabled' => true,
+      '#states' => [
+        //show this submit only if the num rows is not empty
+        'visible' => [
+          //don't mistake :input for the type of field. You'll always use
+          //:input here, no matter whether your source is a select, radio or checkbox element.
+          ':input[name="num_rows"]' => ['!value' => 0],
+        ],
+      ],
+    );
+
+    return $form;
+  }
+
+  // Get the value from example select field and fill
+  // the textbox with the selected text.
+  public function countAjaxCallback(array &$form, FormStateInterface $form_state) {
+    $form['help-wrapper']['#id'] = 'edit-help-wrapper';
+    return $form['help-wrapper'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $content_type_id = $form_state->getValue('node_type');
+    $style_id = $form_state->getValue('style');
+    $batch_size = (int)$form_state->getValue('batch_size');
+
+    $database = \Drupal::database();
+    $query = $database->select('file_managed', 'fm');
+    $query->join('file_usage', 'fu', 'fm.fid = fu.fid');
+    $query->join('node', 'n', 'fu.id = n.nid');
+    $query
+      ->condition('fm.filemime', 'image/%', 'LIKE')
+      ->condition('fu.type', 'node')
+      ->condition('n.type', $content_type_id)
+      ->fields('fm', ['fid', 'uri'])
+      ->fields('fu', ['id']);
+
+    $results = $query->execute();
+
+    $styles_storage = \Drupal::entityTypeManager()->getStorage('image_style');
+    /** @var \Drupal\image\Entity\ImageStyle $style */
+    $style = $styles_storage->load($style_id);
+
+    $operations = [];
+    foreach ($results as $file) {
+      $destination = $style->buildUri($file->uri);
+
+      if (file_exists($destination)) continue; // skip existing files
+
+      $batch_item = new \stdClass();
+      $batch_item->style = $style;
+      $batch_item->uri = $file->uri;
+      $batch_item->destination = $destination;
+
+      $operations[] = ['\Drupal\images_styles_gen\CreateImagesStyles::createStyles', [$batch_item]];
+
+      if($batch_size && count($operations) >= $batch_size){
+        break;
+      }
+    }
+
+    $batch = array(
+      'title' => t('Creating images derivatives ...'),
+      'operations' => $operations,
+      'finished' => '\Drupal\images_styles_gen\CreateImagesStyles::createStylesFinishedCallback',
+    );
+
+    batch_set($batch);
+  }
+}