Current File : /home/pacjaorg/public_html/kmm/components/com_content/src/Model/ArticlesModel.php |
<?php
/**
* @package Joomla.Site
* @subpackage com_content
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Content\Site\Model;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\TagsHelper;
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
use Joomla\Component\Content\Site\Helper\AssociationHelper;
use Joomla\Database\ParameterType;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* This models supports retrieving lists of articles.
*
* @since 1.6
*/
class ArticlesModel extends ListModel
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
*
* @see \JController
* @since 1.6
*/
public function __construct($config = [])
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = [
'id', 'a.id',
'title', 'a.title',
'alias', 'a.alias',
'checked_out', 'a.checked_out',
'checked_out_time', 'a.checked_out_time',
'catid', 'a.catid', 'category_title',
'state', 'a.state',
'access', 'a.access', 'access_level',
'created', 'a.created',
'created_by', 'a.created_by',
'ordering', 'a.ordering',
'featured', 'a.featured',
'language', 'a.language',
'hits', 'a.hits',
'publish_up', 'a.publish_up',
'publish_down', 'a.publish_down',
'images', 'a.images',
'urls', 'a.urls',
'filter_tag',
];
}
parent::__construct($config);
}
/**
* Method to auto-populate the model state.
*
* This method should only be called once per instantiation and is designed
* to be called on the first call to the getState() method unless the model
* configuration flag to ignore the request is set.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 3.0.1
*/
protected function populateState($ordering = 'ordering', $direction = 'ASC')
{
$app = Factory::getApplication();
$input = $app->getInput();
// List state information
$value = $input->get('limit', $app->get('list_limit', 0), 'uint');
$this->setState('list.limit', $value);
$value = $input->get('limitstart', 0, 'uint');
$this->setState('list.start', $value);
$value = $input->get('filter_tag', 0, 'uint');
$this->setState('filter.tag', $value);
$orderCol = $input->get('filter_order', 'a.ordering');
if (!in_array($orderCol, $this->filter_fields)) {
$orderCol = 'a.ordering';
}
$this->setState('list.ordering', $orderCol);
$listOrder = $input->get('filter_order_Dir', 'ASC');
if (!in_array(strtoupper($listOrder), ['ASC', 'DESC', ''])) {
$listOrder = 'ASC';
}
$this->setState('list.direction', $listOrder);
$params = $app->getParams();
$this->setState('params', $params);
$user = $this->getCurrentUser();
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))) {
// Filter on published for those who do not have edit or edit.state rights.
$this->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
}
$this->setState('filter.language', Multilanguage::isEnabled());
// Process show_noauth parameter
if ((!$params->get('show_noauth')) || (!ComponentHelper::getParams('com_content')->get('show_noauth'))) {
$this->setState('filter.access', true);
} else {
$this->setState('filter.access', false);
}
$this->setState('layout', $input->getString('layout'));
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*
* @since 1.6
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . serialize($this->getState('filter.published'));
$id .= ':' . $this->getState('filter.access');
$id .= ':' . $this->getState('filter.featured');
$id .= ':' . serialize($this->getState('filter.article_id'));
$id .= ':' . $this->getState('filter.article_id.include');
$id .= ':' . serialize($this->getState('filter.category_id'));
$id .= ':' . $this->getState('filter.category_id.include');
$id .= ':' . serialize($this->getState('filter.author_id'));
$id .= ':' . $this->getState('filter.author_id.include');
$id .= ':' . serialize($this->getState('filter.author_alias'));
$id .= ':' . $this->getState('filter.author_alias.include');
$id .= ':' . $this->getState('filter.date_filtering');
$id .= ':' . $this->getState('filter.date_field');
$id .= ':' . $this->getState('filter.start_date_range');
$id .= ':' . $this->getState('filter.end_date_range');
$id .= ':' . $this->getState('filter.relative_date');
$id .= ':' . serialize($this->getState('filter.tag'));
return parent::getStoreId($id);
}
/**
* Get the master query for retrieving a list of articles subject to the model state.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
$user = $this->getCurrentUser();
// Create a new query object.
$db = $this->getDatabase();
/** @var \Joomla\Database\DatabaseQuery $query */
$query = $db->getQuery(true);
$nowDate = Factory::getDate()->toSql();
$conditionArchived = ContentComponent::CONDITION_ARCHIVED;
$conditionUnpublished = ContentComponent::CONDITION_UNPUBLISHED;
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('a.id'),
$db->quoteName('a.title'),
$db->quoteName('a.alias'),
$db->quoteName('a.introtext'),
$db->quoteName('a.fulltext'),
$db->quoteName('a.checked_out'),
$db->quoteName('a.checked_out_time'),
$db->quoteName('a.catid'),
$db->quoteName('a.created'),
$db->quoteName('a.created_by'),
$db->quoteName('a.created_by_alias'),
$db->quoteName('a.modified'),
$db->quoteName('a.modified_by'),
// Use created if publish_up is null
'CASE WHEN ' . $db->quoteName('a.publish_up') . ' IS NULL THEN ' . $db->quoteName('a.created')
. ' ELSE ' . $db->quoteName('a.publish_up') . ' END AS ' . $db->quoteName('publish_up'),
$db->quoteName('a.publish_down'),
$db->quoteName('a.images'),
$db->quoteName('a.urls'),
$db->quoteName('a.attribs'),
$db->quoteName('a.metadata'),
$db->quoteName('a.metakey'),
$db->quoteName('a.metadesc'),
$db->quoteName('a.access'),
$db->quoteName('a.hits'),
$db->quoteName('a.featured'),
$db->quoteName('a.language'),
$query->length($db->quoteName('a.fulltext')) . ' AS ' . $db->quoteName('readmore'),
$db->quoteName('a.ordering'),
]
)
)
->select(
[
$db->quoteName('fp.featured_up'),
$db->quoteName('fp.featured_down'),
// Published/archived article in archived category is treated as archived article. If category is not published then force 0.
'CASE WHEN ' . $db->quoteName('c.published') . ' = 2 AND ' . $db->quoteName('a.state') . ' > 0 THEN ' . $conditionArchived
. ' WHEN ' . $db->quoteName('c.published') . ' != 1 THEN ' . $conditionUnpublished
. ' ELSE ' . $db->quoteName('a.state') . ' END AS ' . $db->quoteName('state'),
$db->quoteName('c.title', 'category_title'),
$db->quoteName('c.path', 'category_route'),
$db->quoteName('c.access', 'category_access'),
$db->quoteName('c.alias', 'category_alias'),
$db->quoteName('c.language', 'category_language'),
$db->quoteName('c.published'),
$db->quoteName('c.published', 'parents_published'),
$db->quoteName('c.lft'),
'CASE WHEN ' . $db->quoteName('a.created_by_alias') . ' > ' . $db->quote(' ') . ' THEN ' . $db->quoteName('a.created_by_alias')
. ' ELSE ' . $db->quoteName('ua.name') . ' END AS ' . $db->quoteName('author'),
$db->quoteName('ua.email', 'author_email'),
$db->quoteName('uam.name', 'modified_by_name'),
$db->quoteName('parent.title', 'parent_title'),
$db->quoteName('parent.id', 'parent_id'),
$db->quoteName('parent.path', 'parent_route'),
$db->quoteName('parent.alias', 'parent_alias'),
$db->quoteName('parent.language', 'parent_language'),
]
)
->from($db->quoteName('#__content', 'a'))
->join('LEFT', $db->quoteName('#__categories', 'c'), $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid'))
->join('LEFT', $db->quoteName('#__users', 'ua'), $db->quoteName('ua.id') . ' = ' . $db->quoteName('a.created_by'))
->join('LEFT', $db->quoteName('#__users', 'uam'), $db->quoteName('uam.id') . ' = ' . $db->quoteName('a.modified_by'))
->join('LEFT', $db->quoteName('#__categories', 'parent'), $db->quoteName('parent.id') . ' = ' . $db->quoteName('c.parent_id'));
$params = $this->getState('params');
$orderby_sec = $params->get('orderby_sec');
// Join over the frontpage articles if required.
$frontpageJoin = 'LEFT';
if ($this->getState('filter.frontpage')) {
if ($orderby_sec === 'front') {
$query->select($db->quoteName('fp.ordering'));
$frontpageJoin = 'INNER';
} else {
$query->where($db->quoteName('a.featured') . ' = 1');
}
$query->where(
[
'(' . $db->quoteName('fp.featured_up') . ' IS NULL OR ' . $db->quoteName('fp.featured_up') . ' <= :frontpageUp)',
'(' . $db->quoteName('fp.featured_down') . ' IS NULL OR ' . $db->quoteName('fp.featured_down') . ' >= :frontpageDown)',
]
)
->bind(':frontpageUp', $nowDate)
->bind(':frontpageDown', $nowDate);
} elseif ($orderby_sec === 'front' || $this->getState('list.ordering') === 'fp.ordering') {
$query->select($db->quoteName('fp.ordering'));
}
$query->join($frontpageJoin, $db->quoteName('#__content_frontpage', 'fp'), $db->quoteName('fp.content_id') . ' = ' . $db->quoteName('a.id'));
if (PluginHelper::isEnabled('content', 'vote')) {
// Join on voting table
$query->select(
[
'COALESCE(NULLIF(ROUND(' . $db->quoteName('v.rating_sum') . ' / ' . $db->quoteName('v.rating_count') . ', 1), 0), 0)'
. ' AS ' . $db->quoteName('rating'),
'COALESCE(NULLIF(' . $db->quoteName('v.rating_count') . ', 0), 0) AS ' . $db->quoteName('rating_count'),
]
)
->join('LEFT', $db->quoteName('#__content_rating', 'v'), $db->quoteName('a.id') . ' = ' . $db->quoteName('v.content_id'));
}
// Filter by access level.
if ($this->getState('filter.access', true)) {
$groups = $this->getState('filter.viewlevels', $user->getAuthorisedViewLevels());
$query->whereIn($db->quoteName('a.access'), $groups)
->whereIn($db->quoteName('c.access'), $groups);
}
// Filter by published state
$condition = $this->getState('filter.published');
if (is_numeric($condition) && $condition == 2) {
/**
* If category is archived then article has to be published or archived.
* Or category is published then article has to be archived.
*/
$query->where('((' . $db->quoteName('c.published') . ' = 2 AND ' . $db->quoteName('a.state') . ' > :conditionUnpublished)'
. ' OR (' . $db->quoteName('c.published') . ' = 1 AND ' . $db->quoteName('a.state') . ' = :conditionArchived))')
->bind(':conditionUnpublished', $conditionUnpublished, ParameterType::INTEGER)
->bind(':conditionArchived', $conditionArchived, ParameterType::INTEGER);
} elseif (is_numeric($condition)) {
$condition = (int) $condition;
// Category has to be published
$query->where($db->quoteName('c.published') . ' = 1 AND ' . $db->quoteName('a.state') . ' = :condition')
->bind(':condition', $condition, ParameterType::INTEGER);
} elseif (is_array($condition)) {
// Category has to be published
$query->where(
$db->quoteName('c.published') . ' = 1 AND ' . $db->quoteName('a.state')
. ' IN (' . implode(',', $query->bindArray($condition)) . ')'
);
}
// Filter by featured state
$featured = $this->getState('filter.featured');
switch ($featured) {
case 'hide':
$query->extendWhere(
'AND',
[
$db->quoteName('a.featured') . ' = 0',
'(' . $db->quoteName('fp.featured_up') . ' IS NOT NULL AND ' . $db->quoteName('fp.featured_up') . ' >= :featuredUp)',
'(' . $db->quoteName('fp.featured_down') . ' IS NOT NULL AND ' . $db->quoteName('fp.featured_down') . ' <= :featuredDown)',
],
'OR'
)
->bind(':featuredUp', $nowDate)
->bind(':featuredDown', $nowDate);
break;
case 'only':
$query->where(
[
$db->quoteName('a.featured') . ' = 1',
'(' . $db->quoteName('fp.featured_up') . ' IS NULL OR ' . $db->quoteName('fp.featured_up') . ' <= :featuredUp)',
'(' . $db->quoteName('fp.featured_down') . ' IS NULL OR ' . $db->quoteName('fp.featured_down') . ' >= :featuredDown)',
]
)
->bind(':featuredUp', $nowDate)
->bind(':featuredDown', $nowDate);
break;
case 'show':
default:
// Normally we do not discriminate between featured/unfeatured items.
break;
}
// Filter by a single or group of articles.
$articleId = $this->getState('filter.article_id');
if (is_numeric($articleId)) {
$articleId = (int) $articleId;
$type = $this->getState('filter.article_id.include', true) ? ' = ' : ' <> ';
$query->where($db->quoteName('a.id') . $type . ':articleId')
->bind(':articleId', $articleId, ParameterType::INTEGER);
} elseif (is_array($articleId)) {
$articleId = ArrayHelper::toInteger($articleId);
if ($this->getState('filter.article_id.include', true)) {
$query->whereIn($db->quoteName('a.id'), $articleId);
} else {
$query->whereNotIn($db->quoteName('a.id'), $articleId);
}
}
// Filter by a single or group of categories
$categoryId = $this->getState('filter.category_id');
if (is_numeric($categoryId)) {
$type = $this->getState('filter.category_id.include', true) ? ' = ' : ' <> ';
// Add subcategory check
$includeSubcategories = $this->getState('filter.subcategories', false);
if ($includeSubcategories) {
$categoryId = (int) $categoryId;
$levels = (int) $this->getState('filter.max_category_levels', 1);
// Create a subquery for the subcategory list
$subQuery = $db->getQuery(true)
->select($db->quoteName('sub.id'))
->from($db->quoteName('#__categories', 'sub'))
->join(
'INNER',
$db->quoteName('#__categories', 'this'),
$db->quoteName('sub.lft') . ' > ' . $db->quoteName('this.lft')
. ' AND ' . $db->quoteName('sub.rgt') . ' < ' . $db->quoteName('this.rgt')
)
->where($db->quoteName('this.id') . ' = :subCategoryId');
$query->bind(':subCategoryId', $categoryId, ParameterType::INTEGER);
if ($levels >= 0) {
$subQuery->where($db->quoteName('sub.level') . ' <= ' . $db->quoteName('this.level') . ' + :levels');
$query->bind(':levels', $levels, ParameterType::INTEGER);
}
// Add the subquery to the main query
$query->where(
'(' . $db->quoteName('a.catid') . $type . ':categoryId OR ' . $db->quoteName('a.catid') . ' IN (' . $subQuery . '))'
);
$query->bind(':categoryId', $categoryId, ParameterType::INTEGER);
} else {
$query->where($db->quoteName('a.catid') . $type . ':categoryId');
$query->bind(':categoryId', $categoryId, ParameterType::INTEGER);
}
} elseif (is_array($categoryId) && (count($categoryId) > 0)) {
$categoryId = ArrayHelper::toInteger($categoryId);
if (!empty($categoryId)) {
if ($this->getState('filter.category_id.include', true)) {
$query->whereIn($db->quoteName('a.catid'), $categoryId);
} else {
$query->whereNotIn($db->quoteName('a.catid'), $categoryId);
}
}
}
// Filter by author
$authorId = $this->getState('filter.author_id');
$authorWhere = '';
if (is_numeric($authorId)) {
$authorId = (int) $authorId;
$type = $this->getState('filter.author_id.include', true) ? ' = ' : ' <> ';
$authorWhere = $db->quoteName('a.created_by') . $type . ':authorId';
$query->bind(':authorId', $authorId, ParameterType::INTEGER);
} elseif (is_array($authorId)) {
$authorId = array_values(array_filter($authorId, 'is_numeric'));
if ($authorId) {
$type = $this->getState('filter.author_id.include', true) ? ' IN' : ' NOT IN';
$authorWhere = $db->quoteName('a.created_by') . $type . ' (' . implode(',', $query->bindArray($authorId)) . ')';
}
}
// Filter by author alias
$authorAlias = $this->getState('filter.author_alias');
$authorAliasWhere = '';
if (is_string($authorAlias)) {
$type = $this->getState('filter.author_alias.include', true) ? ' = ' : ' <> ';
$authorAliasWhere = $db->quoteName('a.created_by_alias') . $type . ':authorAlias';
$query->bind(':authorAlias', $authorAlias);
} elseif (\is_array($authorAlias) && !empty($authorAlias)) {
$type = $this->getState('filter.author_alias.include', true) ? ' IN' : ' NOT IN';
$authorAliasWhere = $db->quoteName('a.created_by_alias') . $type
. ' (' . implode(',', $query->bindArray($authorAlias, ParameterType::STRING)) . ')';
}
if (!empty($authorWhere) && !empty($authorAliasWhere)) {
$query->where('(' . $authorWhere . ' OR ' . $authorAliasWhere . ')');
} elseif (!empty($authorWhere) || !empty($authorAliasWhere)) {
// One of these is empty, the other is not so we just add both
$query->where($authorWhere . $authorAliasWhere);
}
// Filter by start and end dates.
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))) {
$query->where(
[
'(' . $db->quoteName('a.publish_up') . ' IS NULL OR ' . $db->quoteName('a.publish_up') . ' <= :publishUp)',
'(' . $db->quoteName('a.publish_down') . ' IS NULL OR ' . $db->quoteName('a.publish_down') . ' >= :publishDown)',
]
)
->bind(':publishUp', $nowDate)
->bind(':publishDown', $nowDate);
}
// Filter by Date Range or Relative Date
$dateFiltering = $this->getState('filter.date_filtering', 'off');
$dateField = $db->escape($this->getState('filter.date_field', 'a.created'));
switch ($dateFiltering) {
case 'range':
$startDateRange = $this->getState('filter.start_date_range', '');
$endDateRange = $this->getState('filter.end_date_range', '');
if ($startDateRange || $endDateRange) {
$query->where($db->quoteName($dateField) . ' IS NOT NULL');
if ($startDateRange) {
$query->where($db->quoteName($dateField) . ' >= :startDateRange')
->bind(':startDateRange', $startDateRange);
}
if ($endDateRange) {
$query->where($db->quoteName($dateField) . ' <= :endDateRange')
->bind(':endDateRange', $endDateRange);
}
}
break;
case 'relative':
$relativeDate = (int) $this->getState('filter.relative_date', 0);
$query->where(
$db->quoteName($dateField) . ' IS NOT NULL AND '
. $db->quoteName($dateField) . ' >= ' . $query->dateAdd($db->quote($nowDate), -1 * $relativeDate, 'DAY')
);
break;
case 'off':
default:
break;
}
// Process the filter for list views with user-entered filters
if (is_object($params) && ($params->get('filter_field') !== 'hide') && ($filter = $this->getState('list.filter'))) {
// Clean filter variable
$filter = StringHelper::strtolower($filter);
$monthFilter = $filter;
$hitsFilter = (int) $filter;
$textFilter = '%' . $filter . '%';
switch ($params->get('filter_field')) {
case 'author':
$query->where(
'LOWER(CASE WHEN ' . $db->quoteName('a.created_by_alias') . ' > ' . $db->quote(' ')
. ' THEN ' . $db->quoteName('a.created_by_alias') . ' ELSE ' . $db->quoteName('ua.name') . ' END) LIKE :search'
)
->bind(':search', $textFilter);
break;
case 'hits':
$query->where($db->quoteName('a.hits') . ' >= :hits')
->bind(':hits', $hitsFilter, ParameterType::INTEGER);
break;
case 'month':
if ($monthFilter != '') {
$monthStart = date("Y-m-d", strtotime($monthFilter)) . ' 00:00:00';
$monthEnd = date("Y-m-t", strtotime($monthFilter)) . ' 23:59:59';
$query->where(
[
':monthStart <= CASE WHEN a.publish_up IS NULL THEN a.created ELSE a.publish_up END',
':monthEnd >= CASE WHEN a.publish_up IS NULL THEN a.created ELSE a.publish_up END',
]
)
->bind(':monthStart', $monthStart)
->bind(':monthEnd', $monthEnd);
}
break;
case 'title':
default:
// Default to 'title' if parameter is not valid
$query->where('LOWER(' . $db->quoteName('a.title') . ') LIKE :search')
->bind(':search', $textFilter);
break;
}
}
// Filter by language
if ($this->getState('filter.language')) {
$query->whereIn($db->quoteName('a.language'), [Factory::getApplication()->getLanguage()->getTag(), '*'], ParameterType::STRING);
}
// Filter by a single or group of tags.
$tagId = $this->getState('filter.tag');
if (is_array($tagId) && count($tagId) === 1) {
$tagId = current($tagId);
}
if (is_array($tagId)) {
$tagId = ArrayHelper::toInteger($tagId);
if ($tagId) {
$subQuery = $db->getQuery(true)
->select('DISTINCT ' . $db->quoteName('content_item_id'))
->from($db->quoteName('#__contentitem_tag_map'))
->where(
[
$db->quoteName('tag_id') . ' IN (' . implode(',', $query->bindArray($tagId)) . ')',
$db->quoteName('type_alias') . ' = ' . $db->quote('com_content.article'),
]
);
$query->join(
'INNER',
'(' . $subQuery . ') AS ' . $db->quoteName('tagmap'),
$db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
);
}
} elseif ($tagId = (int) $tagId) {
$query->join(
'INNER',
$db->quoteName('#__contentitem_tag_map', 'tagmap'),
$db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id')
. ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article')
)
->where($db->quoteName('tagmap.tag_id') . ' = :tagId')
->bind(':tagId', $tagId, ParameterType::INTEGER);
}
// Add the list ordering clause.
$query->order(
$db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))
);
return $query;
}
/**
* Method to get a list of articles.
*
* Overridden to inject convert the attribs field into a Registry object.
*
* @return mixed An array of objects on success, false on failure.
*
* @since 1.6
*/
public function getItems()
{
$items = parent::getItems();
$user = $this->getCurrentUser();
$userId = $user->get('id');
$guest = $user->get('guest');
$groups = $user->getAuthorisedViewLevels();
$input = Factory::getApplication()->getInput();
// Get the global params
$globalParams = ComponentHelper::getParams('com_content', true);
$taggedItems = [];
// Convert the parameter fields into objects.
foreach ($items as $item) {
$articleParams = new Registry($item->attribs);
// Unpack readmore and layout params
$item->alternative_readmore = $articleParams->get('alternative_readmore');
$item->layout = $articleParams->get('layout');
$item->params = clone $this->getState('params');
/**
* For blogs, article params override menu item params only if menu param = 'use_article'
* Otherwise, menu item params control the layout
* If menu item is 'use_article' and there is no article param, use global
*/
if (
($input->getString('layout') === 'blog') || ($input->getString('view') === 'featured')
|| ($this->getState('params')->get('layout_type') === 'blog')
) {
// Create an array of just the params set to 'use_article'
$menuParamsArray = $this->getState('params')->toArray();
$articleArray = [];
foreach ($menuParamsArray as $key => $value) {
if ($value === 'use_article') {
// If the article has a value, use it
if ($articleParams->get($key) != '') {
// Get the value from the article
$articleArray[$key] = $articleParams->get($key);
} else {
// Otherwise, use the global value
$articleArray[$key] = $globalParams->get($key);
}
}
}
// Merge the selected article params
if (count($articleArray) > 0) {
$articleParams = new Registry($articleArray);
$item->params->merge($articleParams);
}
} else {
// For non-blog layouts, merge all of the article params
$item->params->merge($articleParams);
}
// Get display date
switch ($item->params->get('list_show_date')) {
case 'modified':
$item->displayDate = $item->modified;
break;
case 'published':
$item->displayDate = ($item->publish_up == 0) ? $item->created : $item->publish_up;
break;
default:
case 'created':
$item->displayDate = $item->created;
break;
}
/**
* Compute the asset access permissions.
* Technically guest could edit an article, but lets not check that to improve performance a little.
*/
if (!$guest) {
$asset = 'com_content.article.' . $item->id;
// Check general edit permission first.
if ($user->authorise('core.edit', $asset)) {
$item->params->set('access-edit', true);
} elseif (!empty($userId) && $user->authorise('core.edit.own', $asset)) {
// Now check if edit.own is available.
// Check for a valid user and that they are the owner.
if ($userId == $item->created_by) {
$item->params->set('access-edit', true);
}
}
}
$access = $this->getState('filter.access');
if ($access) {
// If the access filter has been set, we already have only the articles this user can view.
$item->params->set('access-view', true);
} else {
// If no access filter is set, the layout takes some responsibility for display of limited information.
if ($item->catid == 0 || $item->category_access === null) {
$item->params->set('access-view', in_array($item->access, $groups));
} else {
$item->params->set('access-view', in_array($item->access, $groups) && in_array($item->category_access, $groups));
}
}
// Some contexts may not use tags data at all, so we allow callers to disable loading tag data
if ($this->getState('load_tags', $item->params->get('show_tags', '1'))) {
$item->tags = new TagsHelper();
$taggedItems[$item->id] = $item;
}
if (Associations::isEnabled() && $item->params->get('show_associations')) {
$item->associations = AssociationHelper::displayAssociations($item->id);
}
}
// Load tags of all items.
if ($taggedItems) {
$tagsHelper = new TagsHelper();
$itemIds = \array_keys($taggedItems);
foreach ($tagsHelper->getMultipleItemTags('com_content.article', $itemIds) as $id => $tags) {
$taggedItems[$id]->tags->itemTags = $tags;
}
}
return $items;
}
/**
* Method to get the starting number of items for the data set.
*
* @return integer The starting number of items available in the data set.
*
* @since 3.0.1
*/
public function getStart()
{
return $this->getState('list.start');
}
/**
* Count Items by Month
*
* @return mixed An array of objects on success, false on failure.
*
* @since 3.9.0
*/
public function countItemsByMonth()
{
// Create a new query object.
$db = $this->getDatabase();
$query = $db->getQuery(true);
// Get the list query.
$listQuery = $this->getListQuery();
$bounded = $listQuery->getBounded();
// Bind list query variables to our new query.
$keys = array_keys($bounded);
$values = array_column($bounded, 'value');
$dataTypes = array_column($bounded, 'dataType');
$query->bind($keys, $values, $dataTypes);
$query
->select(
'DATE(' .
$query->concatenate(
[
$query->year($db->quoteName('publish_up')),
$db->quote('-'),
$query->month($db->quoteName('publish_up')),
$db->quote('-01'),
]
) . ') AS ' . $db->quoteName('d')
)
->select('COUNT(*) AS ' . $db->quoteName('c'))
->from('(' . $this->getListQuery() . ') AS ' . $db->quoteName('b'))
->group($db->quoteName('d'))
->order($db->quoteName('d') . ' DESC');
return $db->setQuery($query)->loadObjectList();
}
}