Файл: contao-3.5.8/system/modules/news/modules/ModuleNews.php
Строк: 300
<?php
/**
* Contao Open Source CMS
*
* Copyright (c) 2005-2016 Leo Feyer
*
* @license LGPL-3.0+
*/
namespace Contao;
/**
* Parent class for news modules.
*
* @author Leo Feyer <https://github.com/leofeyer>
*/
abstract class ModuleNews extends Module
{
/**
* URL cache array
* @var array
*/
private static $arrUrlCache = array();
/**
* Sort out protected archives
*
* @param array $arrArchives
*
* @return array
*/
protected function sortOutProtected($arrArchives)
{
if (BE_USER_LOGGED_IN || !is_array($arrArchives) || empty($arrArchives))
{
return $arrArchives;
}
$this->import('FrontendUser', 'User');
$objArchive = NewsArchiveModel::findMultipleByIds($arrArchives);
$arrArchives = array();
if ($objArchive !== null)
{
while ($objArchive->next())
{
if ($objArchive->protected)
{
if (!FE_USER_LOGGED_IN)
{
continue;
}
$groups = deserialize($objArchive->groups);
if (!is_array($groups) || empty($groups) || !count(array_intersect($groups, $this->User->groups)))
{
continue;
}
}
$arrArchives[] = $objArchive->id;
}
}
return $arrArchives;
}
/**
* Parse an item and return it as string
*
* @param NewsModel $objArticle
* @param boolean $blnAddArchive
* @param string $strClass
* @param integer $intCount
*
* @return string
*/
protected function parseArticle($objArticle, $blnAddArchive=false, $strClass='', $intCount=0)
{
/** @var PageModel $objPage */
global $objPage;
/** @var FrontendTemplate|object $objTemplate */
$objTemplate = new FrontendTemplate($this->news_template);
$objTemplate->setData($objArticle->row());
$objTemplate->class = (($objArticle->cssClass != '') ? ' ' . $objArticle->cssClass : '') . $strClass;
$objTemplate->newsHeadline = $objArticle->headline;
$objTemplate->subHeadline = $objArticle->subheadline;
$objTemplate->hasSubHeadline = $objArticle->subheadline ? true : false;
$objTemplate->linkHeadline = $this->generateLink($objArticle->headline, $objArticle, $blnAddArchive);
$objTemplate->more = $this->generateLink($GLOBALS['TL_LANG']['MSC']['more'], $objArticle, $blnAddArchive, true);
$objTemplate->link = $this->generateNewsUrl($objArticle, $blnAddArchive);
$objTemplate->archive = $objArticle->getRelated('pid');
$objTemplate->count = $intCount; // see #5708
$objTemplate->text = '';
$objTemplate->hasText = false;
$objTemplate->hasTeaser = false;
// Clean the RTE output
if ($objArticle->teaser != '')
{
$objTemplate->hasTeaser = true;
if ($objPage->outputFormat == 'xhtml')
{
$objTemplate->teaser = StringUtil::toXhtml($objArticle->teaser);
}
else
{
$objTemplate->teaser = StringUtil::toHtml5($objArticle->teaser);
}
$objTemplate->teaser = StringUtil::encodeEmail($objTemplate->teaser);
}
// Display the "read more" button for external/article links
if ($objArticle->source != 'default')
{
$objTemplate->text = true;
$objTemplate->hasText = true;
}
// Compile the news text
else
{
$id = $objArticle->id;
$objTemplate->text = function () use ($id)
{
$strText = '';
$objElement = ContentModel::findPublishedByPidAndTable($id, 'tl_news');
if ($objElement !== null)
{
while ($objElement->next())
{
$strText .= $this->getContentElement($objElement->current());
}
}
return $strText;
};
$objTemplate->hasText = (ContentModel::countPublishedByPidAndTable($objArticle->id, 'tl_news') > 0);
}
$arrMeta = $this->getMetaFields($objArticle);
// Add the meta information
$objTemplate->date = $arrMeta['date'];
$objTemplate->hasMetaFields = !empty($arrMeta);
$objTemplate->numberOfComments = $arrMeta['ccount'];
$objTemplate->commentCount = $arrMeta['comments'];
$objTemplate->timestamp = $objArticle->date;
$objTemplate->author = $arrMeta['author'];
$objTemplate->datetime = date('Y-m-dTH:i:sP', $objArticle->date);
$objTemplate->addImage = false;
// Add an image
if ($objArticle->addImage && $objArticle->singleSRC != '')
{
$objModel = FilesModel::findByUuid($objArticle->singleSRC);
if ($objModel === null)
{
if (!Validator::isUuid($objArticle->singleSRC))
{
$objTemplate->text = '<p class="error">'.$GLOBALS['TL_LANG']['ERR']['version2format'].'</p>';
}
}
elseif (is_file(TL_ROOT . '/' . $objModel->path))
{
// Do not override the field now that we have a model registry (see #6303)
$arrArticle = $objArticle->row();
// Override the default image size
if ($this->imgSize != '')
{
$size = deserialize($this->imgSize);
if ($size[0] > 0 || $size[1] > 0 || is_numeric($size[2]))
{
$arrArticle['size'] = $this->imgSize;
}
}
$arrArticle['singleSRC'] = $objModel->path;
$this->addImageToTemplate($objTemplate, $arrArticle);
}
}
$objTemplate->enclosure = array();
// Add enclosures
if ($objArticle->addEnclosure)
{
$this->addEnclosuresToTemplate($objTemplate, $objArticle->row());
}
// HOOK: add custom logic
if (isset($GLOBALS['TL_HOOKS']['parseArticles']) && is_array($GLOBALS['TL_HOOKS']['parseArticles']))
{
foreach ($GLOBALS['TL_HOOKS']['parseArticles'] as $callback)
{
$this->import($callback[0]);
$this->{$callback[0]}->{$callback[1]}($objTemplate, $objArticle->row(), $this);
}
}
return $objTemplate->parse();
}
/**
* Parse one or more items and return them as array
*
* @param ModelCollection $objArticles
* @param boolean $blnAddArchive
*
* @return array
*/
protected function parseArticles($objArticles, $blnAddArchive=false)
{
$limit = $objArticles->count();
if ($limit < 1)
{
return array();
}
$count = 0;
$arrArticles = array();
while ($objArticles->next())
{
/** @var NewsModel $objArticle */
$objArticle = $objArticles->current();
$arrArticles[] = $this->parseArticle($objArticle, $blnAddArchive, ((++$count == 1) ? ' first' : '') . (($count == $limit) ? ' last' : '') . ((($count % 2) == 0) ? ' odd' : ' even'), $count);
}
return $arrArticles;
}
/**
* Return the meta fields of a news article as array
*
* @param NewsModel $objArticle
*
* @return array
*/
protected function getMetaFields($objArticle)
{
$meta = deserialize($this->news_metaFields);
if (!is_array($meta))
{
return array();
}
/** @var PageModel $objPage */
global $objPage;
$return = array();
foreach ($meta as $field)
{
switch ($field)
{
case 'date':
$return['date'] = Date::parse($objPage->datimFormat, $objArticle->date);
break;
case 'author':
/** @var UserModel $objAuthor */
if (($objAuthor = $objArticle->getRelated('author')) !== null)
{
$return['author'] = $GLOBALS['TL_LANG']['MSC']['by'] . ' ' . $objAuthor->name;
}
break;
case 'comments':
if ($objArticle->noComments || !in_array('comments', ModuleLoader::getActive()) || $objArticle->source != 'default')
{
break;
}
$intTotal = CommentsModel::countPublishedBySourceAndParent('tl_news', $objArticle->id);
$return['ccount'] = $intTotal;
$return['comments'] = sprintf($GLOBALS['TL_LANG']['MSC']['commentCount'], $intTotal);
break;
}
}
return $return;
}
/**
* Generate a URL and return it as string
*
* @param NewsModel $objItem
* @param boolean $blnAddArchive
*
* @return string
*/
protected function generateNewsUrl($objItem, $blnAddArchive=false)
{
$strCacheKey = 'id_' . $objItem->id;
// Load the URL from cache
if (isset(self::$arrUrlCache[$strCacheKey]))
{
return self::$arrUrlCache[$strCacheKey];
}
// Initialize the cache
self::$arrUrlCache[$strCacheKey] = null;
switch ($objItem->source)
{
// Link to an external page
case 'external':
if (substr($objItem->url, 0, 7) == 'mailto:')
{
self::$arrUrlCache[$strCacheKey] = StringUtil::encodeEmail($objItem->url);
}
else
{
self::$arrUrlCache[$strCacheKey] = ampersand($objItem->url);
}
break;
// Link to an internal page
case 'internal':
if (($objTarget = $objItem->getRelated('jumpTo')) !== null)
{
/** @var PageModel $objTarget */
self::$arrUrlCache[$strCacheKey] = ampersand($objTarget->getFrontendUrl());
}
break;
// Link to an article
case 'article':
if (($objArticle = ArticleModel::findByPk($objItem->articleId, array('eager'=>true))) !== null && ($objPid = $objArticle->getRelated('pid')) !== null)
{
/** @var PageModel $objPid */
self::$arrUrlCache[$strCacheKey] = ampersand($objPid->getFrontendUrl('/articles/' . ((!Config::get('disableAlias') && $objArticle->alias != '') ? $objArticle->alias : $objArticle->id)));
}
break;
}
// Link to the default page
if (self::$arrUrlCache[$strCacheKey] === null)
{
$objPage = PageModel::findWithDetails($objItem->getRelated('pid')->jumpTo);
if ($objPage === null)
{
self::$arrUrlCache[$strCacheKey] = ampersand(Environment::get('request'), true);
}
else
{
self::$arrUrlCache[$strCacheKey] = ampersand($objPage->getFrontendUrl(((Config::get('useAutoItem') && !Config::get('disableAlias')) ? '/' : '/items/') . ((!Config::get('disableAlias') && $objItem->alias != '') ? $objItem->alias : $objItem->id)));
}
// Add the current archive parameter (news archive)
if ($blnAddArchive && Input::get('month') != '')
{
self::$arrUrlCache[$strCacheKey] .= (Config::get('disableAlias') ? '&' : '?') . 'month=' . Input::get('month');
}
}
return self::$arrUrlCache[$strCacheKey];
}
/**
* Generate a link and return it as string
*
* @param string $strLink
* @param NewsModel $objArticle
* @param boolean $blnAddArchive
* @param boolean $blnIsReadMore
*
* @return string
*/
protected function generateLink($strLink, $objArticle, $blnAddArchive=false, $blnIsReadMore=false)
{
// Internal link
if ($objArticle->source != 'external')
{
return sprintf('<a href="%s" title="%s">%s%s</a>',
$this->generateNewsUrl($objArticle, $blnAddArchive),
specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['readMore'], $objArticle->headline), true),
$strLink,
($blnIsReadMore ? '<span class="invisible"> '.$objArticle->headline.'</span>' : ''));
}
// Encode e-mail addresses
if (substr($objArticle->url, 0, 7) == 'mailto:')
{
$strArticleUrl = StringUtil::encodeEmail($objArticle->url);
}
// Ampersand URIs
else
{
$strArticleUrl = ampersand($objArticle->url);
}
/** @var PageModel $objPage */
global $objPage;
// External link
return sprintf('<a href="%s" title="%s"%s>%s</a>',
$strArticleUrl,
specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['open'], $strArticleUrl)),
($objArticle->target ? (($objPage->outputFormat == 'xhtml') ? ' onclick="return !window.open(this.href)"' : ' target="_blank"') : ''),
$strLink);
}
}