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