Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions administrator/language/en-GB/mod_popular.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ MOD_POPULAR_FIELD_VALUE_ADDED_OR_MODIFIED_BY_ME="Added or modified by me"
MOD_POPULAR_FIELD_VALUE_ANYONE="Anyone"
MOD_POPULAR_FIELD_VALUE_NOT_ADDED_OR_MODIFIED_BY_ME="Not added or modified by me"
MOD_POPULAR_ITEMS="Popular Items"
; The following string is deprecated and will be removed with 7.0
MOD_POPULAR_NO_MATCHING_RESULTS="No Matching Results"
MOD_POPULAR_TITLE="Popular Articles"
MOD_POPULAR_TITLE_1="Top Popular Article"
Expand Down
49 changes: 0 additions & 49 deletions administrator/modules/mod_popular/mod_popular.php

This file was deleted.

2 changes: 1 addition & 1 deletion administrator/modules/mod_popular/mod_popular.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<description>MOD_POPULAR_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Module\Popular</namespace>
<files>
<filename module="mod_popular">mod_popular.php</filename>
<folder module="mod_popular">services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
Expand Down
41 changes: 41 additions & 0 deletions administrator/modules/mod_popular/services/provider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* @package Joomla.Administrator
* @subpackage mod_popular
*
* @copyright (C) 2025 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 latest articles module service provider.
*
* @since __DEPLOY_VERSION__
*/
return new class () implements ServiceProviderInterface {
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function register(Container $container)
{
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Popular'));
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Popular\\Administrator\\Helper'));

$container->registerServiceProvider(new Module());
}
};
59 changes: 59 additions & 0 deletions administrator/modules/mod_popular/src/Dispatcher/Dispatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* @package Joomla.Administrator
* @subpackage mod_popular
*
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

namespace Joomla\Module\Popular\Administrator\Dispatcher;

use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
use Joomla\Module\Popular\Administrator\Helper\PopularHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
* Dispatcher class for mod_popular
*
* @since __DEPLOY_VERSION__
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
use HelperFactoryAwareTrait;

/**
* Returns the layout data.
*
* @return array
*
* @since __DEPLOY_VERSION__
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
/** @var PopularHelper $helper */
$helper = $this->getHelperFactory()->getHelper('PopularHelper', $data);
$articleModel = $this
->getApplication()
->bootComponent('com_content')
->getMVCFactory()
->createModel('Articles', 'Administrator', ['ignore_request' => true]);

if ($data['params']->get('automatic_title', 0)) {
$data['module']->title = $helper->getModuleTitle($data['params']);
}

$data['list'] = $helper->getArticles($data['params'], $articleModel);
$data['record_hits'] = (int) ComponentHelper::getParams('com_content')->get('record_hits', 1);

return $data;
}
}
44 changes: 37 additions & 7 deletions administrator/modules/mod_popular/src/Helper/PopularHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

namespace Joomla\Module\Popular\Administrator\Helper;

use Joomla\CMS\Categories\Categories;
use Joomla\CMS\Factory;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Administrator\Model\ArticlesModel;
Expand All @@ -26,8 +25,35 @@
*
* @since 1.6
*/
abstract class PopularHelper
class PopularHelper
{
/**
* @var CMSApplicationInterface
*
* @since __DEPLOY_VERSION__
*/
protected $app;

/**
* @var Registry
*
* @since __DEPLOY_VERSION__
*/
protected $params;

/**
* Helper class constructor
*
* @param array $config Parameters we are using
*
* @since __DEPLOY_VERSION__
*/
public function __construct($config)
{
$this->app = $config['app'];
$this->params = $config['params'];
}

/**
* Get a list of the most popular articles.
*
Expand All @@ -37,10 +63,12 @@ abstract class PopularHelper
* @return mixed An array of articles, or false on error.
*
* @throws \Exception
*
* @since __DEPLOY_VERSION__
*/
public static function getList(Registry $params, ArticlesModel $model)
public function getArticles(Registry $params, ArticlesModel $model): mixed
{
$user = Factory::getApplication()->getIdentity();
$user = $this->app->getIdentity();

// Set List SELECT
$model->setState('list.select', 'a.id, a.title, a.checked_out, a.checked_out_time, ' .
Expand Down Expand Up @@ -102,15 +130,17 @@ public static function getList(Registry $params, ArticlesModel $model)
* @param Registry $params The module parameters.
*
* @return string The alternate title for the module.
*
* @since __DEPLOY_VERSION__
*/
public static function getTitle($params)
public function getModuleTitle(Registry $params): string
{
$who = $params->get('user_id', 0);
$catid = (int) $params->get('catid', null);
$title = '';

if ($catid) {
$category = Categories::getInstance('Content')->get($catid);
$category = $this->app->bootComponent('com_content')->getCategory()->get($catid);
$title = Text::_('MOD_POPULAR_UNEXISTING');

if ($category) {
Expand Down
100 changes: 57 additions & 43 deletions administrator/modules/mod_popular/tmpl/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,66 @@

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;

$moduleId = str_replace(' ', '', $module->title) . $module->id;

?>
<table class="table" id="<?php echo str_replace(' ', '', $module->title) . $module->id; ?>">
<caption class="visually-hidden"><?php echo $module->title; ?></caption>
<thead>
<tr>
<th scope="col" class="w-60"><?php echo Text::_('JGLOBAL_TITLE'); ?></th>
<th scope="col" class="w-20"><?php echo Text::_('JGLOBAL_HITS'); ?></th>
<th scope="col" class="w-20"><?php echo Text::_('JDATE'); ?></th>
</tr>
</thead>
<tbody>
<?php if (count($list)) : ?>
<?php foreach ($list as $i => $item) : ?>
<?php // Calculate popular items ?>
<?php $hits = (int) $item->hits; ?>
<?php $hits_class = ($hits >= 10000 ? 'danger' : ($hits >= 1000 ? 'warning' : ($hits >= 100 ? 'info' : 'secondary'))); ?>
<tr>
<th scope="row">
<?php if ($item->checked_out) : ?>
<?php echo HTMLHelper::_('jgrid.checkedout', $moduleId . $i, $item->editor, $item->checked_out_time); ?>
<?php endif; ?>
<?php if ($item->link) : ?>
<a href="<?php echo $item->link; ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>">
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
</a>
<?php else : ?>
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
<?php endif; ?>
</th>
<td>
<span class="badge bg-<?php echo $hits_class; ?>"><?php echo $item->hits; ?></span>
</td>
<td>
<?php echo HTMLHelper::_('date', $item->publish_up, Text::_('DATE_FORMAT_LC4')); ?>
</td>
</tr>
<?php endforeach; ?>
<?php if ($record_hits === 0) : ?>
<?php echo LayoutHelper::render('joomla.content.emptystate_module', [
'title' => 'JGLOBAL_RECORD_HITS_DISABLED',
'icon' => 'icon-minus-circle',
]); ?>
<?php else : ?>
<?php if (\count($list)) : ?>
<table class="table" id="<?php echo str_replace(' ', '', $module->title) . $module->id; ?>">
<caption class="visually-hidden"><?php echo $module->title; ?></caption>
<thead>
<tr>
<th scope="col" class="w-60"><?php echo Text::_('JGLOBAL_TITLE'); ?></th>
<th scope="col" class="w-20"><?php echo Text::_('JGLOBAL_HITS'); ?></th>
<th scope="col" class="w-20"><?php echo Text::_('JDATE'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($list as $i => $item) : ?>
<?php // Calculate popular items ?>
<?php $hits = (int) $item->hits; ?>
<?php $hits_class = ($hits >= 10000 ? 'danger' : ($hits >= 1000 ? 'warning' : ($hits >= 100 ? 'info' : 'secondary'))); ?>
<tr>
<th scope="row">
<?php if ($item->checked_out) : ?>
<?php echo HTMLHelper::_('jgrid.checkedout', $moduleId . $i, $item->editor, $item->checked_out_time); ?>
<?php endif; ?>
<?php if ($item->link) : ?>
<a href="<?php echo $item->link; ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>">
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
</a>
<?php else : ?>
<?php echo htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8'); ?>
<?php endif; ?>
</th>
<td>
<span class="badge bg-<?php echo $hits_class; ?>"><?php echo $item->hits; ?></span>
</td>
<td>
<?php echo HTMLHelper::_('date', $item->publish_up, Text::_('DATE_FORMAT_LC4')); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>

<?php else : ?>
<tr>
<td colspan="3">
<?php echo Text::_('MOD_POPULAR_NO_MATCHING_RESULTS'); ?>
</td>
</tr>
<?php
// If there are no articles to display, show empty state.
$app->getLanguage()->load('com_content');

echo LayoutHelper::render('joomla.content.emptystate_module', [
'textPrefix' => 'COM_CONTENT',
'icon' => 'icon-copy',
]);
?>

<?php endif; ?>
</tbody>
</table>
<?php endif; ?>