view_mode_crop-1.0.x-dev/src/Plugin/Field/FieldWidget/ViewModeCropImageWidget.php
src/Plugin/Field/FieldWidget/ViewModeCropImageWidget.php
<?php
namespace Drupal\view_mode_crop\Plugin\Field\FieldWidget;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\FileInterface;
use Drupal\image\Plugin\Field\FieldWidget\ImageWidget;
use Drupal\view_mode_crop\Plugin\Field\FieldType\ViewModeCropImageItem;
use Drupal\view_mode_crop\ViewModeCropState;
use Drupal\view_mode_crop\ViewModeCropUiBuilder;
/**
* Extends the image_image plugin to support cropping.
*
* This is implemented in view_mode_crop_field_widget_info_alter.
*/
class ViewModeCropImageWidget extends ImageWidget {
/**
* {@inheritDoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
if ($this->fieldDefinition->getTargetEntityTypeId() !== 'media') {
// If this image is added to a media entity, we won't allow cropping
// because we only want users to crop images on other entities
// media entities are attached to, for example nodes or paragrpahs.
$element['#view_mode_crop_entity'] = $items->getEntity();
}
return $element;
}
/**
* {@inheritDoc}
*/
public static function process($element, FormStateInterface $form_state, $form) {
$element = parent::process($element, $form_state, $form);
$field_name = $element['#field_name'];
$delta = $element['#delta'];
$file = reset($element['#files']);
if (!$file instanceof FileInterface || empty($element['#view_mode_crop_entity']) || !$element['#view_mode_crop_entity'] instanceof ContentEntityInterface) {
return $element;
}
$entity = $element['#view_mode_crop_entity'];
/**
* @var \Drupal\view_mode_crop\Plugin\Field\FieldType\ViewModeCropImageItem $view_mode_crop_image_item
*/
$view_mode_crop_image_item = $entity->get($field_name)->get($delta);
if (!$view_mode_crop_image_item instanceof ViewModeCropImageItem) {
return $element;
}
$data = $view_mode_crop_image_item->getViewModeCropData();
if (empty($data)) {
// Cropping not available.
return $element;
}
$state = new ViewModeCropState(
$entity->getEntityTypeId(),
$entity->uuid(),
$field_name,
$delta,
\Drupal::service('file_url_generator')
->generateAbsoluteString($file->getFileUri()),
$data
);
$element['view_mode_crop_state'] = [
'#type' => 'textarea',
'#default_value' => json_encode($state),
'#attributes' => [
'data-view-mode-crop-triggering-element-name' => $state->entityTypeId . '-' . $state->id . '-' . $state->fieldName . '-' . $state->delta,
],
];
$element['file_38']['view_mode_crop_open'] = [
'#type' => 'button',
'#value' => t('Crop'),
'#name' => $state->entityTypeId . '-' . $state->id . '-' . $state->fieldName . '-' . $state->delta,
'#view_mode_crop_state' => $state,
'#ajax' => [
'callback' => [static::class, 'openCrop'],
'progress' => [
'type' => 'throbber',
'message' => t('Opening cropper.'),
],
'disable-refocus' => TRUE,
],
'#limit_validation_errors' => [],
'#attached' => [
'library' => [
'view_mode_crop/ui',
],
],
'#attributes' => [
'class' => [
'icon-link',
'button',
'view-mode-crop-open-button',
],
],
];
return $element;
}
/**
* AJAX callback to open the cropper modal.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* An AJAX response to open the cropper.
*/
public static function openCrop(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$view_mode_crop_ui = \Drupal::service('view_mode_crop.ui_builder')
->buildUi($triggering_element);
$dialog_options = ViewModeCropUiBuilder::dialogOptions($triggering_element['#view_mode_crop_state']);
return (new AjaxResponse())
->addCommand(new OpenModalDialogCommand($dialog_options['title'], $view_mode_crop_ui, $dialog_options));
}
/**
* {@inheritDoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
foreach ($values as $delta => $value) {
if (!empty($value['view_mode_crop_state'])) {
$view_mode_crop_state = ViewModeCropState::createFromJsonString($value['view_mode_crop_state']);
$values[$delta]['view_mode_crop'] = json_encode($view_mode_crop_state->data);
}
else {
$values[$delta]['view_mode_crop'] = NULL;
}
}
return parent::massageFormValues($values, $form, $form_state);
}
}
