J'ai répliqué le module mod_article_category de Joomla 3.3.3 pour n'afficher qu'un seul article, filtré par son identifiant (que vous pouvez choisir dans un menu déroulant).
Mon code principal:
defined('_JEXEC') or die;
require_once __DIR__ . '/helper.php';
$article = ModArticleHelper::getArticle($params)[0];
require JModuleHelper::getLayoutPath('mod_article', $params->get('layout', 'default'));
Et mon code de template:
<?php defined('_JEXEC') or die;
$show_title = $params->get('show_title',true);
$h = $params->get('h','h3');
$class = htmlspecialchars($params->get('moduleclass_sfx'));
?>
<article class="<?= $class ?>">
<?php if($show_title){echo "<$h>$article->title</$h>";} ?>
<?= $article->introtext.$article->fulltext ?>
</article>
Si j'utilise ce module pour afficher un article dans une position de module, cela fonctionne. Le problème se pose lorsque j'ai plusieurs fois ce module. L'article affiché est toujours celui du dernier module ajouté et tous les paramètres spécifiques au module (comme afficher le titre de l'article) n'écoutent que le dernier module ajouté. Les paramètres du module dans tout le site (comme l’affichage du titre du module) NE DOIVENT PAS changer.
Pourquoi le module ne fonctionne-t-il pas à plusieurs postes?
CODE COMPLET (helper.php)
defined('_JEXEC') or die;
$com_path = JPATH_SITE . '/components/com_content/';
require_once $com_path . 'helpers/route.php';
JModelLegacy::addIncludePath($com_path . '/models', 'ContentModel');
abstract class ModArticleHelper{
public static function getArticle(&$params){
// Get an instance of the generic articles model
$articles = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true));
// Set application parameters in model
$app = JFactory::getApplication();
$appParams = $app->getParams();
$articles->setState('params', $appParams);
$articles->setState('filter.published', 1);
// Access filter
$access = !JComponentHelper::getParams('com_content')->get('show_noauth');
$authorised = JAccess::getAuthorisedViewLevels(JFactory::getUser()->get('id'));
$articles->setState('filter.access', $access);
// Item ID filter
$articles->setState('filter.id', $params->get('article_id', array()));
// Filter by language
$articles->setState('filter.language', $app->getLanguageFilter());
$items = $articles->getItems();
foreach ($items as &$item){
$item->slug = $item->id . ':' . $item->alias;
$item->catslug = $item->catid . ':' . $item->category_alias;
if ($access || in_array($item->access, $authorised)){
// We know that user has the privilege to view the article
$item->link = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catslug));
} else {
$item->link = JRoute::_('index.php?option=com_users&view=login');
}
}
return $items;
}
}
J'ai refait tout le code d'assistance (en moins de deux minutes) pour utiliser le code de base de données joomla natif au lieu des aides de composants. Le code complet de helper.php est maintenant:
defined('_JEXEC') or die;
$com_path = JPATH_SITE . '/components/com_content/';
//require_once $com_path . 'router.php';
require_once $com_path . 'helpers/route.php';
abstract class ModArticleHelper{
public static function getArticle(&$params){
$app = JFactory::getApplication();
$appParams = $app->getParams();
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('content.*,c.id as catid,c.alias as category_alias');
$query->from('#__content as content, #__categories as c');
$query->where('content.id = '.$params->get('article_id'));
$query->where('content.state = 1');
$query->where('content.catid = c.id');
$db->setQuery($query);
$items = $db->loadObjectList();
foreach ($items as &$item){
$item->slug = $item->id . ':' . $item->alias;
$item->catslug = $item->catid . ':' . $item->category_alias;
$item->link = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catslug));
}
return $items;
}
}
et il fonctionne!
ContentModelArticles dispose d'un cache interne.
ContentModelArticles-> getItems () => JModelList-> getItems (), ligne 155
public function getItems()
{
// Get a storage key.
$store = $this->getStoreId();
// Try to load the data from internal storage.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
Comme l'accès au cache est basé sur StoreId, vous devez définir un contexte différent pour chaque module. Par exemple. $ articles-> set ('context', 'mod_mymodule'. $ id);