<amp-carousel width="400" height="300" layout="responsive" type="slides" autoplay delay="5000">
{content}
{foreach from=$additionalArticles item='additionalArticle'}
- {if $additionalArticle->getImage()}
+ {if $additionalArticle->getTeaserImage()}
<a href="{link controller='ArticleAmp' object=$additionalArticle->getArticleContent()}{/link}">
<figure>
- <amp-img src="{$additionalArticle->getImage()->getThumbnailLink('large')}" layout="fill"></amp-img>
+ <amp-img src="{$additionalArticle->getTeaserImage()->getThumbnailLink('large')}" layout="fill"></amp-img>
<figcaption>{$additionalArticle->getTitle()}</figcaption>
</figure>
</a>
<amp-carousel width="400" height="300" layout="responsive" type="slides" autoplay delay="5000">
{content}
{foreach from=$relatedArticles item='relatedArticle'}
- {if $relatedArticle->getImage()}
+ {if $relatedArticle->getTeaserImage()}
<a href="{link controller='ArticleAmp' object=$relatedArticle->getArticleContent()}{/link}">
<figure>
- <amp-img src="{$relatedArticle->getImage()->getThumbnailLink('large')}" layout="fill"></amp-img>
+ <amp-img src="{$relatedArticle->getTeaserImage()->getThumbnailLink('large')}" layout="fill"></amp-img>
<figcaption>{$relatedArticle->getTitle()}</figcaption>
</figure>
</a>
{if $previousArticle}
<li class="previousArticleButton">
<a href="{$previousArticle->getLink()}" rel="prev">
- {if $previousArticle->getImage()}
+ {if $previousArticle->getTeaserImage()}
<div class="box96">
- <span class="articleNavigationArticleImage">{@$previousArticle->getImage()->getElementTag(96)}</span>
+ <span class="articleNavigationArticleImage">{@$previousArticle->getTeaserImage()->getElementTag(96)}</span>
<div>
<span class="articleNavigationEntityName">{lang}wcf.article.previousArticle{/lang}</span>
{if $nextArticle}
<li class="nextArticleButton">
<a href="{$nextArticle->getLink()}" rel="next">
- {if $nextArticle->getImage()}
+ {if $nextArticle->getTeaserImage()}
<div class="box96">
- <span class="articleNavigationArticleImage">{@$nextArticle->getImage()->getElementTag(96)}</span>
+ <span class="articleNavigationArticleImage">{@$nextArticle->getTeaserImage()->getElementTag(96)}</span>
<div>
<span class="articleNavigationEntityName">{lang}wcf.article.nextArticle{/lang}</span>
{foreach from=$relatedArticles item='relatedArticle'}
<li>
<a href="{$relatedArticle->getLink()}">
- {if $relatedArticle->getImage() && $relatedArticle->getImage()->hasThumbnail('tiny')}
+ {if $relatedArticle->getTeaserImage() && $relatedArticle->getTeaserImage()->hasThumbnail('tiny')}
<div class="box128">
- <div class="articleListImage">{@$relatedArticle->getImage()->getThumbnailTag('tiny')}</div>
+ <div class="articleListImage">{@$relatedArticle->getTeaserImage()->getThumbnailTag('tiny')}</div>
{/if}
<div>
</div>
</div>
- {if $relatedArticle->getImage() && $relatedArticle->getImage()->hasThumbnail('tiny')}
+ {if $relatedArticle->getTeaserImage() && $relatedArticle->getTeaserImage()->hasThumbnail('tiny')}
</div>
{/if}
</a>
{foreach from=$objects item='article'}
<li>
<a href="{$article->getLink()}">
- {if $article->getImage() && $article->getImage()->hasThumbnail('tiny')}
+ {if $article->getTeaserImage() && $article->getTeaserImage()->hasThumbnail('tiny')}
<div class="box128">
- <div class="articleListImage">{@$article->getImage()->getThumbnailTag('tiny')}</div>
+ <div class="articleListImage">{@$article->getTeaserImage()->getThumbnailTag('tiny')}</div>
{/if}
<div>
</div>
</div>
- {if $article->getImage() && $article->getImage()->hasThumbnail('tiny')}
+ {if $article->getTeaserImage() && $article->getTeaserImage()->hasThumbnail('tiny')}
</div>
{/if}
</a>
</dl>
{/if}
+ {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ <dl{if $errorField == 'teaserImage'} class="formError"{/if}>
+ <dt><label for="teaserImage">{lang}wcf.acp.article.teaserImage{/lang}</label></dt>
+ <dd>
+ <div id="teaserImageDisplay" class="selectedImagePreview">
+ {if $teaserImages[0]|isset && $teaserImages[0]->hasThumbnail('small')}
+ {@$teaserImages[0]->getThumbnailTag('small')}
+ {/if}
+ </div>
+ <p class="button jsMediaSelectButton" data-store="teaserImageID0" data-display="teaserImageDisplay">{lang}wcf.media.chooseImage{/lang}</p>
+ <input type="hidden" name="teaserImageID[0]" id="teaserImageID0"{if $teaserImageID[0]|isset} value="{@$teaserImageID[0]}"{/if}>
+ {if $errorField == 'teaserImage'}
+ <small class="innerError">{lang}wcf.acp.article.image.error.{@$errorType}{/lang}</small>
+ {/if}
+ </dd>
+ </dl>
+ {elseif $action == 'edit' && $teaserImages[0]|isset && $teaserImages[0]->hasThumbnail('small')}
+ <dl>
+ <dt>{lang}wcf.acp.article.teaserImage{/lang}</dt>
+ <dd>
+ <div id="teaserImageDisplay">{@$teaserImages[0]->getThumbnailTag('small')}</div>
+ </dd>
+ </dl>
+ {/if}
+
<dl{if $errorField == 'title'} class="formError"{/if}>
<dt><label for="title0">{lang}wcf.global.title{/lang}</label></dt>
<dd>
</dl>
{/if}
+ {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ <dl{if $errorField == 'image'|concat:$availableLanguage->languageID} class="formError"{/if}>
+ <dt><label for="teaserImage{@$availableLanguage->languageID}">{lang}wcf.acp.article.teaserImage{/lang}</label></dt>
+ <dd>
+ <div id="teaserImageDisplay{@$availableLanguage->languageID}">
+ {if $teaserImages[$availableLanguage->languageID]|isset && $teaserImages[$availableLanguage->languageID]->hasThumbnail('small')}
+ {@$teaserImages[$availableLanguage->languageID]->getThumbnailTag('small')}
+ {/if}
+ </div>
+ <p class="button jsMediaSelectButton" data-store="teaserImageID{@$availableLanguage->languageID}" data-display="teaserImageDisplay{@$availableLanguage->languageID}">{lang}wcf.media.chooseImage{/lang}</p>
+ <input type="hidden" name="teaserImageID[{@$availableLanguage->languageID}]" id="teaserImageID{@$availableLanguage->languageID}"{if $teaserImageID[$availableLanguage->languageID]|isset} value="{@$teaserImageID[$availableLanguage->languageID]}"{/if}>
+ {if $errorField == 'teaserImage'|concat:$availableLanguage->languageID}
+ <small class="innerError">{lang}wcf.acp.article.image.error.{@$errorType}{/lang}</small>
+ {/if}
+ </dd>
+ </dl>
+ {elseif $action == 'edit' && $teaserImages[$availableLanguage->languageID]|isset && $teaserImages[$availableLanguage->languageID]->hasThumbnail('small')}
+ <dl>
+ <dt>{lang}wcf.acp.article.teaserImage{/lang}</dt>
+ <dd>
+ <div id="imageDisplay">{@$teaserImages[$availableLanguage->languageID]->getThumbnailTag('small')}</div>
+ </dd>
+ </dl>
+ {/if}
+
<dl{if $errorField == 'title'|concat:$availableLanguage->languageID} class="formError"{/if}>
<dt><label for="title{@$availableLanguage->languageID}">{lang}wcf.global.title{/lang}</label></dt>
<dd>
<td class="columnText columnArticleTitle">
<div class="box48">
<span>
- {if $article->getImage()}
- {@$article->getImage()->getElementTag(48)}
+ {if $article->getTeaserImage()}
+ {@$article->getTeaserImage()->getElementTag(48)}
{else}
<img src="{@$__wcf->getPath()}images/placeholderTiny.png" style="width: 48px; height: 48px" alt="">
{/if}
*/
public $imageID = [];
+ /**
+ * thumbnail image ids
+ * @var integer[]
+ */
+ public $teaserImageID = [];
+
/**
* images
* @var Media[]
*/
public $images = [];
+ /**
+ * thumbnail images
+ * @var Media[]
+ */
+ public $teaserImages = [];
+
/**
* list of available languages
* @var Language[]
if (WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
if (isset($_POST['imageID']) && is_array($_POST['imageID'])) $this->imageID = ArrayUtil::toIntegerArray($_POST['imageID']);
+ if (isset($_POST['teaserImageID']) && is_array($_POST['teaserImageID'])) $this->teaserImageID = ArrayUtil::toIntegerArray($_POST['teaserImageID']);
$this->readImages();
}
* Reads the box images.
*/
protected function readImages() {
- if (!empty($this->imageID)) {
+ if (!empty($this->imageID) || !empty($this->teaserImageID)) {
$mediaList = new ViewableMediaList();
- $mediaList->setObjectIDs($this->imageID);
+ $mediaList->setObjectIDs(array_merge($this->imageID, $this->teaserImageID));
$mediaList->readObjects();
foreach ($this->imageID as $languageID => $imageID) {
$this->images[$languageID] = $image;
}
}
+ foreach ($this->teaserImageID as $languageID => $imageID) {
+ $image = $mediaList->search($imageID);
+ if ($image !== null && $image->isImage) {
+ $this->teaserImages[$languageID] = $image;
+ }
+ }
}
}
'teaser' => !empty($this->teaser[$language->languageID]) ? $this->teaser[$language->languageID] : '',
'content' => !empty($this->content[$language->languageID]) ? $this->content[$language->languageID] : '',
'htmlInputProcessor' => isset($this->htmlInputProcessors[$language->languageID]) ? $this->htmlInputProcessors[$language->languageID] : null,
- 'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null
+ 'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null,
+ 'teaserImageID' => !empty($this->teaserImageID[$language->languageID]) ? $this->teaserImageID[$language->languageID] : null
];
}
}
'teaser' => !empty($this->teaser[0]) ? $this->teaser[0] : '',
'content' => !empty($this->content[0]) ? $this->content[0] : '',
'htmlInputProcessor' => isset($this->htmlInputProcessors[0]) ? $this->htmlInputProcessors[0] : null,
- 'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null
+ 'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null,
+ 'teaserImageID' => !empty($this->teaserImageID[0]) ? $this->teaserImageID[0] : null
];
}
$this->categoryID = 0;
$this->publicationStatus = Article::PUBLISHED;
$this->enableComments = ARTICLE_ENABLE_COMMENTS_DEFAULT_VALUE;
- $this->title = $this->teaser = $this->content = $this->images = $this->imageID = $this->tags = [];
+ $this->title = $this->teaser = $this->content = $this->images = $this->imageID = $this->teaserImages = $this->teaserImageID == $this->tags = [];
$this->setDefaultValues();
}
'publicationDate' => $this->publicationDate,
'imageID' => $this->imageID,
'images' => $this->images,
+ 'teaserImageID' => $this->teaserImageID,
+ 'teaserImages' => $this->teaserImages,
'tags' => $this->tags,
'title' => $this->title,
'teaser' => $this->teaser,
'teaser' => !empty($this->teaser[$language->languageID]) ? $this->teaser[$language->languageID] : '',
'content' => !empty($this->content[$language->languageID]) ? $this->content[$language->languageID] : '',
'htmlInputProcessor' => isset($this->htmlInputProcessors[$language->languageID]) ? $this->htmlInputProcessors[$language->languageID] : null,
- 'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null
+ 'imageID' => !empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null,
+ 'teaserImageID' => !empty($this->teaserImageID[$language->languageID]) ? $this->teaserImageID[$language->languageID] : null
];
}
}
'teaser' => !empty($this->teaser[0]) ? $this->teaser[0] : '',
'content' => !empty($this->content[0]) ? $this->content[0] : '',
'htmlInputProcessor' => isset($this->htmlInputProcessors[0]) ? $this->htmlInputProcessors[0] : null,
- 'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null
+ 'imageID' => !empty($this->imageID[0]) ? $this->imageID[0] : null,
+ 'teaserImageID' => !empty($this->teaserImageID[0]) ? $this->teaserImageID[0] : null
];
}
if (!empty($_POST) && !WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
foreach ($this->article->getArticleContents() as $languageID => $content) {
$this->imageID[$languageID] = $content->imageID;
+ $this->teaserImageID[$languageID] = $content->teaserImageID;
}
$this->readImages();
$this->teaser[$languageID] = $content->teaser;
$this->content[$languageID] = $content->content;
$this->imageID[$languageID] = $content->imageID;
+ $this->teaserImageID[$languageID] = $content->teaserImageID;
// get tags
if (MODULE_TAGGING) {
'title' => $content['title'],
'teaser' => $content['teaser'],
'content' => $content['content'],
- 'imageID' => $content['imageID']
+ 'imageID' => $content['imageID'],
+ 'teaserImageID' => $content['teaserImageID']
]);
$articleContentEditor = new ArticleContentEditor($articleContent);
'title' => $content['title'],
'teaser' => $content['teaser'],
'content' => $content['content'],
- 'imageID' => $content['imageID']
-
+ 'imageID' => $content['imageID'],
+ 'teaserImageID' => $content['teaserImageID']
]);
// delete tags
'title' => $content['title'],
'teaser' => $content['teaser'],
'content' => $content['content'],
- 'imageID' => $content['imageID']
+ 'imageID' => $content['imageID'],
+ 'teaserImageID' => $content['teaserImageID']
]);
$articleContentEditor = new ArticleContentEditor($articleContent);
}
return null;
}
+
+ /**
+ * Returns the article's teaser image.
+ *
+ * @return ViewableMedia|null
+ */
+ public function getTeaserImage() {
+ if ($this->getArticleContent() !== null) {
+ return $this->getArticleContent()->getTeaserImage();
+ }
+
+ return null;
+ }
}
* @property-read string $content actual content of the article in the associated language
* @property-read string $teaser teaser of the article in the associated language or empty if no teaser exists
* @property-read integer|null $imageID id of the (image) media object used as article image for the associated language or `null` if no image is used
+ * @property-read integer|null $teaserImageID id of the (image) media object used as article teaser image for the associated language or `null` if no image is used
* @property-read integer $hasEmbeddedObjects is `1` if there are embedded objects in the article content, otherwise `0`
*/
class ArticleContent extends DatabaseObject implements ILinkableObject, IRouteController {
public function getFormattedMessage() {
$message = SearchResultTextParser::getInstance()->parse($this->getDecoratedObject()->getFormattedContent());
- if ($this->getImage()) {
- return '<div class="box96">'.$this->getImage()->getElementTag(96).'<div>'.$message.'</div></div>';
+ if ($this->getTeaserImage()) {
+ return '<div class="box96">'.$this->getTeaserImage()->getElementTag(96).'<div>'.$message.'</div></div>';
}
return $message;
*/
protected $image;
+ /**
+ * article thumbnail image
+ * @var ViewableMedia
+ */
+ protected $teaserImage;
+
/**
* article object
* @var ViewableArticle
$this->image = $image;
}
+ /**
+ * Returns the article's teaser image if the active user can access it or `null`.
+ *
+ * @return ViewableMedia|null
+ */
+ public function getTeaserImage() {
+ if (!$this->teaserImageID) {
+ return $this->getImage();
+ }
+
+ if ($this->teaserImage === null) {
+ $this->teaserImage = ViewableMedia::getMedia($this->teaserImageID);
+ }
+
+ if ($this->teaserImage === null || !$this->teaserImage->isAccessible()) {
+ return null;
+ }
+
+ return $this->teaserImage;
+ }
+
+ /**
+ * Sets the article's teaser image.
+ *
+ * @param ViewableMedia $image
+ */
+ public function setTeaserImage(ViewableMedia $image) {
+ $this->teaserImage = $image;
+ }
+
/**
* Returns a specific article content decorated as viewable article content.
*
if ($articleContent->imageID) {
$imageIDs[] = $articleContent->imageID;
}
+ if ($articleContent->thumbnailImageID) {
+ $imageIDs[] = $articleContent->thumbnailImageID;
+ }
if ($articleContent->hasEmbeddedObjects) {
$embeddedObjectPostIDs[] = $articleContent->articleContentID;
}
if ($articleContent->imageID && isset($images[$articleContent->imageID])) {
$articleContent->setImage($images[$articleContent->imageID]);
}
+ if ($articleContent->thumbnailImageID && isset($images[$articleContent->thumbnailImageID])) {
+ $articleContent->setThumbnailImage($images[$articleContent->thumbnailImageID]);
+ }
}
}
MetaTagHandler::getInstance()->addTag('og:type', 'og:type', 'article', true);
MetaTagHandler::getInstance()->addTag('og:description', 'og:description', ($this->articleContent->teaser ?: StringUtil::decodeHTML(StringUtil::stripHTML($this->articleContent->getFormattedTeaser()))), true);
- if ($this->articleContent->getImage()) {
- MetaTagHandler::getInstance()->addTag('og:image', 'og:image', $this->articleContent->getImage()->getLink(), true);
+ if ($this->articleContent->getTeaserImage()) {
+ MetaTagHandler::getInstance()->addTag('og:image', 'og:image', $this->articleContent->getTeaserImage()->getLink(), true);
MetaTagHandler::getInstance()->addTag('og:image:width', 'og:image:width', $this->articleContent->getImage()->width, true);
MetaTagHandler::getInstance()->addTag('og:image:height', 'og:image:height', $this->articleContent->getImage()->height, true);
}
<item name="wcf.acp.article.i18n.i18n"><![CDATA[Mehrsprachiger Artikel]]></item>
<item name="wcf.acp.article.i18n.i18n.description"><![CDATA[Inhalt wird individuell pro Sprache festgelegt.]]></item>
<item name="wcf.acp.article.image"><![CDATA[Artikel-Bild]]></item>
+ <item name="wcf.acp.article.teaserImage"><![CDATA[Teaser-Bild]]></item>
<item name="wcf.acp.article.publicationDate"><![CDATA[Veröffentlichungsdatum]]></item>
<item name="wcf.acp.article.publicationDate.error.invalid"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} ein ungültiges Veröffentlichungsdatum angegeben.]]></item>
<item name="wcf.acp.article.publicationStatus"><![CDATA[Status]]></item>
<item name="wcf.acp.article.i18n.i18n"><![CDATA[Multilingual article]]></item>
<item name="wcf.acp.article.i18n.i18n.description"><![CDATA[The content will be provided for each language separately.]]></item>
<item name="wcf.acp.article.image"><![CDATA[Article Image]]></item>
+ <item name="wcf.acp.article.teaserImage"><![CDATA[Teaser Image]]></item>
<item name="wcf.acp.article.publicationDate"><![CDATA[Publication Date]]></item>
<item name="wcf.acp.article.publicationDate.error.invalid"><![CDATA[The publication date is invalid.]]></item>
<item name="wcf.acp.article.publicationStatus"><![CDATA[Status]]></item>
teaser TEXT,
content MEDIUMTEXT,
imageID INT(10),
+ teaserImageID INT(10),
hasEmbeddedObjects TINYINT(1) NOT NULL DEFAULT 0,
UNIQUE KEY (articleID, languageID)
ALTER TABLE wcf1_article_content ADD FOREIGN KEY (articleID) REFERENCES wcf1_article (articleID) ON DELETE CASCADE;
ALTER TABLE wcf1_article_content ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE SET NULL;
ALTER TABLE wcf1_article_content ADD FOREIGN KEY (imageID) REFERENCES wcf1_media (mediaID) ON DELETE SET NULL;
+ALTER TABLE wcf1_article_content ADD FOREIGN KEY (teaserImageID) REFERENCES wcf1_media (mediaID) ON DELETE SET NULL;
ALTER TABLE wcf1_attachment ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE;
ALTER TABLE wcf1_attachment ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;