Nous voulons, en une boucle, récupérer les informations des articles d’une (ou plusieurs) rubrique à laquelle est affecté un mot clef (que nous connaissons).
<BOUCLE_a(ARTICLES spip_mots_rubriques spip_mots){titre_mot=truc}>
produira la requête sql suivante :
SELECT articles.id_rubrique,
articles.id_article,
...
articles.lang
FROM spip_articles AS `articles`
INNER JOIN spip_mots_rubriques AS L1
ON L1.id_rubrique = articles.id_rubrique
INNER JOIN spip_mots AS L2
ON L2.id_mot = L1.id_mot
WHERE articles.statut = 'publie'
AND L2.titre = 'truc'
GROUP BY articles.id_article
nous voulons en une boucle sélectionner aléatoirement un document dans un secteur. À savoir que ce secteur ne contient pas d’articles, seulement des rubriques avec des documents liés (photothèque).
<BOUCLE_d(spip_documents_liens rubriques)
{objet = rubrique}
{rubriques.id_secteur = 13}
{par hasard}
{0, 1}>
#LOGO_DOCUMENT
</BOUCLE_d>
- la table spip_documents_liens est une table qui recense les liens (jointures) entre un document et un objet (article, rubrique, mot, site...).
des entrées type de cette table pourraient ressembler à :
id_document | id_objet | objet | vu |
---|---|---|---|
14 | 36 | article | non |
363 | 66 | rubrique | non |
... | ... | ... | ... |
nous allons donc chercher dans cette table les documents rattachés à une rubrique {objet = rubrique}
Mais nous voulons aussi que cette rubrique soit descendante de la rubrique secteur d’id 13
nous devons donc établir dans notre requête une jointure entre la table spip_documents_liens et spip_rubriques
cette jointure sera faite sur d’un côté :
l’id_objet de spip_documents_liens, de l’autre
l’id_rubrique de spip_rubriques
pour cela nous indiquons à spip que nous voulons cette jointure spécifique en donnant les 2 tables à la boucle
<BOUCLE_d(spip_documents_liens rubriques)...
enfin, pour spécifier notre restriction concernant le secteur 13, nous précisons le critère {rubriques.id_secteur = 13}
en spécifiant explicitement le nom complet du champ (nom de la table inclu) pour que la requête n’aille pas chercher un champ spip_documents_liens.id_secteur qui n’existe pas.
- à partir de cette boucle, donc, nous avons alors accès à tous les champs de spip_documents_liens et tous ceux de spip_rubriques :
#ID_DOCUMENT
#ID_OBJET
#OBJET
#VU
#ID_RUBRIQUE
#ID_PARENT
#TITRE
#DESCRIPTIF
#TEXTE
#ID_SECTEUR
...
- la requête sql produite par notre boucle :
SELECT rand() AS alea,
spip_documents_liens.id_document
FROM spip_documents_liens AS `spip_documents_liens`
INNER JOIN spip_rubriques AS L1
ON L1.id_rubrique = spip_documents_liens.id_objet
AND spip_documents_liens.objet = 'rubrique'
WHERE spip_documents_liens.objet = 'rubrique'
AND L1.id_secteur = 13
GROUP BY spip_documents_liens.id_document,
spip_documents_liens.id_objet,
spip_documents_liens.objet
ORDER BY alea
LIMIT 0,1
- enfin, la balise #LOGO_DOCUMENT nous retournera le source html :
<img src='local/cache-vignettes/L135xH150/Image_10-d84e2.png'
width='135' height='150' style='height:150px;width:135px;' alt=''
class='spip_logos' />
et si nous voulions le nom du fichier document, que nous ne pouvons avoir directement avec cette requête car le champ spip_documents.fichier n’est pas relevé (pas de jointure avec la table spip_documents), alors il faut déclarer une jointure supplémentaire sur la table spip_documents :
<BOUCLE_d(spip_documents_liens documents rubriques)
{objet = rubrique}
{rubriques.id_secteur = 13}
{par hasard}
{0, 1}>
#LOGO_DOCUMENT / #FICHIER
</BOUCLE_d>
requête produite :
SELECT rand() AS alea,
spip_documents_liens.id_document,
L2.fichier
FROM spip_documents_liens AS `spip_documents_liens`
INNER JOIN spip_documents AS L2
ON L2.id_document = spip_documents_liens.id_document
INNER JOIN spip_rubriques AS L1
ON L1.id_rubrique = spip_documents_liens.id_objet
AND spip_documents_liens.objet='rubrique'
WHERE spip_documents_liens.objet = 'rubrique'
AND L1.id_secteur = 13
GROUP BY spip_documents_liens.id_document,
spip_documents_liens.id_objet,
spip_documents_liens.objet
ORDER BY alea
LIMIT 0,1
attention n° 1 :
- ici, nous avons presque accès à tous les champs des 3 tables
« presque » car attention aux champs homonymes :
les #TITRE, #DESCRIPTIF, #MAJ, #STATUT et #DATE affichés, qui sont des champs homonymes dans spip_documents et spip_rubriques, seront ceux de spip_documents (table première de la requête) !
attention n° 2 :
- les écritures de nom de table
si :
<BOUCLE_d(DOCUMENTS_LIENS)>
<BOUCLE_d(documents_liens
<BOUCLE_d(SPIP_DOCUMENTS_LIENS
<BOUCLE_d(spip_documents_liens
sont équivalentes ;
tout comme :
<BOUCLE_d(documents_liens documents rubriques
<BOUCLE_d(documents_liens documents spip_rubriques
<BOUCLE_d(documents_liens documents RUBRIQUES
sont équivalentes ;
et encore :
<BOUCLE_d(documents_liens documents
<BOUCLE_d(documents_liens spip_documents
<BOUCLE_d(spip_documents_liens spip_documents
<BOUCLE_d(spip_documents_liens documents
sont aussi équivalentes ;
il n’en va pas de même avec :
<BOUCLE_d(DOCUMENTS_LIENS DOCUMENTS)>
<BOUCLE_d(documents_liens DOCUMENTS)>
<BOUCLE_d(SPIP_DOCUMENTS_LIENS DOCUMENTS)>
<BOUCLE_d(spip_documents_liens DOCUMENTS)>
où la mise en capitales de documents occasionne une perte de jointure
entre spip_documents_liens et spip_documents
Tables déclarées et tables non déclarées
La documentation ci dessus porte sur des tables du noyau de SPIP, et elle est valable pour toutes tables déclarées au moyen de l’API de déclaration des tables.
Lorsqu’une table n’est pas déclarée, il faut utiliser son nom complet, avec le préfixe, en minuscules.
Voir aussi sur programmer.spip.net : Automatisme des jointures.