Skip to content

Commit 8646d15

Browse files
carlitorweblaoneoQuyTon
authored
Convert mod_articles_popular to new structure (#39539)
Co-authored-by: Allon Moritz <[email protected]> Co-authored-by: Quy <[email protected]>
1 parent 6554f62 commit 8646d15

File tree

6 files changed

+228
-78
lines changed

6 files changed

+228
-78
lines changed

modules/mod_articles_popular/mod_articles_popular.php

Lines changed: 0 additions & 27 deletions
This file was deleted.

modules/mod_articles_popular/mod_articles_popular.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<description>MOD_POPULAR_XML_DESCRIPTION</description>
1212
<namespace path="src">Joomla\Module\ArticlesPopular</namespace>
1313
<files>
14-
<filename module="mod_articles_popular">mod_articles_popular.php</filename>
14+
<folder module="mod_articles_popular">services</folder>
1515
<folder>src</folder>
1616
<folder>tmpl</folder>
1717
</files>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/**
4+
* @package Joomla.Site
5+
* @subpackage mod_articles_popular
6+
*
7+
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
8+
* @license GNU General Public License version 2 or later; see LICENSE.txt
9+
*/
10+
11+
defined('_JEXEC') or die;
12+
13+
use Joomla\CMS\Extension\Service\Provider\HelperFactory;
14+
use Joomla\CMS\Extension\Service\Provider\Module;
15+
use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory;
16+
use Joomla\DI\Container;
17+
use Joomla\DI\ServiceProviderInterface;
18+
19+
/**
20+
* The popular articles module service provider.
21+
*
22+
* @since __DEPLOY_VERSION__
23+
*/
24+
return new class implements ServiceProviderInterface
25+
{
26+
/**
27+
* Registers the service provider with a DI container.
28+
*
29+
* @param Container $container The DI container.
30+
*
31+
* @return void
32+
*
33+
* @since __DEPLOY_VERSION__
34+
*/
35+
public function register(Container $container)
36+
{
37+
$container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\ArticlesPopular'));
38+
$container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\ArticlesPopular\\Site\\Helper'));
39+
40+
$container->registerServiceProvider(new Module());
41+
}
42+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/**
4+
* @package Joomla.Site
5+
* @subpackage mod_articles_popular
6+
*
7+
* @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
8+
* @license GNU General Public License version 2 or later; see LICENSE.txt
9+
*/
10+
11+
namespace Joomla\Module\ArticlesPopular\Site\Dispatcher;
12+
13+
use Joomla\CMS\Component\ComponentHelper;
14+
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
15+
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
16+
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
17+
use Joomla\CMS\Language\Text;
18+
19+
// phpcs:disable PSR1.Files.SideEffects
20+
\defined('JPATH_PLATFORM') or die;
21+
// phpcs:enable PSR1.Files.SideEffects
22+
23+
/**
24+
* Dispatcher class for mod_articles_popular
25+
*
26+
* @since __DEPLOY_VERSION__
27+
*/
28+
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
29+
{
30+
use HelperFactoryAwareTrait;
31+
32+
/**
33+
* Returns the layout data.
34+
*
35+
* @return array
36+
*
37+
* @since __DEPLOY_VERSION__
38+
*/
39+
protected function getLayoutData()
40+
{
41+
$data = parent::getLayoutData();
42+
43+
if (!ComponentHelper::getParams('com_content')->get('record_hits', 1)) {
44+
$data['hitsDisabledMessage'] = Text::_('JGLOBAL_RECORD_HITS_DISABLED');
45+
} else {
46+
$data['list'] = $this->getHelperFactory()->getHelper('ArticlesPopularHelper', $data)->getArticles($data['params'], $data['app']);
47+
}
48+
49+
return $data;
50+
}
51+
}

modules/mod_articles_popular/src/Helper/ArticlesPopularHelper.php

Lines changed: 130 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@
1111
namespace Joomla\Module\ArticlesPopular\Site\Helper;
1212

1313
use Joomla\CMS\Access\Access;
14+
use Joomla\CMS\Application\SiteApplication;
15+
use Joomla\CMS\Cache\CacheControllerFactoryInterface;
16+
use Joomla\CMS\Cache\Controller\OutputController;
1417
use Joomla\CMS\Component\ComponentHelper;
1518
use Joomla\CMS\Factory;
1619
use Joomla\CMS\Router\Route;
1720
use Joomla\Component\Content\Administrator\Extension\ContentComponent;
1821
use Joomla\Component\Content\Site\Helper\RouteHelper;
22+
use Joomla\Component\Content\Site\Model\ArticlesModel;
23+
use Joomla\Database\DatabaseAwareInterface;
24+
use Joomla\Database\DatabaseAwareTrait;
25+
use Joomla\Registry\Registry;
1926

2027
// phpcs:disable PSR1.Files.SideEffects
2128
\defined('_JEXEC') or die;
@@ -24,78 +31,152 @@
2431
/**
2532
* Helper for mod_articles_popular
2633
*
27-
* @since 1.6
34+
* @since __DEPLOY_VERSION__
2835
*/
29-
abstract class ArticlesPopularHelper
36+
class ArticlesPopularHelper
3037
{
3138
/**
32-
* Get a list of popular articles from the articles model
39+
* The module instance
3340
*
34-
* @param \Joomla\Registry\Registry &$params object holding the models parameters
41+
* @var \stdClass
3542
*
36-
* @return mixed
43+
* @since __DEPLOY_VERSION__
3744
*/
38-
public static function getList(&$params)
45+
protected $module;
46+
47+
/**
48+
* Constructor.
49+
*
50+
* @param array $config An optional associative array of configuration settings.
51+
*
52+
* @since __DEPLOY_VERSION__
53+
*/
54+
public function __construct($config = [])
55+
{
56+
$this->module = $config['module'];
57+
}
58+
59+
/**
60+
* Retrieve a list of months with archived articles
61+
*
62+
* @param Registry $params The module parameters.
63+
* @param SiteApplication $app The current application.
64+
*
65+
* @return object[]
66+
*
67+
* @since __DEPLOY_VERSION__
68+
*/
69+
public function getArticles(Registry $moduleParams, SiteApplication $app)
3970
{
40-
$app = Factory::getApplication();
71+
$cacheKey = md5(serialize([$moduleParams->toString(), $this->module->module, $this->module->id]));
4172

42-
// Get an instance of the generic articles model
43-
$model = $app->bootComponent('com_content')
44-
->getMVCFactory()->createModel('Articles', 'Site', ['ignore_request' => true]);
73+
/** @var OutputController $cache */
74+
$cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)
75+
->createCacheController('output', ['defaultgroup' => 'mod_articles_popular']);
4576

46-
// Set application parameters in model
47-
$appParams = $app->getParams();
48-
$model->setState('params', $appParams);
77+
if (!$cache->contains($cacheKey)) {
78+
$mvcContentFactory = $app->bootComponent('com_content')->getMVCFactory();
4979

50-
$model->setState('list.start', 0);
51-
$model->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
80+
/** @var ArticlesModel $articlesModel */
81+
$articlesModel = $mvcContentFactory->createModel('Articles', 'Site', ['ignore_request' => true]);
5282

53-
// Set the filters based on the module params
54-
$model->setState('list.limit', (int) $params->get('count', 5));
55-
$model->setState('filter.featured', $params->get('show_front', 1) == 1 ? 'show' : 'hide');
83+
// Set application parameters in model
84+
$appParams = $app->getParams();
85+
$articlesModel->setState('params', $appParams);
5686

57-
// This module does not use tags data
58-
$model->setState('load_tags', false);
87+
$articlesModel->setState('list.start', 0);
88+
$articlesModel->setState('filter.published', ContentComponent::CONDITION_PUBLISHED);
5989

60-
// Access filter
61-
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
62-
$authorised = Access::getAuthorisedViewLevels(Factory::getUser()->get('id'));
63-
$model->setState('filter.access', $access);
90+
// Set the filters based on the module params
91+
$articlesModel->setState('list.limit', (int) $moduleParams->get('count', 5));
92+
$articlesModel->setState('filter.featured', $moduleParams->get('show_front', 1) == 1 ? 'show' : 'hide');
6493

65-
// Category filter
66-
$model->setState('filter.category_id', $params->get('catid', []));
94+
// This module does not use tags data
95+
$articlesModel->setState('load_tags', false);
6796

68-
// Date filter
69-
$date_filtering = $params->get('date_filtering', 'off');
97+
// Access filter
98+
$access = !ComponentHelper::getParams('com_content')->get('show_noauth');
99+
$articlesModel->setState('filter.access', $access);
70100

71-
if ($date_filtering !== 'off') {
72-
$model->setState('filter.date_filtering', $date_filtering);
73-
$model->setState('filter.date_field', $params->get('date_field', 'a.created'));
74-
$model->setState('filter.start_date_range', $params->get('start_date_range', '1000-01-01 00:00:00'));
75-
$model->setState('filter.end_date_range', $params->get('end_date_range', '9999-12-31 23:59:59'));
76-
$model->setState('filter.relative_date', $params->get('relative_date', 30));
77-
}
101+
// Category filter
102+
$articlesModel->setState('filter.category_id', $moduleParams->get('catid', []));
78103

79-
// Filter by language
80-
$model->setState('filter.language', $app->getLanguageFilter());
104+
// Date filter
105+
$date_filtering = $moduleParams->get('date_filtering', 'off');
81106

82-
// Ordering
83-
$model->setState('list.ordering', 'a.hits');
84-
$model->setState('list.direction', 'DESC');
107+
if ($date_filtering !== 'off') {
108+
$articlesModel->setState('filter.date_filtering', $date_filtering);
109+
$articlesModel->setState('filter.date_field', $moduleParams->get('date_field', 'a.created'));
110+
$articlesModel->setState('filter.start_date_range', $moduleParams->get('start_date_range', '1000-01-01 00:00:00'));
111+
$articlesModel->setState('filter.end_date_range', $moduleParams->get('end_date_range', '9999-12-31 23:59:59'));
112+
$articlesModel->setState('filter.relative_date', $moduleParams->get('relative_date', 30));
113+
}
114+
115+
// Filter by language
116+
$articlesModel->setState('filter.language', $app->getLanguageFilter());
117+
118+
// Ordering
119+
$articlesModel->setState('list.ordering', 'a.hits');
120+
$articlesModel->setState('list.direction', 'DESC');
85121

86-
$items = $model->getItems();
122+
// Prepare the module output
123+
$items = [];
124+
$itemParams = new \stdClass();
87125

88-
foreach ($items as &$item) {
89-
$item->slug = $item->id . ':' . $item->alias;
126+
$itemParams->authorised = Access::getAuthorisedViewLevels($app->getIdentity()->get('id'));
127+
$itemParams->access = $access;
90128

91-
if ($access || \in_array($item->access, $authorised)) {
92-
// We know that user has the privilege to view the article
93-
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
94-
} else {
95-
$item->link = Route::_('index.php?option=com_users&view=login');
129+
foreach ($articlesModel->getItems() as $item) {
130+
$items[] = $this->prepareItem($item, $itemParams);
96131
}
132+
133+
// Cache the output and return
134+
$cache->store($items, $cacheKey);
135+
136+
return $items;
97137
}
98138

99-
return $items;
139+
// Return the cached output
140+
return $cache->get($cacheKey);
141+
}
142+
143+
/**
144+
* Prepare the article before render.
145+
*
146+
* @param object $item The article to prepare
147+
* @param \stdClass $params The model item
148+
*
149+
* @return object
150+
*
151+
* @since __DEPLOY_VERSION__
152+
*/
153+
private function prepareItem($item, $params): object
154+
{
155+
$item->slug = $item->id . ':' . $item->alias;
156+
157+
if ($params->access || \in_array($item->access, $params->authorised)) {
158+
// We know that user has the privilege to view the article
159+
$item->link = Route::_(RouteHelper::getArticleRoute($item->slug, $item->catid, $item->language));
160+
} else {
161+
$item->link = Route::_('index.php?option=com_users&view=login');
162+
}
163+
164+
return $item;
165+
}
166+
167+
/**
168+
* Get a list of popular articles from the articles model
169+
*
170+
* @param \Joomla\Registry\Registry &$params object holding the models parameters
171+
*
172+
* @return mixed
173+
*
174+
* @since __DEPLOY_VERSION__
175+
*
176+
* @deprecated 5.0 Use the none static function getArticles
177+
*/
178+
public static function getList(&$params)
179+
{
180+
return (new self())->getArticles($params, Factory::getApplication());
100181
}
101182
}

modules/mod_articles_popular/tmpl/default.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
defined('_JEXEC') or die;
1212

13-
if (!$list) {
13+
if (!isset($list)) {
14+
if (isset($hitsDisabledMessage)) {
15+
echo $hitsDisabledMessage;
16+
}
1417
return;
1518
}
1619

0 commit comments

Comments
 (0)