You are here

public static function ImageCrop::processCrop in Image Widget Crop 8

Same name and namespace in other branches
  1. 8.2 src/Element/ImageCrop.php \Drupal\image_widget_crop\Element\ImageCrop::processCrop()

Render API callback: Expands the image_crop element type.

File

src/Element/ImageCrop.php, line 57

Class

ImageCrop
Provides a form element for crop.

Namespace

Drupal\image_widget_crop\Element

Code

public static function processCrop(&$element, FormStateInterface $form_state, &$complete_form) {

  /** @var \Drupal\file\Entity\File $file */
  $file = $element['#file'];
  if (!empty($file) && preg_match('/image/', $file
    ->getMimeType())) {
    $element['#attached']['drupalSettings']['crop_default'] = $element['#show_default_crop'];

    /** @var \Drupal\Core\Image\Image $image */
    $image = \Drupal::service('image.factory')
      ->get($file
      ->getFileUri());
    if (!$image
      ->isValid()) {
      $element['message'] = [
        '#type' => 'container',
        '#markup' => t('The file "@file" is not valid on element @name.', [
          '@file' => $file
            ->getFileUri(),
          '@name' => $element['#name'],
        ]),
        '#attributes' => [
          'class' => [
            'messages messages--error',
          ],
        ],
      ];

      // Stop image_crop process and display error message.
      return $element;
    }
    $crop_type_list = $element['#crop_type_list'];

    // Display all crop types if none is selected.
    if (empty($crop_type_list)) {

      /** @var \Drupal\image_widget_crop\ImageWidgetCropManager $image_widget_crop_manager */
      $image_widget_crop_manager = \Drupal::service('image_widget_crop.manager');
      $available_crop_types = $image_widget_crop_manager
        ->getAvailableCropType(CropType::getCropTypeNames());
      $crop_type_list = array_keys($available_crop_types);
    }
    $element['crop_wrapper'] = [
      '#type' => 'details',
      '#title' => t('Crop image'),
      '#attributes' => [
        'class' => [
          'image-data__crop-wrapper',
        ],
      ],
      '#open' => $element['#show_crop_area'],
      '#weight' => 100,
    ];
    if ($element['#warn_multiple_usages']) {

      // Warn the user if the crop is used more than once.
      $usage_counter = self::countFileUsages($file);
      if ($usage_counter > 1) {
        $element['crop_reuse'] = [
          '#type' => 'container',
          '#markup' => t('This crop definition affects more usages of this image'),
          '#attributes' => [
            'class' => [
              'messages messages--warning',
            ],
          ],
          '#weight' => -10,
        ];
      }
    }

    // Ensure that the ID of an element is unique.
    $list_id = \Drupal::service('uuid')
      ->generate();
    $element['crop_wrapper'][$list_id] = [
      '#type' => 'vertical_tabs',
      '#theme_wrappers' => [
        'vertical_tabs',
      ],
      '#parents' => [
        $list_id,
      ],
    ];

    /** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $crop_type_storage */
    $crop_type_storage = \Drupal::entityTypeManager()
      ->getStorage('crop_type');
    if (!empty($crop_type_storage
      ->loadMultiple())) {
      foreach ($crop_type_list as $crop_type) {

        /** @var \Drupal\crop\Entity\CropType $crop_type */
        $crop_type = $crop_type_storage
          ->load($crop_type);
        $ratio = $crop_type
          ->getAspectRatio() ? $crop_type
          ->getAspectRatio() : 'Nan';
        $element['#attached']['drupalSettings']['image_widget_crop'][$crop_type
          ->id()] = [
          'soft_limit' => $crop_type
            ->getSoftLimit(),
          'hard_limit' => $crop_type
            ->getHardLimit(),
        ];
        $element['crop_wrapper'][$crop_type
          ->id()] = [
          '#type' => 'details',
          '#title' => $crop_type
            ->label(),
          '#group' => $list_id,
        ];

        // Generation of html List with image & crop information.
        $element['crop_wrapper'][$crop_type
          ->id()]['crop_container'] = [
          '#type' => 'container',
          '#attributes' => [
            'class' => [
              'crop-preview-wrapper',
              $list_id,
            ],
            'id' => [
              $crop_type
                ->id(),
            ],
            'data-ratio' => [
              $ratio,
            ],
          ],
          '#weight' => -10,
        ];
        $element['crop_wrapper'][$crop_type
          ->id()]['crop_container']['image'] = [
          '#theme' => 'image_style',
          '#style_name' => $element['#crop_preview_image_style'],
          '#attributes' => [
            'class' => [
              'crop-preview-wrapper__preview-image',
            ],
            'data-ratio' => $ratio,
            'data-name' => $crop_type
              ->id(),
            'data-original-width' => $file instanceof FileEntity ? $file
              ->getMetadata('width') : getimagesize($file
              ->getFileUri())[0],
            'data-original-height' => $file instanceof FileEntity ? $file
              ->getMetadata('height') : getimagesize($file
              ->getFileUri())[1],
          ],
          '#uri' => $file
            ->getFileUri(),
          '#weight' => -10,
        ];
        $element['crop_wrapper'][$crop_type
          ->id()]['crop_container']['reset'] = [
          '#type' => 'button',
          '#value' => t('Reset crop'),
          '#attributes' => [
            'class' => [
              'crop-preview-wrapper__crop-reset',
            ],
          ],
          '#weight' => -10,
        ];

        // Generation of html List with image & crop information.
        $element['crop_wrapper'][$crop_type
          ->id()]['crop_container']['values'] = [
          '#type' => 'container',
          '#attributes' => [
            'class' => [
              'crop-preview-wrapper__value',
            ],
          ],
          '#weight' => -9,
        ];

        // Element to track whether cropping is applied or not.
        $element['crop_wrapper'][$crop_type
          ->id()]['crop_container']['values']['crop_applied'] = [
          '#type' => 'hidden',
          '#attributes' => [
            'class' => [
              "crop-applied",
            ],
          ],
          '#default_value' => 0,
        ];
        $edit = FALSE;
        $properties = [];
        $form_state_element_values = $form_state
          ->getValue($element['#parents']);

        // Check if form state has values.
        if ($form_state_element_values) {
          $form_state_properties = $form_state_element_values['crop_wrapper'][$crop_type
            ->id()]['crop_container']['values'];

          // If crop is applied by the form state we keep it that way.
          if ($form_state_properties['crop_applied'] == '1') {
            $element['crop_wrapper'][$crop_type
              ->id()]['crop_container']['values']['crop_applied']['#default_value'] = 1;
            $edit = TRUE;
          }
          $properties = $form_state_properties;
        }

        /** @var \Drupal\crop\Entity\Crop $crop */
        $crop = Crop::findCrop($file
          ->getFileUri(), $crop_type
          ->id());
        if ($crop) {
          $edit = TRUE;

          /** @var \Drupal\image_widget_crop\ImageWidgetCropManager $image_widget_crop_manager */
          $image_widget_crop_manager = \Drupal::service('image_widget_crop.manager');
          $original_properties = $image_widget_crop_manager
            ->getCropProperties($crop);

          // If form state values have the same values that were saved or if
          // form state has no values yet and there are saved values then we
          // use the saved values.
          $properties = $original_properties == $properties || empty($properties) ? $original_properties : $properties;
          $element['crop_wrapper'][$crop_type
            ->id()]['crop_container']['values']['crop_applied']['#default_value'] = 1;

          // If the user edits an entity and while adding new images resets an
          // saved crop we keep it reset.
          if (isset($properties['crop_applied']) && $properties['crop_applied'] == '0') {
            $element['crop_wrapper'][$crop_type
              ->id()]['crop_container']['values']['crop_applied']['#default_value'] = 0;
          }
        }
        self::getCropFormElement($element, 'crop_container', $properties, $edit, $crop_type
          ->id());
      }

      // Stock Original File Values.
      $element['file-uri'] = [
        '#type' => 'value',
        '#value' => $file
          ->getFileUri(),
      ];
      $element['file-id'] = [
        '#type' => 'value',
        '#value' => $file
          ->id(),
      ];
    }
  }
  return $element;
}