var Phenix = function () {
Troll du Web depuis 1996

PHP

Formidablement illisible...

J’ai trouvé ce bout de code dans le plugin formidable de SPIP, je cherchais un moyen d’exporter les réponses d’un formulaire.

Franchement comment savoir ce que contient $exporter ? Ça pourrait être n’importe quoi...
Je suis pas toujours super chaud pour mettre des fonctions dans des variables. S’il est possible de faire une structure de if ... else, je pense que c’est plus souhaitable. Bien sur, il y a beaucoup de cas ou c’est très pratique, mais ici, j’ai comme un doute.

  1. <?php
  2. if ($id_formulaire > 0
  3. and $type_export
  4. and $types_echange = echanges_formulaire_lister_disponibles()
  5. and $exporter = $types_echange['exporter'][$type_export]
  6. ){
  7. $exporter($id_formulaire);
  8. }

Trouver la traduction d’un objet #SPIP

Une fonction bien pratique quand on travaille avec des squelettes multilingues. Avant j’utilisais un assemblage de boucles et de critères, un peu illisible.

Cette fonction simplifie grandement le travail en retrouvant automatiquement une traduction en fonction d’un couple id_objet/objet.
Cela devrait fonctionner avec n’importe quel objet utilisant le système de traduction de SPIP.

  1. <?php
  2. /**
  3.  * Récupère la traduction d'un objet via la langue et l'id_objet
  4.  *
  5.  * @param int $id_objet
  6.  * @param string $objet
  7.  * @param string $lang
  8.  * @access public
  9.  * @return int
  10.  */
  11. function objet_trouver_traduction($id_objet, $objet, $lang) {
  12.  
  13. // Pas de lang, on sort
  14. if (!isset($lang)) {
  15. return $id_objet;
  16. }
  17.  
  18. // Table
  19. $table = table_objet_sql($objet);
  20. $cle_primaire = id_table_objet($objet);
  21. // On récupère l'éventuelle traduction
  22. $id_traduction = sql_getfetsel(
  23. $cle_primaire,
  24. $table,
  25. 'id_trad='.intval($id_objet),
  26. 'lang='.sql_quote($lang),
  27. 'statut='.sql_quote('publie')
  28. )
  29. );
  30.  
  31. return $id_traduction;
  32. }
  33.  
  34. function article_trouver_traduction($id_article, $lang) {
  35. return objet_trouver_traduction($id_article, 'article', $lang);
  36. }
  37.  
  38. // Si le plugin Traduction entre rubriques est activé
  39. // http://contrib.spip.net/Traduction-des-rubriques
  40. function rubrique_trouver_traduction($id_article, $lang) {
  41. return objet_trouver_traduction($id_article, 'rubrique', $lang);
  42. }

Je l’utilise surtout pour les liens directs dans les squelettes :

  1. <a href="#URL_ARTICLE{[(#EVAL{_ID_ARTICLE_CONTACT}|article_trouver_traduction{#ENV{lang}})]}" class="button large">
  2. Nous contacter
  3. </a>

Executer du code lorsqu’un utilisateur ce connecte sous SPIP

J’avais besoin d’exécuter un peu de code lorsqu’un utilisateur ce connecte à SPIP. Il y a un moyen assez simple de le faire : dans le traiter du formulaire login.

La connexion de l’utilisateur ce fait dans la partie vérifier du formulaire CVT. Cela veut dire que la session a été créé.

  1. function prefix_formulaire_traiter($flux) {
  2.  
  3. if ($flux['args']['form'] == 'login') {
  4. // Coder ici
  5. }
  6.  
  7. return $flux;
  8. }

Bien entendu je préfèrerai avoir un pipeline post_login, ce serai plus simple et plus lisible dans le code.
Cela viendra peut-être avec SPIP 3.2 !


Executer du code lorsqu’un inscription est validée sous SPIP

Ou comment avoir un pipeline post_inscription

Dans SPIP, il n’y a pas de pipeline post_inscription. Difficile donc d’exécuter facilement du code lorsque l’inscription est validé par l’utilisateur. Cela va peut être changé avec SPIP 3.2.

En attendant, voici un bricolage avec le pipeline post_edition :

  1. function prefix_post_edition($flux) {
  2.  
  3. // Confirmation d'une inscription
  4. if ($flux['args']['table'] == 'spip_auteurs'
  5. and $flux['args']['statut_ancien'] == 'nouveau'
  6. and $flux['args']['action'] == 'instituer'
  7. and $flux['data']['statut'] == '6forum' ) { // Limité aux visiteurs
  8. $id_auteur = $flux['args']['id_objet'];
  9. // Faire des trucs ici.
  10. }
  11.  
  12. return $flux;
  13. }

Contrôler les index des tableaux #SPIP

SPIP possède un mécanisme de tableau dans le compilateur. C’est plutôt rudimentaire et mériterait certainement plus d’attention de la part des développeurs.

Dans beaucoup de cas, ils sont de précieux alliés mais rapidement limités. On les abandonne généralement rapidement au profit d’une fonction php. Soit parce que le code devient illisible, soit parce qu’ils ne sont pas assez souples.

Cependant, il y a quand même moyen de faire des choses assez puissantes sans prise de tête particulière. L’installation de spip_bonux est indispensable, cela permet d’accéder aux balises #SET_PUSH et #SET_MERGE qui rendent le code plus lisible.

Un système de news par secteur ET par mots-clés

J’ai besoin d’afficher tous les articles d’un secteur mélangés avec les articles qui possèdent un mot-clé défini.
L’idée est de créer un module de « news » qui peut être enrichi par des articles qui ne seraient pas dans la rubrique « news ».
L’idée est simple : remplir un tableau a l’aide de deux boucles SPIP et puis l’afficher avec une boucle DATA.

  1. [(#REM) Initialiser le tableau ]
  2. [(#SET{news, #ARRAY})]
  3. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  4. [(#SET_PUSH{news, #ID_ARTICLE})]
  5. </BOUCLE_article>
  6.  
  7. [(#REM) Recherche sur le mot-clé "news" ]
  8. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  9. [(#SET_PUSH{news, #ID_ARTICLE})]
  10. </BOUCLE_mot>

#GET{news} contient maintenant 4 id_articles : les deux derniers articles du secteur 1 et les deux derniers articles possédant le mot-clé 42.

Mais comme c’est un système de news, il faut tirer l’affichage par date. Or, les données du tableau sont tirées par ordre de boucles : d’abord, les informations de la boucle article, ensuite les informations de la boucle d’article_mot.

En réalité, ce dont j’ai besoin, c’est de la possibilité de trier mon tableau par date une fois qu’il a été généré par les boucles. Il faut donc que je sauvegarde la date de l’article dans mon tableau.

  1. [(#REM) Initialiser le tableau ]
  2. [(#SET{news, #ARRAY})]
  3. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  4. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  5. </BOUCLE_article>
  6.  
  7. [(#REM) Recherche sur le mot-clé "news" ]
  8. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  9. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  10. </BOUCLE_mot>

Voilà, donc maintenant, #GET{news} est un tableau qui contient 4 tableaux à deux clés : id_article et date.

Ensuite, via une petite astuce php, on va utiliser une des deux valeurs comme clé pour recomposer un tableau. Rien de complexe, tout est dans PHP :

  1. [(#REM) Simplifier le tableau pour avoir id_article => date ]
  2. [(#SET{news, #GET{news}|array_column{date, id_article}})]

Array_column est une fonction PHP 5.5. Mais spip_bonux l’apporte au version inférieur.

Ensuite, il ne reste plus qu’à faire une boucle data triée par valeur.

Voici le code complet :

  1. [(#REM)
  2. On va calculer les news:
  3. - Soit cela se trouve dans le secteur des news
  4. - Soit il y a le mot-clé news
  5. ]
  6.  
  7. [(#REM) Initialiser le tableau ]
  8. [(#SET{news, #ARRAY})]
  9. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  10. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  11. </BOUCLE_article>
  12.  
  13. [(#REM) Recherche sur le mot-clé "news" ]
  14. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  15. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  16. </BOUCLE_mot>
  17.  
  18. [(#REM) Simplifier le tableau pour avoir id_article => date ]
  19. [(#SET{news, #GET{news}|array_column{date, id_article}})]
  20.  
  21. <section class="section-news">
  22. <span class="label article-section"><:titre_news:></span>
  23. [(#REM) Affichage de articles du tableau ]
  24. <B_data_news>
  25. <ul class="news-list">
  26. <BOUCLE_data_news(DATA){source tableau, #GET{news}}{par valeur}{inverse}{0,2}>
  27. <li><INCLURE{fond=inclure/article_resume, id_article=#CLE} /></li>
  28. </BOUCLE_data_news>
  29. </ul>
  30. </B_data_news>
  31. </section>