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

SPIP

Truc et astuce autour du CMS SPIP. Je travail depuis 2012 avec ce CMS dont j’apprécie l’ouverture et la communauté.

Executer du code lorsqu’un article #SPIP est publié

Petit pipeline SPIP cool : quand un article SPIP est publié, on exécute le code.

Pratique par exemple pour envoyer une notification spéciale.

  1. <?php
  2. function prefix_post_edition($flux) {
  3.         if ($flux['args']['table'] == table_objet_sql('article')
  4.                 and $flux['args']['action'] == 'instituer'
  5.                 and $flux['args']['statut_ancien'] != 'publie'
  6.                 and $flux['data']['statut'] == 'publie'
  7.         ) {
  8.                 $id_article = $flux['args']['id_objet'];
  9.                 // Coder ici !
  10. }

Autoriser un auteur s’il est présent dans la zone d’une rubrique #SPIP (acces restreint)

Une petite fonction d’autorisation sympas : autoriser un auteur (peu importe son statut) à publier dans une rubrique, s’il est dans la zone de cette rubrique. :

  1. <?php
  2. function autoriser_accesrestreint_publiedans($faire, $type, $id, $qui, $opt) {
  3.         include_spip('accesrestreint_fonctions');
  4.         // On récupère les zones de la rubrique
  5.         $zones = accesrestreint_zones_rubrique_et_hierarchie($id);
  6.         foreach ($zones as $zone) {
  7.                 // Est-ce que l'auteur appartient à la zone ?
  8.                 if (accesrestreint_acces_zone($zone, $qui['id_auteur'])) {
  9.                         return true;
  10.                 }
  11.         }
  12.  
  13.         return false;
  14. }

Ensuite, on peut surcharger les autorisations de SPIP pour qu’elles tiennent compte de cette fonction :

  1. <?php
  2. /**
  3.  * Surcharge de l'autorisation de publication dans les rubriques. On va prendre
  4.  * en compte l'accès restreint. Si un auteur est dans la zone de la rubrique, on
  5.  * l'autorise à publier
  6.  */
  7. function autoriser_rubrique_publierdans($faire, $type, $id, $qui, $opt) {
  8.         if (autoriser('publiedans', 'accesrestreint', $id, $qui, $opt)) {
  9.                 return true;
  10.         }
  11.  
  12.         return autoriser_rubrique_publierdans_dist($faire, $type, $id, $qui, $opt);
  13. }
  14.  
  15. /**
  16.  * Surcharge de l'autorisation de création d'article pour prendre en compte
  17.  * l'autorisation d'accesrestreint
  18.  */
  19. function autoriser_rubrique_creerarticledans($faire, $type, $id, $qui, $opt) {
  20.  
  21.         if (autoriser('publiedans', 'accesrestreint', $id, $qui, $opt)) {
  22.                 return true;
  23.         }
  24.  
  25.         return autoriser_rubrique_creerarticledans_dist($faire, $type, $id, $qui, $opt);
  26. }

Trouver toutes les rubriques enfants d’une rubrique #SPIP

[Edit] : Comme signalé dans un commentaire, il existe bien une fonction native qui s’occupe de cela.

Il est parfois intéressant d’avoir la liste complètes des sous-rubriques d’une rubrique.

Par exemple, pour conditionner l’affichage d’un élément à une rubrique et tous ces enfants.

Il n’existe pas de fonction SPIP pour faire cela (ou en tout cas je ne l’ai pas trouvée). Voici donc un peu de code pour régler le problème.
C’est un collègue qui est à l’origine de cette fonction, je l’ai adaptée.

Attention, il faut PHP >= 5.5 ou installer le plugin SPIP bonux, à cause de la fonction array_column.

  1. /**
  2.  * Retrouver les enfants directs d'une rubrique.
  3.  *
  4.  * @param int $id_rubrique
  5.  * @access public
  6.  * @return array tableau contenant les id_rubrique direct.
  7.  */
  8. function trouver_enfant($id_rubrique) {
  9.         include_spip('base/abstract_sql');
  10.         $sous_rubriques = sql_allfetsel('id_rubrique', 'spip_rubriques', 'id_parent='.intval($id_rubrique));
  11.         return array_column($sous_rubriques, 'id_rubrique');
  12. }
  13.  
  14. /**
  15.  * Trouver les sous-rubriques d'une rubrique.
  16.  *
  17.  * @param int $id_rubrique l'id de la rubrique
  18.  * @return array une liste d'id_rubrique
  19.  */
  20. function trouver_enfants($id_rubrique) {
  21.  
  22.         // Trouver la première série de sous-rubrique.
  23.         $sous_rubriques = trouver_enfant($id_rubrique);
  24.  
  25.         // S'il n'y a pas de sous rubriques, on sort de la boucle avec juste la rubrique de base
  26.         if (count($sous_rubriques) === 0) {
  27.                 return array($id_rubrique);
  28.         } else {
  29.                 // On cherche en profondeur.
  30.                 foreach ($sous_rubriques as $id_sous_rubrique) {
  31.                         $recur = trouver_enfant($id_sous_rubrique);
  32.  
  33.                         // Il y a des enfants, on les ajoute à la liste des sous rubrique
  34.                         // déjà trouvée.
  35.                         if ($recur) {
  36.                                 $sous_rubriques = array_merge($sous_rubriques, $recur);
  37.                         }
  38.                 }
  39.  
  40.                 // Placer la rubrique initiale en première position.
  41.                 array_unshift($sous_rubriques, $id_rubrique);
  42.  
  43.                 return $sous_rubriques;
  44.         }
  45. }

Formulaire générique d’édition de méta #SPIP

L’idée derrière ce formulaire est assez simple, pouvoir gérer n’importe quelle valeur de la table spip_metas et la modifiée. Si elle n’existe pas, la méta sera crée.

Il convient de prendre en compte qu’il y a 2 types de méta dans spip :

  • les métas simples, le casier ne contient qu’une seul valeur .
  • les métas plus complexent qui sont des tableaux php sérialisé.

Cela couvre un besoin similaire à Identité Extra, mais de manière plus générique.

L’idée finale serait d’avoir un plugin de gestion des métas du site (et donc des options des plugins) plus générique et plus facile d’accès. Je trouve qu’il pourrait être plus simple de déclarer des options de plugin sans avoir a déclaré systématiquement un CVT complet.

Fichier formulaires/editer_meta.html :

  1. <div class="formulaire_spip formulaire_#FORM">
  2.  
  3.         [<p class="reponse_formulaire reponse_formulaire_erreur">
  4.     (#ENV*{message_erreur})
  5.         </p>]
  6.         [<p class="reponse_formulaire reponse_formulaire_ok">
  7.                 (#ENV*{message_ok})
  8.         </p>]
  9.  
  10.         [(#EDITABLE|oui)
  11.     <form action="#ENV{action}" method="post">
  12.                 #ACTION_FORMULAIRE{#ENV{action}}
  13.  
  14.                 #GENERER_SAISIES{#ENV{_saisies}}
  15.  
  16.                 <p class="boutons">
  17.                         <input type="submit" class="submit" value="<:pass_ok:>" />
  18.                 </p>
  19.     </form>
  20.         ]
  21. </div>

fichier formulaires/editer_meta.php :

  1. <?php
  2.  
  3. if (!defined('_ECRIRE_INC_VERSION')) {
  4.         return;
  5. }
  6.  
  7. /**
  8.  * Fonction saisie pour le formulaire d'édition générique de méta
  9.  *
  10.  * @param string $casier nom du meta casier
  11.  * @param string $meta nom de l'éventuel sous-méta
  12.  * @param array $options tableau d'options :
  13.  *
  14.  * ```php
  15.  * $options_defaut = array(
  16.  *              'type_saisie' => 'input',
  17.  *              'label' => 'label'
  18.  * );
  19.  * ```
  20.  *
  21.  * @access public
  22.  * @return array
  23.  */
  24. function formulaires_editer_meta_saisies_dist($casier, $meta = null, $options = array()) {
  25.  
  26.         // option par défaut
  27.         $options_defaut = array(
  28.                 'type_saisie' => 'input',
  29.                 'label' => 'label'
  30.         );
  31.         // Fusionner les options par défaut avec les options de l'utilisateur
  32.         $options = array_merge($options_defaut, $options);
  33.  
  34.         // Récupérer le meta casier et créer sa saisie
  35.         $casier = ($meta) ? $casier.'/'.$meta : $casier;
  36.         $saisies = array(
  37.                 array(
  38.                         'saisie' => $options['type_saisie'],
  39.                         'options' => array(
  40.                                 'nom' => $casier,
  41.                                 'label' => $options['label']
  42.                         )
  43.                 )
  44.         );
  45.  
  46.         return $saisies;
  47. }
  48.  
  49. /**
  50.  * Fonction charger pour le formulaire d'édition générique de méta
  51.  *
  52.  * @param string $casier nom du meta casier
  53.  * @param string $meta nom de l'éventuel sous-méta
  54.  * @param array $options tableau d'options :
  55.  *
  56.  * ```php
  57.  * $options_defaut = array(
  58.  *              'type_saisie' => 'input',
  59.  *              'label' => 'label'
  60.  * );
  61.  * ```
  62.  *
  63.  * @access public
  64.  * @return array
  65.  */
  66. function formulaires_editer_meta_charger_dist($casier, $meta = null, $options = array()) {
  67.         // Récupérer le casier
  68.         $casier = ($meta) ? $casier.'/'.$meta : $casier;
  69.  
  70.         // Lire la configuration
  71.         include_spip('inc/config');
  72.         $contexte = lire_config($casier, array());
  73.  
  74.         // Dans le cas d'une saisie simple, on s'assure de renvoyer un tableau
  75.         // valide pour la fonction charger
  76.         if (!is_array($contexte)) {
  77.                 $contexte = array($casier => $contexte);
  78.         }
  79.  
  80.         return $contexte;
  81. }
  82.  
  83. /**
  84.  * Fonction traiter pour le formulaire d'édition générique de méta
  85.  *
  86.  * @param string $casier nom du meta casier
  87.  * @param string $meta nom de l'éventuel sous-méta
  88.  * @param array $options tableau d'options :
  89.  *
  90.  * ```php
  91.  * $options_defaut = array(
  92.  *              'type_saisie' => 'input',
  93.  *              'label' => 'label'
  94.  * );
  95.  * ```
  96.  *
  97.  * @access public
  98.  * @return array
  99.  */
  100. function formulaires_editer_meta_traiter_dist($casier, $meta = null, $options = array()) {
  101.  
  102.         // Enregistrer la méta
  103.         include_spip('inc/config');
  104.  
  105.         // Récupérer l'ancienne configuration du casier
  106.         $old_config = lire_config($casier);
  107.         if (is_array($old_config)) {
  108.                 // Dans le cas d'une méta complexe, on va fusionner les fusionner avec
  109.                 // la nouvelle
  110.                 $new_config = _request($casier);
  111.                 $new_config = array_merge($old_config, $new_config);
  112.         } else {
  113.                 // Cas d'une saisie simple, on enregistre simplement la meta
  114.                 $new_config = _request($casier);
  115.         }
  116.  
  117.         // Ecrire la nouvelle méta
  118.         $ecrire = ecrire_config($casier, $new_config);
  119.  
  120.         // Retour du formulaire
  121.         if ($ecrire) {
  122.                 return array(
  123.                         'editable' => true,
  124.                         'message_ok' => _T('info_modification_enregistree')
  125.                 );
  126.         } else {
  127.                 return array(
  128.                         'editable' => true,
  129.                         'message_erreur' => _T('erreur')
  130.                 );
  131.         }
  132. }

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.                 array(
  26.                         'id_trad='.intval($id_objet),
  27.                         'lang='.sql_quote($lang),
  28.                         'statut='.sql_quote('publie')
  29.                 )
  30.         );
  31.  
  32.         return $id_traduction;
  33. }
  34.  
  35. function article_trouver_traduction($id_article, $lang) {
  36.         return objet_trouver_traduction($id_article, 'article', $lang);
  37. }
  38.  
  39. // Si le plugin Traduction entre rubriques est activé
  40. // http://contrib.spip.net/Traduction-des-rubriques
  41. function rubrique_trouver_traduction($id_article, $lang) {
  42.         return objet_trouver_traduction($id_article, 'rubrique', $lang);
  43. }

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>