‪TYPO3CMS  10.4
GalleryProcessor.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
23 
97 {
103  protected ‪$contentObjectRenderer;
104 
110  protected ‪$processorConfiguration;
111 
117  protected ‪$availableGalleryPositions = [
118  'horizontal' => [
119  'center' => [0, 8],
120  'right' => [1, 9, 17, 25],
121  'left' => [2, 10, 18, 26]
122  ],
123  'vertical' => [
124  'above' => [0, 1, 2],
125  'intext' => [17, 18, 25, 26],
126  'below' => [8, 9, 10]
127  ]
128  ];
129 
135  protected ‪$galleryData = [
136  'position' => [
137  'horizontal' => '',
138  'vertical' => '',
139  'noWrap' => false
140  ],
141  'width' => 0,
142  'count' => [
143  'files' => 0,
144  'columns' => 0,
145  'rows' => 0,
146  ],
147  'columnSpacing' => 0,
148  'border' => [
149  'enabled' => false,
150  'width' => 0,
151  'padding' => 0,
152  ],
153  'rows' => []
154  ];
155 
159  protected ‪$numberOfColumns;
160 
164  protected ‪$mediaOrientation;
165 
169  protected ‪$maxGalleryWidth;
170 
175 
179  protected ‪$equalMediaHeight;
180 
184  protected ‪$equalMediaWidth;
185 
189  protected ‪$columnSpacing;
190 
194  protected ‪$borderEnabled;
195 
199  protected ‪$borderWidth;
200 
204  protected ‪$borderPadding;
205 
209  protected ‪$cropVariant = 'default';
210 
216  protected ‪$fileObjects = [];
217 
223  protected ‪$mediaDimensions = [];
224 
235  public function ‪process(
237  array $contentObjectConfiguration,
239  array $processedData
240  ) {
241  if (isset(‪$processorConfiguration['if.']) && !$cObj->‪checkIf(‪$processorConfiguration['if.'])) {
242  return $processedData;
243  }
244 
245  $this->contentObjectRenderer = $cObj;
246  $this->processorConfiguration = ‪$processorConfiguration;
247 
248  $filesProcessedDataKey = (string)$cObj->‪stdWrapValue(
249  'filesProcessedDataKey',
251  'files'
252  );
253  if (isset($processedData[$filesProcessedDataKey]) && is_array($processedData[$filesProcessedDataKey])) {
254  $this->fileObjects = $processedData[$filesProcessedDataKey];
255  $this->galleryData['count']['files'] = count($this->fileObjects);
256  } else {
257  throw new ‪ContentRenderingException('No files found for key ' . $filesProcessedDataKey . ' in $processedData.', 1436809789);
258  }
259 
260  $this->numberOfColumns = (int)$this->‪getConfigurationValue('numberOfColumns', 'imagecols');
261  $this->mediaOrientation = (int)$this->‪getConfigurationValue('mediaOrientation', 'imageorient');
262  $this->maxGalleryWidth = (int)$this->‪getConfigurationValue('maxGalleryWidth') ?: 600;
263  $this->maxGalleryWidthInText = (int)$this->‪getConfigurationValue('maxGalleryWidthInText') ?: 300;
264  $this->equalMediaHeight = (int)$this->‪getConfigurationValue('equalMediaHeight', 'imageheight');
265  $this->equalMediaWidth = (int)$this->‪getConfigurationValue('equalMediaWidth', 'imagewidth');
266  $this->columnSpacing = (int)$this->‪getConfigurationValue('columnSpacing');
267  $this->borderEnabled = (bool)$this->‪getConfigurationValue('borderEnabled', 'imageborder');
268  $this->borderWidth = (int)$this->‪getConfigurationValue('borderWidth');
269  $this->borderPadding = (int)$this->‪getConfigurationValue('borderPadding');
270  $this->cropVariant = $this->‪getConfigurationValue('cropVariant') ?: 'default';
271 
274 
277 
278  $this->‪prepareGalleryData();
279 
280  $targetFieldName = (string)$cObj->‪stdWrapValue(
281  'as',
283  'gallery'
284  );
285 
286  $processedData[$targetFieldName] = ‪$this->galleryData;
287 
288  return $processedData;
289  }
290 
299  protected function ‪getConfigurationValue($key, $dataArrayKey = null)
300  {
301  $defaultValue = '';
302  if ($dataArrayKey && isset($this->contentObjectRenderer->data[$dataArrayKey])) {
303  $defaultValue = $this->contentObjectRenderer->data[$dataArrayKey];
304  }
305  return $this->contentObjectRenderer->stdWrapValue(
306  $key,
307  $this->processorConfiguration,
308  $defaultValue
309  );
310  }
311 
318  protected function ‪determineGalleryPosition()
319  {
320  foreach ($this->availableGalleryPositions as $positionDirectionKey => $positionDirectionValue) {
321  foreach ($positionDirectionValue as $positionKey => $positionArray) {
322  if (in_array($this->mediaOrientation, $positionArray, true)) {
323  $this->galleryData['position'][$positionDirectionKey] = $positionKey;
324  }
325  }
326  }
327 
328  if ($this->mediaOrientation === 25 || $this->mediaOrientation === 26) {
329  $this->galleryData['position']['noWrap'] = true;
330  }
331  }
332 
336  protected function ‪determineMaximumGalleryWidth()
337  {
338  if ($this->galleryData['position']['vertical'] === 'intext') {
339  $this->galleryData['width'] = ‪$this->maxGalleryWidthInText;
340  } else {
341  $this->galleryData['width'] = ‪$this->maxGalleryWidth;
342  }
343  }
344 
348  protected function ‪calculateRowsAndColumns()
349  {
350 
351  // If no columns defined, set it to 1
352  $columns = max((int)$this->numberOfColumns, 1);
353 
354  // When more columns than media elements, set the columns to the amount of media elements
355  if ($columns > $this->galleryData['count']['files']) {
356  $columns = $this->galleryData['count']['files'];
357  }
358 
359  if ($columns === 0) {
360  $columns = 1;
361  }
362 
363  // Calculate the rows from the amount of files and the columns
364  $rows = ceil($this->galleryData['count']['files'] / $columns);
365 
366  $this->galleryData['count']['columns'] = $columns;
367  $this->galleryData['count']['rows'] = (int)$rows;
368  }
369 
378  protected function ‪calculateMediaWidthsAndHeights()
379  {
380  $columnSpacingTotal = ($this->galleryData['count']['columns'] - 1) * $this->columnSpacing;
381 
382  $galleryWidthMinusBorderAndSpacing = max($this->galleryData['width'] - $columnSpacingTotal, 1);
383 
384  if ($this->borderEnabled) {
385  $borderPaddingTotal = ($this->galleryData['count']['columns'] * 2) * $this->borderPadding;
386  $borderWidthTotal = ($this->galleryData['count']['columns'] * 2) * $this->borderWidth;
387  $galleryWidthMinusBorderAndSpacing = $galleryWidthMinusBorderAndSpacing - $borderPaddingTotal - $borderWidthTotal;
388  }
389 
390  // User entered a predefined height
391  if ($this->equalMediaHeight) {
392  $mediaScalingCorrection = 1;
393  $maximumRowWidth = 0;
394 
395  // Calculate the scaling correction when the total of media elements is wider than the gallery width
396  for ($row = 1; $row <= $this->galleryData['count']['rows']; $row++) {
397  $totalRowWidth = 0;
398  for ($column = 1; $column <= $this->galleryData['count']['columns']; $column++) {
399  $fileKey = (($row - 1) * $this->galleryData['count']['columns']) + $column - 1;
400  if ($fileKey > $this->galleryData['count']['files'] - 1) {
401  break 2;
402  }
403  $currentMediaScaling = $this->equalMediaHeight / max($this->‪getCroppedDimensionalProperty($this->fileObjects[$fileKey], 'height'), 1);
404  $totalRowWidth += $this->‪getCroppedDimensionalProperty($this->fileObjects[$fileKey], 'width') * $currentMediaScaling;
405  }
406  $maximumRowWidth = max($totalRowWidth, $maximumRowWidth);
407  $mediaInRowScaling = $totalRowWidth / $galleryWidthMinusBorderAndSpacing;
408  $mediaScalingCorrection = max($mediaInRowScaling, $mediaScalingCorrection);
409  }
410 
411  // Set the corrected dimensions for each media element
412  foreach ($this->fileObjects as $key => $fileObject) {
413  $mediaHeight = floor($this->equalMediaHeight / $mediaScalingCorrection);
414  $mediaWidth = floor(
415  $this->‪getCroppedDimensionalProperty($fileObject, 'width') * ($mediaHeight / max($this->‪getCroppedDimensionalProperty($fileObject, 'height'), 1))
416  );
417  $this->mediaDimensions[$key] = [
418  'width' => $mediaWidth,
419  'height' => $mediaHeight
420  ];
421  }
422 
423  // Recalculate gallery width
424  $this->galleryData['width'] = floor($maximumRowWidth / $mediaScalingCorrection);
425 
426  // User entered a predefined width
427  } elseif ($this->equalMediaWidth) {
428  $mediaScalingCorrection = 1;
429 
430  // Calculate the scaling correction when the total of media elements is wider than the gallery width
431  $totalRowWidth = $this->galleryData['count']['columns'] * ‪$this->equalMediaWidth;
432  $mediaInRowScaling = $totalRowWidth / $galleryWidthMinusBorderAndSpacing;
433  $mediaScalingCorrection = max($mediaInRowScaling, $mediaScalingCorrection);
434 
435  // Set the corrected dimensions for each media element
436  foreach ($this->fileObjects as $key => $fileObject) {
437  $mediaWidth = floor($this->equalMediaWidth / $mediaScalingCorrection);
438  $mediaHeight = floor(
439  $this->‪getCroppedDimensionalProperty($fileObject, 'height') * ($mediaWidth / max($this->‪getCroppedDimensionalProperty($fileObject, 'width'), 1))
440  );
441  $this->mediaDimensions[$key] = [
442  'width' => $mediaWidth,
443  'height' => $mediaHeight
444  ];
445  }
446 
447  // Recalculate gallery width
448  $this->galleryData['width'] = floor($totalRowWidth / $mediaScalingCorrection);
449 
450  // Automatic setting of width and height
451  } else {
452  $maxMediaWidth = (int)($galleryWidthMinusBorderAndSpacing / $this->galleryData['count']['columns']);
453  foreach ($this->fileObjects as $key => $fileObject) {
454  $croppedWidth = $this->‪getCroppedDimensionalProperty($fileObject, 'width');
455  $mediaWidth = $croppedWidth > 0 ? min($maxMediaWidth, $croppedWidth) : $maxMediaWidth;
456  $mediaHeight = floor(
457  $this->‪getCroppedDimensionalProperty($fileObject, 'height') * ($mediaWidth / max($this->‪getCroppedDimensionalProperty($fileObject, 'width'), 1))
458  );
459  $this->mediaDimensions[$key] = [
460  'width' => $mediaWidth,
461  'height' => $mediaHeight
462  ];
463  }
464  }
465  }
466 
476  protected function ‪getCroppedDimensionalProperty(FileInterface $fileObject, $dimensionalProperty)
477  {
478  if (!$fileObject->hasProperty('crop') || empty($fileObject->getProperty('crop'))) {
479  return $fileObject->getProperty($dimensionalProperty);
480  }
481 
482  $croppingConfiguration = $fileObject->getProperty('crop');
483  $cropVariantCollection = ‪CropVariantCollection::create((string)$croppingConfiguration);
484  return (int)$cropVariantCollection->getCropArea($this->cropVariant)->makeAbsoluteBasedOnFile($fileObject)->asArray()[$dimensionalProperty];
485  }
486 
492  protected function ‪prepareGalleryData()
493  {
494  for ($row = 1; $row <= $this->galleryData['count']['rows']; $row++) {
495  for ($column = 1; $column <= $this->galleryData['count']['columns']; $column++) {
496  $fileKey = (($row - 1) * $this->galleryData['count']['columns']) + $column - 1;
497 
498  $this->galleryData['rows'][$row]['columns'][$column] = [
499  'media' => $this->fileObjects[$fileKey] ?? null,
500  'dimensions' => [
501  'width' => $this->mediaDimensions[$fileKey]['width'] ?? null,
502  'height' => $this->mediaDimensions[$fileKey]['height'] ?? null
503  ]
504  ];
505  }
506  }
507 
508  $this->galleryData['columnSpacing'] = ‪$this->columnSpacing;
509  $this->galleryData['border']['enabled'] = ‪$this->borderEnabled;
510  $this->galleryData['border']['width'] = ‪$this->borderWidth;
511  $this->galleryData['border']['padding'] = ‪$this->borderPadding;
512  }
513 }
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Core\Resource\FileInterface\hasProperty
‪bool hasProperty($key)
‪TYPO3\CMS\Frontend\DataProcessing
Definition: CommaSeparatedValueProcessor.php:16
‪TYPO3\CMS\Frontend\ContentObject\Exception\ContentRenderingException
Definition: ContentRenderingException.php:25
‪TYPO3\CMS\Core\Resource\FileInterface\getProperty
‪string getProperty($key)
‪TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface
Definition: DataProcessorInterface.php:23
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer\stdWrapValue
‪string stdWrapValue($key, array $config, $defaultValue='')
Definition: ContentObjectRenderer.php:1685
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection
Definition: CropVariantCollection.php:23
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
Definition: ContentObjectRenderer.php:97
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection\create
‪static CropVariantCollection create(string $jsonString, array $tcaConfig=[])
Definition: CropVariantCollection.php:42
‪TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer\checkIf
‪bool checkIf($conf)
Definition: ContentObjectRenderer.php:3074