Accueil du site > SPIP > Les itérateurs de SPIP

Les itérateurs de SPIP

jeudi 23 décembre 2010, par Fil, Marcimat

Nous sommes en train de développer dans SPIP une notion générale de boucle, basée sur les itérateurs de PHP.

Ces boucles ne portent plus exclusivement sur des requêtes SQL, mais peuvent tourner sur toutes sortes de listes de données. Par exemple :
— un tableau de données produit par une fonction quelconque
— le contenu d’un fichier local au format XML, CSV, JSON, YAML, etc.
— une liste de fichiers dans un répertoire du serveur
— une requête sur un webservice
— etc (LDAP...).

Les boucles SQL

Sans surprise, l’itérateur classique de SPIP s’appelle SQL. Il exécute la requête telle que SPIP l’a calculée, et sait parcourir la liste de résultats pour les envoyer à la boucle.

La boucle (DATA)

C’est une boucle capable d’itérer n’importe quel tableau de données. Sa syntaxe de base est la suivante :

<BOUCLE(DATA) {source ...}> #BALISES </BOUCLE>

Le critère {source format, données} définit les données sur lesquelles la boucle va itérer.

La définition d’une source de données nécessite deux éléments :

— La partie données : cet élément peut être de plusieurs natures :
- un tableau de données, par exemple #ENV*
- le chemin d’un fichier sur le disque dur, ex : sources/definitions.csv
- l’URL d’un fichier ou d’un webservice, ex : http://per.sonn.es/bases/phobia.fr.yaml
- ou encore, une chaîne quelconque que le format saura transformer en tableau de données, ex : "select * from flickr.photos.search where text='spip'"

— La partie format est à prendre dans la liste ci-dessous :
- table (alias array ou tableau), pour un tableau déjà créé
- csv, json, yaml pour un fichier composé dans l’un de ces formats
- file pour boucler sur les lignes d’un fichier
- glob ou pregfiles pour boucler sur les fichiers d’un répertoire (et plus...)
- rss (alias atom) pour lire un flux de nouvelles
- plugins pour lister les plugins actifs sur le site
- yql pour envoyer une requête sur le webservice de Yahoo Query Language
- sql pour envoyer une requête brute au serveur SQL (utiliser {source sql, connecteur:requete} pour envoyer la requête sur une base externe)
- ics pour boucler sur des calendriers (nécessite le plugin icalendar : lire La boucle iCalendar)
- etc.

Tous ces formats sont déjà disponibles, et il est très aisé d’en ajouter un nouveau, en créant une simple fonction inc_FORMAT_to_array($u). A titre d’exemple voici la fonction qui transforme un fichier JSON en tableau de données :

function inc_json_to_array_dist($u) {
 if (is_array($json = json_decode($u))
 OR is_object($json))
   return (array) $json;
}

A lire : Exemples de BOUCLE(DATA) .

YQL — Yahoo Query Language

YQL est un webservice permettant d’interroger de façon simple de nombreux sites comme google, twitter, flickr, etc. Avec la boucle (DATA), SPIP facilite grandement son intégration sous forme de boucles : Cf. Exemples de boucles YQL.

Itérateurs PHP

SPIP est capable d’utiliser les itérateurs PHP standards. Il convient de se reporter à leur documentation, qui est souvent très succincte, et de vérifier que les itérateurs en questions sont disponibles sur votre système.

Notons, par exemple, DirectoryIterator, qui permet de lister les fichiers d’un répertoire :

Boucle :

<pre>
<BOUCLE_ls(php:DirectoryIterator){args IMG/jpg/}
 {pagination 10}
 {valeur!==^\.}{valeur==\.jpg$}
>[(#VAL{Y-m-d H:i:s}|date{#GETMTIME})] / #VALEUR
</BOUCLE_ls>
</pre>
#PAGINATION
</B_ls>

Résultat :

2008-02-01 23:27:23 / arton2135.jpg
2008-08-21 11:12:58 / DSC03420.jpg
2008-08-21 11:13:11 / DSC03421.jpg
2009-08-27 11:20:11 / hash-1.jpg
2009-08-27 11:20:04 / hash.jpg

Il convient d’indiquer à SPIP qu’il s’agit d’un itérateur PHP, en indiquant (php:...) avant le nom de l’itérateur.

Le critère {args xx,yy} définit les arguments que l’on va passer à l’itérateur lors de son initialisation. Pour DirectoryIterator, il s’agit du chemin du répertoire à lister.

Les méthodes de cet itérateur (cf. http://php.net/manual/fr/class.directoryiterator.php) sont disponibles sous forme de balises (ici, #GETMTIME).

Remarque : pour lister le contenu d’un répertoire, le format glob de la boucle (DATA) est sans doute plus facile à utiliser que cet itérateur PHP.

<BOUCLE_ls(DATA){source ls, IMG/jpg/*.jpg}
{!par mtime}> ...

Filtrage, tri, pagination, fusion

Filtres. Comme les boucles SQL, les boucles (DATA) peuvent être filtrées par des critères du type {valeur=x} ; les opérateurs disponibles sont =, >, <, >=, <=, == (expression rationnelle) et LIKE.

Cependant ce filtrage s’effectue non pas en amont lors de la requête, comme en SQL, mais en aval, sur le tableau de données initialement récupéré.

Tris. Les tris {par xx} sont également possibles, avec leur variante {!par xx} pour trier en ordre inverse.

Pagination. La pagination fonctionne normalement, ainsi que le critère offset/limit {a,b}.

Fusion. Le critère {fusion /x/y} fonctionne aussi. Par exemple, pour un fichier d’adresses au format CSV, si l’email est le champ n° 3, on pourra ne retenir qu’un seul enregistrement par email avec la boucle suivante :

<BOUCLE_csv(DATA){source csv, adresses.csv}
{fusion /3}
{par /0}{'<br />'}>
#VALEUR{0} : #VALEUR{3}
</BOUCLE_csv>

La fusion se fait après le tri, et retient le premier élément
rencontré. De cette manière, si un tableau est trie {!par date} puis fusionné sur l’email, l’enregistrement retenu pour chaque email sera le plus récent.

 

Dans le prochain article, nous verrons des exemples de boucles (DATA).

12 Messages de forum

  • Les itérateurs de SPIP Le 23 décembre 2010 à 18:16 , par Beurt

    Ça coupe le souffle...

  • Les itérateurs de SPIP Le 23 décembre 2010 à 18:19 , par Yohann

    Pareil, terrifiant ! On aura le droit à une beta de la prochaine version de SPIP comprenant ces itérateurs prochainement (plutôt compter pour 2011 ?) ?

  • Les itérateurs de SPIP Le 23 décembre 2010 à 19:18 , par Maïeul

    juste un mot : énorme !

  • Les itérateurs de SPIP Le 26 décembre 2010 à 11:24 , par StrangeBlackHole

    Viiiiiite !! le futur de Spip est beau ! ;)

    merci les gars !

  • Les itérateurs de SPIP Le 27 décembre 2010 à 11:59 , par George

    Un vrai cadeau de fin d’annee

    Merci

  • Les itérateurs de SPIP Le 27 décembre 2010 à 22:44 , par yves29

    wow ! grand merci

  • Les itérateurs de SPIP Le 11 janvier 2011 à 16:57 , par Eric

    Bonjour,

    Pouvez-vous donner un exemple basé sur une requête SQL aussi ?
    (avec connecteur sur une autre base).
    Merci !

    • Les itérateurs de SPIP Le 11 janvier 2011 à 21:34 , par Fil

      Il y a plein d’exemples dans le plugin itérateurs pour SPIP 2.1.

      Pour SQL la démo contient :

      #SET{req,"SHOW FIELDS FROM spip_articles"}
      <dt><kbd>#GET{req}</kbd></dt>
      <dd>
      <ul>
      <BOUCLE_show(DATA){source sql, #GET{req}}>
      <li>[(#VALEUR{Field})][ - (#VALEUR{Type})][ - (#VALEUR{Extra})]</li>
      </BOUCLE_show>
      </ul>
      </dd>

      Pour employer un connecteur sur une base "distante", il suffit de mettre {source sql, connecteur:REQUETE}

  • Les itérateurs de SPIP Le 16 février 2011 à 10:03 , par Quentin

    Juste complètement dingue !!!
    Je suis amoureux !!! j’en veux pour chez moi aussi :)

    Énormissime !!!!