Source of file GalleryPage.php
Size: 6,409 Bytes - Last Modified: 2020-01-07T10:44:43+00:00
/var/www/docs.ssmods.com/process/src/code/pages/GalleryPage.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | <?php /** * Class GalleryPage * @property string Date * @property string Location * @property string Mode * @method ManyManyList Images */ class GalleryPage extends Page { private static $singular_name = 'Galerie'; private static $description = 'Eine Bildergalerie'; private static $can_be_root = false; private static $allowed_children = []; private static $default_child = ''; private static $db = [ 'Date' => 'Date', 'Location' => 'Text', 'Mode' => "Enum('avg,max', 'avg')", ]; private static $many_many = [ 'Images' => 'Image', ]; private static $many_many_extraFields = [ 'Images' => ['SortOrder' => 'Int'], ]; private static $defaults = [ 'ShowInMenus' => false, ]; /** * Returns the cms fields for this page. * @return FieldList */ public function getCMSFields() { $fields = parent::getCMSFields(); $fields->addFieldsToTab('Root.Main', [ DateField::create('Date', 'Datum'), TextareaField::create('Location', 'Ort'), ], 'Content'); $fields->insertAfter(Tab::create('Images', 'Bilder'), 'Main'); $fields->addFieldsToTab('Root.Images', [ SortableUploadField::create('Images', 'Bilder') ->setFolderName('galleries/' . $this->ID) ->setDisplayFolderName('galleries/' . $this->ID) ]); $fields->insertAfter(Tab::create('GalleryLook', 'Galerie Aussehen'), 'Images'); $fields->addFieldsToTab('Root.GalleryLook', [ DropdownField::create('Mode', 'Modus', singleton('GalleryPage')->dbObject('Mode')->enumValues()) ->setDescription(<<<EOL avg: Die Zeilenhöhe der einzelnen Zeilen ist relativ gleich.</br> max: Es werden große Unterschiede zur gewünschten Zeilenhöhe besser vermieden. EOL ) ]); return $fields; } /** * Returns the sorted list of images. * @return DataList */ public function SortedImages() { return $this->Images()->sort('SortOrder', 'ASC'); } /** * Returns the preview image for this gallery. * The preview image is the first image of the gallery. * @return Image */ public function getPreviewImage() { return $this->SortedImages()->First(); } /** * For possible values for $mode see: * @see GalleryPage::calculateDifferenceToEstimatedHeight() * @throws InvalidArgumentException thrown when a mode is specified which does not exist * @return GalleryContainer */ public function MatchedImages() { //put all images to the same height and put them into an array $resizedImages = []; foreach($this->SortedImages() as $image) { $resizedImage = new ResizedImage($image); $resizedImage->changeHeight(Line::getEstimatedLineHeight()); $resizedImages[] = $resizedImage; } $this->getImageResults($resizedImages, $results); $lines = ArrayList::create(); foreach($results as $line) { /** @var Line $line */ foreach($line->getResizedImages() as $resizedImage) { /** @var ResizedImage $resizedImage */ $previewImage = $resizedImage->getImage()->ScaleWidth(Line::getOptimizedLineWidth() - ResizedImage::getPreviewPadding() * 2); if($previewImage->getHeight() > ResizedImage::getMaxPreviewHeight()) { $previewImage = $previewImage->ScaleHeight(ResizedImage::getMaxPreviewHeight()); } $resizedImage->setPreviewImage($previewImage); $resizedImage->resize(); } $lines->push($line); } return GalleryContainer::create($lines); } /** * Private function to fit them to lines and resize them. * @param $imageList array * @param $estimatedLineHeight int * @param $estimatedLineWidth int * @param $results array * @param $mode */ private function getImageResults($imageList, &$results) { //initialize $results if it is not set if(!is_array($results) || !empty($results)) $results = []; //order $imageList array $imageList = array_values($imageList); $line = new Line(); $i = 0; foreach($imageList as $image) { if($line->matchesToLine($image) || $line->getLineWidth() === 0) $line->addResizedImage($image); else break; $i++; } //remove images of this line array_splice($imageList, 0, $i); if(empty($imageList)) { $line->getResizedImages()[count($line->getResizedImages()) - 1]->setMarginRight(0); $line->matchImagesWidth(); array_unshift($results, $line); } else { $clonedLine = clone $line; $clonedImageList = []; foreach($imageList as $resizedImage) $clonedImageList[] = clone $resizedImage; //leave image in this line $imageList[0]->setMarginRight(0); $line->addResizedImage($imageList[0]); $line->matchImagesWidth(); if(count($imageList) === 1) //if there is no image left don't try to calculate new line $resultsThisLine = []; else $this->getImageResults(array_slice($imageList, 1), $resultsThisLine); //put image in next line $clonedLine->getResizedImages()[count($clonedLine->getResizedImages()) - 1]->setMarginRight(0); $clonedLine->matchImagesWidth(); $this->getImageResults($clonedImageList, $resultsNextLine); //put results and current lines together array_unshift($resultsThisLine, $line); array_unshift($resultsNextLine, $clonedLine); //compare the two results $diff1 = $this->calculateDifferenceToEstimatedHeight($resultsThisLine); $diff2 = $this->calculateDifferenceToEstimatedHeight($resultsNextLine); $bestLines = $diff1 < $diff2 ? $resultsThisLine : $resultsNextLine; foreach($bestLines as $line) $results[] = $line; } } /** * Private function which determines the difference between an estimated height and the real height of a couple of lines. * Possible values for $mode are: * 'avg' (The average difference of all rows to the estimated height), * 'max' (The max difference to the estimated height) * @param $lines array * @throws InvalidArgumentException thrown when a mode is specified which does not exist * @return int */ private function calculateDifferenceToEstimatedHeight($lines) { switch($this->Mode) { case 'avg': $averageDiff = 0; foreach($lines as $line) $averageDiff += $line->getDifferenceFromEstimatedHeight(); $averageDiff /= count($lines); return $averageDiff; case 'max': $maxDiff = 0; foreach($lines as $line) { $diff = $line->getDifferenceFromEstimatedHeight(); if($diff > $maxDiff) $maxDiff = $diff; } return $maxDiff; default: throw new InvalidArgumentException('Mode "' . $this->Mode . '" does not exist.'); } } } |