Ми хочемо в одному циклі витягти дані щодо деяких статей з однієї (або кількох) рубрик, до яких були заздалегідь призначені ключі.
<BOUCLE_a(ARTICLES spip_mots_rubriques spip_mots) {titre_mot=search_keyword}>
буде генерувати наступний SQL запит:
SELECT articles.id_rubrique,
articles.id_article,
...
articles.lang
FROM spip_articles AS <span class="base64" title="PGNvZGUgY2xhc3M9J3NwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lJyBkaXI9J2x0cic+YXJ0aWNsZXM8L2NvZGU+"></span>
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 = 'search_keyword'
GROUP BY articles.id_article
Ми хочемо в одному циклі випадковим чином вибрати документ з сектора. Зверніть увагу, що цей сектор не містить будь-яких власних статей, а тільки рубрики і пов’язані з ними документи (насправді це - фото-бібліотека).
<BOUCLE_d(spip_documents_liens rubriques)
{objet = rubrique}
{rubriques.id_secteur = 13}
{par hasard}
{0, 1}>
#LOGO_DOCUMENT
</BOUCLE_d>
- Таблиця spip_documents_liens - це таблиця, яка зіставляє всі посилання (об’єднання) між документом і об’єктами (статтями, рубриками, ключами, сайтами і т.д.)
Деякі типові записи в цій таблиці будуть виглядати так:
id_document | id_objet | objet | vu |
---|---|---|---|
14 | 36 | article | non |
363 | 66 | rubrique | non |
... | ... | ... | ... |
Отже ми, таким чином, будемо шукати в цій таблиці документи, пов’язані з рубрикою {objet = rubrique}
Ми також будемо вважати, що ця рубрика вкладена в сектор з ID = 13.
Тому ми повинні встановити в нашому запиті, що об’єднання (join) зроблено між таблицями spip_documents_liens і spip_rubriques .
Це об’єднання встановлюється між:
id_objet в spip_documents_liens, і
id_rubrique в spip_rubriques.
Щоб зробити об’єднання, ми розповімо SPIP, що ми хочемо виконати це конкретне об’єднання, вказавши 2 таблиці всередині синтаксису циклу <BOUCLE_d(spip_documents_liens rubriques)...
Нарешті, щоб вказати наш обмеження щодо сектора 13, ми використовуємо критерій {rubriques.id_secteur = 13}
, явно прописуючи детальне повне ім’я поля (в тому числі - ім’я таблиці), аби запит не спробував знайти поле spip_documents_liens.id_secteur, якого насправді не існує.
- Використовуючи цей цикл ми отримуємо доступ до всіх полів в таблиці spip_documents_liens і всіх полів в spip_rubriques:
#ID_DOCUMENT
#ID_OBJET
#OBJET
#VU
#ID_RUBRIQUE
#ID_PARENT
#TITRE
#DESCRIPTIF
#TEXTE
#ID_SECTEUR
...
- Поки що наш згенерований SQL запит для нашого циклу виглядає так:
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
</code>
- Нарешті тег #LOGO_DOCUMENT поверне нам HTML-джерело для документу:
<img src='local/cache-vignettes/L135xH150/Image_10-d84e2.png'
width='135' height='150' style='height:150px;width:135px;' alt=''
class='spip_logos' />
Тепер, якщо ми також хочемо одержати ім’я файла документа, оскільки ми не можемо отримати доступ до нього за цим запитом, бо поле spip_documents.fichier не було включене (без з’єднання з таблицею spip_documents), то ми повинні оголосити додаткове об’єднання з таблицею spip_documents:
<BOUCLE_d(spip_documents_liens documents rubriques)
{objet = rubrique}
{rubriques.id_secteur = 13}
{par hasard}
{0, 1}>
#LOGO_DOCUMENT / #FICHIER
</BOUCLE_d>
Запит SQL тоді буде таким:
SELECT rand() AS alea,
spip_documents_liens.id_document,
L2.fichier
FROM spip_documents_liens AS <span class="base64" title="PGNvZGUgY2xhc3M9J3NwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lJyBkaXI9J2x0cic+c3BpcF9kb2N1bWVudHNfbGllbnM8L2NvZGU+"></span>
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
Важливе зауваження № 1:
- за цим сценарієм, ми маємо доступ майже до всіх полів в 3-х таблицях
«майже», бо деякі поля мають однакові імена:
поля #TITRE, #DESCRIPTIF, #MAJ, #STATUT і #DATE, що відображатимуться, мають відповідні поля з такими ж іменами в обох таблицях: spip_documents і spip_rubriques, а відображаєтися будуть значення з таблиці spip_documents (першої таблиці в запиті)!
Важливе зауваження № 2:
- синтаксис для запису імен таблиць.
Хоча:
<BOUCLE_d(DOCUMENTS_LIENS
<BOUCLE_d(documents_liens
<BOUCLE_d(SPIP_DOCUMENTS_LIENS
<BOUCLE_d(spip_documents_liens
всі еквівалентні;
як і цикли:
<BOUCLE_d(documents_liens documents rubriques
<BOUCLE_d(documents_liens documents spip_rubriques
<BOUCLE_d(documents_liens documents RUBRIQUES
будуть еквівалентні один одному;
і навіть в цьому наборі:
<BOUCLE_d(documents_liens documents
<BOUCLE_d(documents_liens spip_documents
<BOUCLE_d(spip_documents_liens spip_documents
<BOUCLE_d(spip_documents_liens documents
цикли також еквівалентні між собою;
ми не можемо сказати те ж саме про цій набір:
<BOUCLE_d(DOCUMENTS_LIENS DOCUMENTS
<BOUCLE_d(documents_liens DOCUMENTS
<BOUCLE_d(SPIP_DOCUMENTS_LIENS DOCUMENTS
<BOUCLE_d(spip_documents_liens DOCUMENTS
де запис documents великими літерами викличе втрату автоматичного об’єднання між spip_documents_liens і spip_documents.