cloudinary-8.x-1.x-dev/modules/cloudinary_media_library_widget/src/Form/CloudinaryUploadForm.php
modules/cloudinary_media_library_widget/src/Form/CloudinaryUploadForm.php
<?php
namespace Drupal\cloudinary_media_library_widget\Form;
use Drupal\cloudinary_sdk\Service\AssetHelperInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\file\Plugin\Field\FieldType\FileItem;
use Drupal\media\MediaInterface;
use Drupal\media_library\Form\AddFormBase;
use Drupal\media_library\MediaLibraryUiBuilderInterface;
use Drupal\media_library\OpenerResolverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Creates a form to create media entities from cloudinary assets.
*
* @internal
* Form classes are internal.
*/
class CloudinaryUploadForm extends AddFormBase {
/**
* The asset helper.
*
* @var \Drupal\cloudinary_sdk\Service\AssetHelperInterface
*/
protected AssetHelperInterface $assetHelper;
/**
* {@inheritdoc}
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, MediaLibraryUiBuilderInterface $library_ui_builder, OpenerResolverInterface $opener_resolver, AssetHelperInterface $asset_helper) {
parent::__construct($entity_type_manager, $library_ui_builder, $opener_resolver);
$this->assetHelper = $asset_helper;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('media_library.ui_builder'),
$container->get('media_library.opener_resolver'),
$container->get('cloudinary_sdk.asset_helper')
);
}
/**
* {@inheritdoc}
*/
protected function buildInputElement(array $form, FormStateInterface $form_state) {
$state = $this->getMediaLibraryState($form_state);
if (!$state->hasSlotsAvailable()) {
return $form;
}
$media_type = $this->getMediaType($form_state);
$field_definition = $media_type->getSource()->getSourceFieldDefinition($media_type);
$configuration = $media_type->getSource()->getConfiguration();
$resource_type = $configuration['resource_type'];
// Add a container to group the input elements for styling purposes.
$form['container'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['js-form-cloudinary-container'],
],
];
$slots = $state->getAvailableSlots();
$form['container']['asset'] = [
'#type' => 'cloudinary_media_library',
'#extended' => TRUE,
'#title' => $field_definition->getLabel(),
'#required' => $field_definition->isRequired(),
'#field_name' => $field_definition->getName(),
'#resource_type' => $resource_type,
'#preview' => TRUE,
'#multiple' => $slots > 1 || $slots === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
'#cardinality' => $slots,
];
$form['container']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Add asset'),
'#button_type' => 'primary',
'#validate' => ['::validateAsset'],
'#submit' => ['::addButtonSubmit'],
'#attributes' => ['class' => ['js-hide', 'add-asset-button']],
// @todo Move validation in https://www.drupal.org/node/2988215
'#ajax' => [
'callback' => '::updateFormCallback',
'wrapper' => 'media-library-wrapper',
// Add a fixed URL to post the form since AJAX forms are automatically
// posted to <current> instead of $form['#action'].
// @todo Remove when https://www.drupal.org/project/drupal/issues/2504115
// is fixed.
'url' => Url::fromRoute('media_library.ui'),
'options' => [
'query' => $this->getMediaLibraryState($form_state)->all() + [
FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
],
],
],
];
return $form;
}
/**
* Validates the asset value.
*
* @param array $form
* The complete form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current form state.
*/
public function validateAsset(array &$form, FormStateInterface $form_state) {
if ($asset_value = $form_state->getValue(['asset', 'value'])) {
$multiple = $form['container']['asset']['#multiple'];
if ($multiple) {
$values = Json::decode($asset_value);
$values = array_column($values, 'value');
}
else {
$values = [$asset_value];
}
foreach ($values as $value) {
if (!$this->assetHelper->isApplicable($value)) {
$form_state->setErrorByName('asset[value]', $this->t('The asset value is invalid.'));
break;
}
}
}
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return $this->getBaseFormId() . '_cloudinary';
}
/**
* {@inheritdoc}
*/
protected function prepareMediaEntityForSave(MediaInterface $media) {
$field_name = $media->getSource()->getConfiguration()['source_field'];
foreach ($media->get($field_name) as $item) {
if ($item instanceof FileItem) {
/** @var \Drupal\file\FileInterface $file */
$file = $item->entity;
$file->setPermanent();
$file->save();
}
}
}
/**
* Submit handler for the add button.
*
* @param array $form
* The form render array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
public function addButtonSubmit(array $form, FormStateInterface $form_state) {
$asset_info = $form_state->getValue('asset');
if (isset($asset_info['type'])) {
unset($asset_info['type']);
}
if (isset($asset_info['value'])) {
unset($asset_info['value']);
}
$multiple = $form['container']['asset']['#multiple'];
if ($multiple) {
$values = [];
foreach ($asset_info as $delta => $value) {
unset($value['type']);
unset($value['value']);
$values[$delta] = $value;
}
}
else {
$values = [$asset_info];
}
$this->processInputValues($values, $form, $form_state);
}
}
