class FocalPointPreviewController in Focal Point 8
Class FocalPointPreviewController.
@package Drupal\focal_point\Controller
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\focal_point\Controller\FocalPointPreviewController
Expanded class hierarchy of FocalPointPreviewController
File
- src/
Controller/ FocalPointPreviewController.php, line 25
Namespace
Drupal\focal_point\ControllerView source
class FocalPointPreviewController extends ControllerBase {
/**
* The image factory service.
*
* @var \Drupal\Core\Image\ImageFactory
*/
protected $imageFactory;
/**
* The request service.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $request;
/**
* The file storage service.
*
* @var \Drupal\file\FileStorage
*/
protected $fileStorage;
/**
* {@inheritdoc}
*
* @param \Drupal\Core\Image\ImageFactory $image_factory
* The image_factory parameter.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request parameter.
*/
public function __construct(ImageFactory $image_factory, RequestStack $request_stack) {
$this->imageFactory = $image_factory;
$this->request = $request_stack
->getCurrentRequest();
$this->fileStorage = $this
->entityTypeManager()
->getStorage('file');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('image.factory'), $container
->get('request_stack'));
}
/**
* {@inheritdoc}
*
* @throws \Symfony\Component\Validator\Exception\InvalidArgumentException
*/
public function content($fid, $focal_point_value) {
$output = [];
$file = $this->fileStorage
->load($fid);
$image = $this->imageFactory
->get($file
->getFileUri());
if (!$image
->isValid()) {
throw new InvalidArgumentException('The file with id = $fid is not an image.');
}
$styles = $this
->getFocalPointImageStyles();
// Since we are about to create a new preview of this image, we first must
// flush the old one. This should not be a performance hit since there is
// no good reason for anyone to preview an image unless they are changing
// the focal point value.
image_path_flush($image
->getSource());
$derivative_images = [];
$derivative_image_note = '';
$original_image = [
'#theme' => 'image',
'#uri' => $image
->getSource(),
'#alt' => $this
->t('Focal Point Preview Image'),
'#attributes' => [
'id' => 'focal-point-preview-image',
],
];
if (!empty($styles)) {
foreach ($styles as $style) {
$style_label = $style
->get('label');
$url = $this
->buildUrl($style, $file, $focal_point_value);
$derivative_images[$style
->getName()] = [
'style' => $style_label,
'url' => $url,
'image' => [
'#theme' => 'image',
'#uri' => $url,
'#alt' => $this
->t('Focal Point Preview: %label', [
'%label' => $style_label,
]),
'#attributes' => [
'class' => [
'focal-point-derivative-preview-image',
],
],
],
];
}
$derivative_image_note = $this
->t('Click an image to see a larger preview. You may need to scroll horizontally for more image styles.');
}
else {
// There are no styles that use a focal point effect to preview.
$image_styles_url = Url::fromRoute('entity.image_style.collection')
->toString();
$this
->messenger()
->addWarning($this
->t('You must have at least one <a href=":url">image style</a> defined that uses a focal point effect in order to preview.', [
':url' => $image_styles_url,
]));
}
$output['focal_point_preview_page'] = [
'#theme' => "focal_point_preview_page",
"#original_image" => $original_image,
'#derivative_images' => $derivative_images,
'#focal_point' => $focal_point_value,
'#preview_image_note' => $this
->t('This preview image above may have been scaled to fit on the page.'),
'#derivative_image_note' => $derivative_image_note,
];
$options = [
'dialogClass' => 'popup-dialog-class',
'width' => '80%',
];
$response = new AjaxResponse();
$response
->addCommand(new OpenModalDialogCommand($this
->t('Images preview'), $output, $options));
return $response;
}
/**
* Define access control for the preview page.
*
* Deny users access to the preview page unless they have permission to edit
* an entity (any entity) that references the current image being previewed or
* if they've provide a valid token as a query string. The later is needed so
* preview will work when creating a new entity that has not yet been saved.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param int $fid
* The file id for the image being previewed from the URL.
*
* @return \Drupal\Core\Access\AccessResult
* An AccessResult object defining if permission is granted or not.
*/
public function access(AccountInterface $account, $fid) {
$access = AccessResult::forbidden();
// @todo: I should be able to use "magic args" to load the file directly.
$file = $this->fileStorage
->load($fid);
$image = $this->imageFactory
->get($file
->getFileUri());
if (!$image
->isValid()) {
throw new InvalidArgumentException('The file with id = $fid is not an image.');
}
// Check if there was a valid token provided in with the HTTP request so
// that preview is available on a "create entity" form.
if ($this
->validTokenProvided()) {
$access = AccessResult::allowed();
}
// If access has not yet been granted and the file module is enabled, check
// if there is an entity that references this file which the current user
// has access to edit.
if (function_exists('file_get_file_references') && !$access
->isAllowed()) {
$references = file_get_file_references($file, NULL, EntityStorageInterface::FIELD_LOAD_REVISION, '');
foreach ($references as $data) {
foreach (array_keys($data) as $entity_type_id) {
if ($account
->hasPermission($entity_type_id . ".edit")) {
$access = AccessResult::allowed();
break;
}
}
}
}
return $access;
}
/**
* Build a list of image styles that include an effect defined by focal point.
*
* @return array
* An array of machine names of image styles that use a focal point effect.
*/
public function getFocalPointImageStyles() {
// @todo: Can this be generated? See $imageEffectManager->getDefinitions();
$focal_point_effects = [
'focal_point_crop',
'focal_point_scale_and_crop',
];
$styles_using_focal_point = [];
$styles = $this
->entityTypeManager()
->getStorage('image_style')
->loadMultiple();
foreach ($styles as $image_style_id => $style) {
foreach ($style
->getEffects() as $effect) {
$style_using_focal_point = in_array($effect
->getPluginId(), $focal_point_effects, TRUE);
if ($style_using_focal_point) {
$styles_using_focal_point[$image_style_id] = $style;
break;
}
}
}
return $styles_using_focal_point;
}
/**
* Create the URL for a preview image including a query parameter.
*
* @param \Drupal\image\ImageStyleInterface $style
* The image style being previewed.
* @param \Drupal\file\Entity\File $image
* The image being previewed.
* @param string $focal_point_value
* The focal point being previewed in the format XxY where x and y are the
* left and top offsets in percentages.
*
* @return \Drupal\Core\GeneratedUrl|string
* The URL of the preview image.
*/
protected function buildUrl(ImageStyleInterface $style, File $image, $focal_point_value) {
$url = $style
->buildUrl($image
->getFileUri());
$url .= (strpos($url, '?') !== FALSE ? '&' : '?') . 'focal_point_preview_value=' . $focal_point_value;
return $url;
}
/**
* Was a valid token found?
*
* Determine if a valid focal point token was provided in the query string of
* the current request. If no token is provided in the query string then this
* method will return FALSE.
*
* @return bool
* Indicates if a valid token was provided in the query string.
*/
protected function validTokenProvided() {
try {
if (\Drupal::request()->query
->has('focal_point_token')) {
$token = \Drupal::request()->query
->get('focal_point_token');
return FocalPointImageWidget::validatePreviewToken($token);
}
else {
return FALSE;
}
} catch (\InvalidArgumentException $e) {
return FALSE;
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
FocalPointPreviewController:: |
protected | property | The file storage service. | |
FocalPointPreviewController:: |
protected | property | The image factory service. | |
FocalPointPreviewController:: |
protected | property | The request service. | |
FocalPointPreviewController:: |
public | function | Define access control for the preview page. | |
FocalPointPreviewController:: |
protected | function | Create the URL for a preview image including a query parameter. | |
FocalPointPreviewController:: |
public | function | ||
FocalPointPreviewController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
FocalPointPreviewController:: |
public | function | Build a list of image styles that include an effect defined by focal point. | |
FocalPointPreviewController:: |
protected | function | Was a valid token found? | |
FocalPointPreviewController:: |
public | function | ||
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |