Vous utilisez FlexiContent et YOOtheme Pro sur Joomla 5, et l'éditeur admin refuse de s'ouvrir avec l'erreur Argument #1 ($id) must be of type int, null given dans ArticleHelper.php ? Un template bien configuré, un FlexiContent bien en place, et pourtant le Customizer plante au démarrage — voici pourquoi ça arrive et comment s'en sortir en deux étapes : correction SQL et patch de code expliqués pas à pas.
Le problème
Vous utilisez le composant FlexiContent pour gérer vos contenus Joomla, et vous avez installé le template YOOtheme Pro pour concevoir votre site. Tout fonctionne en frontend, mais dès que vous essayez d'ouvrir l'éditeur YOOtheme (le Customizer) depuis l'administration, vous obtenez cette erreur fatale :
Joomla\CMS\User\UserFactory::loadUserById():
Argument #1 ($id) must be of type int, null given,
called in .../templates/yootheme/packages/builder-joomla/src/ArticleHelper.php on line 32
La page du Customizer reste blanche ou affiche un écran d'erreur, impossible de modifier votre template. En revanche, si vous passez la source de contenu en Joomla Content natif, l'éditeur s'ouvre sans problème.
Pourquoi ça se produit
Contexte : ce que fait YOOtheme à l'ouverture du Customizer
Quand vous ouvrez le Customizer YOOtheme, le builder charge en arrière-plan une prévisualisation de votre page d'accueil (ou de la page cible). Pour détecter les modifications concurrentes (deux éditeurs travaillant simultanément sur le même article), YOOtheme appelle la méthode ArticleHelper::getCollision() dans le fichier :
/templates/yootheme/packages/builder-joomla/src/ArticleHelper.php
Cette méthode, à partir de la ligne 28, fait ceci :
public static function getCollision(object $article): array
{
$user = Factory::getContainer()
->get(UserFactoryInterface::class)
->loadUserById($article->modified_by); // ← ligne 32 : le crash
return [
'contentHash' => md5($article->fulltext . $article->introtext),
'modifiedBy' => $user->username ?: '',
];
}
Elle appelle loadUserById() en lui passant le champ modified_by de l'article, sans vérifier si cette valeur est NULL.
Pourquoi FlexiContent renvoie NULL
FlexiContent gère ses items dans #__content (la table d'articles standard de Joomla), mais il possède son propre système de versionning et de champs personnalisés. Contrairement à com_content qui force un modified_by valide à chaque enregistrement, FlexiContent ne remplit pas systématiquement ce champ. Les items créés par import, soumission frontend anonyme, ou script SQL peuvent donc avoir modified_by = NULL.
Pourquoi ça plante en Joomla 5 et pas avant
Depuis Joomla 5, la méthode UserFactory::loadUserById() est strictement typée :
public function loadUserById(int $id): User
Elle attend un int obligatoirement. En Joomla 4, la tolérance PHP sur le typage était plus souple. En Joomla 5 + PHP 8, passer NULL lève une TypeError fatale.
Résumé : FlexiContent ne remplit pas modified_by → YOOtheme le passe tel quel à loadUserById() → Joomla 5 rejette NULL → crash.
La solution en deux étapes
Étape 1 — Corriger les items en base de données
Connectez-vous à phpMyAdmin (ou votre client MySQL) et lancez ces requêtes.
Récupérez d'abord l'ID d'un Super User valide (remplacez le préfixe #__ par le vôtre) :
SELECT id, username FROM `#__users` WHERE block = 0 ORDER BY id;
Notez l'ID (ex. 62). Ensuite, corrigez les items FlexiContent fautifs en attribuant modified_by = created_by quand c'est possible, sinon votre ID Super User :
UPDATE `#__content` AS c
INNER JOIN `#__flexicontent_items_ext` AS fie ON fie.item_id = c.id
SET c.modified_by = IFNULL(NULLIF(c.created_by, 0), 62)
WHERE c.modified_by IS NULL OR c.modified_by = 0;
Et blindez created_by tant qu'on y est :
UPDATE `#__content` AS c
INNER JOIN `#__flexicontent_items_ext` AS fie ON fie.item_id = c.id
SET c.created_by = 62
WHERE c.created_by IS NULL OR c.created_by = 0;
Videz ensuite le cache Joomla : Système → Maintenance → Purger le cache expiré.
Étape 2 — Patcher le fichier ArticleHelper.php
La correction SQL règle le problème pour les items existants, mais tout nouvel item FlexiContent créé sans modified_by pourra déclencher à nouveau l'erreur. Il faut donc blinder le code YOOtheme lui-même.
Éditez le fichier (via FTP ou le gestionnaire de fichiers de votre hébergeur) :
/templates/yootheme/packages/builder-joomla/src/ArticleHelper.php
Remplacez tout le contenu du fichier par le code suivant :
<?php
namespace YOOtheme\Builder\Joomla;
use Joomla\CMS\Factory;
use Joomla\CMS\User\UserFactoryInterface;
class ArticleHelper
{
public const PATTERN = '/^<!--\s?(\{.*})\s?-->/';
public static function matchContent(?string $content): ?string
{
return str_contains((string) $content, '<!--') &&
preg_match(static::PATTERN, $content, $matches)
? $matches[1]
: null;
}
public static function getCollision(object $article): array
{
$modifiedBy = (int) ($article->modified_by ?? 0);
$username = '';
if ($modifiedBy > 0) {
$user = Factory::getContainer()
->get(UserFactoryInterface::class)
->loadUserById($modifiedBy);
$username = $user && $user->username ? $user->username : '';
}
return [
'contentHash' => md5(($article->fulltext ?? '') . ($article->introtext ?? '')),
'modifiedBy' => $username,
];
}
public static function isArticleView(): bool
{
$input = Factory::getApplication()->getInput();
$option = $input->getCmd('option');
$view = $input->getCmd('view');
$task = $input->getCmd('task', '');
return $option === 'com_content' && $view === 'article' && $task === '';
}
}
Ce qui change par rapport à l'original :
$modifiedByest casté en(int)et protégé par?? 0avant tout appelloadUserById()n'est appelé que si$modifiedBy > 0fulltextetintrotextsont protégés par?? ''car FlexiContent peut les laisser ànull, etmd5(null)est déprécié depuis PHP 8.1isArticleView()est décomposé en variables pour éviter les erreurs de copier-coller (guillemets typographiques, etc.)
⚠️ Attention : Ce patch est appliqué directement dans le dossier du template YOOtheme et sera écrasé à chaque mise à jour YOOtheme Pro. Notez-le dans votre suivi de maintenance et réappliquez-le après chaque mise à jour jusqu'à correction officielle par l'équipe YOOtheme.
Vérification
Après le patch, ouvrez le Customizer YOOtheme depuis l'administration. La prévisualisation doit s'afficher normalement, que votre page d'accueil soit alimentée par FlexiContent ou com_content.
Pour aller plus loin — Prévenir les nouveaux items sans auteur
Si vous permettez les soumissions frontend via FlexiContent (formulaire de dépôt d'articles pour les membres), vérifiez dans les paramètres du menu concerné que le champ "Item author for anonymous" pointe vers un ID utilisateur valide. Cela évitera que de nouveaux items se retrouvent sans created_by ni modified_by.
Article rédigé par Serge Billon — web54.fr |
Reproduction autorisée avec mention de la source.
