URLs arbo non mise à jour au changement de rubrique
Etapes pour reproduire :
- Utiliser les URL arbos
- Créer un article "Lorem ipsum" dans la rubrique 1
- Publier l'article, son URL est /rubrique-1/lorem-ipsum
- Créer un article "Lorem ipsum" dans la rubrique 2
- Proposer l'article à la publication, son URL est /rubrique-2/lorem-ipsum
- Déplacer l'article dans la rubrique 1
- SPIP génère une erreur dans les logs :
2021-06-23 11:32:54 127.0.0.1 (pid 498) :Pri:ERREUR: Erreur 1062 de mysql: Duplicate entry '1-lorem-ipsum' for key 'PRIMARY' in .../plugins-dist/urls_etendues/action/editer_url.php L155 [sql_insertq(),url_insert(),declarer_url_arbo(),_generer_url_arbo(),urls_arbo_dist(),generer_url_entite(),html_af5c93b1e9d12543df40c819344ffc73(),public_parametrer_dist(),public_produire_page_dist(),inclure_page(),evaluer_fond(),recuperer_fond(),urls_afficher_fiche_objet(),minipipe(),execute_pipeline_afficher_fiche_objet(),pipeline(),f_afficher_blocs_ecrire(),f_recuperer_fond(),minipipe(),execute_pipeline_recuperer_fond(),pipeline(),recuperer_fond(),traiter_appels_inclusions_ajax()]
- Publier l'article
- L'URL du nouvel article est inchangée donc il est inaccessible (= son URL a déjà été "prise" par un autre)
Comportement attendu
Au changement de rubrique, URL arbos regénère une URL unique (avec l'ID donc).
Résolution temporaire
J'ai réglé ça de la manière suivante, via un plugin et la pipeline post_edition :
function plugin_post_edition($e) {
switch (objet_type($e['args']['table'])) {
case 'article';
if (!empty($e['data']['id_rubrique'])) {
$id_rubrique = intval($e['data']['id_rubrique']);
$id_article = intval($e['args']['id_objet']);
if ($url = sql_fetsel('url', 'spip_urls', "type = 'article' AND id_objet = $id_article", '', 'perma DESC, date DESC', '1')) {
$url = $url['url'];
if (sql_countsel('spip_urls', "url = ".sql_quote($url)." AND type = 'article' AND id_parent = $id_rubrique AND id_objet != $id_article")) {
sql_delete('spip_urls', "type = 'article' AND id_objet = $id_article AND url = ".sql_quote($url));
}
}
}
break;
default:
break;
}
return $e;
}
Ce n'est peut être pas élégant mais ça marche en attendant un fix :)