public static \stdClass[]
countRelations
(mixed &$items, mixed $config)
/**
* Adds Count relations for Category and Tag Managers
*
* @param \stdClass[] &$items The category or tag objects
* @param \stdClass $config Configuration object allowing to use a custom relations table
*
* @return \stdClass[]
*
* @since 3.9.1
*/
public static function countRelations(&$items, $config)
{
$db = Factory::getDbo();
// Allow custom state / condition values and custom column names to support custom components
$counter_names = isset($config->counter_names) ? $config->counter_names : array('-2' => 'count_trashed', '0' => 'count_unpublished', '1' => 'count_published', '2' => 'count_archived');
// Index category objects by their ID
$records = array();
foreach ($items as $item) {
$records[(int) $item->id] = $item;
}
// The relation query does not return a value for cases without relations of a particular state / condition, set zero as default
foreach ($items as $item) {
foreach ($counter_names as $n) {
$item->{$n} = 0;
}
}
// Table alias for related data table below will be 'c', and state / condition column is inside related data table
$related_tbl = '#__' . $config->related_tbl;
$state_col = 'c.' . $config->state_col;
// Supported cases
switch ($config->relation_type) {
case 'tag_assigments':
$recid_col = 'ct.' . $config->group_col;
$query = $db->getQuery(true)->from($db->quoteName('#__contentitem_tag_map', 'ct'))->join('INNER', $db->quoteName($related_tbl, 'c'), $db->quoteName('ct.content_item_id') . ' = ' . $db->quoteName('c.id') . ' AND ' . $db->quoteName('ct.type_alias') . ' = :extension')->bind(':extension', $config->extension);
break;
case 'category_or_group':
$recid_col = 'c.' . $config->group_col;
$query = $db->getQuery(true)->from($db->quoteName($related_tbl, 'c'));
break;
default:
return $items;
}
/**
* Get relation counts for all category objects with single query
* NOTE: 'state IN', allows counting specific states / conditions only, also prevents warnings with custom states / conditions, do not remove
*/
$query->select([$db->quoteName($recid_col, 'catid'), $db->quoteName($state_col, 'state'), 'COUNT(*) AS ' . $db->quoteName('count')])->whereIn($db->quoteName($recid_col), array_keys($records))->whereIn($db->quoteName($state_col), array_keys($counter_names))->group($db->quoteName([$recid_col, $state_col]));
$relationsAll = $db->setQuery($query)->loadObjectList();
// Loop through the DB data overwriting the above zeros with the found count
foreach ($relationsAll as $relation) {
// Sanity check in case someone removes the state IN above ... and some views may start throwing warnings
if (isset($counter_names[$relation->state])) {
$id = (int) $relation->catid;
$cn = $counter_names[$relation->state];
$records[$id]->{$cn} = $relation->count;
}
}
return $items;
}