class QuickEditImageController

Same name in this branch
  1. 9 core/modules/quickedit/src/Controller/QuickEditImageController.php \Drupal\quickedit\Controller\QuickEditImageController
Same name in other branches
  1. 8.9.x core/modules/image/src/Controller/QuickEditImageController.php \Drupal\image\Controller\QuickEditImageController

Returns responses for our image routes.

Hierarchy

Expanded class hierarchy of QuickEditImageController

1 file declares its use of QuickEditImageController
QuickEditImageControllerTest.php in core/modules/image/tests/src/Kernel/QuickEditImageControllerTest.php

File

core/modules/image/src/Controller/QuickEditImageController.php, line 24

Namespace

Drupal\image\Controller
View source
class QuickEditImageController extends ControllerBase {
    
    /**
     * Stores The Quick Edit tempstore.
     *
     * @var \Drupal\Core\TempStore\PrivateTempStore
     */
    protected $tempStore;
    
    /**
     * The renderer.
     *
     * @var \Drupal\Core\Render\RendererInterface
     */
    protected $renderer;
    
    /**
     * The image factory.
     *
     * @var \Drupal\Core\Image\ImageFactory
     */
    protected $imageFactory;
    
    /**
     * The entity display repository service.
     *
     * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
     */
    protected $entityDisplayRepository;
    
    /**
     * The file system.
     *
     * @var \Drupal\Core\File\FileSystemInterface
     */
    protected $fileSystem;
    
    /**
     * Constructs a new QuickEditImageController.
     *
     * @param \Drupal\Core\Render\RendererInterface $renderer
     *   The renderer.
     * @param \Drupal\Core\Image\ImageFactory $image_factory
     *   The image factory.
     * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
     *   The tempstore factory.
     * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
     *   The entity display repository service.
     * @param \Drupal\Core\File\FileSystemInterface $file_system
     *   The file system.
     */
    public function __construct(RendererInterface $renderer, ImageFactory $image_factory, PrivateTempStoreFactory $temp_store_factory, EntityDisplayRepositoryInterface $entity_display_repository, FileSystemInterface $file_system) {
        $this->renderer = $renderer;
        $this->imageFactory = $image_factory;
        $this->tempStore = $temp_store_factory->get('quickedit');
        $this->entityDisplayRepository = $entity_display_repository;
        $this->fileSystem = $file_system;
    }
    
    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container) {
        return new static($container->get('renderer'), $container->get('image.factory'), $container->get('tempstore.private'), $container->get('entity_display.repository'), $container->get('file_system'));
    }
    
    /**
     * Returns JSON representing the new file upload, or validation errors.
     *
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The entity of which an image field is being rendered.
     * @param string $field_name
     *   The name of the (image) field that is being rendered
     * @param string $langcode
     *   The language code of the field that is being rendered.
     * @param string $view_mode_id
     *   The view mode of the field that is being rendered.
     *
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     *   The JSON response.
     */
    public function upload(EntityInterface $entity, $field_name, $langcode, $view_mode_id) {
        $field = $this->getField($entity, $field_name, $langcode);
        $field_validators = $field->getUploadValidators();
        $field_settings = $field->getFieldDefinition()
            ->getSettings();
        $destination = $field->getUploadLocation();
        // Add upload resolution validation.
        if ($field_settings['max_resolution'] || $field_settings['min_resolution']) {
            $field_validators['file_validate_image_resolution'] = [
                $field_settings['max_resolution'],
                $field_settings['min_resolution'],
            ];
        }
        // Create the destination directory if it does not already exist.
        if (isset($destination) && !$this->fileSystem
            ->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {
            return new JsonResponse([
                'main_error' => $this->t('The destination directory could not be created.'),
                'errors' => '',
            ]);
        }
        // Attempt to save the image given the field's constraints.
        $result = file_save_upload('image', $field_validators, $destination);
        if (is_array($result) && $result[0]) {
            
            /** @var \Drupal\file\Entity\File $file */
            $file = $result[0];
            $image = $this->imageFactory
                ->get($file->getFileUri());
            // Set the value in the Entity to the new file.
            
            /** @var \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $field_list */
            $value = $entity->{$field_name}
                ->getValue();
            $value[0]['target_id'] = $file->id();
            $value[0]['width'] = $image->getWidth();
            $value[0]['height'] = $image->getHeight();
            $entity->{$field_name}
                ->setValue($value);
            // Render the new image using the correct formatter settings.
            $entity_view_mode_ids = array_keys($this->entityDisplayRepository
                ->getViewModes($entity->getEntityTypeId()));
            if (in_array($view_mode_id, $entity_view_mode_ids, TRUE)) {
                $output = $entity->{$field_name}
                    ->view($view_mode_id);
            }
            else {
                // Each part of a custom (non-Entity Display) view mode ID is separated
                // by a dash; the first part must be the module name.
                $mode_id_parts = explode('-', $view_mode_id, 2);
                $module = reset($mode_id_parts);
                $args = [
                    $entity,
                    $field_name,
                    $view_mode_id,
                    $langcode,
                ];
                $output = $this->moduleHandler()
                    ->invoke($module, 'quickedit_render_field', $args);
            }
            // Save the Entity to tempstore.
            $this->tempStore
                ->set($entity->uuid(), $entity);
            $data = [
                'fid' => $file->id(),
                'html' => $this->renderer
                    ->renderRoot($output),
            ];
            return new JsonResponse($data);
        }
        else {
            // Return a JSON object containing the errors from Drupal and our
            // "main_error", which is displayed inside the dropzone area.
            $messages = StatusMessages::renderMessages('error');
            return new JsonResponse([
                'errors' => $this->renderer
                    ->render($messages),
                'main_error' => $this->t('The image failed validation.'),
            ]);
        }
    }
    
    /**
     * Returns JSON representing an image field's metadata.
     *
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The entity of which an image field is being rendered.
     * @param string $field_name
     *   The name of the (image) field that is being rendered
     * @param string $langcode
     *   The language code of the field that is being rendered.
     * @param string $view_mode_id
     *   The view mode of the field that is being rendered.
     *
     * @return \Drupal\Core\Cache\CacheableJsonResponse
     *   The JSON response.
     */
    public function getInfo(EntityInterface $entity, $field_name, $langcode, $view_mode_id) {
        $field = $this->getField($entity, $field_name, $langcode);
        $settings = $field->getFieldDefinition()
            ->getSettings();
        $info = [
            'alt' => $field->alt,
            'title' => $field->title,
            'alt_field' => $settings['alt_field'],
            'title_field' => $settings['title_field'],
            'alt_field_required' => $settings['alt_field_required'],
            'title_field_required' => $settings['title_field_required'],
        ];
        $response = new CacheableJsonResponse($info);
        $response->addCacheableDependency($entity);
        return $response;
    }
    
    /**
     * Returns JSON representing the current state of the field.
     *
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The entity of which an image field is being rendered.
     * @param string $field_name
     *   The name of the (image) field that is being rendered
     * @param string $langcode
     *   The language code of the field that is being rendered.
     *
     * @return \Drupal\image\Plugin\Field\FieldType\ImageItem
     *   The field for this request.
     *
     * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
     *   Throws an exception if the request is invalid.
     */
    protected function getField(EntityInterface $entity, $field_name, $langcode) {
        // Ensure that this is a valid Entity.
        if (!$entity instanceof ContentEntityInterface) {
            throw new BadRequestHttpException('Requested Entity is not a Content Entity.');
        }
        // Check that this field exists.
        
        /** @var \Drupal\Core\Field\FieldItemListInterface $field_list */
        $field_list = $entity->getTranslation($langcode)
            ->get($field_name);
        if (!$field_list) {
            throw new BadRequestHttpException('Requested Field does not exist.');
        }
        // If the list is empty, append an empty item to use.
        if ($field_list->isEmpty()) {
            $field = $field_list->appendItem();
        }
        else {
            $field = $entity->getTranslation($langcode)
                ->get($field_name)
                ->first();
        }
        // Ensure that the field is the type we expect.
        if (!$field instanceof ImageItem) {
            throw new BadRequestHttpException('Requested Field is not of type "image".');
        }
        return $field;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 3
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 1
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 1
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 3
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 1
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 1
ControllerBase::redirect protected function Returns a redirect response object for the specified route.
ControllerBase::state protected function Returns the state storage service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 17
MessengerTrait::messenger public function Gets the messenger. 17
MessengerTrait::setMessenger public function Sets the messenger.
QuickEditImageController::$entityDisplayRepository protected property The entity display repository service.
QuickEditImageController::$fileSystem protected property The file system.
QuickEditImageController::$imageFactory protected property The image factory.
QuickEditImageController::$renderer protected property The renderer.
QuickEditImageController::$tempStore protected property Stores The Quick Edit tempstore.
QuickEditImageController::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
QuickEditImageController::getField protected function Returns JSON representing the current state of the field.
QuickEditImageController::getInfo public function Returns JSON representing an image field's metadata.
QuickEditImageController::upload public function Returns JSON representing the new file upload, or validation errors.
QuickEditImageController::__construct public function Constructs a new QuickEditImageController.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 3
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.