view_mode_crop-1.0.x-dev/src/Plugin/Field/FieldWidget/ViewModeCropMediaLibraryWidget.php
src/Plugin/Field/FieldWidget/ViewModeCropMediaLibraryWidget.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\media\MediaInterface;
use Drupal\media_library\Plugin\Field\FieldWidget\MediaLibraryWidget;
use Drupal\view_mode_crop\CropImageHelper;
use Drupal\view_mode_crop\ViewModeCropData;
use Drupal\view_mode_crop\ViewModeCropState;
use Drupal\view_mode_crop\ViewModeCropUiBuilder;
/**
* Extends the media_library_widget plugin to support cropping.
*
* This is implemented in view_mode_crop_field_widget_info_alter.
*/
class ViewModeCropMediaLibraryWidget extends MediaLibraryWidget {
/**
* {@inheritDoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$entity = $items->getEntity();
if (!$entity instanceof ContentEntityInterface) {
return $element;
}
$referenced_entities = $items->referencedEntities();
foreach ($referenced_entities as $referenced_entity_delta => $entity_reference_item) {
/**
* @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem|null $entity_reference_item
*/
$entity_reference_item = $items->get($referenced_entity_delta);
if ($entity_reference_item === NULL) {
continue;
}
if (!isset($entity_reference_item->entity) || !($media_entity = $entity_reference_item->entity) instanceof MediaInterface) {
continue;
}
$source_field = $media_entity->getSource()
->getConfiguration()['source_field'];
$file = $media_entity->get($source_field)->entity;
if (!$file instanceof FileInterface) {
continue;
}
$view_mode_crop = $entity_reference_item->get('view_mode_crop')
->getString();
if (empty($view_mode_crop)) {
$view_mode_crop = [];
}
else {
$view_mode_crop = ViewModeCropData::createFromJsonStringArray($view_mode_crop);
}
$data = CropImageHelper::getCropData($entity, $items->getName(), $view_mode_crop);
if (empty($data)) {
continue;
}
$image_url = $file->getFileUri();
$state = new ViewModeCropState(
$entity->getEntityTypeId(),
$entity->id(),
$items->getName(),
$referenced_entity_delta,
\Drupal::service('file_url_generator')
->generateAbsoluteString($image_url),
$data
);
$element['selection'][$referenced_entity_delta]['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['selection'][$referenced_entity_delta]['view_mode_crop_open'] = [
'#type' => 'button',
'#value' => $this->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' => $this->t('Opening cropper.'),
],
'disable-refocus' => TRUE,
],
'#limit_validation_errors' => [],
'#attached' => [
'library' => [
'view_mode_crop/ui',
],
],
'#attributes' => [
'class' => [
'view_mode_crop_media_library_widget_crop_open',
'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) {
if (isset($values['selection'])) {
foreach ($values['selection'] as $delta => $value) {
if (!isset($value['view_mode_crop_state'])) {
continue;
}
$view_mode_crop_state = ViewModeCropState::createFromJsonString($value['view_mode_crop_state']);
$values['selection'][$delta]['view_mode_crop'] = json_encode($view_mode_crop_state->data);
}
}
return parent::massageFormValues($values, $form, $form_state);
}
}
