Wrapper for cover photos with a fallback mechanism
authorAlexander Ebert <ebert@woltlab.com>
Thu, 21 Mar 2019 22:36:36 +0000 (23:36 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 21 Mar 2019 22:36:36 +0000 (23:36 +0100)
wcfsetup/install/files/lib/system/image/cover/photo/CoverPhotoImage.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/image/cover/photo/ICoverPhotoImage.class.php [new file with mode: 0644]
wcfsetup/install/files/style/ui/article.scss
wcfsetup/install/files/style/ui/contentItem.scss

diff --git a/wcfsetup/install/files/lib/system/image/cover/photo/CoverPhotoImage.class.php b/wcfsetup/install/files/lib/system/image/cover/photo/CoverPhotoImage.class.php
new file mode 100644 (file)
index 0000000..f76b5c2
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+namespace wcf\system\image\cover\photo;
+use wcf\system\style\StyleHandler;
+
+/**
+ * Wrapper for cover photos with an automatic fallback to the global cover photo.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Image\Cover\Photo
+ * @since       5.2
+ */
+class CoverPhotoImage {
+       /**
+        * @var ICoverPhotoImage
+        */
+       protected $coverPhotoImage;
+       
+       /**
+        * @var int[]
+        */
+       protected $dimensions;
+       
+       /**
+        * @var ICoverPhotoImage
+        */
+       protected static $defaultCoverPhotoImage;
+       
+       /**
+        * @param ICoverPhotoImage|null $coverPhotoImage
+        */
+       public function __construct(ICoverPhotoImage $coverPhotoImage = null) {
+               $this->coverPhotoImage = $coverPhotoImage ?: self::getDefaultCoverPhoto();
+       }
+       
+       /**
+        * @return string
+        */
+       public function getCaption() {
+               return $this->coverPhotoImage->getCoverPhotoCaption();
+       }
+       
+       /**
+        * @return int
+        */
+       public function getHeight() {
+               return $this->getDimensions()['height'];
+       }
+       
+       /**
+        * @return string
+        */
+       public function getLocation() {
+               return $this->coverPhotoImage->getCoverPhotoLocation();
+       }
+       
+       /**
+        * @return string
+        */
+       public function getUrl() {
+               return $this->coverPhotoImage->getCoverPhotoUrl();
+       }
+       
+       /**
+        * @return int
+        */
+       public function getWidth() {
+               return $this->getDimensions()['width'];
+       }
+       
+       /**
+        * @return int[]
+        */
+       protected function getDimensions() {
+               if ($this->dimensions === null) {
+                       $this->dimensions = ['height' => 0, 'width' => 0];
+                       $dimensions = @getimagesize($this->getLocation());
+                       if (is_array($dimensions)) {
+                               $this->dimensions['width'] = $dimensions[0];
+                               $this->dimensions['height'] = $dimensions[1];
+                       }
+               }
+               
+               return $this->dimensions;
+       }
+       
+       /**
+        * @return ICoverPhotoImage
+        */
+       protected static function getDefaultCoverPhoto() {
+               if (self::$defaultCoverPhotoImage === null) {
+                       self::$defaultCoverPhotoImage = new class implements ICoverPhotoImage {
+                               public function getCoverPhotoCaption() {
+                                       return '';
+                               }
+                               
+                               public function getCoverPhotoLocation() {
+                                       return StyleHandler::getInstance()->getStyle()->getCoverPhotoLocation();
+                               }
+                               
+                               public function getCoverPhotoUrl() {
+                                       return StyleHandler::getInstance()->getStyle()->getCoverPhotoUrl();
+                               }
+                               
+                       };
+               }
+               
+               return self::$defaultCoverPhotoImage;
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/image/cover/photo/ICoverPhotoImage.class.php b/wcfsetup/install/files/lib/system/image/cover/photo/ICoverPhotoImage.class.php
new file mode 100644 (file)
index 0000000..ae426ab
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+namespace wcf\system\image\cover\photo;
+
+/**
+ * Default interface for all objects that represent cover photos.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\System\Image\Cover\Photo
+ * @since       5.2
+ */
+interface ICoverPhotoImage {
+       /**
+        * Returns the optional caption that should be displayed below the photo.
+        * 
+        * @return string
+        */
+       public function getCoverPhotoCaption();
+       
+       /**
+        * Returns the absolute path to the physical location of the image.
+        * 
+        * @return string
+        */
+       public function getCoverPhotoLocation();
+       
+       /**
+        * Returns the full url of the image.
+        * 
+        * @return string
+        */
+       public function getCoverPhotoUrl();
+}
index 77fd840a77c21f68f1beb1556796e1ef613e8411..53ba8d59cb3370c54f2c4f4dc7ea8101cc601baa 100644 (file)
@@ -7,12 +7,14 @@
        margin-top: 20px !important;
 }
 
-.articleImage {
+.articleImage,
+.contentCoverPhotoImage {
        /* work-around for IE 11 to properly align the image if overflowing */
        display: flex;
        flex-wrap: wrap;
        
-       .articleImageWrapper {
+       .articleImageWrapper,
+       .contentCoverPhotoImageWrapper {
                align-items: center;
                border-radius: 3px;
                box-shadow: 0 0 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
index dd2c35bba4b5eb42b8072c4d4266813af66770b4..3315a679e86dd377585c6d15f31e4308076180c5 100644 (file)
        background-position: center;
        background-repeat: no-repeat;
        background-size: cover;
+       padding: 10px;
        position: relative;
 }
 
 .contentItemImageSmall {
-       height: 75px;
+       min-height: 75px;
 }
 
 .contentItemImageLarge {
-       height: 150px;
+       min-height: 150px;
 }
 
 .contentItemBadges,
        align-items: flex-start;
        display: flex;
        flex-direction: column;
-       position: absolute;
-       top: 10px;
-}
-
-.contentItemBadges {
-       left: 10px;
 }
 
 .contentItemOptions {
+       position: absolute;
        right: 10px;
+       top: 10px;
        z-index: 1;
 }