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

1
modules/index.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_archive</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_ARCHIVE_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesArchive</namespace>
<files>
<folder module="mod_articles_archive">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_archive.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_archive.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Archived" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="count"
type="number"
label="MOD_ARTICLES_ARCHIVE_FIELD_COUNT_LABEL"
default="10"
filter="integer"
min="1"
validate="number"
/>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_archive
*
* @copyright (C) 2023 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 archive 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): void
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesArchive'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesArchive\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_archive
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\ArticlesArchive\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_articles_archive
*
* @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();
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesArchiveHelper')->getArticlesByMonths($data['params'], $data['app']);
return $data;
}
}

View File

@ -0,0 +1,125 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_archive
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\ArticlesArchive\Site\Helper;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Database\ParameterType;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_archive
*
* @since 1.5
*/
class ArticlesArchiveHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Retrieve a list of months with archived articles
*
* @param Registry $moduleParams The module parameters.
* @param SiteApplication $app The current application.
*
* @return \stdClass[]
*
* @since 4.4.0
*/
public function getArticlesByMonths(Registry $moduleParams, SiteApplication $app): array
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
$query->select($query->month($db->quoteName('created')) . ' AS created_month')
->select('MIN(' . $db->quoteName('created') . ') AS created')
->select($query->year($db->quoteName('created')) . ' AS created_year')
->from($db->quoteName('#__content', 'c'))
->where($db->quoteName('c.state') . ' = ' . ContentComponent::CONDITION_ARCHIVED)
->group($query->year($db->quoteName('c.created')) . ', ' . $query->month($db->quoteName('c.created')))
->order($query->year($db->quoteName('c.created')) . ' DESC, ' . $query->month($db->quoteName('c.created')) . ' DESC');
// Filter by language
if ($app->getLanguageFilter()) {
$query->whereIn($db->quoteName('language'), [$app->getLanguage()->getTag(), '*'], ParameterType::STRING);
}
$query->setLimit((int) $moduleParams->get('count'));
$db->setQuery($query);
try {
$rows = (array) $db->loadObjectList();
} catch (\RuntimeException $e) {
$app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return [];
}
$menu = $app->getMenu();
$item = $menu->getItems('link', 'index.php?option=com_content&view=archive', true);
$itemid = (isset($item) && !empty($item->id)) ? '&Itemid=' . $item->id : '';
$i = 0;
$lists = [];
foreach ($rows as $row) {
$date = Factory::getDate($row->created);
$createdMonth = $date->format('n');
$createdYear = $date->format('Y');
$createdYearCal = HTMLHelper::_('date', $row->created, 'Y');
$monthNameCal = HTMLHelper::_('date', $row->created, 'F');
$lists[$i] = new \stdClass();
$lists[$i]->link = Route::_('index.php?option=com_content&view=archive&year=' . $createdYear . '&month=' . $createdMonth . $itemid);
$lists[$i]->text = Text::sprintf('MOD_ARTICLES_ARCHIVE_DATE', $monthNameCal, $createdYearCal);
$i++;
}
return $lists;
}
/**
* Retrieve list of archived articles
*
* @param Registry &$params module parameters
*
* @return \stdClass[]
*
* @since 1.5
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getArticlesByMonths
* Example: Factory::getApplication()->bootModule('mod_articles_archive', 'site')
* ->getHelper('ArticlesArchiveHelper')
* ->getArticlesByMonths($params, Factory::getApplication())
*/
public static function getList(&$params)
{
/** @var SiteApplication $app */
$app = Factory::getApplication();
return (new self())->getArticlesByMonths($params, $app);
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_archive
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
if (!$list) {
return;
}
?>
<ul class="mod-articlesarchive archive-module mod-list">
<?php foreach ($list as $item) : ?>
<li>
<a href="<?php echo $item->link; ?>">
<?php echo $item->text; ?>
</a>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_categories</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_CATEGORIES_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesCategories</namespace>
<files>
<folder module="mod_articles_categories">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_categories.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_categories.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Categories" />
<config>
<fields name="params">
<fieldset name="basic" addfieldprefix="Joomla\Component\Categories\Administrator\Field">
<field
name="parent"
type="modal_category"
label="MOD_ARTICLES_CATEGORIES_FIELD_PARENT_LABEL"
extension="com_content"
filter="integer"
published=""
select="true"
new="true"
edit="true"
clear="true"
/>
<field
name="show_description"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORIES_FIELD_SHOW_DESCRIPTION_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="numitems"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORIES_FIELD_NUMITEMS_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_children"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_CATEGORIES_FIELD_SHOW_CHILDREN_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="count"
type="list"
label="MOD_ARTICLES_CATEGORIES_FIELD_COUNT_LABEL"
description="MOD_ARTICLES_CATEGORIES_FIELD_COUNT_DESC"
default="0"
filter="integer"
validate="options"
>
<option value="0">JALL</option>
<option value="1">J1</option>
<option value="2">J2</option>
<option value="3">J3</option>
<option value="4">J4</option>
<option value="5">J5</option>
<option value="6">J6</option>
<option value="7">J7</option>
<option value="8">J8</option>
<option value="9">J9</option>
<option value="10">J10</option>
</field>
<field
name="maxlevel"
type="list"
label="MOD_ARTICLES_CATEGORIES_FIELD_MAXLEVEL_LABEL"
default="0"
filter="integer"
validate="options"
>
<option value="0">JALL</option>
<option value="1">J1</option>
<option value="2">J2</option>
<option value="3">J3</option>
<option value="4">J4</option>
<option value="5">J5</option>
<option value="6">J6</option>
<option value="7">J7</option>
<option value="8">J8</option>
<option value="9">J9</option>
<option value="10">J10</option>
</field>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="form-select"
validate="moduleLayout"
/>
<field
name="item_heading"
type="list"
label="MOD_ARTICLES_CATEGORIES_TITLE_HEADING_LABEL"
default="4"
filter="integer"
validate="options"
>
<option value="1">JH1</option>
<option value="2">JH2</option>
<option value="3">JH3</option>
<option value="4">JH4</option>
<option value="5">JH5</option>
</field>
<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_categories
*
* @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 categories 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\\ArticlesCategories'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesCategories\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,56 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_categories
*
* @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\ArticlesCategories\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_categories
*
* @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'];
$cacheParams = new \stdClass();
$cacheParams->cachemode = 'id';
$cacheParams->class = $this->getHelperFactory()->getHelper('ArticlesCategoriesHelper');
$cacheParams->method = 'getChildrenCategories';
$cacheParams->methodparams = [$params, $data['app']];
$cacheParams->modeparams = md5(serialize($this->module->id));
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
$data['startLevel'] = $data['list'] ? reset($data['list'])->getParent()->level : null;
return $data;
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_categories
*
* @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\ArticlesCategories\Site\Helper;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Categories\CategoryInterface;
use Joomla\CMS\Categories\CategoryNode;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_categories
*
* @since 1.5
*/
class ArticlesCategoriesHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Given a parent category, return a list of children categories
*
* @param Registry $moduleParams The module parameters.
* @param SiteApplication $app The current application.
*
* @return CategoryNode[]
*
* @since 4.4.0
*/
public function getChildrenCategories(Registry $moduleParams, SiteApplication $app): array
{
// Joomla\CMS\Categories\Categories options to set
$options = [];
// Get the number of items in this category or descendants of this category at the expense of performance.
$options['countItems'] = $moduleParams->get('numitems', 0);
/** @var CategoryInterface $categoryFactory */
$categoryFactory = $app->bootComponent('com_content')->getCategory($options);
/** @var CategoryNode $parentCategory */
$parentCategory = $categoryFactory->get($moduleParams->get('parent', 'root'));
if ($parentCategory === null) {
return [];
}
// Get all the children categories of this node
$childrenCategories = $parentCategory->getChildren(true);
$count = $moduleParams->get('count', 0);
if ($count > 0 && \count($childrenCategories) > $count) {
$childrenCategories = \array_slice($childrenCategories, 0, $count);
}
return $childrenCategories;
}
/**
* Get list of categories
*
* @param Registry $params module parameters
*
* @return array
*
* @since 1.6
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getChildrenCategories
* Example: Factory::getApplication()->bootModule('mod_articles_categories', 'site')
* ->getHelper('ArticlesCategoriesHelper')
* ->getChildrenCategories($params, Factory::getApplication())
*/
public static function getList($params)
{
/** @var SiteApplication $app */
$app = Factory::getApplication();
return (new self())->getChildrenCategories($params, $app);
}
}

View File

@ -0,0 +1,22 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_categories
*
* @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;
if (!$list) {
return;
}
?>
<ul class="mod-articlescategories categories-module mod-list">
<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>
</ul>

View File

@ -0,0 +1,51 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_categories
*
* @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\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Site\Helper\RouteHelper;
$input = $app->getInput();
$option = $input->getCmd('option');
$view = $input->getCmd('view');
$id = $input->getInt('id');
foreach ($list as $item) : ?>
<li<?php if ($id == $item->id && in_array($view, ['category', 'categories']) && $option == 'com_content') {
echo ' class="active"';
} ?>> <?php $levelup = $item->level - $startLevel - 1; ?>
<a href="<?php echo Route::_(RouteHelper::getCategoryRoute($item->id, $item->language)); ?>">
<?php echo $item->title; ?>
<?php if ($params->get('numitems')) : ?>
(<?php echo $item->numitems; ?>)
<?php endif; ?>
</a>
<?php if ($params->get('show_description', 0)) : ?>
<?php echo HTMLHelper::_('content.prepare', $item->description, $item->getParams(), 'mod_articles_categories.content'); ?>
<?php endif; ?>
<?php
if (
$params->get('show_children', 0) && (($params->get('maxlevel', 0) == 0)
|| ($params->get('maxlevel') >= ($item->level - $startLevel)))
&& count($item->getChildren())
) : ?>
<?php echo '<ul>'; ?>
<?php $temp = $list; ?>
<?php $list = $item->getChildren(); ?>
<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>
<?php $list = $temp; ?>
<?php echo '</ul>'; ?>
<?php endif; ?>
</li>
<?php endforeach; ?>

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; ?>

View File

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_latest</name>
<author>Joomla! Project</author>
<creationDate>2004-07</creationDate>
<copyright>(C) 2005 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_LATEST_NEWS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesLatest</namespace>
<files>
<folder module="mod_articles_latest">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_latest.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_latest.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Latest" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="catid"
type="category"
label="JCATEGORY"
extension="com_content"
multiple="true"
layout="joomla.form.field.list-fancy-select"
filter="intarray"
/>
<field
name="count"
type="number"
label="MOD_LATEST_NEWS_FIELD_COUNT_LABEL"
default="5"
filter="integer"
min="1"
validate="number"
/>
<field
name="show_featured"
type="list"
label="MOD_LATEST_NEWS_FIELD_FEATURED_LABEL"
default=""
filter="integer"
validate="options"
>
<option value="">JSHOW</option>
<option value="0">JHIDE</option>
<option value="1">MOD_LATEST_NEWS_VALUE_ONLY_SHOW_FEATURED</option>
</field>
<field
name="ordering"
type="list"
label="MOD_LATEST_NEWS_FIELD_ORDERING_LABEL"
default="p_dsc"
validate="options"
>
<option value="c_dsc">MOD_LATEST_NEWS_VALUE_RECENT_ADDED</option>
<option value="m_dsc">MOD_LATEST_NEWS_VALUE_RECENT_MODIFIED</option>
<option value="p_dsc">MOD_LATEST_NEWS_VALUE_RECENT_PUBLISHED</option>
<option value="mc_dsc">MOD_LATEST_NEWS_VALUE_RECENT_TOUCHED</option>
<option value="random">MOD_LATEST_NEWS_VALUE_RECENT_RAND</option>
</field>
<field
name="user_id"
type="list"
label="MOD_LATEST_NEWS_FIELD_USER_LABEL"
default="0"
validate="options"
>
<option value="0">MOD_LATEST_NEWS_VALUE_ANYONE</option>
<option value="by_me">MOD_LATEST_NEWS_VALUE_ADDED_BY_ME</option>
<option value="not_me">MOD_LATEST_NEWS_VALUE_NOTADDED_BY_ME</option>
<option value="created_by">MOD_LATEST_NEWS_VALUE_CREATED_BY</option>
</field>
<field
name="author"
type="author"
label="MOD_LATEST_NEWS_FIELD_AUTHOR_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
showon="user_id:created_by"
/>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_latest
*
* @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 article latest module service provider.
*
* @since 4.2.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.2.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesLatest'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesLatest\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_latest
*
* @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\ArticlesLatest\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_articles_latest
*
* @since 4.2.0
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;
/**
* Returns the layout data.
*
* @return array
*
* @since 4.2.0
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesLatestHelper')->getArticles($data['params'], $this->getApplication());
return $data;
}
}

View File

@ -0,0 +1,169 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_latest
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\ArticlesLatest\Site\Helper;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Component\Content\Site\Model\ArticlesModel;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_latest
*
* @since 1.6
*/
class ArticlesLatestHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Retrieve a list of article
*
* @param Registry $params The module parameters.
* @param ArticlesModel $model The model.
*
* @return mixed
*
* @since 4.2.0
*/
public function getArticles(Registry $params, SiteApplication $app)
{
// Get the Dbo and User object
$db = $this->getDatabase();
$user = $app->getIdentity();
/** @var ArticlesModel $model */
$model = $app->bootComponent('com_content')->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]);
// Set application parameters in model
$model->setState('params', $app->getParams());
$model->setState('list.start', 0);
$model->setState('filter.published', 1);
// Set the filters based on the module params
$model->setState('list.limit', (int) $params->get('count', 5));
// This module does not use tags data
$model->setState('load_tags', false);
// Access filter
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = Access::getAuthorisedViewLevels($user->get('id'));
$model->setState('filter.access', $access);
// Category filter
$model->setState('filter.category_id', $params->get('catid', []));
// State filter
$model->setState('filter.condition', 1);
// User filter
$userId = $user->get('id');
switch ($params->get('user_id')) {
case 'by_me':
$model->setState('filter.author_id', (int) $userId);
break;
case 'not_me':
$model->setState('filter.author_id', $userId);
$model->setState('filter.author_id.include', false);
break;
case 'created_by':
$model->setState('filter.author_id', $params->get('author', []));
break;
case '0':
break;
default:
$model->setState('filter.author_id', (int) $params->get('user_id'));
break;
}
// Filter by language
$model->setState('filter.language', $app->getLanguageFilter());
// Featured switch
$featured = $params->get('show_featured', '');
if ($featured === '') {
$model->setState('filter.featured', 'show');
} elseif ($featured) {
$model->setState('filter.featured', 'only');
} else {
$model->setState('filter.featured', 'hide');
}
// Set ordering
$order_map = [
'm_dsc' => 'a.modified DESC, a.created',
'mc_dsc' => 'a.modified',
'c_dsc' => 'a.created',
'p_dsc' => 'a.publish_up',
'random' => $db->getQuery(true)->rand(),
];
$ordering = ArrayHelper::getValue($order_map, $params->get('ordering', 'p_dsc'), 'a.publish_up');
$dir = 'DESC';
$model->setState('list.ordering', $ordering);
$model->setState('list.direction', $dir);
$items = $model->getItems();
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 {
$item->link = Route::_('index.php?option=com_users&view=login');
}
}
return $items;
}
/**
* Retrieve a list of articles
*
* @param Registry $params The module parameters.
* @param ArticlesModel $model The model.
*
* @return mixed
*
* @since 1.6
*
* @deprecated 4.3 will be removed in 6.0
* Use the non-static method getArticles
* Example: Factory::getApplication()->bootModule('mod_articles_latest', 'site')
* ->getHelper('ArticlesLatestHelper')
* ->getArticles($params, Factory::getApplication())
*/
public static function getList(Registry $params, ArticlesModel $model)
{
return (new self())->getArticles($params, Factory::getApplication());
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_latest
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
if (!$list) {
return;
}
?>
<ul class="mod-articleslatest latestnews mod-list">
<?php foreach ($list as $item) : ?>
<li itemscope itemtype="https://schema.org/Article">
<a href="<?php echo $item->link; ?>" itemprop="url">
<span itemprop="name">
<?php echo $item->title; ?>
</span>
</a>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_news</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_NEWS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesNews</namespace>
<files>
<folder module="mod_articles_news">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_news.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_news.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Newsflash"/>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="catid"
type="category"
label="JCATEGORY"
extension="com_content"
multiple="true"
filter="intarray"
class="multipleCategories"
layout="joomla.form.field.list-fancy-select"
/>
<field
name="tag"
type="tag"
label="JTAG"
mode="nested"
multiple="true"
filter="intarray"
class="multipleTags"
custom="deny"
/>
<field
name="image"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_NEWS_FIELD_IMAGES_LABEL"
description="MOD_ARTICLES_NEWS_FIELD_IMAGES_DESC"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="img_intro_full"
type="list"
label="MOD_ARTICLES_NEWS_FIELD_IMAGES_ARTICLE_LABEL"
default="none"
validate="options"
>
<option value="intro">MOD_ARTICLES_NEWS_OPTION_INTROIMAGE</option>
<option value="full">MOD_ARTICLES_NEWS_OPTION_FULLIMAGE</option>
<option value="none">JNO</option>
</field>
<field
name="item_title"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_NEWS_FIELD_TITLE_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="link_titles"
type="list"
label="MOD_ARTICLES_NEWS_FIELD_LINKTITLE_LABEL"
default=""
filter="integer"
class="form-select-color"
showon="item_title:1"
validate="options"
>
<option value="">JGLOBAL_USE_GLOBAL</option>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="item_heading"
type="list"
label="MOD_ARTICLES_NEWS_TITLE_HEADING"
default="h4"
showon="item_title:1"
validate="options"
>
<option value="h1">JH1</option>
<option value="h2">JH2</option>
<option value="h3">JH3</option>
<option value="h4">JH4</option>
<option value="h5">JH5</option>
</field>
<field
name="triggerevents"
type="radio"
label="MOD_ARTICLES_NEWS_FIELD_TRIGGEREVENTS_LABEL"
layout="joomla.form.field.radio.switcher"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="showLastSeparator"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_NEWS_FIELD_SEPARATOR_LABEL"
default="1"
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_NEWS_FIELD_SHOWINTROTEXT_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="readmore"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_ARTICLES_NEWS_FIELD_READMORE_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="count"
type="number"
label="MOD_ARTICLES_NEWS_FIELD_ITEMS_LABEL"
default="5"
filter="integer"
min="1"
validate="number"
/>
<field
name="show_featured"
type="list"
label="MOD_ARTICLES_NEWS_FIELD_FEATURED_LABEL"
default=""
filter="integer"
validate="options"
>
<option value="">JSHOW</option>
<option value="0">JHIDE</option>
<option value="1">MOD_ARTICLES_NEWS_VALUE_ONLY_SHOW_FEATURED</option>
</field>
<field
name="exclude_current"
type="radio"
label="MOD_ARTICLES_NEWS_FIELD_EXCLUDE_CURRENT_LABEL"
layout="joomla.form.field.radio.switcher"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="ordering"
type="list"
label="MOD_ARTICLES_NEWS_FIELD_ORDERING_LABEL"
default="a.publish_up"
validate="options"
>
<option value="a.publish_up">MOD_ARTICLES_NEWS_FIELD_ORDERING_PUBLISHED_DATE</option>
<option value="a.created">MOD_ARTICLES_NEWS_FIELD_ORDERING_CREATED_DATE</option>
<option value="a.modified">MOD_ARTICLES_NEWS_FIELD_ORDERING_MODIFIED_DATE</option>
<option value="a.ordering">MOD_ARTICLES_NEWS_FIELD_ORDERING_ORDERING</option>
<option value="a.hits">JGLOBAL_HITS</option>
<option value="rand()">MOD_ARTICLES_NEWS_FIELD_ORDERING_RANDOM</option>
</field>
<field
name="direction"
type="list"
label="JGLOBAL_ORDER_DIRECTION_LABEL"
default="1"
filter="integer"
showon="ordering:a.publish_up,a.created,a.modified,a.ordering,a.hits"
validate="options"
>
<option value="0">JGLOBAL_ORDER_ASCENDING</option>
<option value="1">JGLOBAL_ORDER_DESCENDING</option>
</field>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @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 article news module service provider.
*
* @since 4.2.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.2.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesNews'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesNews\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,45 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @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\ArticlesNews\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_articles_news
*
* @since 4.2.0
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;
/**
* Returns the layout data.
*
* @return array
*
* @since 4.2.0
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesNewsHelper')->getArticles($data['params'], $this->getApplication());
return $data;
}
}

View File

@ -0,0 +1,209 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @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\ArticlesNews\Site\Helper;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_news
*
* @since 1.6
*/
class ArticlesNewsHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Get a list of the latest articles from the article model.
*
* @param Registry $params Object holding the models parameters
* @param SiteApplication $app The app
*
* @return mixed
*
* @since 4.2.0
*/
public function getArticles(Registry $params, SiteApplication $app)
{
/** @var \Joomla\Component\Content\Site\Model\ArticlesModel $model */
$model = $app->bootComponent('com_content')->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]);
// Set application parameters in model
$appParams = $app->getParams();
$model->setState('params', $appParams);
$model->setState('list.start', 0);
$model->setState('filter.published', 1);
// Set the filters based on the module params
$model->setState('list.limit', (int) $params->get('count', 5));
// This module does not use tags data
$model->setState('load_tags', false);
// Access filter
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = Access::getAuthorisedViewLevels($app->getIdentity() ? $app->getIdentity()->id : 0);
$model->setState('filter.access', $access);
// Category filter
$model->setState('filter.category_id', $params->get('catid', []));
// Filter by language
$model->setState('filter.language', $app->getLanguageFilter());
// Filter by tag
$model->setState('filter.tag', $params->get('tag', []));
// Featured switch
$featured = $params->get('show_featured', '');
if ($featured === '') {
$model->setState('filter.featured', 'show');
} elseif ($featured) {
$model->setState('filter.featured', 'only');
} else {
$model->setState('filter.featured', 'hide');
}
$input = $app->getInput();
// Filter by id in case it should be excluded
if (
$params->get('exclude_current', true)
&& $input->get('option') === 'com_content'
&& $input->get('view') === 'article'
) {
// Exclude the current article from displaying in this module
$model->setState('filter.article_id', $input->get('id', 0, 'UINT'));
$model->setState('filter.article_id.include', false);
}
// Set ordering
$ordering = $params->get('ordering', 'a.publish_up');
$model->setState('list.ordering', $ordering);
if (trim($ordering) === 'rand()') {
$model->setState('list.ordering', $this->getDatabase()->getQuery(true)->rand());
} else {
$direction = $params->get('direction', 1) ? 'DESC' : 'ASC';
$model->setState('list.direction', $direction);
$model->setState('list.ordering', $ordering);
}
// Check if we should trigger additional plugin events
$triggerEvents = $params->get('triggerevents', 1);
// Retrieve Content
$items = $model->getItems();
foreach ($items as &$item) {
$item->readmore = \strlen(trim($item->fulltext));
$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));
$item->linkText = Text::_('MOD_ARTICLES_NEWS_READMORE');
} else {
$item->link = new Uri(Route::_('index.php?option=com_users&view=login', false));
$item->link->setVar('return', base64_encode(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language)));
$item->linkText = Text::_('MOD_ARTICLES_NEWS_READMORE_REGISTER');
}
$item->introtext = HTMLHelper::_('content.prepare', $item->introtext, '', 'mod_articles_news.content');
// Remove any images belongs to the text
if (!$params->get('image')) {
$item->introtext = preg_replace('/<img[^>]*>/', '', $item->introtext);
}
// Show the Intro/Full image field of the article
if ($params->get('img_intro_full') !== 'none') {
$images = json_decode($item->images);
$item->imageSrc = '';
$item->imageAlt = '';
$item->imageCaption = '';
if ($params->get('img_intro_full') === 'intro' && !empty($images->image_intro)) {
$item->imageSrc = htmlspecialchars($images->image_intro, ENT_COMPAT, 'UTF-8');
$item->imageAlt = htmlspecialchars($images->image_intro_alt, ENT_COMPAT, 'UTF-8');
if ($images->image_intro_caption) {
$item->imageCaption = htmlspecialchars($images->image_intro_caption, ENT_COMPAT, 'UTF-8');
}
} elseif ($params->get('img_intro_full') === 'full' && !empty($images->image_fulltext)) {
$item->imageSrc = htmlspecialchars($images->image_fulltext, ENT_COMPAT, 'UTF-8');
$item->imageAlt = htmlspecialchars($images->image_fulltext_alt, ENT_COMPAT, 'UTF-8');
if ($images->image_intro_caption) {
$item->imageCaption = htmlspecialchars($images->image_fulltext_caption, ENT_COMPAT, 'UTF-8');
}
}
}
if ($triggerEvents) {
$item->text = '';
$app->triggerEvent('onContentPrepare', ['com_content.article', &$item, &$params, 0]);
$results = $app->triggerEvent('onContentAfterTitle', ['com_content.article', &$item, &$params, 0]);
$item->afterDisplayTitle = trim(implode("\n", $results));
$results = $app->triggerEvent('onContentBeforeDisplay', ['com_content.article', &$item, &$params, 0]);
$item->beforeDisplayContent = trim(implode("\n", $results));
$results = $app->triggerEvent('onContentAfterDisplay', ['com_content.article', &$item, &$params, 0]);
$item->afterDisplayContent = trim(implode("\n", $results));
} else {
$item->afterDisplayTitle = '';
$item->beforeDisplayContent = '';
$item->afterDisplayContent = '';
}
}
return $items;
}
/**
* Get a list of the latest articles from the article model
*
* @param \Joomla\Registry\Registry &$params object holding the models parameters
*
* @return mixed
*
* @since 1.6
*
* @deprecated 4.3 will be removed in 6.0
* Use the non-static method getArticles
* Example: Factory::getApplication()->bootModule('mod_articles_news', 'site')
* ->getHelper('ArticlesNewsHelper')
* ->getArticles($params, Factory::getApplication())
*/
public static function getList(&$params)
{
return (new self())->getArticles($params, Factory::getApplication());
}
}

View File

@ -0,0 +1,59 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @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\Layout\LayoutHelper;
?>
<?php if ($params->get('item_title')) : ?>
<?php $item_heading = $params->get('item_heading', 'h4'); ?>
<<?php echo $item_heading; ?> class="newsflash-title">
<?php if ($item->link !== '' && $params->get('link_titles')) : ?>
<a href="<?php echo $item->link; ?>">
<?php echo $item->title; ?>
</a>
<?php else : ?>
<?php echo $item->title; ?>
<?php endif; ?>
</<?php echo $item_heading; ?>>
<?php endif; ?>
<?php if ($params->get('img_intro_full') !== 'none' && !empty($item->imageSrc)) : ?>
<figure class="newsflash-image">
<?php echo LayoutHelper::render(
'joomla.html.image',
[
'src' => $item->imageSrc,
'alt' => $item->imageAlt,
]
); ?>
<?php if (!empty($item->imageCaption)) : ?>
<figcaption>
<?php echo $item->imageCaption; ?>
</figcaption>
<?php endif; ?>
</figure>
<?php endif; ?>
<?php if (!$params->get('intro_only')) : ?>
<?php echo $item->afterDisplayTitle; ?>
<?php endif; ?>
<?php echo $item->beforeDisplayContent; ?>
<?php if ($params->get('show_introtext', 1)) : ?>
<?php echo $item->introtext; ?>
<?php endif; ?>
<?php echo $item->afterDisplayContent; ?>
<?php if (isset($item->link) && $item->readmore != 0 && $params->get('readmore')) : ?>
<?php echo LayoutHelper::render('joomla.content.readmore', ['item' => $item, 'params' => $item->params, 'link' => $item->link]); ?>
<?php endif; ?>

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @copyright (C) 2006 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;
if (!$list) {
return;
}
?>
<div class="mod-articlesnews newsflash">
<?php foreach ($list as $item) : ?>
<div class="mod-articlesnews__item" itemscope itemtype="https://schema.org/Article">
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
</div>
<?php endforeach; ?>
</div>

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @copyright (C) 2006 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;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$wa->registerAndUseStyle('mod_articles_news_horizontal', 'mod_articles_news/template.css');
if (empty($list)) {
return;
}
?>
<ul class="mod-articlesnews-horizontal newsflash-horiz mod-list">
<?php foreach ($list as $item) : ?>
<li itemscope itemtype="https://schema.org/Article">
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,35 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_news
*
* @copyright (C) 2006 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;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$wa->registerAndUseStyle('mod_articles_news_vertical', 'mod_articles_news/template-vert.css');
if (!$list) {
return;
}
?>
<ul class="mod-articlesnews-vertical newsflash-vert mod-list">
<?php for ($i = 0, $n = count($list); $i < $n; $i++) : ?>
<?php $item = $list[$i]; ?>
<li class="newsflash-item" itemscope itemtype="https://schema.org/Article">
<?php require ModuleHelper::getLayoutPath('mod_articles_news', '_item'); ?>
<?php if ($n > 1 && (($i < $n - 1) || $params->get('showLastSeparator'))) : ?>
<span class="article-separator">&#160;</span>
<?php endif; ?>
</li>
<?php endfor; ?>
</ul>

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_articles_popular</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_POPULAR_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\ArticlesPopular</namespace>
<files>
<folder module="mod_articles_popular">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_articles_popular.ini</language>
<language tag="en-GB">language/en-GB/mod_articles_popular.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Most_Read" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="catid"
type="category"
label="JCATEGORY"
extension="com_content"
multiple="true"
filter="intarray"
layout="joomla.form.field.list-fancy-select"
/>
<field
name="count"
type="number"
label="MOD_POPULAR_FIELD_COUNT_LABEL"
default="5"
filter="integer"
/>
<field
name="show_front"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_POPULAR_FIELD_FEATURED_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="basicspacer1"
type="spacer"
hr="true"
/>
<field
name="date_filtering"
type="list"
label="MOD_POPULAR_FIELD_DATEFILTERING_LABEL"
default="off"
validate="options"
>
<option value="off">MOD_POPULAR_OPTION_OFF_VALUE</option>
<option value="range">MOD_POPULAR_OPTION_DATERANGE_VALUE</option>
<option value="relative">MOD_POPULAR_OPTION_RELATIVEDAY_VALUE</option>
</field>
<field
name="date_field"
type="list"
label="MOD_POPULAR_FIELD_DATEFIELD_LABEL"
default="a.created"
showon="date_filtering:range,relative"
validate="options"
>
<option value="a.created">MOD_POPULAR_OPTION_CREATED_VALUE</option>
<option value="a.modified">MOD_POPULAR_OPTION_MODIFIED_VALUE</option>
<option value="a.publish_up">MOD_POPULAR_OPTION_STARTPUBLISHING_VALUE</option>
</field>
<field
name="start_date_range"
type="calendar"
label="MOD_POPULAR_FIELD_STARTDATE_LABEL"
translateformat="true"
showtime="true"
filter="user_utc"
showon="date_filtering:range"
/>
<field
name="end_date_range"
type="calendar"
label="MOD_POPULAR_FIELD_ENDDATE_LABEL"
translateformat="true"
showtime="true"
filter="user_utc"
showon="date_filtering:range"
/>
<field
name="relative_date"
type="number"
label="MOD_POPULAR_FIELD_RELATIVEDATE_LABEL"
default="30"
filter="integer"
showon="date_filtering:relative"
/>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_popular
*
* @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 popular articles module service provider.
*
* @since 4.3.0
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since 4.3.0
*/
public function register(Container $container)
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesPopular'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesPopular\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,51 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_popular
*
* @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\ArticlesPopular\Site\Dispatcher;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
use Joomla\CMS\Language\Text;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_articles_popular
*
* @since 4.3.0
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;
/**
* Returns the layout data.
*
* @return array
*
* @since 4.3.0
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
if (!ComponentHelper::getParams('com_content')->get('record_hits', 1)) {
$data['hitsDisabledMessage'] = Text::_('JGLOBAL_RECORD_HITS_DISABLED');
} else {
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesPopularHelper', $data)->getArticles($data['params'], $data['app']);
}
return $data;
}
}

View File

@ -0,0 +1,184 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_popular
*
* @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\Module\ArticlesPopular\Site\Helper;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Cache\CacheControllerFactoryInterface;
use Joomla\CMS\Cache\Controller\OutputController;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Component\Content\Site\Model\ArticlesModel;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_articles_popular
*
* @since 4.3.0
*/
class ArticlesPopularHelper
{
/**
* The module instance
*
* @var \stdClass
*
* @since 4.3.0
*/
protected $module;
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
*
* @since 4.3.0
*/
public function __construct($config = [])
{
$this->module = $config['module'];
}
/**
* Retrieve a list of months with archived articles
*
* @param Registry $params The module parameters.
* @param SiteApplication $app The current application.
*
* @return object[]
*
* @since 4.3.0
*/
public function getArticles(Registry $moduleParams, SiteApplication $app)
{
$cacheKey = md5(serialize([$moduleParams->toString(), $this->module->module, $this->module->id]));
/** @var OutputController $cache */
$cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
->createCacheController('output', ['defaultgroup' => 'mod_articles_popular']);
if (!$cache->contains($cacheKey)) {
$mvcContentFactory = $app->bootComponent('com_content')->getMVCFactory();
/** @var ArticlesModel $articlesModel */
$articlesModel = $mvcContentFactory->createModel('Articles', 'Site', ['ignore_request' => true]);
// Set application parameters in model
$appParams = $app->getParams();
$articlesModel->setState('params', $appParams);
$articlesModel->setState('list.start', 0);
$articlesModel->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
// Set the filters based on the module params
$articlesModel->setState('list.limit', (int) $moduleParams->get('count', 5));
$articlesModel->setState('filter.featured', $moduleParams->get('show_front', 1) == 1 ? 'show' : 'hide');
// This module does not use tags data
$articlesModel->setState('load_tags', false);
// Access filter
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
$articlesModel->setState('filter.access', $access);
// Category filter
$articlesModel->setState('filter.category_id', $moduleParams->get('catid', []));
// Date filter
$date_filtering = $moduleParams->get('date_filtering', 'off');
if ($date_filtering !== 'off') {
$articlesModel->setState('filter.date_filtering', $date_filtering);
$articlesModel->setState('filter.date_field', $moduleParams->get('date_field', 'a.created'));
$articlesModel->setState('filter.start_date_range', $moduleParams->get('start_date_range', '1000-01-01 00:00:00'));
$articlesModel->setState('filter.end_date_range', $moduleParams->get('end_date_range', '9999-12-31 23:59:59'));
$articlesModel->setState('filter.relative_date', $moduleParams->get('relative_date', 30));
}
// Filter by language
$articlesModel->setState('filter.language', $app->getLanguageFilter());
// Ordering
$articlesModel->setState('list.ordering', 'a.hits');
$articlesModel->setState('list.direction', 'DESC');
// Prepare the module output
$items = [];
$itemParams = new \stdClass();
$itemParams->authorised = Access::getAuthorisedViewLevels($app->getIdentity()->get('id'));
$itemParams->access = $access;
foreach ($articlesModel->getItems() as $item) {
$items[] = $this->prepareItem($item, $itemParams);
}
// Cache the output and return
$cache->store($items, $cacheKey);
return $items;
}
// Return the cached output
return $cache->get($cacheKey);
}
/**
* Prepare the article before render.
*
* @param object $item The article to prepare
* @param \stdClass $params The model item
*
* @return object
*
* @since 4.3.0
*/
private function prepareItem($item, $params): object
{
$item->slug = $item->id . ':' . $item->alias;
if ($params->access || \in_array($item->access, $params->authorised)) {
// We know that user has the privilege to view the article
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
} else {
$item->link = Route::_('index.php?option=com_users&view=login');
}
return $item;
}
/**
* Get a list of popular articles from the articles model
*
* @param \Joomla\Registry\Registry &$params object holding the models parameters
*
* @return mixed
*
* @since 4.3.0
*
* @deprecated 4.3 will be removed in 6.0
* Use the non-static method getArticles
* Example: Factory::getApplication()->bootModule('mod_articles_popular', 'site')
* ->getHelper('ArticlesPopularHelper')
* ->getArticles($params, Factory::getApplication())
*/
public static function getList(&$params)
{
return (new self())->getArticles($params, Factory::getApplication());
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_articles_popular
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
if (!isset($list)) {
if (isset($hitsDisabledMessage)) {
echo $hitsDisabledMessage;
}
return;
}
?>
<ul class="mostread mod-list">
<?php foreach ($list as $item) : ?>
<li itemscope itemtype="https://schema.org/Article">
<a href="<?php echo $item->link; ?>" itemprop="url">
<span itemprop="name">
<?php echo $item->title; ?>
</span>
</a>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,25 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_banners
*
* @copyright (C) 2005 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\Component\Banners\Administrator\Helper\BannersHelper as BannersComponentHelper;
use Joomla\Module\Banners\Site\Helper\BannersHelper;
$headerText = trim($params->get('header_text', ''));
$footerText = trim($params->get('footer_text', ''));
BannersComponentHelper::updateReset();
$model = $app->bootComponent('com_banners')->getMVCFactory()->createModel('Banners', 'Site', ['ignore_request' => true]);
$list = BannersHelper::getList($params, $model, $app);
require ModuleHelper::getLayoutPath('mod_banners', $params->get('layout', 'default'));

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_banners</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_BANNERS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Banners</namespace>
<files>
<filename module="mod_banners">mod_banners.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_banners.ini</language>
<language tag="en-GB">language/en-GB/mod_banners.sys.ini</language>
</languages>
<help key="Site_Modules:_Banners" />
<config>
<fields name="params">
<fieldset
name="basic"
addfieldprefix="Joomla\Component\Banners\Administrator\Field"
>
<field
name="target"
type="list"
label="MOD_BANNERS_FIELD_TARGET_LABEL"
default="1"
filter="integer"
validate="options"
>
<option value="0">JBROWSERTARGET_PARENT</option>
<option value="1">JBROWSERTARGET_NEW</option>
<option value="2">JBROWSERTARGET_POPUP</option>
</field>
<field
name="count"
type="number"
label="MOD_BANNERS_FIELD_COUNT_LABEL"
description="MOD_BANNERS_FIELD_COUNT_DESC"
default="5"
filter="integer"
class="validate-numeric"
min="1"
validate="number"
/>
<field
name="cid"
type="bannerclient"
label="MOD_BANNERS_FIELD_BANNERCLIENT_LABEL"
description="MOD_BANNERS_FIELD_BANNERCLIENT_DESC"
filter="integer"
/>
<field
name="catid"
type="category"
label="JCATEGORY"
extension="com_banners"
multiple="true"
filter="intarray"
class="multipleCategories"
layout="joomla.form.field.list-fancy-select"
/>
<field
name="tag_search"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_BANNERS_FIELD_TAG_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="ordering"
type="list"
label="MOD_BANNERS_FIELD_RANDOMISE_LABEL"
default="0"
validate="options"
>
<option value="0">MOD_BANNERS_VALUE_STICKYORDERING</option>
<option value="random">MOD_BANNERS_VALUE_STICKYRANDOMISE</option>
</field>
<field
name="header_text"
type="textarea"
label="MOD_BANNERS_FIELD_HEADER_LABEL"
filter="safehtml"
rows="3"
cols="40"
/>
<field
name="footer_text"
type="textarea"
label="MOD_BANNERS_FIELD_FOOTER_LABEL"
filter="safehtml"
rows="3"
cols="40"
/>
</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="cache"
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,63 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_banners
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Banners\Site\Helper;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Environment\Browser;
use Joomla\Component\Banners\Site\Model\BannersModel;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_banners
*
* @since 1.5
*/
class BannersHelper
{
/**
* Retrieve list of banners
*
* @param Registry $params The module parameters
* @param BannersModel $model The model
* @param CMSApplication $app The application
*
* @return mixed
*/
public static function getList(Registry $params, BannersModel $model, CMSApplication $app)
{
$keywords = explode(',', $app->getDocument()->getMetaData('keywords'));
$config = ComponentHelper::getParams('com_banners');
$model->setState('filter.client_id', (int) $params->get('cid'));
$model->setState('filter.category_id', $params->get('catid', []));
$model->setState('list.limit', (int) $params->get('count', 1));
$model->setState('list.start', 0);
$model->setState('filter.ordering', $params->get('ordering'));
$model->setState('filter.tag_search', $params->get('tag_search'));
$model->setState('filter.keywords', $keywords);
$model->setState('filter.language', $app->getLanguageFilter());
$banners = $model->getItems();
if ($banners) {
if ($config->get('track_robots_impressions', 1) == 1 || !Browser::getInstance()->isRobot()) {
$model->impress();
}
}
return $banners;
}
}

View File

@ -0,0 +1,119 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_banners
*
* @copyright (C) 2006 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\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Banners\Site\Helper\BannerHelper;
?>
<div class="mod-banners bannergroup">
<?php if ($headerText) : ?>
<div class="bannerheader">
<?php echo $headerText; ?>
</div>
<?php endif; ?>
<?php foreach ($list as $item) : ?>
<div class="mod-banners__item banneritem">
<?php $link = Route::_('index.php?option=com_banners&task=click&id=' . $item->id); ?>
<?php if ($item->type == 1) : ?>
<?php // Text based banners ?>
<?php echo str_replace(['{CLICKURL}', '{NAME}'], [$link, $item->name], $item->custombannercode); ?>
<?php else : ?>
<?php $imageurl = $item->params->get('imageurl'); ?>
<?php $width = $item->params->get('width'); ?>
<?php $height = $item->params->get('height'); ?>
<?php if (BannerHelper::isImage($imageurl)) : ?>
<?php // Image based banner ?>
<?php $baseurl = strpos($imageurl, 'http') === 0 ? '' : Uri::base(); ?>
<?php $alt = $item->params->get('alt'); ?>
<?php $alt = $alt ?: $item->name; ?>
<?php $alt = $alt ?: Text::_('MOD_BANNERS_BANNER'); ?>
<?php if ($item->clickurl) : ?>
<?php // Wrap the banner in a link ?>
<?php $target = $params->get('target', 1); ?>
<?php if ($target == 1) : ?>
<?php // Open in a new window ?>
<a
href="<?php echo $link; ?>" target="_blank" rel="noopener noreferrer"
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
<img
src="<?php echo $baseurl . $imageurl; ?>"
alt="<?php echo htmlspecialchars($alt, ENT_QUOTES, 'UTF-8'); ?>"
<?php if (!empty($width)) {
echo 'width="' . $width . '"';
} ?>
<?php if (!empty($height)) {
echo 'height="' . $height . '"';
} ?>
>
</a>
<?php elseif ($target == 2) : ?>
<?php // Open in a popup window ?>
<a
href="<?php echo $link; ?>" onclick="window.open(this.href, '',
'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=550');
return false"
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
<img
src="<?php echo $baseurl . $imageurl; ?>"
alt="<?php echo htmlspecialchars($alt, ENT_QUOTES, 'UTF-8'); ?>"
<?php if (!empty($width)) {
echo 'width="' . $width . '"';
} ?>
<?php if (!empty($height)) {
echo 'height="' . $height . '"';
} ?>
>
</a>
<?php else : ?>
<?php // Open in parent window ?>
<a
href="<?php echo $link; ?>"
title="<?php echo htmlspecialchars($item->name, ENT_QUOTES, 'UTF-8'); ?>">
<img
src="<?php echo $baseurl . $imageurl; ?>"
alt="<?php echo htmlspecialchars($alt, ENT_QUOTES, 'UTF-8'); ?>"
<?php if (!empty($width)) {
echo 'width="' . $width . '"';
} ?>
<?php if (!empty($height)) {
echo 'height="' . $height . '"';
} ?>
>
</a>
<?php endif; ?>
<?php else : ?>
<?php // Just display the image if no link specified ?>
<img
src="<?php echo $baseurl . $imageurl; ?>"
alt="<?php echo htmlspecialchars($alt, ENT_QUOTES, 'UTF-8'); ?>"
<?php if (!empty($width)) {
echo 'width="' . $width . '"';
} ?>
<?php if (!empty($height)) {
echo 'height="' . $height . '"';
} ?>
>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php if ($footerText) : ?>
<div class="mod-banners__footer bannerfooter">
<?php echo $footerText; ?>
</div>
<?php endif; ?>
</div>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_breadcrumbs</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_BREADCRUMBS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Breadcrumbs</namespace>
<files>
<folder module="mod_breadcrumbs">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_breadcrumbs.ini</language>
<language tag="en-GB">language/en-GB/mod_breadcrumbs.sys.ini</language>
</languages>
<help key="Site_Modules:_Breadcrumbs" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="showHere"
type="radio"
label="MOD_BREADCRUMBS_FIELD_SHOWHERE_LABEL"
layout="joomla.form.field.radio.switcher"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="showHome"
type="radio"
label="MOD_BREADCRUMBS_FIELD_SHOWHOME_LABEL"
layout="joomla.form.field.radio.switcher"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="homeText"
type="text"
label="MOD_BREADCRUMBS_FIELD_HOMETEXT_LABEL"
description="MOD_BREADCRUMBS_FIELD_HOMETEXT_DESC"
showon="showHome:1"
/>
<field
name="showLast"
type="radio"
label="MOD_BREADCRUMBS_FIELD_SHOWLAST_LABEL"
default="1"
layout="joomla.form.field.radio.switcher"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</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="cache"
type="list"
label="COM_MODULES_FIELD_CACHING_LABEL"
default="0"
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="0"
filter="integer"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,41 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_breadcrumbs
*
* @copyright (C) 2023 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 breadcrumbs 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): void
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Breadcrumbs'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Breadcrumbs\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,50 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_breadcrumbs
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Breadcrumbs\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_breadcrumbs
*
* @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();
$data['list'] = $this->getHelperFactory()->getHelper('BreadcrumbsHelper')->getBreadcrumbs($data['params'], $data['app']);
$data['count'] = \count($data['list']);
if (!$data['params']->get('showHome', 1)) {
$data['homeCrumb'] = $this->getHelperFactory()->getHelper('BreadcrumbsHelper')->getHomeItem($data['params'], $data['app']);
}
return $data;
}
}

View File

@ -0,0 +1,162 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_breadcrumbs
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Breadcrumbs\Site\Helper;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_breadcrumbs
*
* @since 1.5
*/
class BreadcrumbsHelper
{
/**
* Retrieve breadcrumb items
*
* @param Registry $params The module parameters
* @param SiteApplication $app The application
*
* @return array
*
* @since 4.4.0
*/
public function getBreadcrumbs(Registry $params, SiteApplication $app): array
{
// Get the PathWay object from the application
$pathway = $app->getPathway();
$items = $pathway->getPathway();
$count = \count($items);
// Don't use $items here as it references JPathway properties directly
$crumbs = [];
for ($i = 0; $i < $count; $i++) {
$crumbs[$i] = new \stdClass();
$crumbs[$i]->name = stripslashes(htmlspecialchars($items[$i]->name, ENT_COMPAT, 'UTF-8'));
$crumbs[$i]->link = $items[$i]->link;
}
if ($params->get('showHome', 1)) {
array_unshift($crumbs, $this->getHomeItem($params, $app));
}
return $crumbs;
}
/**
* Retrieve home item (start page)
*
* @param Registry $params The module parameters
* @param SiteApplication $app The application
*
* @return object
*
* @since 4.4.0
*/
public function getHomeItem(Registry $params, SiteApplication $app): object
{
$menu = $app->getMenu();
if (Multilanguage::isEnabled()) {
$home = $menu->getDefault($app->getLanguage()->getTag());
} else {
$home = $menu->getDefault();
}
$item = new \stdClass();
$item->name = htmlspecialchars($params->get('homeText', $app->getLanguage()->_('MOD_BREADCRUMBS_HOME')), ENT_COMPAT, 'UTF-8');
$item->link = 'index.php?Itemid=' . $home->id;
return $item;
}
/**
* Set the breadcrumbs separator for the breadcrumbs display.
*
* @param string $custom Custom xhtml compliant string to separate the items of the breadcrumbs
*
* @return string Separator string
*
* @since 1.5
*
* @deprecated 4.4.0 will be removed in 6.0 as this function is not used anymore
*/
public static function setSeparator($custom = null)
{
$lang = Factory::getApplication()->getLanguage();
// If a custom separator has not been provided we try to load a template
// specific one first, and if that is not present we load the default separator
if ($custom === null) {
if ($lang->isRtl()) {
$_separator = HTMLHelper::_('image', 'system/arrow_rtl.png', null, null, true);
} else {
$_separator = HTMLHelper::_('image', 'system/arrow.png', null, null, true);
}
} else {
$_separator = htmlspecialchars($custom, ENT_COMPAT, 'UTF-8');
}
return $_separator;
}
/**
* Retrieve breadcrumb items
*
* @param Registry $params The module parameters
* @param CMSApplication $app The application
*
* @return array
*
* @since 1.5
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getBreadcrumbs
* Example: Factory::getApplication()->bootModule('mod_breadcrumbs', 'site')
* ->getHelper('BreadcrumbsHelper')
* ->getBreadcrumbs($params, Factory::getApplication())
*/
public static function getList(Registry $params, CMSApplication $app)
{
return (new self())->getBreadcrumbs($params, Factory::getApplication());
}
/**
* Retrieve home item (start page)
*
* @param Registry $params The module parameters
* @param CMSApplication $app The application
*
* @return object
*
* @since 4.2.0
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getHomeItem
* Example: Factory::getApplication()->bootModule('mod_breadcrumbs', 'site')
* ->getHelper('BreadcrumbsHelper')
* ->getHomeItem($params, Factory::getApplication())
*/
public static function getHome(Registry $params, CMSApplication $app)
{
return (new self())->getHomeItem($params, Factory::getApplication());
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_breadcrumbs
*
* @copyright (C) 2006 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\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\WebAsset\WebAssetManager;
?>
<nav class="mod-breadcrumbs__wrapper" aria-label="<?php echo htmlspecialchars($module->title, ENT_QUOTES, 'UTF-8'); ?>">
<ol class="mod-breadcrumbs breadcrumb px-3 py-2">
<?php if ($params->get('showHere', 1)) : ?>
<li class="mod-breadcrumbs__here float-start">
<?php echo Text::_('MOD_BREADCRUMBS_HERE'); ?>&#160;
</li>
<?php else : ?>
<li class="mod-breadcrumbs__divider float-start">
<span class="divider icon-location icon-fw" aria-hidden="true"></span>
</li>
<?php endif; ?>
<?php
// Get rid of duplicated entries on trail including home page when using multilanguage
for ($i = 0; $i < $count; $i++) {
if ($i === 1 && !empty($list[$i]->link) && !empty($list[$i - 1]->link) && $list[$i]->link === $list[$i - 1]->link) {
unset($list[$i]);
}
}
// Find last and penultimate items in breadcrumbs list
end($list);
$last_item_key = key($list);
prev($list);
$penult_item_key = key($list);
// Make a link if not the last item in the breadcrumbs
$show_last = $params->get('showLast', 1);
$class = null;
// Generate the trail
foreach ($list as $key => $item) :
if ($key !== $last_item_key) :
if (!empty($item->link)) :
$breadcrumbItem = HTMLHelper::_('link', Route::_($item->link), '<span>' . $item->name . '</span>', ['class' => 'pathway']);
else :
$breadcrumbItem = '<span>' . $item->name . '</span>';
endif;
echo '<li class="mod-breadcrumbs__item breadcrumb-item' . $class . '">' . $breadcrumbItem . '</li>';
elseif ($show_last) :
// Render last item if required.
$breadcrumbItem = '<span>' . $item->name . '</span>';
$class = ' active';
echo '<li class="mod-breadcrumbs__item breadcrumb-item' . $class . '">' . $breadcrumbItem . '</li>';
endif;
endforeach; ?>
</ol>
<?php
// Structured data as JSON
$data = [
'@context' => 'https://schema.org',
'@type' => 'BreadcrumbList',
'@id' => Uri::root() . '#/schema/BreadcrumbList/' . (int) $module->id,
'itemListElement' => []
];
// Use an independent counter for positions. E.g. if Heading items in pathway.
$itemsCounter = 0;
// If showHome is disabled use the fallback $homeCrumb for startpage at first position.
if (isset($homeCrumb)) {
$data['itemListElement'][] = [
'@type' => 'ListItem',
'position' => ++$itemsCounter,
'item' => [
'@id' => Route::_($homeCrumb->link, true, Route::TLS_IGNORE, true),
'name' => $homeCrumb->name,
],
];
}
foreach ($list as $key => $item) {
// Only add item to JSON if it has a valid link, otherwise skip it.
if (!empty($item->link)) {
$data['itemListElement'][] = [
'@type' => 'ListItem',
'position' => ++$itemsCounter,
'item' => [
'@id' => Route::_($item->link, true, Route::TLS_IGNORE, true),
'name' => $item->name,
],
];
} elseif ($key === $last_item_key) {
// Add the last item (current page) to JSON, but without a link.
// Google accepts items without a URL only as the current page.
$data['itemListElement'][] = [
'@type' => 'ListItem',
'position' => ++$itemsCounter,
'item' => [
'name' => $item->name,
],
];
}
}
if ($itemsCounter) {
/** @var WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$prettyPrint = JDEBUG ? JSON_PRETTY_PRINT : 0;
$wa->addInline('script', json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | $prettyPrint), [], ['type' => 'application/ld+json']);
}
?>
</nav>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_custom</name>
<author>Joomla! Project</author>
<creationDate>2004-07</creationDate>
<copyright>(C) 2005 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_CUSTOM_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Custom</namespace>
<customContent />
<files>
<folder module="mod_custom">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_custom.ini</language>
<language tag="en-GB">language/en-GB/mod_custom.sys.ini</language>
</languages>
<help key="Site_Modules:_Custom" />
<config>
<fields name="params">
<fieldset name="options" label="COM_MODULES_BASIC_FIELDSET_LABEL">
<field
name="prepare_content"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_CUSTOM_FIELD_PREPARE_CONTENT_LABEL"
description="MOD_CUSTOM_FIELD_PREPARE_CONTENT_DESC"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="backgroundimage"
type="media"
label="MOD_CUSTOM_FIELD_BACKGROUNDIMAGE_LABEL"
/>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,38 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_custom
*
* @copyright (C) 2023 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\Module;
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
/**
* The module Custom HTML 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): void
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Custom'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_custom
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Custom\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\HTML\HTMLHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_custom
*
* @since 4.4.0
*/
class Dispatcher extends AbstractModuleDispatcher
{
/**
* Returns the layout data.
*
* @return array
*
* @since 4.4.0
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
if (($data['params'])->get('prepare_content', 1)) {
($data['module'])->content = HTMLHelper::_('content.prepare', ($data['module'])->content, '', 'mod_custom.content');
}
return $data;
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_custom
*
* @copyright (C) 2009 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\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Uri\Uri;
$modId = 'mod-custom' . $module->id;
if ($params->get('backgroundimage')) {
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->addInlineStyle('
#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}
', ['name' => $modId]);
}
?>
<div id="<?php echo $modId; ?>" class="mod-custom custom">
<?php echo $module->content; ?>
</div>

View File

@ -0,0 +1,21 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_feed
*
* @copyright (C) 2005 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\Module\Feed\Site\Helper\FeedHelper;
$rssurl = $params->get('rssurl', '');
$rssrtl = $params->get('rssrtl', 0);
$feed = FeedHelper::getFeed($params);
require ModuleHelper::getLayoutPath('mod_feed', $params->get('layout', 'default'));

View File

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_feed</name>
<author>Joomla! Project</author>
<creationDate>2005-07</creationDate>
<copyright>(C) 2005 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_FEED_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Feed</namespace>
<files>
<filename module="mod_feed">mod_feed.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_feed.ini</language>
<language tag="en-GB">language/en-GB/mod_feed.sys.ini</language>
</languages>
<help key="Site_Modules:_Feed_Display" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="rssurl"
type="url"
label="MOD_FEED_FIELD_RSSURL_LABEL"
filter="url"
required="true"
validate="url"
/>
<field
name="rssrtl"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FEED_FIELD_RTL_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="rsstitle"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FEED_FIELD_RSSTITLE_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="rssdesc"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FEED_FIELD_DESCRIPTION_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="rssdate"
type="radio"
label="MOD_FEED_FIELD_DATE_LABEL"
layout="joomla.form.field.radio.switcher"
default="0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="rssimage"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FEED_FIELD_IMAGE_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="rssitems"
type="number"
label="MOD_FEED_FIELD_ITEMS_LABEL"
default="3"
filter="integer"
min="1"
validate="number"
/>
<field
name="rssitemdesc"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FEED_FIELD_ITEMDESCRIPTION_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="rssitemdate"
type="radio"
label="MOD_FEED_FIELD_ITEMDATE_LABEL"
layout="joomla.form.field.radio.switcher"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="word_count"
type="text"
label="MOD_FEED_FIELD_WORDCOUNT_LABEL"
description="MOD_FEED_FIELD_WORDCOUNT_DESC"
default="0"
filter="integer"
/>
</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="cache"
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,55 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_feed
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Feed\Site\Helper;
use Joomla\CMS\Feed\FeedFactory;
use Joomla\CMS\Language\Text;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_feed
*
* @since 1.5
*/
class FeedHelper
{
/**
* Retrieve feed information
*
* @param \Joomla\Registry\Registry $params module parameters
*
* @return \Joomla\CMS\Feed\Feed|string
*/
public static function getFeed($params)
{
// Module params
$rssurl = $params->get('rssurl', '');
// Get RSS parsed object
try {
$feed = new FeedFactory();
$rssDoc = $feed->getFeed($rssurl);
} catch (\Exception $e) {
return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED');
}
if (empty($rssDoc)) {
return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED');
}
if ($rssDoc) {
return $rssDoc;
}
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_feed
*
* @copyright (C) 2006 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\Filter\OutputFilter;
// Check if feed URL has been set
if (empty($rssurl)) {
echo '<div>' . Text::_('MOD_FEED_ERR_NO_URL') . '</div>';
return;
}
if (!empty($feed) && is_string($feed)) {
echo $feed;
} else {
$lang = $app->getLanguage();
$myrtl = $params->get('rssrtl', 0);
$direction = ' ';
$isRtl = $lang->isRtl();
if ($isRtl && $myrtl == 0) {
$direction = ' redirect-rtl';
} elseif ($isRtl && $myrtl == 1) {
// Feed description
$direction = ' redirect-ltr';
} elseif ($isRtl && $myrtl == 2) {
$direction = ' redirect-rtl';
} elseif ($myrtl == 0) {
$direction = ' redirect-ltr';
} elseif ($myrtl == 1) {
$direction = ' redirect-ltr';
} elseif ($myrtl == 2) {
$direction = ' redirect-rtl';
}
if ($feed !== false) {
?>
<div style="direction: <?php echo $rssrtl ? 'rtl' : 'ltr'; ?>;" class="text-<?php echo $rssrtl ? 'right' : 'left'; ?> feed">
<?php
// Feed title
if ($feed->title !== null && $params->get('rsstitle', 1)) {
?>
<h2 class="<?php echo $direction; ?>">
<a href="<?php echo htmlspecialchars($rssurl, ENT_COMPAT, 'UTF-8'); ?>" target="_blank" rel="noopener">
<?php echo $feed->title; ?></a>
</h2>
<?php
}
// Feed date
if ($params->get('rssdate', 1)) : ?>
<h3>
<?php echo HTMLHelper::_('date', $feed->publishedDate, Text::_('DATE_FORMAT_LC3')); ?>
</h3>
<?php endif;
// Feed description
if ($params->get('rssdesc', 1)) {
?>
<?php echo $feed->description; ?>
<?php
}
// Feed image
if ($feed->image && $params->get('rssimage', 1)) :
?>
<?php echo HTMLHelper::_('image', $feed->image->uri, $feed->image->title); ?>
<?php endif; ?>
<!-- Show items -->
<?php if (!empty($feed)) { ?>
<ul class="newsfeed">
<?php for ($i = 0, $max = min(count($feed), $params->get('rssitems', 3)); $i < $max; $i++) { ?>
<?php
$uri = $feed[$i]->uri || !$feed[$i]->isPermaLink ? trim($feed[$i]->uri) : trim($feed[$i]->guid);
$uri = !$uri || stripos($uri, 'http') !== 0 ? $rssurl : $uri;
$text = $feed[$i]->content !== '' ? trim($feed[$i]->content) : '';
?>
<li>
<?php if (!empty($uri)) : ?>
<span class="feed-link">
<a href="<?php echo htmlspecialchars($uri, ENT_COMPAT, 'UTF-8'); ?>" target="_blank" rel="noopener">
<?php echo trim($feed[$i]->title); ?></a></span>
<?php else : ?>
<span class="feed-link"><?php echo trim($feed[$i]->title); ?></span>
<?php endif; ?>
<?php if ($params->get('rssitemdate', 0)) : ?>
<div class="feed-item-date">
<?php echo HTMLHelper::_('date', $feed[$i]->publishedDate, Text::_('DATE_FORMAT_LC3')); ?>
</div>
<?php endif; ?>
<?php if ($params->get('rssitemdesc', 1) && $text !== '') : ?>
<div class="feed-item-description">
<?php
// Strip the images.
$text = OutputFilter::stripImages($text);
$text = HTMLHelper::_('string.truncate', $text, $params->get('word_count', 0));
echo str_replace('&apos;', "'", $text);
?>
</div>
<?php endif; ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</div>
<?php }
}

View File

@ -0,0 +1,54 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_finder
*
* @copyright (C) 2011 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\Component\ComponentHelper;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Finder\Administrator\Helper\LanguageHelper;
use Joomla\Component\Finder\Site\Helper\RouteHelper;
use Joomla\Module\Finder\Site\Helper\FinderHelper;
$cparams = ComponentHelper::getParams('com_finder');
// Check for OpenSearch
if ($params->get('opensearch', $cparams->get('opensearch', 1))) {
$defaultTitle = Text::_('MOD_FINDER_OPENSEARCH_NAME') . ' ' . $app->get('sitename');
$ostitle = $params->get('opensearch_name', $cparams->get('opensearch_name', $defaultTitle));
$app->getDocument()->addHeadLink(
Uri::getInstance()->toString(['scheme', 'host', 'port']) . Route::_('index.php?option=com_finder&view=search&format=opensearch'),
'search',
'rel',
['title' => $ostitle, 'type' => 'application/opensearchdescription+xml']
);
}
// Get the route.
$route = RouteHelper::getSearchRoute($params->get('searchfilter', null));
if ($params->get('set_itemid')) {
$uri = Uri::getInstance($route);
$uri->setVar('Itemid', $params->get('set_itemid'));
$route = $uri->toString(['path', 'query']);
}
// Load component language file.
LanguageHelper::loadComponentLanguage();
// Load plugin language files.
LanguageHelper::loadPluginLanguage();
// Get Smart Search query object.
$query = FinderHelper::getQuery($params);
require ModuleHelper::getLayoutPath('mod_finder', $params->get('layout', 'default'));

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_finder</name>
<author>Joomla! Project</author>
<creationDate>2011-08</creationDate>
<copyright>(C) 2011 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_FINDER_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Finder</namespace>
<files>
<filename module="mod_finder">mod_finder.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_finder.ini</language>
<language tag="en-GB">language/en-GB/mod_finder.sys.ini</language>
</languages>
<help key="Site_Modules:_Smart_Search" />
<config>
<fields name="params" addfieldprefix="Joomla\Component\Finder\Administrator\Field">
<fieldset name="basic">
<field
name="searchfilter"
type="searchfilter"
label="MOD_FINDER_FIELDSET_BASIC_SEARCHFILTER_LABEL"
default=""
/>
<field
name="show_autosuggest"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FINDER_FIELDSET_BASIC_AUTOSUGGEST_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="show_advanced"
type="list"
label="MOD_FINDER_FIELDSET_BASIC_SHOW_ADVANCED_LABEL"
default="0"
filter="integer"
validate="options"
>
<option value="2">MOD_FINDER_FIELDSET_BASIC_SHOW_ADVANCED_OPTION_LINK</option>
<option value="1">JSHOW</option>
<option value="0">JHIDE</option>
</field>
<field
name="show_label"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FINDER_FIELDSET_ADVANCED_SHOW_LABEL_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="alt_label"
type="text"
label="MOD_FINDER_FIELDSET_ADVANCED_ALT_LABEL"
/>
<field
name="show_button"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FINDER_FIELDSET_ADVANCED_SHOW_BUTTON_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="opensearch"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_FINDER_FIELD_OPENSEARCH_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="opensearch_name"
type="text"
label="MOD_FINDER_FIELD_OPENSEARCH_TEXT_LABEL"
showon="opensearch:1"
/>
<field
name="set_itemid"
type="menuitem"
label="MOD_FINDER_FIELDSET_ADVANCED_SETITEMID_LABEL"
filter="integer"
>
<option value="0">MOD_FINDER_SELECT_MENU_ITEMID</option>
</field>
</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"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,84 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_finder
*
* @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Finder\Site\Helper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\InputFilter;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Finder\Administrator\Indexer\Query;
use Joomla\Database\DatabaseInterface;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Finder module helper.
*
* @since 2.5
*/
class FinderHelper
{
/**
* Method to get hidden input fields for a get form so that control variables
* are not lost upon form submission.
*
* @param string $route The route to the page. [optional]
* @param integer $paramItem The menu item ID. (@since 3.1) [optional]
*
* @return string A string of hidden input form fields
*
* @since 2.5
*/
public static function getGetFields($route = null, $paramItem = 0)
{
$fields = [];
$uri = Uri::getInstance(Route::_($route));
$uri->delVar('q');
// Create hidden input elements for each part of the URI.
foreach ($uri->getQuery(true) as $n => $v) {
$fields[] = '<input type="hidden" name="' . $n . '" value="' . $v . '">';
}
return implode('', $fields);
}
/**
* Get Smart Search query object.
*
* @param \Joomla\Registry\Registry $params Module parameters.
*
* @return Query object
*
* @since 2.5
*/
public static function getQuery($params)
{
$request = Factory::getApplication()->getInput()->request;
$filter = InputFilter::getInstance();
// Get the static taxonomy filters.
$options = [];
$options['filter'] = ($request->get('f', 0, 'int') !== 0) ? $request->get('f', '', 'int') : $params->get('searchfilter');
$options['filter'] = $filter->clean($options['filter'], 'int');
// Get the dynamic taxonomy filters.
$options['filters'] = $request->get('t', '', 'array');
$options['filters'] = $filter->clean($options['filters'], 'array');
$options['filters'] = ArrayHelper::toInteger($options['filters']);
// Instantiate a query object.
return new Query($options, Factory::getContainer()->get(DatabaseInterface::class));
}
}

View File

@ -0,0 +1,76 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_finder
*
* @copyright (C) 2011 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\Router\Route;
use Joomla\Module\Finder\Site\Helper\FinderHelper;
// Load the smart search component language file.
$lang = $app->getLanguage();
$lang->load('com_finder', JPATH_SITE);
$input = '<input type="text" name="q" id="mod-finder-searchword' . $module->id . '" class="js-finder-search-query form-control" value="' . htmlspecialchars($app->getInput()->get('q', '', 'string'), ENT_COMPAT, 'UTF-8') . '"'
. ' placeholder="' . Text::_('MOD_FINDER_SEARCH_VALUE') . '">';
$showLabel = $params->get('show_label', 1);
$labelClass = (!$showLabel ? 'visually-hidden ' : '') . 'finder';
$label = '<label for="mod-finder-searchword' . $module->id . '" class="' . $labelClass . '">' . $params->get('alt_label', Text::_('JSEARCH_FILTER_SUBMIT')) . '</label>';
$output = '';
if ($params->get('show_button', 0)) {
$output .= $label;
$output .= '<div class="mod-finder__search input-group">';
$output .= $input;
$output .= '<button class="btn btn-primary" type="submit"><span class="icon-search icon-white" aria-hidden="true"></span> ' . Text::_('JSEARCH_FILTER_SUBMIT') . '</button>';
$output .= '</div>';
} else {
$output .= $label;
$output .= $input;
}
Text::script('MOD_FINDER_SEARCH_VALUE');
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$wa->getRegistry()->addExtensionRegistryFile('com_finder');
/*
* This segment of code sets up the autocompleter.
*/
if ($params->get('show_autosuggest', 1)) {
$wa->usePreset('awesomplete');
$app->getDocument()->addScriptOptions('finder-search', ['url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component', false)]);
Text::script('JLIB_JS_AJAX_ERROR_OTHER');
Text::script('JLIB_JS_AJAX_ERROR_PARSE');
}
$wa->useScript('com_finder.finder');
?>
<form class="mod-finder js-finder-searchform form-search" action="<?php echo Route::_($route); ?>" method="get" role="search">
<?php echo $output; ?>
<?php $show_advanced = $params->get('show_advanced', 0); ?>
<?php if ($show_advanced == 2) : ?>
<br>
<a href="<?php echo Route::_($route); ?>" class="mod-finder__advanced-link"><?php echo Text::_('COM_FINDER_ADVANCED_SEARCH'); ?></a>
<?php elseif ($show_advanced == 1) : ?>
<div class="mod-finder__advanced js-finder-advanced">
<?php echo HTMLHelper::_('filter.select', $query, $params); ?>
</div>
<?php endif; ?>
<?php echo FinderHelper::getGetFields($route, (int) $params->get('set_itemid', 0)); ?>
</form>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_footer</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_FOOTER_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Footer</namespace>
<files>
<folder module="mod_footer">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_footer.ini</language>
<language tag="en-GB">language/en-GB/mod_footer.sys.ini</language>
</languages>
<help key="Site_Modules:_Footer" />
<config>
<fields name="params">
<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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,38 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_footer
*
* @copyright (C) 2023 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\Module;
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
/**
* The footer 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): void
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Footer'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,46 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_footer
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Footer\Site\Dispatcher;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\HTML\HTMLHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_footer
*
* @since 4.4.0
*/
class Dispatcher extends AbstractModuleDispatcher
{
/**
* Returns the layout data.
*
* @return array
*
* @since 4.4.0
*/
protected function getLayoutData(): array
{
$data = parent::getLayoutData();
$lineOne = $this->getApplication()->getLanguage()->_('MOD_FOOTER_LINE1');
$lineOne = str_replace('%date%', HTMLHelper::_('date', 'now', 'Y'), $lineOne);
$lineOne = str_replace('%sitename%', $this->getApplication()->get('sitename', ''), $lineOne);
$data['lineone'] = $lineOne;
return $data;
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_footer
*
* @copyright (C) 2006 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\Language\Text;
?>
<div class="mod-footer">
<div class="footer1"><?php echo $lineone; ?></div>
<div class="footer2"><?php echo Text::_('MOD_FOOTER_LINE2'); ?></div>
</div>

View File

@ -0,0 +1,20 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_languages
*
* @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\Module\Languages\Site\Helper\LanguagesHelper;
$headerText = $params->get('header_text');
$footerText = $params->get('footer_text');
$list = LanguagesHelper::getList($params);
require ModuleHelper::getLayoutPath('mod_languages', $params->get('layout', 'default'));

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_languages</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.5.0</version>
<description>MOD_LANGUAGES_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Languages</namespace>
<files>
<filename module="mod_languages">mod_languages.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_languages.ini</language>
<language tag="en-GB">language/en-GB/mod_languages.sys.ini</language>
</languages>
<help key="Site_Modules:_Language_Switcher" />
<config>
<fieldset>
<field
name="language"
type="list"
label="JFIELD_LANGUAGE_LABEL"
description="JFIELD_MODULE_LANGUAGE_DESC"
validate="options"
>
<option value="*">JALL</option>
</field>
</fieldset>
<fields name="params">
<fieldset name="basic">
<field
name="header_text"
type="textarea"
label="MOD_LANGUAGES_FIELD_HEADER_LABEL"
filter="safehtml"
rows="3"
cols="40"
/>
<field
name="footer_text"
type="textarea"
label="MOD_LANGUAGES_FIELD_FOOTER_LABEL"
filter="safehtml"
rows="3"
cols="40"
/>
<field
name="dropdown"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_DROPDOWN_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="dropdownimage"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_DROPDOWN_IMAGE_LABEL"
default="1"
filter="integer"
showon="dropdown:1"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="image"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_USEIMAGE_LABEL"
default="1"
filter="integer"
showon="dropdown:0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="full_name"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_FULL_NAME_LABEL"
showon="dropdown:1[OR]image:0"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="show_active"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_ACTIVE_LABEL"
default="1"
showon="dropdownimage:1[OR]dropdown:0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="inline"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LANGUAGES_FIELD_INLINE_LABEL"
default="1"
filter="integer"
showon="dropdown:0"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</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"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,137 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_languages
*
* @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\Languages\Site\Helper;
use Joomla\CMS\Association\AssociationServiceInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_languages
*
* @since 1.6
*/
abstract class LanguagesHelper
{
/**
* Gets a list of available languages
*
* @param \Joomla\Registry\Registry &$params module params
*
* @return array
*/
public static function getList(&$params)
{
$user = Factory::getUser();
$lang = Factory::getLanguage();
$languages = LanguageHelper::getLanguages();
$app = Factory::getApplication();
$menu = $app->getMenu();
$active = $menu->getActive();
// Get menu home items
$homes = [];
$homes['*'] = $menu->getDefault('*');
foreach ($languages as $item) {
$default = $menu->getDefault($item->lang_code);
if ($default && $default->language === $item->lang_code) {
$homes[$item->lang_code] = $default;
}
}
// Load associations
$assoc = Associations::isEnabled();
if ($assoc) {
if ($active) {
$associations = MenusHelper::getAssociations($active->id);
}
$option = $app->getInput()->get('option');
$component = $app->bootComponent($option);
if ($component instanceof AssociationServiceInterface) {
$cassociations = $component->getAssociationsExtension()->getAssociationsForItem();
} else {
// Load component associations
$class = str_replace('com_', '', $option) . 'HelperAssociation';
\JLoader::register($class, JPATH_SITE . '/components/' . $option . '/helpers/association.php');
if (class_exists($class) && \is_callable([$class, 'getAssociations'])) {
$cassociations = \call_user_func([$class, 'getAssociations']);
}
}
}
$levels = $user->getAuthorisedViewLevels();
$sitelangs = LanguageHelper::getInstalledLanguages(0);
$multilang = Multilanguage::isEnabled();
// Filter allowed languages
foreach ($languages as $i => &$language) {
// Do not display language without frontend UI
if (!\array_key_exists($language->lang_code, $sitelangs)) {
unset($languages[$i]);
} elseif (!isset($homes[$language->lang_code])) {
// Do not display language without specific home menu
unset($languages[$i]);
} elseif (isset($language->access) && $language->access && !\in_array($language->access, $levels)) {
// Do not display language without authorized access level
unset($languages[$i]);
} else {
$language->active = ($language->lang_code === $lang->getTag());
// Fetch language rtl
// If loaded language get from current JLanguage metadata
if ($language->active) {
$language->rtl = $lang->isRtl();
} else {
// If not loaded language fetch metadata directly for performance
$languageMetadata = LanguageHelper::getMetadata($language->lang_code);
$language->rtl = $languageMetadata['rtl'];
}
if ($multilang) {
if (isset($cassociations[$language->lang_code])) {
$language->link = Route::_($cassociations[$language->lang_code]);
} elseif (isset($associations[$language->lang_code]) && $menu->getItem($associations[$language->lang_code])) {
$itemid = $associations[$language->lang_code];
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $itemid);
} elseif ($active && $active->language === '*') {
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $active->id);
} else {
if ($language->active) {
$language->link = Uri::getInstance()->toString(['path', 'query']);
} else {
$itemid = isset($homes[$language->lang_code]) ? $homes[$language->lang_code]->id : $homes['*']->id;
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $itemid);
}
}
} else {
$language->link = Route::_('&Itemid=' . $homes['*']->id);
}
}
}
return $languages;
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_languages
*
* @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\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$wa->registerAndUseStyle('mod_languages', 'mod_languages/template.css');
?>
<div class="mod-languages">
<p class="visually-hidden" id="language_picker_des_<?php echo $module->id; ?>"><?php echo Text::_('MOD_LANGUAGES_DESC'); ?></p>
<?php if ($headerText) : ?>
<div class="mod-languages__pretext pretext"><p><?php echo $headerText; ?></p></div>
<?php endif; ?>
<?php if ($params->get('dropdown', 0)) : ?>
<?php HTMLHelper::_('bootstrap.dropdown', '.dropdown-toggle'); ?>
<div class="mod-languages__select btn-group">
<?php foreach ($list as $language) : ?>
<?php if ($language->active) : ?>
<button id="language_btn_<?php echo $module->id; ?>" type="button" data-bs-toggle="dropdown" class="btn btn-secondary dropdown-toggle" aria-haspopup="listbox" aria-labelledby="language_picker_des_<?php echo $module->id; ?> language_btn_<?php echo $module->id; ?>" aria-expanded="false">
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
<?php endif; ?>
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
</button>
<?php endif; ?>
<?php endforeach; ?>
<ul aria-labelledby="language_picker_des_<?php echo $module->id; ?>" class="lang-block dropdown-menu">
<?php foreach ($list as $language) : ?>
<?php
$lbl = '';
if ($params->get('full_name') === 0) {
$lbl = 'aria-label="' . $language->title_native . '"';
}
?>
<?php if (!$language->active) : ?>
<li>
<a <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($language->link, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
<?php endif; ?>
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
</a>
</li>
<?php elseif ($params->get('show_active', 1)) : ?>
<?php $base = Uri::getInstance(); ?>
<li class="lang-active">
<a aria-current="true" <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($base, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
<?php if ($params->get('dropdownimage', 1) && ($language->image)) : ?>
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $params->get('full_name') ? '' : $language->title_native, null, true); ?>
<?php endif; ?>
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>
<?php else : ?>
<ul aria-labelledby="language_picker_des_<?php echo $module->id; ?>" class="mod-languages__list <?php echo $params->get('inline', 1) ? 'lang-inline' : 'lang-block'; ?>">
<?php foreach ($list as $language) : ?>
<?php
$lbl = '';
if ((($params->get('full_name') === 0) && ($params->get('image') === 0)) || (!$language->image)) {
$lbl = 'aria-label="' . $language->title_native . '"';
}
?>
<?php if (!$language->active) : ?>
<li>
<a <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($language->link, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
<?php if ($params->get('image', 1)) : ?>
<?php if ($language->image) : ?>
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $language->title_native, ['title' => $language->title_native], true); ?>
<?php else : ?>
<span class="label" title="<?php echo $language->title_native; ?>"><?php echo strtoupper($language->sef); ?></span>
<?php endif; ?>
<?php else : ?>
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
<?php endif; ?>
</a>
</li>
<?php elseif ($params->get('show_active', 1)) : ?>
<?php $base = Uri::getInstance(); ?>
<li class="lang-active">
<a aria-current="true" <?php echo $lbl; ?> href="<?php echo htmlspecialchars_decode(htmlspecialchars($base, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES); ?>">
<?php if ($params->get('image', 1)) : ?>
<?php if ($language->image) : ?>
<?php echo HTMLHelper::_('image', 'mod_languages/' . $language->image . '.gif', $language->title_native, ['title' => $language->title_native], true); ?>
<?php else : ?>
<span class="badge bg-secondary" title="<?php echo $language->title_native; ?>"><?php echo strtoupper($language->sef); ?></span>
<?php endif; ?>
<?php else : ?>
<?php echo $params->get('full_name', 1) ? $language->title_native : strtoupper($language->sef); ?>
<?php endif; ?>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ($footerText) : ?>
<div class="mod-languages__posttext posttext"><p><?php echo $footerText; ?></p></div>
<?php endif; ?>
</div>

View File

@ -0,0 +1,34 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_login
*
* @copyright (C) 2005 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\Factory;
use Joomla\CMS\Helper\AuthenticationHelper;
use Joomla\CMS\Helper\ModuleHelper;
use Joomla\Module\Login\Site\Helper\LoginHelper;
$params->def('greeting', 1);
// HTML IDs
$formId = 'login-form-' . $module->id;
$type = LoginHelper::getType();
$return = LoginHelper::getReturnUrl($params, $type);
$registerLink = LoginHelper::getRegistrationUrl($params);
$extraButtons = AuthenticationHelper::getLoginButtons($formId);
$user = Factory::getUser();
$layout = $params->get('layout', 'default');
// Logged users must load the logout sublayout
if (!$user->guest) {
$layout .= '_logout';
}
require ModuleHelper::getLayoutPath('mod_login', $layout);

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_login</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_LOGIN_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Login</namespace>
<files>
<filename module="mod_login">mod_login.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_login.ini</language>
<language tag="en-GB">language/en-GB/mod_login.sys.ini</language>
</languages>
<help key="Site_Modules:_Login" />
<config>
<fields name="params">
<fieldset name="basic" addfieldprefix="Joomla\Component\Menus\Administrator\Field">
<field
name="pretext"
type="textarea"
label="MOD_LOGIN_FIELD_PRE_TEXT_LABEL"
filter="safehtml"
cols="30"
rows="5"
/>
<field
name="posttext"
type="textarea"
label="MOD_LOGIN_FIELD_POST_TEXT_LABEL"
filter="safehtml"
cols="30"
rows="5"
/>
<field
name="login"
type="modal_menu"
label="MOD_LOGIN_FIELD_LOGIN_REDIRECTURL_LABEL"
description="MOD_LOGIN_FIELD_LOGIN_REDIRECTURL_DESC"
disable="separator,alias,heading,url"
select="true"
new="true"
edit="true"
clear="true"
>
<option value="">JOPTION_SELECT_MENU_ITEM</option>
</field>
<field
name="logout"
type="modal_menu"
label="MOD_LOGIN_FIELD_LOGOUT_REDIRECTURL_LABEL"
description="MOD_LOGIN_FIELD_LOGOUT_REDIRECTURL_DESC"
disable="separator,alias,heading,url"
select="true"
new="true"
edit="true"
clear="true"
>
<option value="">JOPTION_SELECT_MENU_ITEM</option>
</field>
<field
name="customRegLinkMenu"
type="modal_menu"
label="MOD_LOGIN_FIELD_REGISTRATION_MENU_LABEL"
disable="separator,alias,heading,url"
select="true"
new="true"
edit="true"
clear="true"
>
<option value="">JOPTION_SELECT_MENU_ITEM</option>
</field>
<field
name="greeting"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LOGIN_FIELD_GREETING_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="name"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LOGIN_FIELD_NAME_LABEL"
default="0"
filter="integer"
showon="greeting:1"
>
<option value="0">MOD_LOGIN_VALUE_NAME</option>
<option value="1">MOD_LOGIN_VALUE_USERNAME</option>
</field>
<field
name="profilelink"
type="radio"
label="MOD_LOGIN_FIELD_PROFILE_LABEL"
layout="joomla.form.field.radio.switcher"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="usetext"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_LOGIN_FIELD_USETEXT_LABEL"
default="0"
filter="integer"
>
<option value="0">MOD_LOGIN_VALUE_ICONS</option>
<option value="1">MOD_LOGIN_VALUE_TEXT</option>
</field>
</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"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,95 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_login
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Login\Site\Helper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Uri\Uri;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_login
*
* @since 1.5
*/
class LoginHelper
{
/**
* Retrieve the URL where the user should be returned after logging in
*
* @param \Joomla\Registry\Registry $params module parameters
* @param string $type return type
*
* @return string
*/
public static function getReturnUrl($params, $type)
{
$item = Factory::getApplication()->getMenu()->getItem($params->get($type));
// Stay on the same page
$url = Uri::getInstance()->toString();
if ($item) {
$lang = '';
if ($item->language !== '*' && Multilanguage::isEnabled()) {
$lang = '&lang=' . $item->language;
}
$url = 'index.php?Itemid=' . $item->id . $lang;
}
return base64_encode($url);
}
/**
* Returns the current users type
*
* @return string
*/
public static function getType()
{
$user = Factory::getUser();
return (!$user->get('guest')) ? 'logout' : 'login';
}
/**
* Retrieve the URL for the registration page
*
* @param \Joomla\Registry\Registry $params module parameters
*
* @return string
*/
public static function getRegistrationUrl($params)
{
$regLink = 'index.php?option=com_users&view=registration';
$regLinkMenuId = $params->get('customRegLinkMenu');
// If there is a custom menu item set for registration => override default
if ($regLinkMenuId) {
$item = Factory::getApplication()->getMenu()->getItem($regLinkMenuId);
if ($item) {
$regLink = 'index.php?Itemid=' . $regLinkMenuId;
if ($item->language !== '*' && Multilanguage::isEnabled()) {
$regLink .= '&lang=' . $item->language;
}
}
}
return $regLink;
}
}

View File

@ -0,0 +1,139 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_login
*
* @copyright (C) 2006 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\Component\ComponentHelper;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
$app->getDocument()->getWebAssetManager()
->useScript('core')
->useScript('keepalive')
->useScript('field.passwordview');
Text::script('JSHOWPASSWORD');
Text::script('JHIDEPASSWORD');
?>
<form id="login-form-<?php echo $module->id; ?>" class="mod-login" action="<?php echo Route::_('index.php', true); ?>" method="post">
<?php if ($params->get('pretext')) : ?>
<div class="mod-login__pretext pretext">
<p><?php echo $params->get('pretext'); ?></p>
</div>
<?php endif; ?>
<div class="mod-login__userdata userdata">
<div class="mod-login__username form-group">
<?php if (!$params->get('usetext', 0)) : ?>
<div class="input-group">
<input id="modlgn-username-<?php echo $module->id; ?>" type="text" name="username" class="form-control" autocomplete="username" placeholder="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
<label for="modlgn-username-<?php echo $module->id; ?>" class="visually-hidden"><?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?></label>
<span class="input-group-text" title="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
<span class="icon-user icon-fw" aria-hidden="true"></span>
</span>
</div>
<?php else : ?>
<label for="modlgn-username-<?php echo $module->id; ?>"><?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?></label>
<input id="modlgn-username-<?php echo $module->id; ?>" type="text" name="username" class="form-control" autocomplete="username" placeholder="<?php echo Text::_('MOD_LOGIN_VALUE_USERNAME'); ?>">
<?php endif; ?>
</div>
<div class="mod-login__password form-group">
<?php if (!$params->get('usetext', 0)) : ?>
<div class="input-group">
<input id="modlgn-passwd-<?php echo $module->id; ?>" type="password" name="password" autocomplete="current-password" class="form-control" placeholder="<?php echo Text::_('JGLOBAL_PASSWORD'); ?>">
<label for="modlgn-passwd-<?php echo $module->id; ?>" class="visually-hidden"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
<button type="button" class="btn btn-secondary input-password-toggle">
<span class="icon-eye icon-fw" aria-hidden="true"></span>
<span class="visually-hidden"><?php echo Text::_('JSHOWPASSWORD'); ?></span>
</button>
</div>
<?php else : ?>
<label for="modlgn-passwd-<?php echo $module->id; ?>"><?php echo Text::_('JGLOBAL_PASSWORD'); ?></label>
<input id="modlgn-passwd-<?php echo $module->id; ?>" type="password" name="password" autocomplete="current-password" class="form-control" placeholder="<?php echo Text::_('JGLOBAL_PASSWORD'); ?>">
<?php endif; ?>
</div>
<?php if (PluginHelper::isEnabled('system', 'remember')) : ?>
<div class="mod-login__remember form-group">
<div id="form-login-remember-<?php echo $module->id; ?>" class="form-check">
<input type="checkbox" name="remember" class="form-check-input" value="yes" id="form-login-input-remember-<?php echo $module->id; ?>">
<label class="form-check-label" for="form-login-input-remember-<?php echo $module->id; ?>">
<?php echo Text::_('MOD_LOGIN_REMEMBER_ME'); ?>
</label>
</div>
</div>
<?php endif; ?>
<?php foreach ($extraButtons as $button) :
$dataAttributeKeys = array_filter(array_keys($button), function ($key) {
return substr($key, 0, 5) == 'data-';
});
?>
<div class="mod-login__submit form-group">
<button type="button"
class="btn btn-secondary w-100 <?php echo $button['class'] ?? '' ?>"
<?php foreach ($dataAttributeKeys as $key) : ?>
<?php echo $key ?>="<?php echo $button[$key] ?>"
<?php endforeach; ?>
<?php if ($button['onclick']) : ?>
onclick="<?php echo $button['onclick'] ?>"
<?php endif; ?>
title="<?php echo Text::_($button['label']) ?>"
id="<?php echo $button['id'] ?>"
>
<?php if (!empty($button['icon'])) : ?>
<span class="<?php echo $button['icon'] ?>"></span>
<?php elseif (!empty($button['image'])) : ?>
<?php echo $button['image']; ?>
<?php elseif (!empty($button['svg'])) : ?>
<?php echo $button['svg']; ?>
<?php endif; ?>
<?php echo Text::_($button['label']) ?>
</button>
</div>
<?php endforeach; ?>
<div class="mod-login__submit form-group">
<button type="submit" name="Submit" class="btn btn-primary w-100"><?php echo Text::_('JLOGIN'); ?></button>
</div>
<?php
$usersConfig = ComponentHelper::getParams('com_users'); ?>
<ul class="mod-login__options list-unstyled">
<li>
<a href="<?php echo Route::_('index.php?option=com_users&view=reset'); ?>">
<?php echo Text::_('MOD_LOGIN_FORGOT_YOUR_PASSWORD'); ?></a>
</li>
<li>
<a href="<?php echo Route::_('index.php?option=com_users&view=remind'); ?>">
<?php echo Text::_('MOD_LOGIN_FORGOT_YOUR_USERNAME'); ?></a>
</li>
<?php if ($usersConfig->get('allowUserRegistration')) : ?>
<li>
<a href="<?php echo Route::_($registerLink); ?>">
<?php echo Text::_('MOD_LOGIN_REGISTER'); ?> <span class="icon-register" aria-hidden="true"></span></a>
</li>
<?php endif; ?>
</ul>
<input type="hidden" name="option" value="com_users">
<input type="hidden" name="task" value="user.login">
<input type="hidden" name="return" value="<?php echo $return; ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</div>
<?php if ($params->get('posttext')) : ?>
<div class="mod-login__posttext posttext">
<p><?php echo $params->get('posttext'); ?></p>
</div>
<?php endif; ?>
</form>

View File

@ -0,0 +1,47 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_login
*
* @copyright (C) 2006 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\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = \Joomla\CMS\Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->useScript('keepalive');
?>
<form class="mod-login-logout form-vertical" action="<?php echo Route::_('index.php', true); ?>" method="post" id="login-form-<?php echo $module->id; ?>">
<?php if ($params->get('greeting', 1)) : ?>
<div class="mod-login-logout__login-greeting login-greeting">
<?php if (!$params->get('name', 0)) : ?>
<?php echo Text::sprintf('MOD_LOGIN_HINAME', htmlspecialchars($user->get('name'), ENT_COMPAT, 'UTF-8')); ?>
<?php else : ?>
<?php echo Text::sprintf('MOD_LOGIN_HINAME', htmlspecialchars($user->get('username'), ENT_COMPAT, 'UTF-8')); ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ($params->get('profilelink', 0)) : ?>
<ul class="mod-login-logout__options list-unstyled">
<li>
<a href="<?php echo Route::_('index.php?option=com_users&view=profile'); ?>">
<?php echo Text::_('MOD_LOGIN_PROFILE'); ?></a>
</li>
</ul>
<?php endif; ?>
<div class="mod-login-logout__button logout-button">
<button type="submit" name="Submit" class="btn btn-primary"><?php echo Text::_('JLOGOUT'); ?></button>
<input type="hidden" name="option" value="com_users">
<input type="hidden" name="task" value="user.logout">
<input type="hidden" name="return" value="<?php echo $return; ?>">
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</form>

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2009 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\Module\Menu\Site\Helper\MenuHelper;
$list = MenuHelper::getList($params);
$base = MenuHelper::getBase($params);
$active = MenuHelper::getActive($params);
$default = MenuHelper::getDefault();
$active_id = $active->id;
$default_id = $default->id;
$path = $base->tree;
$showAll = $params->get('showAllChildren', 1);
$class_sfx = htmlspecialchars($params->get('class_sfx', ''), ENT_COMPAT, 'UTF-8');
if (!$list) {
return;
}
require ModuleHelper::getLayoutPath('mod_menu', $params->get('layout', 'default'));

View File

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_menu</name>
<author>Joomla! Project</author>
<creationDate>2004-07</creationDate>
<copyright>(C) 2005 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_MENU_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Menu</namespace>
<files>
<filename module="mod_menu">mod_menu.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_menu.ini</language>
<language tag="en-GB">language/en-GB/mod_menu.sys.ini</language>
</languages>
<help key="Site_Modules:_Menu" />
<config>
<fields name="params">
<fieldset name="basic" addfieldprefix="Joomla\Component\Menus\Administrator\Field">
<field
name="menutype"
type="menu"
label="MOD_MENU_FIELD_MENUTYPE_LABEL"
clientid="0"
/>
<field
name="base"
type="modal_menu"
label="MOD_MENU_FIELD_ACTIVE_LABEL"
select="true"
new="true"
edit="true"
clear="true"
filter="integer"
>
<option value="">JCURRENT</option>
</field>
<field
name="startLevel"
type="list"
label="MOD_MENU_FIELD_STARTLEVEL_LABEL"
default="1"
filter="integer"
validate="options"
>
<option value="1">J1</option>
<option value="2">J2</option>
<option value="3">J3</option>
<option value="4">J4</option>
<option value="5">J5</option>
<option value="6">J6</option>
<option value="7">J7</option>
<option value="8">J8</option>
<option value="9">J9</option>
<option value="10">J10</option>
</field>
<field
name="endLevel"
type="list"
label="MOD_MENU_FIELD_ENDLEVEL_LABEL"
default="0"
filter="integer"
validate="options"
>
<option value="0">JALL</option>
<option value="1">J1</option>
<option value="2">J2</option>
<option value="3">J3</option>
<option value="4">J4</option>
<option value="5">J5</option>
<option value="6">J6</option>
<option value="7">J7</option>
<option value="8">J8</option>
<option value="9">J9</option>
<option value="10">J10</option>
</field>
<field
name="showAllChildren"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_MENU_FIELD_ALLCHILDREN_LABEL"
default="1"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
</fieldset>
<fieldset name="advanced">
<field
name="tag_id"
type="text"
label="MOD_MENU_FIELD_TAG_ID_LABEL"
/>
<field
name="class_sfx"
type="text"
label="MOD_MENU_FIELD_CLASS_LABEL"
validate="CssIdentifier"
/>
<field
name="window_open"
type="text"
label="MOD_MENU_FIELD_TARGET_LABEL"
description="MOD_MENU_FIELD_TARGET_DESC"
/>
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="form-select"
default="_:default"
validate="moduleLayout"
/>
<field
name="moduleclass_sfx"
type="textarea"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
rows="3"
validate="CssIdentifier"
/>
<field
name="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="itemid"
>
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,241 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @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\Module\Menu\Site\Helper;
use Joomla\CMS\Cache\CacheControllerFactoryInterface;
use Joomla\CMS\Cache\Controller\OutputController;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_menu
*
* @since 1.5
*/
class MenuHelper
{
/**
* Get a list of the menu items.
*
* @param \Joomla\Registry\Registry &$params The module options.
*
* @return array
*
* @since 1.5
*/
public static function getList(&$params)
{
$app = Factory::getApplication();
$menu = $app->getMenu();
// Get active menu item
$base = self::getBase($params);
$levels = Factory::getUser()->getAuthorisedViewLevels();
asort($levels);
// Compose cache key
$cacheKey = 'menu_items' . $params . implode(',', $levels) . '.' . $base->id;
/** @var OutputController $cache */
$cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
->createCacheController('output', ['defaultgroup' => 'mod_menu']);
if ($cache->contains($cacheKey)) {
$items = $cache->get($cacheKey);
} else {
$path = $base->tree;
$start = (int) $params->get('startLevel', 1);
$end = (int) $params->get('endLevel', 0);
$showAll = $params->get('showAllChildren', 1);
$items = $menu->getItems('menutype', $params->get('menutype'));
$hidden_parents = [];
$lastitem = 0;
if ($items) {
$inputVars = $app->getInput()->getArray();
foreach ($items as $i => $item) {
$item->parent = false;
$itemParams = $item->getParams();
if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id && $itemParams->get('menu_show', 1) == 1) {
$items[$lastitem]->parent = true;
}
if (
($start && $start > $item->level)
|| ($end && $item->level > $end)
|| (!$showAll && $item->level > 1 && !\in_array($item->parent_id, $path))
|| ($start > 1 && !\in_array($item->tree[$start - 2], $path))
) {
unset($items[$i]);
continue;
}
// Exclude item with menu item option set to exclude from menu modules
if (($itemParams->get('menu_show', 1) == 0) || \in_array($item->parent_id, $hidden_parents)) {
$hidden_parents[] = $item->id;
unset($items[$i]);
continue;
}
$item->current = true;
foreach ($item->query as $key => $value) {
if (!isset($inputVars[$key]) || $inputVars[$key] !== $value) {
$item->current = false;
break;
}
}
$item->deeper = false;
$item->shallower = false;
$item->level_diff = 0;
if (isset($items[$lastitem])) {
$items[$lastitem]->deeper = ($item->level > $items[$lastitem]->level);
$items[$lastitem]->shallower = ($item->level < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - $item->level);
}
$lastitem = $i;
$item->active = false;
$item->flink = $item->link;
// Reverted back for CMS version 2.5.6
switch ($item->type) {
case 'separator':
break;
case 'heading':
// No further action needed.
break;
case 'url':
if ((strpos($item->link, 'index.php?') === 0) && (strpos($item->link, 'Itemid=') === false)) {
// If this is an internal Joomla link, ensure the Itemid is set.
$item->flink = $item->link . '&Itemid=' . $item->id;
}
break;
case 'alias':
$item->flink = 'index.php?Itemid=' . $itemParams->get('aliasoptions');
// Get the language of the target menu item when site is multilingual
if (Multilanguage::isEnabled()) {
$newItem = Factory::getApplication()->getMenu()->getItem((int) $itemParams->get('aliasoptions'));
// Use language code if not set to ALL
if ($newItem != null && $newItem->language && $newItem->language !== '*') {
$item->flink .= '&lang=' . $newItem->language;
}
}
break;
default:
$item->flink = 'index.php?Itemid=' . $item->id;
break;
}
if ((strpos($item->flink, 'index.php?') !== false) && strcasecmp(substr($item->flink, 0, 4), 'http')) {
$item->flink = Route::_($item->flink, true, $itemParams->get('secure'));
} else {
$item->flink = Route::_($item->flink);
}
// We prevent the double encoding because for some reason the $item is shared for menu modules and we get double encoding
// when the cause of that is found the argument should be removed
$item->title = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8', false);
$item->menu_icon = htmlspecialchars($itemParams->get('menu_icon_css', ''), ENT_COMPAT, 'UTF-8', false);
$item->anchor_css = htmlspecialchars($itemParams->get('menu-anchor_css', ''), ENT_COMPAT, 'UTF-8', false);
$item->anchor_title = htmlspecialchars($itemParams->get('menu-anchor_title', ''), ENT_COMPAT, 'UTF-8', false);
$item->anchor_rel = htmlspecialchars($itemParams->get('menu-anchor_rel', ''), ENT_COMPAT, 'UTF-8', false);
$item->menu_image = htmlspecialchars($itemParams->get('menu_image', ''), ENT_COMPAT, 'UTF-8', false);
$item->menu_image_css = htmlspecialchars($itemParams->get('menu_image_css', ''), ENT_COMPAT, 'UTF-8', false);
}
if (isset($items[$lastitem])) {
$items[$lastitem]->deeper = (($start ?: 1) > $items[$lastitem]->level);
$items[$lastitem]->shallower = (($start ?: 1) < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - ($start ?: 1));
}
}
$cache->store($items, $cacheKey);
}
return $items;
}
/**
* Get base menu item.
*
* @param \Joomla\Registry\Registry &$params The module options.
*
* @return object
*
* @since 3.0.2
*/
public static function getBase(&$params)
{
// Get base menu item from parameters
if ($params->get('base')) {
$base = Factory::getApplication()->getMenu()->getItem($params->get('base'));
} else {
$base = false;
}
// Use active menu item if no base found
if (!$base) {
$base = self::getActive($params);
}
return $base;
}
/**
* Get active menu item.
*
* @param \Joomla\Registry\Registry &$params The module options.
*
* @return object
*
* @since 3.0.2
*/
public static function getActive(&$params)
{
$menu = Factory::getApplication()->getMenu();
return $menu->getActive() ?: self::getDefault();
}
/**
* Get default menu item (home page) for current language.
*
* @return object
*/
public static function getDefault()
{
$menu = Factory::getApplication()->getMenu();
// Look for the home menu
if (Multilanguage::isEnabled()) {
return $menu->getDefault(Factory::getLanguage()->getTag());
}
return $menu->getDefault();
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2021 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;
HTMLHelper::_('bootstrap.collapse');
?>
<nav class="navbar navbar-expand-md" aria-label="<?php echo htmlspecialchars($module->title, ENT_QUOTES, 'UTF-8'); ?>">
<button class="navbar-toggler navbar-toggler-right" type="button" data-bs-toggle="collapse" data-bs-target="#navbar<?php echo $module->id; ?>" aria-controls="navbar<?php echo $module->id; ?>" aria-expanded="false" aria-label="<?php echo Text::_('MOD_MENU_TOGGLE'); ?>">
<span class="icon-menu" aria-hidden="true"></span>
</button>
<div class="collapse navbar-collapse" id="navbar<?php echo $module->id; ?>">
<?php require __DIR__ . '/default.php'; ?>
</div>
</nav>

View File

@ -0,0 +1,91 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2009 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;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $app->getDocument()->getWebAssetManager();
$wa->registerAndUseScript('mod_menu', 'mod_menu/menu.min.js', [], ['type' => 'module']);
$id = '';
if ($tagId = $params->get('tag_id', '')) {
$id = ' id="' . $tagId . '"';
}
// The menu class is deprecated. Use mod-menu instead
?>
<ul<?php echo $id; ?> class="mod-menu mod-list nav <?php echo $class_sfx; ?>">
<?php foreach ($list as $i => &$item) {
$itemParams = $item->getParams();
$class = 'nav-item item-' . $item->id;
if ($item->id == $default_id) {
$class .= ' default';
}
if ($item->id == $active_id || ($item->type === 'alias' && $itemParams->get('aliasoptions') == $active_id)) {
$class .= ' current';
}
if (in_array($item->id, $path)) {
$class .= ' active';
} elseif ($item->type === 'alias') {
$aliasToId = $itemParams->get('aliasoptions');
if (count($path) > 0 && $aliasToId == $path[count($path) - 1]) {
$class .= ' active';
} elseif (in_array($aliasToId, $path)) {
$class .= ' alias-parent-active';
}
}
if ($item->type === 'separator') {
$class .= ' divider';
}
if ($item->deeper) {
$class .= ' deeper';
}
if ($item->parent) {
$class .= ' parent';
}
echo '<li class="' . $class . '">';
switch ($item->type) :
case 'separator':
case 'component':
case 'heading':
case 'url':
require ModuleHelper::getLayoutPath('mod_menu', 'default_' . $item->type);
break;
default:
require ModuleHelper::getLayoutPath('mod_menu', 'default_url');
break;
endswitch;
// The next item is deeper.
if ($item->deeper) {
echo '<ul class="mod-menu__sub list-unstyled small">';
} elseif ($item->shallower) {
// The next item is shallower.
echo '</li>';
echo str_repeat('</ul></li>', $item->level_diff);
} else {
// The next item is on the same level.
echo '</li>';
}
}
?></ul>

View File

@ -0,0 +1,72 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2009 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\Filter\OutputFilter;
$attributes = [];
if ($item->anchor_title) {
$attributes['title'] = $item->anchor_title;
}
if ($item->anchor_css) {
$attributes['class'] = $item->anchor_css;
}
if ($item->anchor_rel) {
$attributes['rel'] = $item->anchor_rel;
}
if ($item->id == $active_id) {
$attributes['aria-current'] = 'location';
if ($item->current) {
$attributes['aria-current'] = 'page';
}
}
$linktype = $item->title;
if ($item->menu_icon) {
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
// If the icon itself is the link, it needs a visually hidden text
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
}
} elseif ($item->menu_image) {
// The link is an image, maybe with its own class
$image_attributes = [];
if ($item->menu_image_css) {
$image_attributes['class'] = $item->menu_image_css;
}
$linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
if ($itemParams->get('menu_text', 1)) {
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
if ($item->browserNav == 1) {
$attributes['target'] = '_blank';
} elseif ($item->browserNav == 2) {
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes';
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
}
echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2012 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;
$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
$anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
// If the icon itself is the link, it needs a visually hidden text
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
}
} elseif ($item->menu_image) {
// The link is an image, maybe with its own class
$image_attributes = [];
if ($item->menu_image_css) {
$image_attributes['class'] = $item->menu_image_css;
}
$linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
if ($itemParams->get('menu_text', 1)) {
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
?>
<span class="mod-menu__heading nav-header <?php echo $anchor_css; ?>"<?php echo $title; ?>><?php echo $linktype; ?></span>

View File

@ -0,0 +1,44 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2009 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;
$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
$anchor_css = $item->anchor_css ?: '';
$linktype = $item->title;
if ($item->menu_icon) {
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
// If the icon itself is the link, it needs a visually hidden text
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
}
} elseif ($item->menu_image) {
// The link is an image, maybe with its own class
$image_attributes = [];
if ($item->menu_image_css) {
$image_attributes['class'] = $item->menu_image_css;
}
$linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
if ($itemParams->get('menu_text', 1)) {
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
?>
<span class="mod-menu__separator separator <?php echo $anchor_css; ?>"<?php echo $title; ?>><?php echo $linktype; ?></span>

View File

@ -0,0 +1,69 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright (C) 2009 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\Filter\OutputFilter;
$attributes = [];
if ($item->anchor_title) {
$attributes['title'] = $item->anchor_title;
}
if ($item->anchor_css) {
$attributes['class'] = $item->anchor_css;
}
if ($item->anchor_rel) {
$attributes['rel'] = $item->anchor_rel;
}
$linktype = $item->title;
if ($item->menu_icon) {
// The link is an icon
if ($itemParams->get('menu_text', 1)) {
// If the link text is to be displayed, the icon is added with aria-hidden
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span>' . $item->title;
} else {
// If the icon itself is the link, it needs a visually hidden text
$linktype = '<span class="p-2 ' . $item->menu_icon . '" aria-hidden="true"></span><span class="visually-hidden">' . $item->title . '</span>';
}
} elseif ($item->menu_image) {
// The link is an image, maybe with an own class
$image_attributes = [];
if ($item->menu_image_css) {
$image_attributes['class'] = $item->menu_image_css;
}
$linktype = HTMLHelper::_('image', $item->menu_image, $item->title, $image_attributes);
if ($itemParams->get('menu_text', 1)) {
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
if ($item->browserNav == 1) {
$attributes['target'] = '_blank';
$attributes['rel'] = 'noopener noreferrer';
if ($item->anchor_rel == 'nofollow') {
$attributes['rel'] .= ' nofollow';
}
} elseif ($item->browserNav == 2) {
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
}
echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);

View File

@ -0,0 +1,21 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_random_image
*
* @copyright (C) 2005 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\Module\RandomImage\Site\Helper\RandomImageHelper;
$link = $params->get('link');
$folder = RandomImageHelper::getFolder($params);
$images = RandomImageHelper::getImages($params, $folder);
$image = RandomImageHelper::getRandomImage($params, $images);
require ModuleHelper::getLayoutPath('mod_random_image', $params->get('layout', 'default'));

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_random_image</name>
<author>Joomla! Project</author>
<creationDate>2006-07</creationDate>
<copyright>(C) 2006 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_RANDOM_IMAGE_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\RandomImage</namespace>
<files>
<filename module="mod_random_image">mod_random_image.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_random_image.ini</language>
<language tag="en-GB">language/en-GB/mod_random_image.sys.ini</language>
</languages>
<help key="Site_Modules:_Random_Image" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="type"
type="text"
label="MOD_RANDOM_IMAGE_FIELD_TYPE_LABEL"
default="jpg"
/>
<field
name="folder"
type="text"
label="MOD_RANDOM_IMAGE_FIELD_FOLDER_LABEL"
validate="filePath"
/>
<field
name="link"
type="text"
label="MOD_RANDOM_IMAGE_FIELD_LINK_LABEL"
/>
<field
name="width"
type="number"
label="MOD_RANDOM_IMAGE_FIELD_WIDTH_LABEL"
default="100"
filter="integer"
/>
<field
name="height"
type="number"
label="MOD_RANDOM_IMAGE_FIELD_HEIGHT_LABEL"
filter="integer"
/>
</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"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,143 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_random_image
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\RandomImage\Site\Helper;
use Joomla\CMS\Uri\Uri;
use Joomla\String\StringHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_random_image
*
* @since 1.5
*/
class RandomImageHelper
{
/**
* Retrieves a random image
*
* @param \Joomla\Registry\Registry &$params module parameters object
* @param array $images list of images
*
* @return mixed
*/
public static function getRandomImage(&$params, $images)
{
$width = $params->get('width', 100);
$height = $params->get('height', null);
$i = \count($images);
if ($i === 0) {
return null;
}
$random = mt_rand(0, $i - 1);
$image = $images[$random];
$size = getimagesize(JPATH_BASE . '/' . $image->folder . '/' . $image->name);
if ($size[0] < $width) {
$width = $size[0];
}
$coeff = $size[0] / $size[1];
if ($height === null) {
$height = (int) ($width / $coeff);
} else {
$newheight = min($height, (int) ($width / $coeff));
if ($newheight < $height) {
$height = $newheight;
} else {
$width = $height * $coeff;
}
}
$image->width = $width;
$image->height = $height;
$image->folder = str_replace('\\', '/', $image->folder);
return $image;
}
/**
* Retrieves images from a specific folder
*
* @param \Joomla\Registry\Registry &$params module params
* @param string $folder folder to get the images from
*
* @return array
*/
public static function getImages(&$params, $folder)
{
$type = $params->get('type', 'jpg');
$files = [];
$images = [];
$dir = JPATH_BASE . '/' . $folder;
// Check if directory exists
if (is_dir($dir)) {
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file !== '.' && $file !== '..' && $file !== 'CVS' && $file !== 'index.html') {
$files[] = $file;
}
}
}
closedir($handle);
$i = 0;
foreach ($files as $img) {
if (!is_dir($dir . '/' . $img) && preg_match('/' . $type . '/', $img)) {
$images[$i] = new \stdClass();
$images[$i]->name = $img;
$images[$i]->folder = $folder;
$i++;
}
}
}
return $images;
}
/**
* Get sanitized folder
*
* @param \Joomla\Registry\Registry &$params module params objects
*
* @return mixed
*/
public static function getFolder(&$params)
{
$folder = $params->get('folder');
$LiveSite = Uri::base();
// If folder includes livesite info, remove
if (StringHelper::strpos($folder, $LiveSite) === 0) {
$folder = str_replace($LiveSite, '', $folder);
}
// If folder includes absolute path, remove
if (StringHelper::strpos($folder, JPATH_SITE) === 0) {
$folder = str_replace(JPATH_BASE, '', $folder);
}
return str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $folder);
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_random_image
*
* @copyright (C) 2006 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;
if (!count($images)) {
echo Text::_('MOD_RANDOM_IMAGE_NO_IMAGES');
return;
}
?>
<div class="mod-randomimage random-image">
<?php if ($link) : ?>
<a href="<?php echo htmlspecialchars($link, ENT_QUOTES, 'UTF-8'); ?>">
<?php endif; ?>
<?php echo HTMLHelper::_('image', $image->folder . '/' . htmlspecialchars($image->name, ENT_COMPAT, 'UTF-8'), '', ['width' => $image->width, 'height' => $image->height]); ?>
<?php if ($link) : ?>
</a>
<?php endif; ?>
</div>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_related_items</name>
<author>Joomla! Project</author>
<creationDate>2004-07</creationDate>
<copyright>(C) 2005 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_RELATED_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\RelatedItems</namespace>
<files>
<folder module="mod_related_items">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_related_items.ini</language>
<language tag="en-GB">language/en-GB/mod_related_items.sys.ini</language>
</languages>
<help key="Site_Modules:_Articles_-_Related" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="showDate"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_RELATED_FIELD_SHOWDATE_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="maximum"
type="number"
label="MOD_RELATED_FIELD_MAX_LABEL"
default="5"
filter="integer"
min="1"
validate="number"
/>
</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_related_items
*
* @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 related 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\\RelatedItems'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\RelatedItems\\Site\\Helper'));
$container->registerServiceProvider(new Module());
}
};

View File

@ -0,0 +1,55 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_related_items
*
* @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\RelatedItems\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_popular
*
* @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'];
$cacheParams = new \stdClass();
$cacheParams->cachemode = 'safeuri';
$cacheParams->class = $this->getHelperFactory()->getHelper('RelatedItemsHelper');
$cacheParams->method = 'getRelatedArticles';
$cacheParams->methodparams = [$params, $data['app']];
$cacheParams->modeparams = ['id' => 'int', 'Itemid' => 'int'];
$data['list'] = ModuleHelper::moduleCache($this->module, $params, $cacheParams);
$data['showDate'] = $params->get('showDate', 0);
return $data;
}
}

View File

@ -0,0 +1,202 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_related_items
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\RelatedItems\Site\Helper;
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
use Joomla\Component\Content\Site\Helper\RouteHelper;
use Joomla\Component\Content\Site\Model\ArticlesModel;
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
use Joomla\Database\ParameterType;
use Joomla\Registry\Registry;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_related_items
*
* @since 1.5
*/
class RelatedItemsHelper implements DatabaseAwareInterface
{
use DatabaseAwareTrait;
/**
* Retrieve a list of related articles based on the metakey field
*
* @param Registry $params The module parameters.
* @param SiteApplication $app The current application.
*
* @return \stdClass[]
*
* @since 4.4.0
*/
public function getRelatedArticles(Registry $params, SiteApplication $app): array
{
$db = $this->getDatabase();
$input = $app->getInput();
$groups = $app->getIdentity()->getAuthorisedViewLevels();
$maximum = (int) $params->get('maximum', 5);
$factory = $app->bootComponent('com_content')->getMVCFactory();
// Get an instance of the generic articles model
/** @var ArticlesModel $articles */
$articles = $factory->createModel('Articles', 'Site', ['ignore_request' => true]);
// Set application parameters in model
$articles->setState('params', $app->getParams());
$option = $input->get('option');
$view = $input->get('view');
if (!($option === 'com_content' && $view === 'article')) {
return [];
}
$temp = $input->getString('id');
$temp = explode(':', $temp);
$id = (int) $temp[0];
$now = Factory::getDate()->toSql();
$related = [];
$query = $db->getQuery(true);
if ($id) {
// Select the meta keywords from the item
$query->select($db->quoteName('metakey'))
->from($db->quoteName('#__content'))
->where($db->quoteName('id') . ' = :id')
->bind(':id', $id, ParameterType::INTEGER);
$db->setQuery($query);
try {
$metakey = trim($db->loadResult());
} catch (\RuntimeException $e) {
$app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return [];
}
// Explode the meta keys on a comma
$keys = explode(',', $metakey);
$likes = [];
// Assemble any non-blank word(s)
foreach ($keys as $key) {
$key = trim($key);
if ($key) {
$likes[] = $db->escape($key);
}
}
if (\count($likes)) {
// Select other items based on the metakey field 'like' the keys found
$query->clear()
->select($db->quoteName('a.id'))
->from($db->quoteName('#__content', 'a'))
->where($db->quoteName('a.id') . ' != :id')
->where($db->quoteName('a.state') . ' = ' . ContentComponent::CONDITION_PUBLISHED)
->whereIn($db->quoteName('a.access'), $groups)
->bind(':id', $id, ParameterType::INTEGER);
$binds = [];
$wheres = [];
foreach ($likes as $keyword) {
$binds[] = '%' . $keyword . '%';
}
$bindNames = $query->bindArray($binds, ParameterType::STRING);
foreach ($bindNames as $keyword) {
$wheres[] = $db->quoteName('a.metakey') . ' LIKE ' . $keyword;
}
$query->extendWhere('AND', $wheres, 'OR')
->extendWhere('AND', [ $db->quoteName('a.publish_up') . ' IS NULL', $db->quoteName('a.publish_up') . ' <= :nowDate1'], 'OR')
->extendWhere(
'AND',
[
$db->quoteName('a.publish_down') . ' IS NULL',
$db->quoteName('a.publish_down') . ' >= :nowDate2',
],
'OR'
)
->bind([':nowDate1', ':nowDate2'], $now);
// Filter by language
if (Multilanguage::isEnabled()) {
$query->whereIn($db->quoteName('a.language'), [$app->getLanguage()->getTag(), '*'], ParameterType::STRING);
}
$query->setLimit($maximum);
$db->setQuery($query);
try {
$articleIds = $db->loadColumn();
} catch (\RuntimeException $e) {
$app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return [];
}
if (\count($articleIds)) {
$articles->setState('filter.article_id', $articleIds);
$articles->setState('filter.published', 1);
$related = $articles->getItems();
}
unset($articleIds);
}
}
if (\count($related)) {
// Prepare data for display using display options
foreach ($related as &$item) {
$item->slug = $item->id . ':' . $item->alias;
$item->route = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
}
}
return $related;
}
/**
* Get a list of related articles
*
* @param Registry &$params module parameters
*
* @return array
*
* @since 1.6
*
* @deprecated 4.4.0 will be removed in 6.0
* Use the non-static method getRelatedArticles
* Example: Factory::getApplication()->bootModule('mod_related_items', 'site')
* ->getHelper('RelatedItemsHelper')
* ->getRelatedArticles($params, Factory::getApplication())
*/
public static function getList(&$params)
{
/** @var SiteApplication $app */
$app = Factory::getApplication();
return (new self())->getRelatedArticles($params, $app);
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_related_items
*
* @copyright (C) 2006 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;
?>
<ul class="mod-relateditems relateditems mod-list">
<?php foreach ($list as $item) : ?>
<li>
<a href="<?php echo $item->route; ?>">
<?php if ($showDate) {
echo HTMLHelper::_('date', $item->created, Text::_('DATE_FORMAT_LC4')) . ' - ';
} ?>
<?php echo $item->title; ?></a>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,20 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_stats
*
* @copyright (C) 2005 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\Module\Stats\Site\Helper\StatsHelper;
$serverinfo = $params->get('serverinfo', 0);
$siteinfo = $params->get('siteinfo', 0);
$list = StatsHelper::getList($params);
require ModuleHelper::getLayoutPath('mod_stats', $params->get('layout', 'default'));

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_stats</name>
<author>Joomla! Project</author>
<creationDate>2004-07</creationDate>
<copyright>(C) 2005 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_STATS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Stats</namespace>
<files>
<filename module="mod_stats">mod_stats.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_stats.ini</language>
<language tag="en-GB">language/en-GB/mod_stats.sys.ini</language>
</languages>
<help key="Site_Modules:_Statistics" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="serverinfo"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_STATS_FIELD_SERVERINFO_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="siteinfo"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_STATS_FIELD_SITEINFO_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="counter"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_STATS_FIELD_COUNTER_LABEL"
default="0"
filter="integer"
>
<option value="0">JHIDE</option>
<option value="1">JSHOW</option>
</field>
<field
name="increase"
type="number"
label="MOD_STATS_FIELD_INCREASECOUNTER_LABEL"
default="0"
filter="integer"
/>
</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="cache"
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"
/>
<field
name="cachemode"
type="hidden"
default="static"
>
<option value="static"></option>
</field>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,161 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_stats
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Stats\Site\Helper;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_stats
*
* @since 1.5
*/
class StatsHelper
{
/**
* Get list of stats
*
* @param \Joomla\Registry\Registry &$params module parameters
*
* @return array
*/
public static function &getList(&$params)
{
$app = Factory::getApplication();
$db = Factory::getDbo();
$rows = [];
$query = $db->getQuery(true);
$serverinfo = $params->get('serverinfo', 0);
$siteinfo = $params->get('siteinfo', 0);
$counter = $params->get('counter', 0);
$increase = $params->get('increase', 0);
$i = 0;
if ($serverinfo) {
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_OS');
$rows[$i]->data = substr(php_uname(), 0, 7);
$i++;
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_PHP');
$rows[$i]->data = PHP_VERSION;
$i++;
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_($db->name);
$rows[$i]->data = $db->getVersion();
$i++;
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_TIME');
$rows[$i]->data = HTMLHelper::_('date', 'now', 'H:i');
$i++;
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_CACHING');
$rows[$i]->data = $app->get('caching') ? Text::_('JENABLED') : Text::_('JDISABLED');
$i++;
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_GZIP');
$rows[$i]->data = $app->get('gzip') ? Text::_('JENABLED') : Text::_('JDISABLED');
$i++;
}
if ($siteinfo) {
$query->select('COUNT(' . $db->quoteName('id') . ') AS count_users')
->from($db->quoteName('#__users'));
$db->setQuery($query);
try {
$users = $db->loadResult();
} catch (\RuntimeException $e) {
$users = false;
}
$query->clear()
->select('COUNT(' . $db->quoteName('c.id') . ') AS count_items')
->from($db->quoteName('#__content', 'c'))
->where($db->quoteName('c.state') . ' = ' . ContentComponent::CONDITION_PUBLISHED);
$db->setQuery($query);
try {
$items = $db->loadResult();
} catch (\RuntimeException $e) {
$items = false;
}
if ($users) {
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_USERS');
$rows[$i]->data = $users;
$i++;
}
if ($items) {
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_ARTICLES');
$rows[$i]->data = $items;
$i++;
}
}
if ($counter) {
$query->clear()
->select('SUM(' . $db->quoteName('hits') . ') AS count_hits')
->from($db->quoteName('#__content'))
->where($db->quoteName('state') . ' = ' . ContentComponent::CONDITION_PUBLISHED);
$db->setQuery($query);
try {
$hits = $db->loadResult();
} catch (\RuntimeException $e) {
$hits = false;
}
if ($hits) {
$rows[$i] = new \stdClass();
$rows[$i]->title = Text::_('MOD_STATS_ARTICLES_VIEW_HITS');
$rows[$i]->data = $hits + $increase;
$i++;
}
}
// Include additional data defined by published system plugins
PluginHelper::importPlugin('system');
$arrays = (array) $app->triggerEvent('onGetStats', ['mod_stats']);
foreach ($arrays as $response) {
foreach ($response as $row) {
// We only add a row if the title and data are given
if (isset($row['title']) && isset($row['data'])) {
$rows[$i] = new \stdClass();
$rows[$i]->title = $row['title'];
$rows[$i]->icon = $row['icon'] ?? 'info';
$rows[$i]->data = $row['data'];
$i++;
}
}
}
return $rows;
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_stats
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<ul class="mod-stats list-group">
<?php foreach ($list as $item) : ?>
<li class="list-group-item">
<?php echo $item->title; ?>
<span class="badge bg-secondary float-end rounded-pill"><?php echo $item->data; ?></span>
</li>
<?php endforeach; ?>
</ul>

View File

@ -0,0 +1,26 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_syndicate
*
* @copyright (C) 2006 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\Module\Syndicate\Site\Helper\SyndicateHelper;
$params->def('format', 'rss');
$link = SyndicateHelper::getLink($params, $app->getDocument());
if ($link === null) {
return;
}
$text = htmlspecialchars($params->get('text', ''), ENT_COMPAT, 'UTF-8');
require ModuleHelper::getLayoutPath('mod_syndicate', $params->get('layout', 'default'));

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_syndicate</name>
<author>Joomla! Project</author>
<creationDate>2006-05</creationDate>
<copyright>(C) 2006 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_SYNDICATE_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Syndicate</namespace>
<files>
<filename module="mod_syndicate">mod_syndicate.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_syndicate.ini</language>
<language tag="en-GB">language/en-GB/mod_syndicate.sys.ini</language>
</languages>
<help key="Site_Modules:_Syndication_Feeds" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="text"
type="text"
label="MOD_SYNDICATE_FIELD_TEXT_LABEL"
description="MOD_SYNDICATE_FIELD_TEXT_DESC"
/>
<field
name="display_text"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_SYNDICATE_FIELD_DISPLAYTEXT_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="format"
type="list"
label="MOD_SYNDICATE_FIELD_FORMAT_LABEL"
default="rss"
validate="options"
>
<option value="rss">MOD_SYNDICATE_FIELD_VALUE_RSS</option>
<option value="atom">MOD_SYNDICATE_FIELD_VALUE_ATOM</option>
</field>
</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"
/>
</fieldset>
</fields>
</config>
</extension>

View File

@ -0,0 +1,50 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_syndicate
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\Syndicate\Site\Helper;
use Joomla\CMS\Document\HtmlDocument;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_syndicate
*
* @since 1.5
*/
class SyndicateHelper
{
/**
* Gets the link
*
* @param Registry $params The module parameters
* @param HtmlDocument $document The document
*
* @return string|null The link as a string, if found
*
* @since 1.5
*/
public static function getLink(Registry $params, HtmlDocument $document)
{
foreach ($document->_links as $link => $value) {
$value = ArrayHelper::toString($value);
if (strpos($value, 'application/' . $params->get('format') . '+xml')) {
return $link;
}
}
return null;
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_syndicate
*
* @copyright (C) 2006 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;
$textClass = ($params->get('display_text', 1) ? '' : 'class="visually-hidden"');
$linkText = '<span class="icon-feed m-1" aria-hidden="true"></span>';
$linkText .= '<span ' . $textClass . '>' . (!empty($text) ? $text : Text::_('MOD_SYNDICATE_DEFAULT_FEED_ENTRIES')) . '</span>';
$attribs = [
'class' => 'mod-syndicate syndicate-module'
];
echo HTMLHelper::_('link', $link, $linkText, $attribs);

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_tags_popular
*
* @copyright (C) 2013 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;
$cacheparams = new \stdClass();
$cacheparams->cachemode = 'safeuri';
$cacheparams->class = 'Joomla\Module\TagsPopular\Site\Helper\TagsPopularHelper';
$cacheparams->method = 'getList';
$cacheparams->methodparams = $params;
$cacheparams->modeparams = ['id' => 'array', 'Itemid' => 'int'];
$list = ModuleHelper::moduleCache($module, $params, $cacheparams);
if (!\count($list) && !$params->get('no_results_text')) {
return;
}
$display_count = $params->get('display_count', 0);
require ModuleHelper::getLayoutPath('mod_tags_popular', $params->get('layout', 'default'));

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" client="site" method="upgrade">
<name>mod_tags_popular</name>
<author>Joomla! Project</author>
<creationDate>2013-01</creationDate>
<copyright>(C) 2013 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.1.0</version>
<description>MOD_TAGS_POPULAR_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\TagsPopular</namespace>
<files>
<filename module="mod_tags_popular">mod_tags_popular.php</filename>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">language/en-GB/mod_tags_popular.ini</language>
<language tag="en-GB">language/en-GB/mod_tags_popular.sys.ini</language>
</languages>
<help key="Site_Modules:_Tags_-_Popular" />
<config>
<fields name="params">
<fieldset name="basic">
<field
name="parentTag"
type="tag"
label="MOD_TAGS_POPULAR_PARENT_TAG_LABEL"
description="MOD_TAGS_POPULAR_PARENT_TAG_DESC"
multiple="true"
filter="intarray"
mode="nested"
/>
<field
name="maximum"
type="number"
label="MOD_TAGS_POPULAR_MAX_LABEL"
default="5"
filter="integer"
min="0"
validate="number"
/>
<field
name="timeframe"
type="list"
label="MOD_TAGS_POPULAR_FIELD_TIMEFRAME_LABEL"
default="alltime"
validate="options"
>
<option value="alltime">MOD_TAGS_POPULAR_FIELD_ALL_TIME</option>
<option value="hour">MOD_TAGS_POPULAR_FIELD_LAST_HOUR</option>
<option value="day">MOD_TAGS_POPULAR_FIELD_LAST_DAY</option>
<option value="week">MOD_TAGS_POPULAR_FIELD_LAST_WEEK</option>
<option value="month">MOD_TAGS_POPULAR_FIELD_LAST_MONTH</option>
<option value="year">MOD_TAGS_POPULAR_FIELD_LAST_YEAR</option>
</field>
<field
name="order_value"
type="list"
label="MOD_TAGS_POPULAR_FIELD_ORDER_VALUE_LABEL"
default="count"
validate="options"
>
<option value="title">MOD_TAGS_POPULAR_FIELD_ORDER_VALUE_TITLE</option>
<option value="count">MOD_TAGS_POPULAR_FIELD_ORDER_VALUE_COUNT</option>
<option value="rand()">MOD_TAGS_POPULAR_FIELD_ORDER_VALUE_RANDOM</option>
</field>
<field
name="order_direction"
type="list"
label="JGLOBAL_ORDER_DIRECTION_LABEL"
default="1"
filter="integer"
validate="options"
>
<option value="0">JGLOBAL_ORDER_ASCENDING</option>
<option value="1">JGLOBAL_ORDER_DESCENDING</option>
</field>
<field
name="display_count"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_TAGS_POPULAR_FIELD_DISPLAY_COUNT_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="no_results_text"
type="radio"
layout="joomla.form.field.radio.switcher"
label="MOD_TAGS_POPULAR_FIELD_NO_RESULTS_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
<fieldset
name="cloud"
label="MOD_TAGS_POPULAR_FIELDSET_CLOUD_LABEL"
>
<field
name="minsize"
type="number"
label="MOD_TAGS_POPULAR_FIELD_MINSIZE_LABEL"
description="MOD_TAGS_POPULAR_FIELD_MINSIZE_DESC"
default="1"
filter="float"
/>
<field
name="maxsize"
type="number"
label="MOD_TAGS_POPULAR_FIELD_MAXSIZE_LABEL"
description="MOD_TAGS_POPULAR_FIELD_MAXSIZE_DESC"
default="2"
filter="float"
/>
</fieldset>
<fieldset name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
class="form-select"
default="_:default"
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,191 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_tags_popular
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Module\TagsPopular\Site\Helper;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Helper for mod_tags_popular
*
* @since 3.1
*/
abstract class TagsPopularHelper
{
/**
* Get list of popular tags
*
* @param \Joomla\Registry\Registry &$params module parameters
*
* @return mixed
*
* @since 3.1
*/
public static function getList(&$params)
{
$db = Factory::getDbo();
$user = Factory::getUser();
$groups = $user->getAuthorisedViewLevels();
$timeframe = $params->get('timeframe', 'alltime');
$maximum = (int) $params->get('maximum', 5);
$order_value = $params->get('order_value', 'title');
$nowDate = Factory::getDate()->toSql();
$nullDate = $db->getNullDate();
$query = $db->getQuery(true)
->select(
[
'MAX(' . $db->quoteName('tag_id') . ') AS ' . $db->quoteName('tag_id'),
'COUNT(*) AS ' . $db->quoteName('count'),
'MAX(' . $db->quoteName('t.title') . ') AS ' . $db->quoteName('title'),
'MAX(' . $db->quoteName('t.access') . ') AS ' . $db->quoteName('access'),
'MAX(' . $db->quoteName('t.alias') . ') AS ' . $db->quoteName('alias'),
'MAX(' . $db->quoteName('t.params') . ') AS ' . $db->quoteName('params'),
'MAX(' . $db->quoteName('t.language') . ') AS ' . $db->quoteName('language'),
]
)
->group($db->quoteName(['tag_id', 't.title', 't.access', 't.alias']))
->from($db->quoteName('#__contentitem_tag_map', 'm'))
->whereIn($db->quoteName('t.access'), $groups);
// Only return published tags
$query->where($db->quoteName('t.published') . ' = 1 ');
// Filter by Parent Tag
$parentTags = $params->get('parentTag', []);
if ($parentTags) {
$query->whereIn($db->quoteName('t.parent_id'), $parentTags);
}
// Filter on category state
$query->join(
'INNER',
$db->quoteName('#__ucm_content', 'ucm'),
$db->quoteName('m.content_item_id') . ' = ' . $db->quoteName('ucm.core_content_item_id') .
' AND ' . $db->quoteName('m.type_id') . ' = ' . $db->quoteName('ucm.core_type_id')
);
$query->join(
'INNER',
$db->quoteName('#__categories', 'cat'),
$db->quoteName('ucm.core_catid') . ' = ' . $db->quoteName('cat.id')
);
$query->where($db->quoteName('cat.published') . ' > 0');
// Optionally filter on language
$language = ComponentHelper::getParams('com_tags')->get('tag_list_language_filter', 'all');
if ($language !== 'all') {
if ($language === 'current_language') {
$language = ContentHelper::getCurrentLanguage();
}
$query->whereIn($db->quoteName('t.language'), [$language, '*'], ParameterType::STRING);
}
if ($timeframe !== 'alltime') {
$query->where($db->quoteName('tag_date') . ' > ' . $query->dateAdd($db->quote($nowDate), '-1', strtoupper($timeframe)));
}
$query->join('INNER', $db->quoteName('#__tags', 't'), $db->quoteName('tag_id') . ' = ' . $db->quoteName('t.id'))
->join(
'INNER',
$db->quoteName('#__ucm_content', 'c'),
$db->quoteName('m.core_content_id') . ' = ' . $db->quoteName('c.core_content_id')
);
$query->where($db->quoteName('m.type_alias') . ' = ' . $db->quoteName('c.core_type_alias'));
// Only return tags connected to published and authorised items
$query->where($db->quoteName('c.core_state') . ' = 1')
->where(
'(' . $db->quoteName('c.core_access') . ' IN (' . implode(',', $query->bindArray($groups)) . ')'
. ' OR ' . $db->quoteName('c.core_access') . ' = 0)'
)
->where(
'(' . $db->quoteName('c.core_publish_up') . ' IS NULL'
. ' OR ' . $db->quoteName('c.core_publish_up') . ' = :nullDate2'
. ' OR ' . $db->quoteName('c.core_publish_up') . ' <= :nowDate2)'
)
->where(
'(' . $db->quoteName('c.core_publish_down') . ' IS NULL'
. ' OR ' . $db->quoteName('c.core_publish_down') . ' = :nullDate3'
. ' OR ' . $db->quoteName('c.core_publish_down') . ' >= :nowDate3)'
)
->bind([':nullDate2', ':nullDate3'], $nullDate)
->bind([':nowDate2', ':nowDate3'], $nowDate);
// Set query depending on order_value param
if ($order_value === 'rand()') {
$query->order($query->rand());
} else {
$order_direction = $params->get('order_direction', 1) ? 'DESC' : 'ASC';
if ($params->get('order_value', 'title') === 'title') {
// Backup bound parameters array of the original query
$bounded = $query->getBounded();
if ($maximum > 0) {
$query->setLimit($maximum);
}
$query->order($db->quoteName('count') . ' DESC');
$equery = $db->getQuery(true)
->select(
$db->quoteName(
[
'a.tag_id',
'a.count',
'a.title',
'a.access',
'a.alias',
'a.language',
]
)
)
->from('(' . (string) $query . ') AS ' . $db->quoteName('a'))
->order($db->quoteName('a.title') . ' ' . $order_direction);
$query = $equery;
// Rebind parameters
foreach ($bounded as $key => $obj) {
$query->bind($key, $obj->value, $obj->dataType);
}
} else {
$query->order($db->quoteName($order_value) . ' ' . $order_direction);
}
}
if ($maximum > 0) {
$query->setLimit($maximum);
}
$db->setQuery($query);
try {
$results = $db->loadObjectList();
} catch (\RuntimeException $e) {
$results = [];
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
return $results;
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* @package Joomla.Site
* @subpackage mod_tags_popular
*
* @copyright (C) 2013 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\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Tags\Site\Helper\RouteHelper;
$minsize = $params->get('minsize', 1);
$maxsize = $params->get('maxsize', 2);
?>
<div class="mod-tagspopular-cloud tagspopular tagscloud">
<?php
if (!count($list)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('MOD_TAGS_POPULAR_NO_ITEMS_FOUND'); ?>
</div>
<?php else :
// Find maximum and minimum count
$mincount = null;
$maxcount = null;
foreach ($list as $item) {
if ($mincount === null || $mincount > $item->count) {
$mincount = $item->count;
}
if ($maxcount === null || $maxcount < $item->count) {
$maxcount = $item->count;
}
}
$countdiff = $maxcount - $mincount;
foreach ($list as $item) :
if ($countdiff === 0) :
$fontsize = $minsize;
else :
$fontsize = $minsize + (($maxsize - $minsize) / $countdiff) * ($item->count - $mincount);
endif;
?>
<span class="tag">
<a class="tag-name" style="font-size: <?php echo $fontsize . 'em'; ?>" href="<?php echo Route::_(RouteHelper::getComponentTagRoute($item->tag_id . ':' . $item->alias, $item->language)); ?>">
<?php echo htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8'); ?></a>
<?php if ($display_count) : ?>
<span class="tag-count badge bg-info"><?php echo $item->count; ?></span>
<?php endif; ?>
</span>
<?php endforeach; ?>
<?php endif; ?>
</div>

Some files were not shown because too many files have changed in this diff Show More