|
@@ -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);
|
|
|
+ }
|
|
|
+}
|