/** * Form API callback: Processes a crop_image field element. * * Expands the image_image type to include the alt and title fields. * * This method is assigned as a #process callback in formElement() method. */ public static function process($element, FormStateInterface $form_state, $form) { $item = $element['#value']; $item['fids'] = $element['fids']['#value']; $edit = FALSE; $route_params = \Drupal::requestStack()->getCurrentRequest()->attributes->get('_route_params'); if (isset($route_params['_entity_form']) && preg_match('/.edit/', $route_params['_entity_form'])) { $edit = TRUE; } $element['#theme'] = 'image_widget'; $element['#attached']['library'][] = 'image/form'; $element['#attached']['library'][] = 'image_widget_crop/drupal.image_widget_crop.admin'; $element['#attached']['library'][] = 'image_widget_crop/drupal.image_widget_crop.upload.admin'; // Add the image preview. if (!empty($element['#files']) && $element['#preview_image_style']) { $file = reset($element['#files']); $variables = array('style_name' => $element['#preview_image_style'], 'uri' => $file->getFileUri(), 'file_id' => $file->id()); /** @var \Drupal\image_widget_crop\ImageWidgetCrop $ImageWidgetCrop */ $ImageWidgetCrop = new ImageWidgetCrop(); // Determine image dimensions. if (isset($element['#value']['width']) && isset($element['#value']['height'])) { $variables['width'] = $element['#value']['width']; $variables['height'] = $element['#value']['height']; } else { $image = \Drupal::service('image.factory')->get($file->getFileUri()); if ($image->isValid()) { $variables['width'] = $image->getWidth(); $variables['height'] = $image->getHeight(); } else { $variables['width'] = $variables['height'] = NULL; } } $element['crop_preview_wrapper'] = ['#type' => 'container', '#prefix' => '<ul>', '#suffix' => '</ul>', '#attributes' => ['class' => ['preview-wrapper-crop']], '#weight' => 100]; $image_styles = \Drupal::service('entity.manager')->getStorage('image_style')->loadByProperties(['status' => TRUE]); if ($image_styles) { /** @var \Drupal\image\Entity\ImageStyle $image_style */ foreach ($image_styles as $image_style) { if (in_array($image_style->getName(), $element['#crop_list'])) { // Get the ratio of image by ImageStyle. $ratio = $ImageWidgetCrop->getSizeRatio($image_style); // Generation of html List with image & crop informations. // @todo Create new elements for styling the crop container & lists. $element['crop_preview_wrapper'][$image_style->getName()] = ['#type' => 'container', '#prefix' => "<li data-ratio={$ratio}>", '#suffix' => '</li>', '#attributes' => ['class' => ['crop-preview-wrapper-list']], '#weight' => -10]; $element['crop_preview_wrapper'][$image_style->getName()]['title'] = ['#prefix' => '<p>', '#suffix' => '</p>', '#markup' => t('@style_label - ( <b>real ratio</b> @ratio )', ['@style_label' => $image_style->label(), '@ratio' => $ratio])]; $element['crop_preview_wrapper'][$image_style->getName()]['image'] = ['#theme' => 'image_style', '#style_name' => $element['#crop_preview_image_style'], '#uri' => $variables['uri']]; // GET CROP LIBRARIE VALUES. $crop_elements = ['x1' => ['label' => t('crop x1'), 'value' => NULL], 'x2' => ['label' => t('crop x2'), 'value' => NULL], 'y1' => ['label' => t('crop y1'), 'value' => NULL], 'y2' => ['label' => t('crop y2'), 'value' => NULL], 'crop-w' => ['label' => t('crop size width'), 'value' => NULL], 'crop-h' => ['label' => t('crop size height'), 'value' => NULL], 'thumb-w' => ['label' => t('Thumbnail Width'), 'value' => NULL], 'thumb-h' => ['label' => t('Thumbnail Height'), 'value' => NULL]]; if ($edit) { $crop = \Drupal::service('entity.manager')->getStorage('crop')->loadByProperties(['type' => $ImageWidgetCrop->getCropType($image_style), 'uri' => $variables['uri'], 'image_style' => $image_style->getName()]); // Only if the crop already exist pre-populate, // all cordinates values. if (!empty($crop)) { /** @var \Drupal\crop\Entity\Crop $crop_entity */ foreach ($crop as $crop_id => $crop_entity) { $crop_properties = ['anchor' => $crop_entity->position(), 'size' => $crop_entity->size()]; } // If the current crop have a position & sizes, // calculate properties to apply crop selection into preview. if (isset($crop_properties)) { $values = static::getThumbnailCropProperties($variables['uri'], $crop_properties); } if (!empty($values)) { // Populate form crop value with values store into crop API. foreach ($crop_elements as $properties => $value) { $crop_elements[$properties]['value'] = $values[$properties]; } } } } // Generate all cordinates elements into the form when, // process is active. foreach ($crop_elements as $crop_elements_name => $crop_elements_value) { $element['crop_preview_wrapper'][$image_style->getName()][$crop_elements_name] = ['#type' => 'textfield', '#title' => $crop_elements_value['label'], '#attributes' => ['class' => ["crop-{$crop_elements_name}"]], '#default_value' => !empty($edit) ? $crop_elements_value['value'] : NULL]; } // Stock Original File Values. $element['file-uri'] = ['#type' => 'value', '#value' => $variables['uri']]; $element['file-id'] = ['#type' => 'value', '#value' => $variables['file_id']]; } } } } return parent::process($element, $form_state, $form); }
/** * Save the crop when this crop not exist. * * @param array $crop_properties * The properties of the crop applied to the original image (dimensions). * @param array|mixed $field_value * An array of values for the contained properties of image_crop widget. * @param string $image_style_name * The machine name of ImageStyle. * @param ImageWidgetCrop $image_crop * Instance of ImageWidgetCrop. */ public function saveCrop(array $crop_properties, $field_value, $image_style_name, ImageWidgetCrop $image_crop) { // Load the style image corresponding to the crop previously. /** @var \Drupal\image\Entity\ImageStyle $image_style */ $image_style = \Drupal::entityManager()->getStorage('image_style')->load($image_style_name); if ($crop_type = $image_crop->getCropType($image_style)) { $values = ['type' => $crop_type, 'entity_id' => $field_value['file-id'], 'entity_type' => 'file', 'uri' => $field_value['file-uri'], 'x' => $crop_properties['x'], 'y' => $crop_properties['y'], 'width' => $crop_properties['width'], 'height' => $crop_properties['height'], 'image_style' => $image_style_name]; // Save crop with previous values. /** @var \Drupal\crop\CropInterface $crop */ $crop = \Drupal::entityManager()->getStorage('crop')->create($values); $crop->save(); // Generate the image derivate uri. $destination_uri = $image_style->buildUri($field_value['file-uri']); // Create a derivate of the original image with a good uri. $image_style->createDerivative($field_value['file-uri'], $destination_uri); // Flush the cache of this ImageStyle. $image_style->flush($field_value['file-uri']); } else { drupal_set_message(t("The type of crop does not exist, please check the configuration of the ImageStyle ('@imageStyle')", ['@imageStyle' => $image_style_name]), 'error'); } }