first commit

This commit is contained in:
2025-06-17 11:53:18 +02:00
commit 9f0f7ba12b
8804 changed files with 1369176 additions and 0 deletions

View File

@ -0,0 +1,571 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_category</name>
<author>Joomla! Project</author>
<creationDate>2010-02</creationDate>
<copyright>(C) 2010 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.0.0</version>
<description>MOD_ARTICLES_CATEGORY_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesCategory</namespace>
<files>
<folder module="mod_articles_category">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_category.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_category.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Category" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="mode"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_MODE_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_MODE_DESC"
default="normal"
validate="options"
>
<option value="normal">MOD_ARTICLES_CATEGORY_OPTION_NORMAL_VALUE</option>
<option value="dynamic">MOD_ARTICLES_CATEGORY_OPTION_DYNAMIC_VALUE</option>
</field>
<field
name="show_on_article_page"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWONARTICLEPAGE_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_SHOWONARTICLEPAGE_DESC"
default="1"
filter="integer"
showon="mode:dynamic"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
<fieldset
name="filtering"
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_FILTERING_LABEL"
>
<field
name="count"
type="number"
label="MOD_ARTICLES_CATEGORY_FIELD_COUNT_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_COUNT_DESC"
default="0"
filter="integer"
/>
<field
name="show_front"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWFEATURED_LABEL"
default="show"
validate="options"
>
<option value="show">JSHOW</option>
<option value="hide">JHIDE</option>
<option value="only">MOD_ARTICLES_CATEGORY_OPTION_ONLYFEATURED_VALUE</option>
</field>
<field
name="filteringspacer0"
type="spacer"
hr="true"
/>
<field
name="category_filtering_type"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_CATFILTERINGTYPE_LABEL"
default="1"
filter="integer"
>
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
</field>
<field
name="catid"
type="category"
label="JCATEGORY"
extension="com_content"
multiple="true"
layout="joomla.form.field.list-fancy-select"
filter="intarray"
class="multipleCategories"
/>
<field
name="show_child_category_articles"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWCHILDCATEGORYARTICLES_LABEL"
default="0"
filter="integer"
>
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUDE_VALUE</option>
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUDE_VALUE</option>
</field>
<field
name="levels"
type="number"
label="MOD_ARTICLES_CATEGORY_FIELD_CATDEPTH_LABEL"
default="1"
filter="integer"
showon="show_child_category_articles:1"
/>
<field
name="filteringspacer1"
type="spacer"
hr="true"
/>
<field
name="filter_tag"
type="tag"
label="JTAG"
mode="nested"
multiple="true"
filter="intarray"
class="multipleTags"
/>
<field
name="filteringspacer2"
type="spacer"
hr="true"
/>
<field
name="author_filtering_type"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORFILTERING_LABEL"
default="1"
filter="integer"
>
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
</field>
<field
name="created_by"
type="author"
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHOR_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
filter="intarray"
class="multipleAuthors"
/>
<field
name="filteringspacer3"
type="spacer"
hr="true"
/>
<field
name="author_alias_filtering_type"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORALIASFILTERING_LABEL"
default="1"
filter="integer"
>
<option value="0">MOD_ARTICLES_CATEGORY_OPTION_EXCLUSIVE_VALUE</option>
<option value="1">MOD_ARTICLES_CATEGORY_OPTION_INCLUSIVE_VALUE</option>
</field>
<field
name="created_by_alias"
type="sql"
label="MOD_ARTICLES_CATEGORY_FIELD_AUTHORALIAS_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
query="select distinct(created_by_alias) from #__content where created_by_alias != '' order by created_by_alias ASC"
key_field="created_by_alias"
value_field="created_by_alias"
class="multipleAuthorAliases"
/>
<field
name="filteringspacer4"
type="spacer"
hr="true"
/>
<field
name="excluded_articles"
type="textarea"
label="MOD_ARTICLES_CATEGORY_FIELD_EXCLUDEDARTICLES_LABEL"
cols="10"
rows="3"
/>
<field
name="filteringspacer5"
type="spacer"
hr="true"
/>
<field
name="date_filtering"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFILTERING_LABEL"
default="off"
validate="options"
>
<option value="off">MOD_ARTICLES_CATEGORY_OPTION_OFF_VALUE</option>
<option value="range">MOD_ARTICLES_CATEGORY_OPTION_DATERANGE_VALUE</option>
<option value="relative">MOD_ARTICLES_CATEGORY_OPTION_RELATIVEDAY_VALUE</option>
</field>
<field
name="date_field"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_DATERANGEFIELD_LABEL"
default="a.created"
showon="date_filtering!:off"
validate="options"
>
<option value="a.created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
<option value="a.modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
<option value="a.publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
</field>
<field
name="start_date_range"
type="calendar"
label="MOD_ARTICLES_CATEGORY_FIELD_STARTDATE_LABEL"
translateformat="true"
showtime="true"
filter="user_utc"
showon="date_filtering:range"
/>
<field
name="end_date_range"
type="calendar"
label="MOD_ARTICLES_CATEGORY_FIELD_ENDDATE_LABEL"
translateformat="true"
showtime="true"
filter="user_utc"
showon="date_filtering:range"
/>
<field
name="relative_date"
type="number"
label="MOD_ARTICLES_CATEGORY_FIELD_RELATIVEDATE_LABEL"
default="30"
filter="integer"
showon="date_filtering:relative"
/>
</fieldset>
<fieldset
name="ordering"
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_ORDERING_LABEL"
>
<field
name="article_ordering"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEORDERING_LABEL"
default="a.title"
validate="options"
>
<option value="a.ordering">MOD_ARTICLES_CATEGORY_OPTION_ORDERING_VALUE</option>
<option value="fp.ordering">MOD_ARTICLES_CATEGORY_OPTION_ORDERINGFEATURED_VALUE</option>
<option value="a.hits" requires="hits">MOD_ARTICLES_CATEGORY_OPTION_HITS_VALUE</option>
<option value="a.title">JGLOBAL_TITLE</option>
<option value="a.id">MOD_ARTICLES_CATEGORY_OPTION_ID_VALUE</option>
<option value="a.alias">JFIELD_ALIAS_LABEL</option>
<option value="a.created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
<option value="a.publish_down">MOD_ARTICLES_CATEGORY_OPTION_FINISHPUBLISHING_VALUE</option>
<option value="random">MOD_ARTICLES_CATEGORY_OPTION_RANDOM_VALUE</option>
<option value="rating_count" requires="vote">MOD_ARTICLES_CATEGORY_OPTION_VOTE_VALUE</option>
<option value="rating" requires="vote">MOD_ARTICLES_CATEGORY_OPTION_RATING_VALUE</option>
</field>
<field
name="article_ordering_direction"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEORDERINGDIR_LABEL"
default="ASC"
validate="options"
>
<option value="DESC">MOD_ARTICLES_CATEGORY_OPTION_DESCENDING_VALUE</option>
<option value="ASC">MOD_ARTICLES_CATEGORY_OPTION_ASCENDING_VALUE</option>
</field>
</fieldset>
<fieldset
name="grouping"
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_GROUPING_LABEL"
>
<field
name="article_grouping"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEGROUPING_LABEL"
default="none"
validate="options"
>
<option value="none">JNONE</option>
<option value="year">MOD_ARTICLES_CATEGORY_OPTION_YEAR_VALUE</option>
<option value="month_year">MOD_ARTICLES_CATEGORY_OPTION_MONTHYEAR_VALUE</option>
<option value="author">JAUTHOR</option>
<option value="category_title">JCATEGORY</option>
<option value="tags">JTAG</option>
</field>
<field
name="date_grouping_field"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_DATEGROUPINGFIELD_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_DATEGROUPINGFIELD_DESC"
default="created"
showon="article_grouping:year,month_year"
validate="options"
>
<option value="created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
</field>
<field
name="month_year_format"
type="text"
label="MOD_ARTICLES_CATEGORY_FIELD_MONTHYEARFORMAT_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_MONTHYEARFORMAT_DESC"
default="F Y"
showon="article_grouping:year,month_year"
/>
<field
name="article_grouping_direction"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_ARTICLEGROUPINGDIR_LABEL"
default="ksort"
showon="article_grouping!:none"
validate="options"
>
<option value="krsort">MOD_ARTICLES_CATEGORY_OPTION_DESCENDING_VALUE</option>
<option value="ksort">MOD_ARTICLES_CATEGORY_OPTION_ASCENDING_VALUE</option>
</field>
</fieldset>
<fieldset
name="display"
label="MOD_ARTICLES_CATEGORY_FIELD_GROUP_DISPLAY_LABEL"
>
<field
name="link_titles"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_LINKTITLES_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="show_date"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JDATE"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_date_field"
type="list"
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELD_LABEL"
default="created"
showon="show_date:1"
validate="options"
>
<option value="created">MOD_ARTICLES_CATEGORY_OPTION_CREATED_VALUE</option>
<option value="modified">MOD_ARTICLES_CATEGORY_OPTION_MODIFIED_VALUE</option>
<option value="publish_up">MOD_ARTICLES_CATEGORY_OPTION_STARTPUBLISHING_VALUE</option>
</field>
<field
name="show_date_format"
type="text"
label="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELDFORMAT_LABEL"
description="MOD_ARTICLES_CATEGORY_FIELD_DATEFIELDFORMAT_DESC"
default="Y-m-d H:i:s"
showon="show_date:1"
/>
<field
name="show_category"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JCATEGORY"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_hits"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWHITS_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_author"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JAUTHOR"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_tags"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JTAG"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_introtext"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORY_FIELD_SHOWINTROTEXT_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="introtext_limit"
type="number"
label="MOD_ARTICLES_CATEGORY_FIELD_INTROTEXTLIMIT_LABEL"
default="100"
filter="integer"
showon="show_introtext:1"
/>
<field
name="show_readmore"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JGLOBAL_SHOW_READMORE_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_readmore_title"
type="radio"
layout="joomla.form.field.radio.switcher"
label="JGLOBAL_SHOW_READMORE_TITLE_LABEL"
default="1"
filter="integer"
showon="show_readmore:1"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="readmore_limit"
type="number"
label="JGLOBAL_SHOW_READMORE_LIMIT_LABEL"
default="15"
filter="integer"
showon="show_readmore:1[AND]show_readmore_title:1"
/>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="form-select"
validate="moduleLayout"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
validate="CssIdentifier"
/>
<field
name="owncache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="1"
filter="integer"
validate="options"
>
<option value="1">JGLOBAL_USE_GLOBAL</option>
<option value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="number"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
default="900"
filter="integer"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
*
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
\defined('_JEXEC') or die;
use Joomla\CMS\Extension\Service\Provider\HelperFactory;
use Joomla\CMS\Extension\Service\Provider\Module;
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
/**
* The articles category module service provider.
*
* @since 4.4.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.4.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesCategory'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesCategory\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,84 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
*
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\ArticlesCategory\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
use Joomla\CMS\Helper\ModuleHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_articles_category
*
* @since 4.4.0
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;
/**
* Returns the layout data.
*
* @return array
*
* @since 4.4.0
*/
protected function getLayoutData(): array
{
$data = parent::getLayoutData();
$params = $data['params'];
// Prep for Normal or Dynamic Modes
$mode = $params->get('mode', 'normal');
$idBase = null;
switch ($mode) {
case 'dynamic':
$option = $data['input']->get('option');
$view = $data['input']->get('view');
if ($option === 'com_content') {
switch ($view) {
case 'category':
case 'categories':
$idBase = $data['input']->getInt('id');
break;
case 'article':
if ($params->get('show_on_article_page', 1)) {
$idBase = $data['input']->getInt('catid');
}
break;
}
}
break;
default:
$idBase = $params->get('catid');
break;
}
$cacheParams = new \stdClass();
$cacheParams->cachemode = 'id';
$cacheParams->class = $this->getHelperFactory()->getHelper('ArticlesCategoryHelper');
$cacheParams->method = 'getArticles';
$cacheParams->methodparams = [$params, $data['app']];
$cacheParams->modeparams = md5(serialize([$idBase, $this->module->module, $this->module->id]));
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
$data['grouped'] = $params->get('article_grouping', 'none') !== 'none';
return $data;
}
}

View File

@ -0,0 +1,551 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
*
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\ArticlesCategory\Site\Helper;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Date\Date;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_category
*
* @since 1.6
*/
class ArticlesCategoryHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Retrieve a list of article
*
* @param Registry $params The module parameters.
* @param SiteApplication $app The current application.
*
* @return object[]
*
* @since 4.4.0
*/
public function getArticles(Registry $params, SiteApplication $app)
{
$factory = $app->bootComponent('com_content')->getMVCFactory();
// Get an instance of the generic articles model
$articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]);
// Set application parameters in model
$input = $app->getInput();
$appParams = $app->getParams();
$articles->setState('params', $appParams);
$articles->setState('list.start', 0);
$articles->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
// Set the filters based on the module params
$articles->setState('list.limit', (int) $params->get('count', 0));
$articles->setState('load_tags', $params->get('show_tags', 0) || $params->get('article_grouping', 'none') === 'tags');
// Access filter
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = Access::getAuthorisedViewLevels($app->getIdentity()->get('id'));
$articles->setState('filter.access', $access);
// Prep for Normal or Dynamic Modes
$mode = $params->get('mode', 'normal');
switch ($mode) {
case 'dynamic':
$option = $input->get('option');
$view = $input->get('view');
if ($option === 'com_content') {
switch ($view) {
case 'category':
case 'categories':
$catids = [$input->getInt('id')];
break;
case 'article':
if ($params->get('show_on_article_page', 1)) {
$article_id = $input->getInt('id');
$catid = $input->getInt('catid');
if (!$catid) {
// Get an instance of the generic article model
$article = $factory->createModel('Article', 'Site', ['ignore_request' => true]);
$article->setState('params', $appParams);
$article->setState('filter.published', 1);
$article->setState('article.id', (int) $article_id);
$item = $article->getItem();
$catids = [$item->catid];
} else {
$catids = [$catid];
}
} else {
// Return right away if show_on_article_page option is off
return;
}
break;
default:
// Return right away if not on the category or article views
return;
}
} else {
// Return right away if not on a com_content page
return;
}
break;
default:
$catids = $params->get('catid');
$articles->setState('filter.category_id.include', (bool) $params->get('category_filtering_type', 1));
break;
}
// Category filter
if ($catids) {
if ($params->get('show_child_category_articles', 0) && (int) $params->get('levels', 0) > 0) {
// Get an instance of the generic categories model
$categories = $factory->createModel('Categories', 'Site', ['ignore_request' => true]);
$categories->setState('params', $appParams);
$levels = $params->get('levels', 1) ?: 9999;
$categories->setState('filter.get_children', $levels);
$categories->setState('filter.published', 1);
$categories->setState('filter.access', $access);
$additional_catids = [];
foreach ($catids as $catid) {
$categories->setState('filter.parentId', $catid);
$recursive = true;
$items = $categories->getItems($recursive);
if ($items) {
foreach ($items as $category) {
$condition = (($category->level - $categories->getParent()->level) <= $levels);
if ($condition) {
$additional_catids[] = $category->id;
}
}
}
}
$catids = array_unique(array_merge($catids, $additional_catids));
}
$articles->setState('filter.category_id', $catids);
}
// Ordering
$ordering = $params->get('article_ordering', 'a.ordering');
switch ($ordering) {
case 'random':
$articles->setState('list.ordering', $this->getDatabase()->getQuery(true)->rand());
break;
case 'rating_count':
case 'rating':
$articles->setState('list.ordering', $ordering);
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
if (!PluginHelper::isEnabled('content', 'vote')) {
$articles->setState('list.ordering', 'a.ordering');
}
break;
default:
$articles->setState('list.ordering', $ordering);
$articles->setState('list.direction', $params->get('article_ordering_direction', 'ASC'));
break;
}
// Filter by multiple tags
$articles->setState('filter.tag', $params->get('filter_tag', []));
$articles->setState('filter.featured', $params->get('show_front', 'show'));
$articles->setState('filter.author_id', $params->get('created_by', []));
$articles->setState('filter.author_id.include', $params->get('author_filtering_type', 1));
$articles->setState('filter.author_alias', $params->get('created_by_alias', []));
$articles->setState('filter.author_alias.include', $params->get('author_alias_filtering_type', 1));
$excluded_articles = $params->get('excluded_articles', '');
if ($excluded_articles) {
$excluded_articles = explode("\r\n", $excluded_articles);
$articles->setState('filter.article_id', $excluded_articles);
// Exclude
$articles->setState('filter.article_id.include', false);
}
$date_filtering = $params->get('date_filtering', 'off');
if ($date_filtering !== 'off') {
$articles->setState('filter.date_filtering', $date_filtering);
$articles->setState('filter.date_field', $params->get('date_field', 'a.created'));
$articles->setState('filter.start_date_range', $params->get('start_date_range', '1000-01-01 00:00:00'));
$articles->setState('filter.end_date_range', $params->get('end_date_range', '9999-12-31 23:59:59'));
$articles->setState('filter.relative_date', $params->get('relative_date', 30));
}
// Filter by language
$articles->setState('filter.language', $app->getLanguageFilter());
$items = $articles->getItems();
// Display options
$show_date = $params->get('show_date', 0);
$show_date_field = $params->get('show_date_field', 'created');
$show_date_format = $params->get('show_date_format', 'Y-m-d H:i:s');
$show_category = $params->get('show_category', 0);
$show_hits = $params->get('show_hits', 0);
$show_author = $params->get('show_author', 0);
$show_introtext = $params->get('show_introtext', 0);
$introtext_limit = $params->get('introtext_limit', 100);
// Find current Article ID if on an article page
$option = $input->get('option');
$view = $input->get('view');
if ($option === 'com_content' && $view === 'article') {
$active_article_id = $input->getInt('id');
} else {
$active_article_id = 0;
}
// Prepare data for display using display options
foreach ($items as &$item) {
$item->slug = $item->id . ':' . $item->alias;
if ($access || \in_array($item->access, $authorised)) {
// We know that user has the privilege to view the article
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
} else {
$menu = $app->getMenu();
$menuitems = $menu->getItems('link', 'index.php?option=com_users&view=login');
if (isset($menuitems[0])) {
$Itemid = $menuitems[0]->id;
} elseif ($input->getInt('Itemid') > 0) {
// Use Itemid from requesting page only if there is no existing menu
$Itemid = $input->getInt('Itemid');
}
$item->link = Route::_('index.php?option=com_users&view=login&Itemid=' . $Itemid);
}
// Used for styling the active article
$item->active = $item->id == $active_article_id ? 'active' : '';
$item->displayDate = '';
if ($show_date) {
$item->displayDate = HTMLHelper::_('date', $item->$show_date_field, $show_date_format);
}
if ($item->catid) {
$item->displayCategoryLink = Route::_(RouteHelper::getCategoryRoute($item->catid, $item->category_language));
$item->displayCategoryTitle = $show_category ? '<a href="' . $item->displayCategoryLink . '">' . $item->category_title . '</a>' : '';
} else {
$item->displayCategoryTitle = $show_category ? $item->category_title : '';
}
$item->displayHits = $show_hits ? $item->hits : '';
$item->displayAuthorName = $show_author ? $item->author : '';
if ($show_introtext) {
$item->introtext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles_category.content');
$item->introtext = self::_cleanIntrotext($item->introtext);
}
$item->displayIntrotext = $show_introtext ? self::truncate($item->introtext, $introtext_limit) : '';
$item->displayReadmore = $item->alternative_readmore;
}
// Check if items need be grouped
$article_grouping = $params->get('article_grouping', 'none');
$article_grouping_direction = $params->get('article_grouping_direction', 'ksort');
$grouped = $article_grouping !== 'none';
if ($items && $grouped) {
switch ($article_grouping) {
case 'year':
case 'month_year':
$items = ArticlesCategoryHelper::groupByDate(
$items,
$article_grouping_direction,
$article_grouping,
$params->get('month_year_format', 'F Y'),
$params->get('date_grouping_field', 'created')
);
break;
case 'author':
case 'category_title':
$items = ArticlesCategoryHelper::groupBy($items, $article_grouping, $article_grouping_direction);
break;
case 'tags':
$items = ArticlesCategoryHelper::groupByTags($items, $article_grouping_direction);
break;
}
}
return $items;
}
/**
* Get a list of articles from a specific category
*
* @param Registry &$params object holding the models parameters
*
* @return array The array of users
*
* @since 1.6
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getArticles
* Example: Factory::getApplication()->bootModule('mod_articles_category', 'site')
* ->getHelper('ArticlesCategoryHelper')
* ->getArticles($params, Factory::getApplication())
*/
public static function getList(&$params)
{
/* @var SiteApplication $app */
$app = Factory::getApplication();
return (new self())->getArticles($params, $app);
}
/**
* Strips unnecessary tags from the introtext
*
* @param string $introtext introtext to sanitize
*
* @return string
*
* @since 1.6
*/
public static function _cleanIntrotext($introtext)
{
$introtext = str_replace(['<p>', '</p>'], ' ', $introtext);
$introtext = strip_tags($introtext, '<a><em><strong><joomla-hidden-mail>');
return trim($introtext);
}
/**
* Method to truncate introtext
*
* The goal is to get the proper length plain text string with as much of
* the html intact as possible with all tags properly closed.
*
* @param string $html The content of the introtext to be truncated
* @param int $maxLength The maximum number of characters to render
*
* @return string The truncated string
*
* @since 1.6
*/
public static function truncate($html, $maxLength = 0)
{
$baseLength = \strlen($html);
// First get the plain text string. This is the rendered text we want to end up with.
$ptString = HTMLHelper::_('string.truncate', $html, $maxLength, true, false);
for ($maxLength; $maxLength < $baseLength;) {
// Now get the string if we allow html.
$htmlString = HTMLHelper::_('string.truncate', $html, $maxLength, true, true);
// Now get the plain text from the html string.
$htmlStringToPtString = HTMLHelper::_('string.truncate', $htmlString, $maxLength, true, false);
// If the new plain text string matches the original plain text string we are done.
if ($ptString === $htmlStringToPtString) {
return $htmlString;
}
// Get the number of html tag characters in the first $maxlength characters
$diffLength = \strlen($ptString) - \strlen($htmlStringToPtString);
// Set new $maxlength that adjusts for the html tags
$maxLength += $diffLength;
if ($baseLength <= $maxLength || $diffLength <= 0) {
return $htmlString;
}
}
return $ptString;
}
/**
* Groups items by field
*
* @param array $list list of items
* @param string $fieldName name of field that is used for grouping
* @param string $direction ordering direction
* @param null $fieldNameToKeep field name to keep
*
* @return array
*
* @since 1.6
*/
public static function groupBy($list, $fieldName, $direction, $fieldNameToKeep = null)
{
$grouped = [];
if (!\is_array($list)) {
if ($list === '') {
return $grouped;
}
$list = [$list];
}
foreach ($list as $key => $item) {
if (!isset($grouped[$item->$fieldName])) {
$grouped[$item->$fieldName] = [];
}
if ($fieldNameToKeep === null) {
$grouped[$item->$fieldName][$key] = $item;
} else {
$grouped[$item->$fieldName][$key] = $item->$fieldNameToKeep;
}
unset($list[$key]);
}
$direction($grouped);
return $grouped;
}
/**
* Groups items by date
*
* @param array $list list of items
* @param string $direction ordering direction
* @param string $type type of grouping
* @param string $monthYearFormat date format to use
* @param string $field date field to group by
*
* @return array
*
* @since 1.6
*/
public static function groupByDate($list, $direction = 'ksort', $type = 'year', $monthYearFormat = 'F Y', $field = 'created')
{
$grouped = [];
if (!\is_array($list)) {
if ($list === '') {
return $grouped;
}
$list = [$list];
}
foreach ($list as $key => $item) {
switch ($type) {
case 'month_year':
$month_year = StringHelper::substr($item->$field, 0, 7);
if (!isset($grouped[$month_year])) {
$grouped[$month_year] = [];
}
$grouped[$month_year][$key] = $item;
break;
default:
$year = StringHelper::substr($item->$field, 0, 4);
if (!isset($grouped[$year])) {
$grouped[$year] = [];
}
$grouped[$year][$key] = $item;
break;
}
unset($list[$key]);
}
$direction($grouped);
if ($type === 'month_year') {
foreach ($grouped as $group => $items) {
$date = new Date($group);
$formatted_group = $date->format($monthYearFormat);
$grouped[$formatted_group] = $items;
unset($grouped[$group]);
}
}
return $grouped;
}
/**
* Groups items by tags
*
* @param array $list list of items
* @param string $direction ordering direction
*
* @return array
*
* @since 3.9.0
*/
public static function groupByTags($list, $direction = 'ksort')
{
$grouped = [];
$untagged = [];
if (!$list) {
return $grouped;
}
foreach ($list as $item) {
if ($item->tags->itemTags) {
foreach ($item->tags->itemTags as $tag) {
$grouped[$tag->title][] = $item;
}
} else {
$untagged[] = $item;
}
}
$direction($grouped);
if ($untagged) {
$grouped['MOD_ARTICLES_CATEGORY_UNTAGGED'] = $untagged;
}
return $grouped;
}
}

View File

@ -0,0 +1,35 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
*
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\CMS\Language\Text;
if (!$list) {
return;
}
?>
<ul class="mod-articlescategory category-module mod-list">
<?php if ($grouped) : ?>
<?php foreach ($list as $groupName => $items) : ?>
<li>
<div class="mod-articles-category-group"><?php echo Text::_($groupName); ?></div>
<ul>
<?php require ModuleHelper::getLayoutPath('mod_articles_category', $params->get('layout', 'default') . '_items'); ?>
</ul>
</li>
<?php endforeach; ?>
<?php else : ?>
<?php $items = $list; ?>
<?php require ModuleHelper::getLayoutPath('mod_articles_category', $params->get('layout', 'default') . '_items'); ?>
<?php endif; ?>
</ul>

View File

@ -0,0 +1,84 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_category
*
* @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
?>
<?php foreach ($items as $item) : ?>
<li>
<?php if ($params->get('link_titles') == 1) : ?>
<?php $attributes = ['class' => 'mod-articles-category-title ' . $item->active]; ?>
<?php $link = htmlspecialchars($item->link, ENT_COMPAT, 'UTF-8', false); ?>
<?php $title = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false); ?>
<?php echo HTMLHelper::_('link', $link, $title, $attributes); ?>
<?php else : ?>
<?php echo $item->title; ?>
<?php endif; ?>
<?php if ($item->displayHits) : ?>
<span class="mod-articles-category-hits">
(<?php echo $item->displayHits; ?>)
</span>
<?php endif; ?>
<?php if ($params->get('show_author')) : ?>
<span class="mod-articles-category-writtenby">
<?php echo $item->displayAuthorName; ?>
</span>
<?php endif; ?>
<?php if ($item->displayCategoryTitle) : ?>
<span class="mod-articles-category-category">
(<?php echo $item->displayCategoryTitle; ?>)
</span>
<?php endif; ?>
<?php if ($item->displayDate) : ?>
<span class="mod-articles-category-date"><?php echo $item->displayDate; ?></span>
<?php endif; ?>
<?php if ($params->get('show_tags', 0) && $item->tags->itemTags) : ?>
<div class="mod-articles-category-tags">
<?php echo LayoutHelper::render('joomla.content.tags', $item->tags->itemTags); ?>
</div>
<?php endif; ?>
<?php if ($params->get('show_introtext')) : ?>
<p class="mod-articles-category-introtext">
<?php echo $item->displayIntrotext; ?>
</p>
<?php endif; ?>
<?php if ($params->get('show_readmore')) : ?>
<p class="mod-articles-category-readmore">
<a class="mod-articles-category-title <?php echo $item->active; ?>" href="<?php echo $item->link; ?>">
<?php if ($item->params->get('access-view') == false) : ?>
<?php echo Text::_('MOD_ARTICLES_CATEGORY_REGISTER_TO_READ_MORE'); ?>
<?php elseif ($item->alternative_readmore) : ?>
<?php echo $item->alternative_readmore; ?>
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit')); ?>
<?php if ($params->get('show_readmore_title', 0)) : ?>
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit')); ?>
<?php endif; ?>
<?php elseif ($params->get('show_readmore_title', 0)) : ?>
<?php echo Text::_('MOD_ARTICLES_CATEGORY_READ_MORE'); ?>
<?php echo HTMLHelper::_('string.truncate', $item->title, $params->get('readmore_limit')); ?>
<?php else : ?>
<?php echo Text::_('MOD_ARTICLES_CATEGORY_READ_MORE_TITLE'); ?>
<?php endif; ?>
</a>
</p>
<?php endif; ?>
</li>
<?php endforeach; ?>