Completed
Push — master ( 1fe7c3...e997e0 )
by cam
02:01
created
ecrire/lang/ecrire_de.php 1 patch
Indentation   +839 added lines, -839 removed lines patch added patch discarded remove patch
@@ -4,886 +4,886 @@
 block discarded – undo
4 4
 // ** ne pas modifier le fichier **
5 5
 
6 6
 if (!defined('_ECRIRE_INC_VERSION')) {
7
-	return;
7
+    return;
8 8
 }
9 9
 
10 10
 $GLOBALS[$GLOBALS['idx_lang']] = array(
11 11
 
12
-	// A
13
-	'activer_plugin' => 'Plugin aktivieren',
14
-	'affichage' => 'Anzeigen',
15
-	'aide_non_disponible' => 'Dieser Teil der Online-Hilfe ist in dieser Sprache noch nicht verfügbar.',
16
-	'annuler_recherche' => 'Sucheingabe löschen',
17
-	'auteur' => 'Autor:',
18
-	'avis_acces_interdit' => 'Zugang gesperrt.',
19
-	'avis_acces_interdit_prive' => 'Sie haben nicht die Berechtigung zum Öffnen der Seite<b>@exec@</b>.',
20
-	'avis_article_modifie' => 'Achtung, @nom_auteur_modif@ hat vor @date_diff@ Minute(n) an diesem Artikel gearbeitet.',
21
-	'avis_aucun_resultat' => 'Kein Ergebnis.',
22
-	'avis_base_inaccessible' => 'Keine Verbindung mit Datenbank @base@ möglich.',
23
-	'avis_chemin_invalide_1' => 'Der von ihnen gewählte Pfad',
24
-	'avis_chemin_invalide_2' => 'scheint nicht zu stimmen. Bitte kehren Sie zur vorigen Seite zurück und überprüfen sie die Angaben.',
25
-	'avis_connexion_echec_1' => 'Die Verbindung zur Datenbank ist fehlgeschlagen.',
26
-	'avis_connexion_echec_2' => 'Kehren Sie zur vorigen Seite zurück und überprüfen sie ihre Eingaben.',
27
-	'avis_connexion_echec_3' => '<b>N.B.</b> Bei vielen Servern müssen Sie Ihre Datenbank ausdrücklich <b>freischalten lassen</b> um sie nutzen zu können. Falls die Verbindung wieder fehlschlägt, stellen Sie bitte sicher, dass Ihre Datenbank freigeschaltet wurde.',
28
-	'avis_connexion_erreur_creer_base' => 'Die Datenbank konnte nicht erstellt werden.',
29
-	'avis_connexion_erreur_fichier_cle_manquant_1' => 'Die Installation muss von einem Webmaster mit einem Backup der Schlüssel und seinem Passwort durchgeführt werden',
30
-	'avis_connexion_erreur_fichier_cle_manquant_2' => 'Die Installation muss von einem Webmaster mit einem Backup der Schlüssel durchgeführt werden',
31
-	'avis_connexion_erreur_nom_base' => 'Der Datenbankname darf nur Buchstaben, Ziffern und Bindestriche "-" enthalten.',
32
-	'avis_connexion_ldap_echec_1' => 'Die Verbindung zum LDAP-Server ist fehlgeschlagen.',
33
-	'avis_connexion_ldap_echec_2' => 'Kehren Sie zur vorigen Seite zurück und überprüfen sie ihre Eingaben.',
34
-	'avis_connexion_ldap_echec_3' => 'Sie können Benutzer auch ohne LDAP-Support importieren.',
35
-	'avis_deplacement_rubrique' => 'Achtung! diese Rubrik enthält @contient_breves@ Meldungen@scb@: wenn Sie Rubrik verschieben wollen, markieren Sie bitte zur Bestätigung dieses Kästchen.',
36
-	'avis_erreur_connexion_mysql' => 'SQL-Verbindungsfehler',
37
-	'avis_erreur_creation_compte' => 'Konto konnte nicht initialisiert werden',
38
-	'avis_espace_interdit' => '<b>Gesperrter Bereich</b> <div>SPIP ist bereits installiert.</div>',
39
-	'avis_lecture_noms_bases_1' => 'Das Installationsprogramm konnte die Namen der vorhandenen Datenbanken nicht lesen.',
40
-	'avis_lecture_noms_bases_2' => 'Entweder ist keine Datenbank vorhanden oder die Funktion zum Auflisten der Datenbanken ist aus Sicherheitsgründen abgeschaltet
12
+    // A
13
+    'activer_plugin' => 'Plugin aktivieren',
14
+    'affichage' => 'Anzeigen',
15
+    'aide_non_disponible' => 'Dieser Teil der Online-Hilfe ist in dieser Sprache noch nicht verfügbar.',
16
+    'annuler_recherche' => 'Sucheingabe löschen',
17
+    'auteur' => 'Autor:',
18
+    'avis_acces_interdit' => 'Zugang gesperrt.',
19
+    'avis_acces_interdit_prive' => 'Sie haben nicht die Berechtigung zum Öffnen der Seite<b>@exec@</b>.',
20
+    'avis_article_modifie' => 'Achtung, @nom_auteur_modif@ hat vor @date_diff@ Minute(n) an diesem Artikel gearbeitet.',
21
+    'avis_aucun_resultat' => 'Kein Ergebnis.',
22
+    'avis_base_inaccessible' => 'Keine Verbindung mit Datenbank @base@ möglich.',
23
+    'avis_chemin_invalide_1' => 'Der von ihnen gewählte Pfad',
24
+    'avis_chemin_invalide_2' => 'scheint nicht zu stimmen. Bitte kehren Sie zur vorigen Seite zurück und überprüfen sie die Angaben.',
25
+    'avis_connexion_echec_1' => 'Die Verbindung zur Datenbank ist fehlgeschlagen.',
26
+    'avis_connexion_echec_2' => 'Kehren Sie zur vorigen Seite zurück und überprüfen sie ihre Eingaben.',
27
+    'avis_connexion_echec_3' => '<b>N.B.</b> Bei vielen Servern müssen Sie Ihre Datenbank ausdrücklich <b>freischalten lassen</b> um sie nutzen zu können. Falls die Verbindung wieder fehlschlägt, stellen Sie bitte sicher, dass Ihre Datenbank freigeschaltet wurde.',
28
+    'avis_connexion_erreur_creer_base' => 'Die Datenbank konnte nicht erstellt werden.',
29
+    'avis_connexion_erreur_fichier_cle_manquant_1' => 'Die Installation muss von einem Webmaster mit einem Backup der Schlüssel und seinem Passwort durchgeführt werden',
30
+    'avis_connexion_erreur_fichier_cle_manquant_2' => 'Die Installation muss von einem Webmaster mit einem Backup der Schlüssel durchgeführt werden',
31
+    'avis_connexion_erreur_nom_base' => 'Der Datenbankname darf nur Buchstaben, Ziffern und Bindestriche "-" enthalten.',
32
+    'avis_connexion_ldap_echec_1' => 'Die Verbindung zum LDAP-Server ist fehlgeschlagen.',
33
+    'avis_connexion_ldap_echec_2' => 'Kehren Sie zur vorigen Seite zurück und überprüfen sie ihre Eingaben.',
34
+    'avis_connexion_ldap_echec_3' => 'Sie können Benutzer auch ohne LDAP-Support importieren.',
35
+    'avis_deplacement_rubrique' => 'Achtung! diese Rubrik enthält @contient_breves@ Meldungen@scb@: wenn Sie Rubrik verschieben wollen, markieren Sie bitte zur Bestätigung dieses Kästchen.',
36
+    'avis_erreur_connexion_mysql' => 'SQL-Verbindungsfehler',
37
+    'avis_erreur_creation_compte' => 'Konto konnte nicht initialisiert werden',
38
+    'avis_espace_interdit' => '<b>Gesperrter Bereich</b> <div>SPIP ist bereits installiert.</div>',
39
+    'avis_lecture_noms_bases_1' => 'Das Installationsprogramm konnte die Namen der vorhandenen Datenbanken nicht lesen.',
40
+    'avis_lecture_noms_bases_2' => 'Entweder ist keine Datenbank vorhanden oder die Funktion zum Auflisten der Datenbanken ist aus Sicherheitsgründen abgeschaltet
41 41
 (Das ist bei vielen Webhostern der Fall).',
42
-	'avis_lecture_noms_bases_3' => 'Im zweiten Fall ist wahrscheinlich eine Datenbank vorhanden, die Ihren Anmeldenamen trägt:',
43
-	'avis_non_acces_page' => 'Sie haben keinen Zugriff auf diese Seite.',
44
-	'avis_operation_echec' => 'Aktion fehlgeschlagen.',
45
-	'avis_operation_impossible' => 'Aktion nicht möglich',
46
-	'avis_suppression_base' => 'ACHTUNG, Daten werden unwiderruflich gelöscht.',
42
+    'avis_lecture_noms_bases_3' => 'Im zweiten Fall ist wahrscheinlich eine Datenbank vorhanden, die Ihren Anmeldenamen trägt:',
43
+    'avis_non_acces_page' => 'Sie haben keinen Zugriff auf diese Seite.',
44
+    'avis_operation_echec' => 'Aktion fehlgeschlagen.',
45
+    'avis_operation_impossible' => 'Aktion nicht möglich',
46
+    'avis_suppression_base' => 'ACHTUNG, Daten werden unwiderruflich gelöscht.',
47 47
 
48
-	// B
49
-	'bouton_acces_ldap' => 'LDAP Zugang hinzufügen',
50
-	'bouton_ajouter' => 'Hinzufügen',
51
-	'bouton_annuler' => 'Abbrechen',
52
-	'bouton_cache_activer' => 'Cache aktivieren',
53
-	'bouton_cache_desactiver' => 'Cache vorübergehend abschalten',
54
-	'bouton_demande_publication' => 'Artikel zur Veröffentlichung vorschlagen',
55
-	'bouton_desactive_tout' => 'Alles deaktivieren',
56
-	'bouton_desinstaller' => 'Deinstallieren',
57
-	'bouton_effacer_tout' => 'ALLES löschen',
58
-	'bouton_envoyer_message' => 'Nachricht fertig: Senden',
59
-	'bouton_fermer' => 'Schließen',
60
-	'bouton_mettre_a_jour_base' => 'Datenbank updaten',
61
-	'bouton_modifier' => 'Ändern',
62
-	'bouton_radio_afficher' => 'Anzeigen',
63
-	'bouton_radio_apparaitre_liste_redacteurs_connectes' => 'Auf der Liste angemeldeter Redakteure anzeigen',
64
-	'bouton_radio_envoi_annonces_adresse' => 'Editorische Ankündigungen an diese Adresse senden:',
65
-	'bouton_radio_envoi_liste_nouveautes' => 'Liste der neuesten Veröffentlichungen verschicken',
66
-	'bouton_radio_non_apparaitre_liste_redacteurs_connectes' => 'Ich will nicht auf dieser Liste zu sehen sein.',
67
-	'bouton_radio_non_envoi_annonces_editoriales' => 'Keine editorischen Ankündigungen verschicken',
68
-	'bouton_redirection' => 'UMLEITUNG',
69
-	'bouton_reinitialiser_aux_valeurs_par_defaut' => 'Mit Standardwerten neu initialisieren',
70
-	'bouton_relancer_inscription' => 'Anmeldung neu starten',
71
-	'bouton_relancer_inscriptions' => 'Anmeldungen neu starten',
72
-	'bouton_relancer_installation' => 'Installation wiederholen',
73
-	'bouton_reset_password' => 'Neues Passwort erzeugen und per Mail zusenden',
74
-	'bouton_suivant' => 'weiter',
75
-	'bouton_tenter_recuperation' => 'Reparatur versuchen',
76
-	'bouton_test_proxy' => 'Proxy testen',
77
-	'bouton_vider_cache' => 'Cache leeren',
48
+    // B
49
+    'bouton_acces_ldap' => 'LDAP Zugang hinzufügen',
50
+    'bouton_ajouter' => 'Hinzufügen',
51
+    'bouton_annuler' => 'Abbrechen',
52
+    'bouton_cache_activer' => 'Cache aktivieren',
53
+    'bouton_cache_desactiver' => 'Cache vorübergehend abschalten',
54
+    'bouton_demande_publication' => 'Artikel zur Veröffentlichung vorschlagen',
55
+    'bouton_desactive_tout' => 'Alles deaktivieren',
56
+    'bouton_desinstaller' => 'Deinstallieren',
57
+    'bouton_effacer_tout' => 'ALLES löschen',
58
+    'bouton_envoyer_message' => 'Nachricht fertig: Senden',
59
+    'bouton_fermer' => 'Schließen',
60
+    'bouton_mettre_a_jour_base' => 'Datenbank updaten',
61
+    'bouton_modifier' => 'Ändern',
62
+    'bouton_radio_afficher' => 'Anzeigen',
63
+    'bouton_radio_apparaitre_liste_redacteurs_connectes' => 'Auf der Liste angemeldeter Redakteure anzeigen',
64
+    'bouton_radio_envoi_annonces_adresse' => 'Editorische Ankündigungen an diese Adresse senden:',
65
+    'bouton_radio_envoi_liste_nouveautes' => 'Liste der neuesten Veröffentlichungen verschicken',
66
+    'bouton_radio_non_apparaitre_liste_redacteurs_connectes' => 'Ich will nicht auf dieser Liste zu sehen sein.',
67
+    'bouton_radio_non_envoi_annonces_editoriales' => 'Keine editorischen Ankündigungen verschicken',
68
+    'bouton_redirection' => 'UMLEITUNG',
69
+    'bouton_reinitialiser_aux_valeurs_par_defaut' => 'Mit Standardwerten neu initialisieren',
70
+    'bouton_relancer_inscription' => 'Anmeldung neu starten',
71
+    'bouton_relancer_inscriptions' => 'Anmeldungen neu starten',
72
+    'bouton_relancer_installation' => 'Installation wiederholen',
73
+    'bouton_reset_password' => 'Neues Passwort erzeugen und per Mail zusenden',
74
+    'bouton_suivant' => 'weiter',
75
+    'bouton_tenter_recuperation' => 'Reparatur versuchen',
76
+    'bouton_test_proxy' => 'Proxy testen',
77
+    'bouton_vider_cache' => 'Cache leeren',
78 78
 
79
-	// C
80
-	'cache_modifiable_webmestre' => 'Dieser Parameter kann vom Webmaster eingestellt werden.',
81
-	'calendrier_synchro' => 'Wenn Sie eine mit <b>iCal</b> kompatibles PIM-Programm verwenden, könne Sie es mit den Einträgen dieser Website synchronisieren.',
82
-	'config_activer_champs' => 'Aktivieren Sie folgende Felder',
83
-	'config_choix_base_sup' => 'Eine Datenbank auf diesem Server angeben',
84
-	'config_erreur_base_sup' => 'SPIP kann nicht auf die Liste der verfügbaren Datenbanken zugreifen.',
85
-	'config_info_base_sup' => 'Wenn Sie andere Datenbanken auf dem selben Server oder auf einem anderen mit SPIP abfragen möchten, können Sie sie mit dem Formular weiter unten deklarieren. Wenn Sie Felder leer lassen, werden die Verbindungsdaten der Hauptdatenbank verwendet.',
86
-	'config_info_base_sup_disponibles' => 'Bereits abfragbare Datenbanken:',
87
-	'config_info_enregistree' => 'Neue Einstellungen wurden gespeichert',
88
-	'config_info_logos' => 'Jedes Element der Website kann ein Logo und ein «mouseover-Logo» erhalten.',
89
-	'config_info_logos_utiliser' => 'Logos verwenden',
90
-	'config_info_logos_utiliser_non' => 'Logos nicht verwenden',
91
-	'config_info_logos_utiliser_survol' => 'Mouseover-Logos verwenden',
92
-	'config_info_logos_utiliser_survol_non' => 'Mouseover-Logos nicht verwenden',
93
-	'config_info_redirection' => 'Mit dieser Option können Sie virtuelle Artikel anlegen, die als Weiterleitung zu Artikeln anderer Websites oder ausserhalb von SPIP funktionieren.',
94
-	'config_redirection' => 'Virtuelle Artikel',
95
-	'config_titre_base_sup' => 'Deklaration einer zusätzlichen Datenbank',
96
-	'config_titre_base_sup_choix' => 'Wählen Sie eine zusätzliche Datenbank',
97
-	'connexion_ldap' => 'Verbindung:',
98
-	'creer_et_associer_un_auteur' => 'Autor anlegen und zuordnen',
79
+    // C
80
+    'cache_modifiable_webmestre' => 'Dieser Parameter kann vom Webmaster eingestellt werden.',
81
+    'calendrier_synchro' => 'Wenn Sie eine mit <b>iCal</b> kompatibles PIM-Programm verwenden, könne Sie es mit den Einträgen dieser Website synchronisieren.',
82
+    'config_activer_champs' => 'Aktivieren Sie folgende Felder',
83
+    'config_choix_base_sup' => 'Eine Datenbank auf diesem Server angeben',
84
+    'config_erreur_base_sup' => 'SPIP kann nicht auf die Liste der verfügbaren Datenbanken zugreifen.',
85
+    'config_info_base_sup' => 'Wenn Sie andere Datenbanken auf dem selben Server oder auf einem anderen mit SPIP abfragen möchten, können Sie sie mit dem Formular weiter unten deklarieren. Wenn Sie Felder leer lassen, werden die Verbindungsdaten der Hauptdatenbank verwendet.',
86
+    'config_info_base_sup_disponibles' => 'Bereits abfragbare Datenbanken:',
87
+    'config_info_enregistree' => 'Neue Einstellungen wurden gespeichert',
88
+    'config_info_logos' => 'Jedes Element der Website kann ein Logo und ein «mouseover-Logo» erhalten.',
89
+    'config_info_logos_utiliser' => 'Logos verwenden',
90
+    'config_info_logos_utiliser_non' => 'Logos nicht verwenden',
91
+    'config_info_logos_utiliser_survol' => 'Mouseover-Logos verwenden',
92
+    'config_info_logos_utiliser_survol_non' => 'Mouseover-Logos nicht verwenden',
93
+    'config_info_redirection' => 'Mit dieser Option können Sie virtuelle Artikel anlegen, die als Weiterleitung zu Artikeln anderer Websites oder ausserhalb von SPIP funktionieren.',
94
+    'config_redirection' => 'Virtuelle Artikel',
95
+    'config_titre_base_sup' => 'Deklaration einer zusätzlichen Datenbank',
96
+    'config_titre_base_sup_choix' => 'Wählen Sie eine zusätzliche Datenbank',
97
+    'connexion_ldap' => 'Verbindung:',
98
+    'creer_et_associer_un_auteur' => 'Autor anlegen und zuordnen',
99 99
 
100
-	// D
101
-	'date_mot_heures' => 'Stunden',
100
+    // D
101
+    'date_mot_heures' => 'Stunden',
102 102
 
103
-	// E
104
-	'ecran_connexion_couleur_principale' => 'Grundfarbe',
105
-	'ecran_connexion_image_fond' => 'Hintergrundbild',
106
-	'ecran_connexion_image_fond_explication' => 'Ein Bild verwenden (fFormat JPEG, 1920x1080 Pixel)',
107
-	'ecran_connexion_image_revenir_couleur_defaut' => 'Standardfarbe verwenden',
108
-	'ecran_connexion_titre' => 'Anmeldebildschirm',
109
-	'ecran_securite' => ' + Sicherheitsschirm @version@',
110
-	'email' => 'E-Mail',
111
-	'email_2' => 'E-Mail:',
112
-	'en_savoir_plus' => 'Weitere Informationen',
113
-	'entree_adresse_annuaire' => 'Adresse des Verzeichnisses',
114
-	'entree_adresse_email' => 'Ihre E-Mail Adresse',
115
-	'entree_adresse_email_2' => 'Mailadresse',
116
-	'entree_base_donnee_1' => 'Adresse des Datenbankservers',
117
-	'entree_base_donnee_2' => '(Oftmals entspricht diese Adresse der Ihrer Website, sie kann auch einfach „localhost“ lauten und gelegentlich darf das Feld leer bleiben.)',
118
-	'entree_biographie' => 'Ganz kurze Vorstellung / Lebenslauf',
119
-	'entree_chemin_acces' => 'Bitte den <b>Pfad angeben</b>:',
120
-	'entree_cle_pgp' => 'Ihr öffentlicher PGP-Schlüssel',
121
-	'entree_cle_pgp_2' => 'PGP-Schlüssel',
122
-	'entree_contenu_rubrique' => '(Inhalt der Rubrik)',
123
-	'entree_identifiants_connexion' => 'Ihre Verbindungsdaten ...',
124
-	'entree_identifiants_connexion_2' => 'Logindaten',
125
-	'entree_informations_connexion_ldap' => 'Bitte tragen Sie in dieses Formular die Zugangsdaten zu Ihrem LDAP-Verzeichnis ein. Sie erhalten diese Informationen von Ihrem System- oder Netzwerkadministrator.',
126
-	'entree_infos_perso' => 'Wer sind Sie?',
127
-	'entree_infos_perso_2' => 'Wer ist der Autor?',
128
-	'entree_interieur_rubrique' => 'In der Rubrik:',
129
-	'entree_liens_sites' => '<b>Hyperlink</b> (Quelle, Website zum Thema ...)',
130
-	'entree_login' => 'Ihr Login',
131
-	'entree_login_connexion_1' => 'Login für die Verbindung',
132
-	'entree_login_connexion_2' => '(Dieser entspricht häufig Ihrem FTP-Login, bleibt in manchen Fällen leer)',
133
-	'entree_mot_passe' => 'Ihr Passwort',
134
-	'entree_mot_passe_1' => 'Passwort für die Verbindung',
135
-	'entree_mot_passe_2' => '(Entspricht häufig Ihrem FTP-Login, bleibt in manchen Fällen leer)',
136
-	'entree_nom_fichier' => 'Bitte geben Sie den Namen der Datei @texte_compresse@ an:',
137
-	'entree_nom_pseudo' => 'Ihr Name oder Pseudonym',
138
-	'entree_nom_pseudo_1' => '(Ihr Name oder Nickname)',
139
-	'entree_nom_pseudo_2' => 'Name oder Pseudonym',
140
-	'entree_nom_site' => 'Der Titel Ihrer Website',
141
-	'entree_nom_site_2' => 'Name der Website des Autors',
142
-	'entree_nouveau_passe' => 'Neues Passwort',
143
-	'entree_passe_ldap' => 'Passwort',
144
-	'entree_port_annuaire' => 'Port (Nummer) des Verzeichnisses',
145
-	'entree_signature' => 'Unterschrift',
146
-	'entree_titre_obligatoire' => '<b>Titel</b> [Pflichtfeld]<br />',
147
-	'entree_url' => 'Adresse (URL) Ihrer Website',
148
-	'entree_url_2' => 'Adresse (URL) der Website',
149
-	'erreur_connect_deja_existant' => 'Ein Server mit diesem Namen existiert bereits.',
150
-	'erreur_contenu_suspect' => 'Text mit Escape-Zeichen',
151
-	'erreur_email_deja_existant' => 'Diese Adresse ist bereits gespeichert.',
152
-	'erreur_nom_connect_incorrect' => 'Dieser Servername ist nicht zulässig.',
153
-	'erreur_plugin_attribut_balise_manquant' => 'Attribut @attribut@ fehlt im Tag @balise@.',
154
-	'erreur_plugin_desinstalation_echouee' => 'Das Deinstallieren des Plugins ist fehlgeschlagen. Sie können es jedoch deaktivieren.',
155
-	'erreur_plugin_fichier_absent' => 'Datei nicht vorhanden',
156
-	'erreur_plugin_fichier_def_absent' => 'Definitionsdatei nicht vorhanden',
157
-	'erreur_plugin_nom_fonction_interdit' => 'Unzulässiger Funktionsname',
158
-	'erreur_plugin_nom_manquant' => 'Name des Plugin fehlt',
159
-	'erreur_plugin_prefix_manquant' => 'Namespace des Plugin nicht definiert',
160
-	'erreur_plugin_tag_plugin_absent' => '&lt;plugin&gt; fehlt in der Definitionsdatei',
161
-	'erreur_plugin_version_manquant' => 'Version des Plugin fehlt',
162
-	'erreur_type_fichier' => 'Falsches Dateiformat',
103
+    // E
104
+    'ecran_connexion_couleur_principale' => 'Grundfarbe',
105
+    'ecran_connexion_image_fond' => 'Hintergrundbild',
106
+    'ecran_connexion_image_fond_explication' => 'Ein Bild verwenden (fFormat JPEG, 1920x1080 Pixel)',
107
+    'ecran_connexion_image_revenir_couleur_defaut' => 'Standardfarbe verwenden',
108
+    'ecran_connexion_titre' => 'Anmeldebildschirm',
109
+    'ecran_securite' => ' + Sicherheitsschirm @version@',
110
+    'email' => 'E-Mail',
111
+    'email_2' => 'E-Mail:',
112
+    'en_savoir_plus' => 'Weitere Informationen',
113
+    'entree_adresse_annuaire' => 'Adresse des Verzeichnisses',
114
+    'entree_adresse_email' => 'Ihre E-Mail Adresse',
115
+    'entree_adresse_email_2' => 'Mailadresse',
116
+    'entree_base_donnee_1' => 'Adresse des Datenbankservers',
117
+    'entree_base_donnee_2' => '(Oftmals entspricht diese Adresse der Ihrer Website, sie kann auch einfach „localhost“ lauten und gelegentlich darf das Feld leer bleiben.)',
118
+    'entree_biographie' => 'Ganz kurze Vorstellung / Lebenslauf',
119
+    'entree_chemin_acces' => 'Bitte den <b>Pfad angeben</b>:',
120
+    'entree_cle_pgp' => 'Ihr öffentlicher PGP-Schlüssel',
121
+    'entree_cle_pgp_2' => 'PGP-Schlüssel',
122
+    'entree_contenu_rubrique' => '(Inhalt der Rubrik)',
123
+    'entree_identifiants_connexion' => 'Ihre Verbindungsdaten ...',
124
+    'entree_identifiants_connexion_2' => 'Logindaten',
125
+    'entree_informations_connexion_ldap' => 'Bitte tragen Sie in dieses Formular die Zugangsdaten zu Ihrem LDAP-Verzeichnis ein. Sie erhalten diese Informationen von Ihrem System- oder Netzwerkadministrator.',
126
+    'entree_infos_perso' => 'Wer sind Sie?',
127
+    'entree_infos_perso_2' => 'Wer ist der Autor?',
128
+    'entree_interieur_rubrique' => 'In der Rubrik:',
129
+    'entree_liens_sites' => '<b>Hyperlink</b> (Quelle, Website zum Thema ...)',
130
+    'entree_login' => 'Ihr Login',
131
+    'entree_login_connexion_1' => 'Login für die Verbindung',
132
+    'entree_login_connexion_2' => '(Dieser entspricht häufig Ihrem FTP-Login, bleibt in manchen Fällen leer)',
133
+    'entree_mot_passe' => 'Ihr Passwort',
134
+    'entree_mot_passe_1' => 'Passwort für die Verbindung',
135
+    'entree_mot_passe_2' => '(Entspricht häufig Ihrem FTP-Login, bleibt in manchen Fällen leer)',
136
+    'entree_nom_fichier' => 'Bitte geben Sie den Namen der Datei @texte_compresse@ an:',
137
+    'entree_nom_pseudo' => 'Ihr Name oder Pseudonym',
138
+    'entree_nom_pseudo_1' => '(Ihr Name oder Nickname)',
139
+    'entree_nom_pseudo_2' => 'Name oder Pseudonym',
140
+    'entree_nom_site' => 'Der Titel Ihrer Website',
141
+    'entree_nom_site_2' => 'Name der Website des Autors',
142
+    'entree_nouveau_passe' => 'Neues Passwort',
143
+    'entree_passe_ldap' => 'Passwort',
144
+    'entree_port_annuaire' => 'Port (Nummer) des Verzeichnisses',
145
+    'entree_signature' => 'Unterschrift',
146
+    'entree_titre_obligatoire' => '<b>Titel</b> [Pflichtfeld]<br />',
147
+    'entree_url' => 'Adresse (URL) Ihrer Website',
148
+    'entree_url_2' => 'Adresse (URL) der Website',
149
+    'erreur_connect_deja_existant' => 'Ein Server mit diesem Namen existiert bereits.',
150
+    'erreur_contenu_suspect' => 'Text mit Escape-Zeichen',
151
+    'erreur_email_deja_existant' => 'Diese Adresse ist bereits gespeichert.',
152
+    'erreur_nom_connect_incorrect' => 'Dieser Servername ist nicht zulässig.',
153
+    'erreur_plugin_attribut_balise_manquant' => 'Attribut @attribut@ fehlt im Tag @balise@.',
154
+    'erreur_plugin_desinstalation_echouee' => 'Das Deinstallieren des Plugins ist fehlgeschlagen. Sie können es jedoch deaktivieren.',
155
+    'erreur_plugin_fichier_absent' => 'Datei nicht vorhanden',
156
+    'erreur_plugin_fichier_def_absent' => 'Definitionsdatei nicht vorhanden',
157
+    'erreur_plugin_nom_fonction_interdit' => 'Unzulässiger Funktionsname',
158
+    'erreur_plugin_nom_manquant' => 'Name des Plugin fehlt',
159
+    'erreur_plugin_prefix_manquant' => 'Namespace des Plugin nicht definiert',
160
+    'erreur_plugin_tag_plugin_absent' => '&lt;plugin&gt; fehlt in der Definitionsdatei',
161
+    'erreur_plugin_version_manquant' => 'Version des Plugin fehlt',
162
+    'erreur_type_fichier' => 'Falsches Dateiformat',
163 163
 
164
-	// H
165
-	'htaccess_a_simuler' => 'Achtung: Ihr HTTP-Server ist so konfiguriert, daß er @htaccess@ Dateien ignoriert. Eine sichere Konfiguration des Servers erzielen sie, indem sie diese Einstellung ändern, oder indem sie die Konstanten  @constantes@ in der Datei mes_options.php so setzen, daß die Verzeichnisse außerhalb des @document_root@ liegen.',
166
-	'htaccess_inoperant' => 'htaccess unwirksam',
164
+    // H
165
+    'htaccess_a_simuler' => 'Achtung: Ihr HTTP-Server ist so konfiguriert, daß er @htaccess@ Dateien ignoriert. Eine sichere Konfiguration des Servers erzielen sie, indem sie diese Einstellung ändern, oder indem sie die Konstanten  @constantes@ in der Datei mes_options.php so setzen, daß die Verzeichnisse außerhalb des @document_root@ liegen.',
166
+    'htaccess_inoperant' => 'htaccess unwirksam',
167 167
 
168
-	// I
169
-	'ical_info1' => 'Diese Seite ermöglicht auf mehrere Arten an der Entwicklung der Website teilzunehmen.',
170
-	'ical_info2' => 'Um mehr über diese Techniken zu erfahren, lesen Sie bitte die <a href="@spipnet@">SPIP Dokumentation</a>.',
171
-	'ical_info_calendrier' => 'Sie verfügen über zwei Kalender. Einer gibt Ihnen eine Übersicht über die Website und alle dort veröffentlichten Artikel. Der zweite enthält editorische Ankündigungen und Ihre persönlichen Nachrichten. Sie allein haben Zugriff auf ihn indem Sie Ihr Passwort eingeben. Sie könne es ändern, indem Sie Ihr Zugangspasswort für diese Website ändern.',
172
-	'ical_methode_http' => 'Download',
173
-	'ical_methode_webcal' => 'Synchronisierung (webcal://)',
174
-	'ical_texte_prive' => 'Dieser nur für Sie selbst zugängliche Kalender hält Sie auf dem Laufenden über die internen redaktionellen Vorgänge dieser Website (Aufgaben und persönliche Termine, vorgeschlagene Artikel und Meldungen ...).',
175
-	'ical_texte_public' => 'Dieser Kalender gibt Ihnen einen Überblick über die Ereignisse im öffentlichen Bereich der Website.',
176
-	'ical_texte_rss' => 'Sie können die Neuheiten dieser Website mit einem beliebigen Programm anzeigen, dass das Format XML/RSS (Rich Site Summary) beherrscht. SPIP nutz dieses Protokoll auch, um neue Einträge aus anderen Websites zu übernehmen (sog. syndizierte Websites).',
177
-	'ical_titre_js' => 'Javascript',
178
-	'ical_titre_mailing' => 'Mailing-List',
179
-	'ical_titre_rss' => '"Backend" Datei',
180
-	'icone_accueil' => 'Start',
181
-	'icone_activer_cookie' => 'Verwaltungs-Cookie setzen',
182
-	'icone_activite' => 'Aktivität',
183
-	'icone_admin_plugin' => 'Plugin-Verwaltung',
184
-	'icone_administration' => 'Wartung',
185
-	'icone_afficher_auteurs' => 'Autoren anzeigen',
186
-	'icone_afficher_visiteurs' => 'Besucher anzeigen',
187
-	'icone_arret_discussion' => 'Aus dieser Diskussion aussteigen',
188
-	'icone_calendrier' => 'Kalender',
189
-	'icone_configuration' => 'Konfiguration',
190
-	'icone_creer_auteur' => 'Neuen Autor anlegen und diesem Artikel zuordnen',
191
-	'icone_creer_mot_cle' => 'Neues Schlagwort anlegen und mit diesem Artikel verknüpfen',
192
-	'icone_creer_rubrique_2' => 'Neue Rubrik anlegen',
193
-	'icone_developpement' => 'Entwicklung',
194
-	'icone_edition' => 'Redaktion',
195
-	'icone_ma_langue' => 'Meine Sprache',
196
-	'icone_mes_infos' => 'Meine Informationen',
197
-	'icone_mes_preferences' => 'Meine Einstellungen',
198
-	'icone_modifier_article' => 'Artikel bearbeiten',
199
-	'icone_modifier_rubrique' => 'Rubrik bearbeiten',
200
-	'icone_publication' => 'Veröffentlichen',
201
-	'icone_relancer_signataire' => 'Unterzeichner erneut benachrichtigen',
202
-	'icone_retour' => 'Zurück',
203
-	'icone_retour_article' => 'Zurück zum Artikel',
204
-	'icone_squelette' => 'Skelette',
205
-	'icone_suivi_publication' => 'Verlauf der Veröffentlichungen',
206
-	'icone_supprimer_cookie' => 'Verwaltungs-Cookie löschen',
207
-	'icone_supprimer_rubrique' => 'Rubrik löschen',
208
-	'icone_supprimer_signature' => 'Unterschrift löschen',
209
-	'icone_valider_signature' => 'Unterschrift bestätigen',
210
-	'image_administrer_rubrique' => 'Sie können diese Rubrik verwalten',
211
-	'impossible_modifier_login_auteur' => 'Login-ID kann nicht geändert werden.',
212
-	'impossible_modifier_pass_auteur' => 'Passwort kann nicht geändert werden.',
213
-	'info_1_article' => '1 Artikel',
214
-	'info_1_auteur' => '1 Autor',
215
-	'info_1_message' => '1 Nachricht',
216
-	'info_1_mot_cle' => '1 Schlagwort',
217
-	'info_1_rubrique' => '1 Rubrik',
218
-	'info_1_visiteur' => '1 Besucher',
219
-	'info_activer_cookie' => 'Sie können ein <b>Verwaltungs-Cookie</b> setzen. Es erlaubt Ihnen, Artikel und Rubriken direkt aus der Website zu bearbeiten.',
220
-	'info_activer_menu_developpement' => 'Entwicklermenü anzeigen',
221
-	'info_admin_etre_webmestre' => 'Mir Webmaster-Rechte geben',
222
-	'info_admin_je_suis_webmestre' => 'Ich bin <b>Webmaster</b>',
223
-	'info_admin_statuer_webmestre' => 'Diesem Administrator Webmaster-Rechte geben',
224
-	'info_admin_webmestre' => 'Dieser Administrator ist <b>Webmaster</b>',
225
-	'info_administrateur' => 'Administrator',
226
-	'info_administrateur_1' => 'Administrator',
227
-	'info_administrateur_2' => 'der Website (<i>vorsichtig einsetzen</i>)',
228
-	'info_administrateur_site_01' => 'Wenn Sie Administrator der Website sind, bitte',
229
-	'info_administrateur_site_02' => 'auf diesen Link klicken.',
230
-	'info_administrateurs' => 'Administratoren',
231
-	'info_administrer_rubrique' => 'Sie können diese Rubrik verwalten',
232
-	'info_adresse' => 'an Adresse:',
233
-	'info_adresse_desinscription' => 'Adresse für die Abmeldung:',
234
-	'info_adresse_url' => 'Adresse (URL) der öffentlichen Website',
235
-	'info_afficher_par_nb' => 'Anzeigen nach',
236
-	'info_aide_en_ligne' => 'SPIP Online-Hilfe',
237
-	'info_ajout_image' => 'Wenn Sie Bilder als Dokumente anlegen, die einem Artikel zugeordnet sind, kann SPIP automatisch (Miniatur-)Vorschaubilder dazu erstellen. Sie können so eine automatische Galerie oder Bildermappe einrichten.',
238
-	'info_ajouter_rubrique' => 'Eine weitere zu verwaltende Rubrik hinzufügen:',
239
-	'info_annonce_nouveautes' => 'Ankündigung der Neuigkeiten',
240
-	'info_article' => 'Artikel',
241
-	'info_article_2' => 'Artikel',
242
-	'info_article_a_paraitre' => 'Vordatierte Artikel, die noch nicht erschienen sind.',
243
-	'info_articles_02' => 'Artikel',
244
-	'info_articles_2' => 'Artikel',
245
-	'info_articles_auteur' => 'Alle Artikel dieses Autors',
246
-	'info_articles_miens' => 'Meine Artikel',
247
-	'info_articles_tous' => 'Alle Artikel',
248
-	'info_articles_trouves' => 'Gefundene Artikel',
249
-	'info_attente_validation' => 'Ihre zur Veröffentlichung vorgeschlagenen Artikel',
250
-	'info_aucun_article' => 'Kein Artikel',
251
-	'info_aucun_auteur' => 'Kein Autor',
252
-	'info_aucun_message' => 'Keine Nachricht',
253
-	'info_aucun_rubrique' => 'Keine Rubrik',
254
-	'info_aujourdhui' => 'heute: ',
255
-	'info_auteur_gere_rubriques' => 'Dieser Autor verwaltet folgende Rubriken :',
256
-	'info_auteur_gere_toutes_rubriques' => 'Dieser Autor verwaltet <b>alle Rubriken</b>.',
257
-	'info_auteur_gere_toutes_rubriques_2' => 'Ich verwalte <b>alle Rubriken</b>.',
258
-	'info_auteurs' => 'Autoren',
259
-	'info_auteurs_par_tri' => 'Autoren@partri@',
260
-	'info_auteurs_trouves' => 'Gefundene Autoren',
261
-	'info_authentification_externe' => 'Externe Authentifizierung',
262
-	'info_avertissement' => 'Warnung',
263
-	'info_barre_outils' => 'mit Symbolleiste?',
264
-	'info_base_installee' => 'Die Struktur Ihrer Datenbank wurde angelegt.',
265
-	'info_bio' => 'Biographie',
266
-	'info_cache_desactive' => 'Der Cache ist vorübergehend deaktiviert.',
267
-	'info_chapeau' => 'Kopf',
268
-	'info_chapeau_2' => 'Kopf:',
269
-	'info_chemin_acces_1' => 'Optionen: <b>Pfad im Verzeichnis</b>',
270
-	'info_chemin_acces_2' => 'Sie müssen jetzt den Pfad zu den Informationen im Verzeichnis angeben. Diese Information ist unbedingt erforderlich, um die Benutzerprofile im Verzeichnis lesen zu können.',
271
-	'info_chemin_acces_annuaire' => 'Optionen: <b>Pfad im Verzeichnis</b>',
272
-	'info_choix_base' => 'Schritt 3: ',
273
-	'info_classement_1' => ' von @liste@',
274
-	'info_classement_2' => 'von @liste@',
275
-	'info_code_acces' => 'Vergessen Sie ihre Zugangsdaten nicht!',
276
-	'info_config_suivi' => 'Wenn es sich bei dieser Adresse um eine Mailing-Liste handelt, können Sie unten die Adresse angeben, unter der sich Teilnehmer der Website anmelden können. Es kann sich um den URL einer Webseite handeln (die ein Anmeldeformular enthält) oder um eine E-Mail Adresse mit angehängtem Parameter (z.B. <tt>@adresse_suivi@?subject=subscribe</tt>):',
277
-	'info_config_suivi_explication' => 'Sie können die Mailing-Liste dieser Website abonnieren. Sie werden dann per E-Mail über neu zur Veröffentlichung vorgeschlagene Artikel informiert.',
278
-	'info_confirmer_passe' => 'Neues Passwort bestätigen:',
279
-	'info_conflit_edition_avis_non_sauvegarde' => 'Achtung, die folgenden Felder wurden von anderen geändert. Ihre Änderungen in diesen Feldern wurden deshalb nicht gespeichert.',
280
-	'info_conflit_edition_differences' => 'Unterschiede:',
281
-	'info_conflit_edition_version_enregistree' => 'Die gespeicherte Fassung:',
282
-	'info_conflit_edition_votre_version' => 'Ihre Fassung:',
283
-	'info_connexion_base' => 'Test der Verbindung zur Datenbank',
284
-	'info_connexion_base_donnee' => 'Verbindung mit Ihrer Datenbank',
285
-	'info_connexion_ldap_ok' => 'Die LDAP-Verbindung wurde hergestellt.</b><p> Sie können mit dem nächsten Schritt fortfahren.</p>',
286
-	'info_connexion_mysql' => 'Verbindung zur SQL-Datenbank',
287
-	'info_connexion_ok' => 'Die Verbindung wurde hergestellt.',
288
-	'info_contact' => 'Kontakt',
289
-	'info_contenu_articles' => 'Inhalt der Artikel',
290
-	'info_contributions' => 'Beiträge',
291
-	'info_creation_paragraphe' => 'Um einen Absatz einzufügen, lassen Sie einfach eine Zeile frei.',
292
-	'info_creation_rubrique' => 'Bevor Sie Artikel schreiben können,<br /> müssen Sie eine Rubrik anlegen.<br />',
293
-	'info_creation_tables' => 'Anlegen der Datentabellen',
294
-	'info_creer_base' => 'Neue Datenbank <b>anlegen</b>:',
295
-	'info_dans_rubrique' => 'In der Rubrik:',
296
-	'info_date_publication_anterieure' => 'Datum einer früheren Bearbeitung:',
297
-	'info_date_referencement' => 'DATUM DER VERLINKUNG DIESER WEBSITE:',
298
-	'info_derniere_etape' => 'Fertig!',
299
-	'info_descriptif' => 'Beschreibung:',
300
-	'info_desinstaller_plugin' => 'löscht die Daten und desktiviert das Plugin',
301
-	'info_discussion_cours' => 'Aktuelle Diskussionen',
302
-	'info_ecrire_article' => 'Bevor Sie Artikel schreiben könnnen, müssen Sie mindestens eine Rubrik anlegen.',
303
-	'info_email_envoi' => 'Absenderadresse (freiwillige Angabe)',
304
-	'info_email_envoi_txt' => 'Geben Sie hier die Absenderadresse der E-Mails an (ohne diese Angabe wird die Empfängeradresse als Absender eingetragen). ',
305
-	'info_email_webmestre' => 'E-Mail des Webmasters',
306
-	'info_envoi_email_automatique' => 'Automatischer Mailversand',
307
-	'info_envoyer_maintenant' => 'Jetzt schicken',
308
-	'info_etape_suivante' => 'Weiter',
309
-	'info_etape_suivante_1' => 'Sie können den nächsten Schritt ausführen.',
310
-	'info_etape_suivante_2' => 'Sie können den nächsten Schritt ausführen.',
311
-	'info_exceptions_proxy' => 'Ausnahmen für den Proxy',
312
-	'info_exportation_base' => 'Export der Datenbank nach @archive@',
313
-	'info_facilite_suivi_activite' => 'Um die editorische Arbeit zu erleichtern kann SPIP Veröffentlichungsvorschläge und Freischaltungen z.B. an eine Mailing-Liste der Redakteure schicken. Geben Sie eine oder mehrere Adressen an, die durch Kommata getrennt sind. ',
314
-	'info_fichiers_authent' => '“.htpasswd” Dateien',
315
-	'info_forums_abo_invites' => 'Ihre Website hat Foren für eingetragene Teilnehmer. Ihre Leser werden aus diesem Gund aufgefordert, sich bei Ihrer Website anzumelden.',
316
-	'info_gauche_admin_tech' => '<b>Diese Seite ist nur für den Verantwortlichen der Website zugänglich.</b><p>Sie erlaubt bestimmte technische Wartungsvorgänge auszulösen. Für manche Funktionen ist die Authentifizierung per FTP Voraussetzung.',
317
-	'info_gauche_admin_vider' => '<b>Diese Seite ist nur für den Verantwortlichen der Website zugänglich.</b><p>Sie erlaubt bestimmte technische Wartungsvorgänge auszulösen. Für manche Funktionen ist die Authentifizierung per FTP Voraussetzung.',
318
-	'info_gauche_auteurs' => 'Hier sehen Sie alle Autoren der Website.
168
+    // I
169
+    'ical_info1' => 'Diese Seite ermöglicht auf mehrere Arten an der Entwicklung der Website teilzunehmen.',
170
+    'ical_info2' => 'Um mehr über diese Techniken zu erfahren, lesen Sie bitte die <a href="@spipnet@">SPIP Dokumentation</a>.',
171
+    'ical_info_calendrier' => 'Sie verfügen über zwei Kalender. Einer gibt Ihnen eine Übersicht über die Website und alle dort veröffentlichten Artikel. Der zweite enthält editorische Ankündigungen und Ihre persönlichen Nachrichten. Sie allein haben Zugriff auf ihn indem Sie Ihr Passwort eingeben. Sie könne es ändern, indem Sie Ihr Zugangspasswort für diese Website ändern.',
172
+    'ical_methode_http' => 'Download',
173
+    'ical_methode_webcal' => 'Synchronisierung (webcal://)',
174
+    'ical_texte_prive' => 'Dieser nur für Sie selbst zugängliche Kalender hält Sie auf dem Laufenden über die internen redaktionellen Vorgänge dieser Website (Aufgaben und persönliche Termine, vorgeschlagene Artikel und Meldungen ...).',
175
+    'ical_texte_public' => 'Dieser Kalender gibt Ihnen einen Überblick über die Ereignisse im öffentlichen Bereich der Website.',
176
+    'ical_texte_rss' => 'Sie können die Neuheiten dieser Website mit einem beliebigen Programm anzeigen, dass das Format XML/RSS (Rich Site Summary) beherrscht. SPIP nutz dieses Protokoll auch, um neue Einträge aus anderen Websites zu übernehmen (sog. syndizierte Websites).',
177
+    'ical_titre_js' => 'Javascript',
178
+    'ical_titre_mailing' => 'Mailing-List',
179
+    'ical_titre_rss' => '"Backend" Datei',
180
+    'icone_accueil' => 'Start',
181
+    'icone_activer_cookie' => 'Verwaltungs-Cookie setzen',
182
+    'icone_activite' => 'Aktivität',
183
+    'icone_admin_plugin' => 'Plugin-Verwaltung',
184
+    'icone_administration' => 'Wartung',
185
+    'icone_afficher_auteurs' => 'Autoren anzeigen',
186
+    'icone_afficher_visiteurs' => 'Besucher anzeigen',
187
+    'icone_arret_discussion' => 'Aus dieser Diskussion aussteigen',
188
+    'icone_calendrier' => 'Kalender',
189
+    'icone_configuration' => 'Konfiguration',
190
+    'icone_creer_auteur' => 'Neuen Autor anlegen und diesem Artikel zuordnen',
191
+    'icone_creer_mot_cle' => 'Neues Schlagwort anlegen und mit diesem Artikel verknüpfen',
192
+    'icone_creer_rubrique_2' => 'Neue Rubrik anlegen',
193
+    'icone_developpement' => 'Entwicklung',
194
+    'icone_edition' => 'Redaktion',
195
+    'icone_ma_langue' => 'Meine Sprache',
196
+    'icone_mes_infos' => 'Meine Informationen',
197
+    'icone_mes_preferences' => 'Meine Einstellungen',
198
+    'icone_modifier_article' => 'Artikel bearbeiten',
199
+    'icone_modifier_rubrique' => 'Rubrik bearbeiten',
200
+    'icone_publication' => 'Veröffentlichen',
201
+    'icone_relancer_signataire' => 'Unterzeichner erneut benachrichtigen',
202
+    'icone_retour' => 'Zurück',
203
+    'icone_retour_article' => 'Zurück zum Artikel',
204
+    'icone_squelette' => 'Skelette',
205
+    'icone_suivi_publication' => 'Verlauf der Veröffentlichungen',
206
+    'icone_supprimer_cookie' => 'Verwaltungs-Cookie löschen',
207
+    'icone_supprimer_rubrique' => 'Rubrik löschen',
208
+    'icone_supprimer_signature' => 'Unterschrift löschen',
209
+    'icone_valider_signature' => 'Unterschrift bestätigen',
210
+    'image_administrer_rubrique' => 'Sie können diese Rubrik verwalten',
211
+    'impossible_modifier_login_auteur' => 'Login-ID kann nicht geändert werden.',
212
+    'impossible_modifier_pass_auteur' => 'Passwort kann nicht geändert werden.',
213
+    'info_1_article' => '1 Artikel',
214
+    'info_1_auteur' => '1 Autor',
215
+    'info_1_message' => '1 Nachricht',
216
+    'info_1_mot_cle' => '1 Schlagwort',
217
+    'info_1_rubrique' => '1 Rubrik',
218
+    'info_1_visiteur' => '1 Besucher',
219
+    'info_activer_cookie' => 'Sie können ein <b>Verwaltungs-Cookie</b> setzen. Es erlaubt Ihnen, Artikel und Rubriken direkt aus der Website zu bearbeiten.',
220
+    'info_activer_menu_developpement' => 'Entwicklermenü anzeigen',
221
+    'info_admin_etre_webmestre' => 'Mir Webmaster-Rechte geben',
222
+    'info_admin_je_suis_webmestre' => 'Ich bin <b>Webmaster</b>',
223
+    'info_admin_statuer_webmestre' => 'Diesem Administrator Webmaster-Rechte geben',
224
+    'info_admin_webmestre' => 'Dieser Administrator ist <b>Webmaster</b>',
225
+    'info_administrateur' => 'Administrator',
226
+    'info_administrateur_1' => 'Administrator',
227
+    'info_administrateur_2' => 'der Website (<i>vorsichtig einsetzen</i>)',
228
+    'info_administrateur_site_01' => 'Wenn Sie Administrator der Website sind, bitte',
229
+    'info_administrateur_site_02' => 'auf diesen Link klicken.',
230
+    'info_administrateurs' => 'Administratoren',
231
+    'info_administrer_rubrique' => 'Sie können diese Rubrik verwalten',
232
+    'info_adresse' => 'an Adresse:',
233
+    'info_adresse_desinscription' => 'Adresse für die Abmeldung:',
234
+    'info_adresse_url' => 'Adresse (URL) der öffentlichen Website',
235
+    'info_afficher_par_nb' => 'Anzeigen nach',
236
+    'info_aide_en_ligne' => 'SPIP Online-Hilfe',
237
+    'info_ajout_image' => 'Wenn Sie Bilder als Dokumente anlegen, die einem Artikel zugeordnet sind, kann SPIP automatisch (Miniatur-)Vorschaubilder dazu erstellen. Sie können so eine automatische Galerie oder Bildermappe einrichten.',
238
+    'info_ajouter_rubrique' => 'Eine weitere zu verwaltende Rubrik hinzufügen:',
239
+    'info_annonce_nouveautes' => 'Ankündigung der Neuigkeiten',
240
+    'info_article' => 'Artikel',
241
+    'info_article_2' => 'Artikel',
242
+    'info_article_a_paraitre' => 'Vordatierte Artikel, die noch nicht erschienen sind.',
243
+    'info_articles_02' => 'Artikel',
244
+    'info_articles_2' => 'Artikel',
245
+    'info_articles_auteur' => 'Alle Artikel dieses Autors',
246
+    'info_articles_miens' => 'Meine Artikel',
247
+    'info_articles_tous' => 'Alle Artikel',
248
+    'info_articles_trouves' => 'Gefundene Artikel',
249
+    'info_attente_validation' => 'Ihre zur Veröffentlichung vorgeschlagenen Artikel',
250
+    'info_aucun_article' => 'Kein Artikel',
251
+    'info_aucun_auteur' => 'Kein Autor',
252
+    'info_aucun_message' => 'Keine Nachricht',
253
+    'info_aucun_rubrique' => 'Keine Rubrik',
254
+    'info_aujourdhui' => 'heute: ',
255
+    'info_auteur_gere_rubriques' => 'Dieser Autor verwaltet folgende Rubriken :',
256
+    'info_auteur_gere_toutes_rubriques' => 'Dieser Autor verwaltet <b>alle Rubriken</b>.',
257
+    'info_auteur_gere_toutes_rubriques_2' => 'Ich verwalte <b>alle Rubriken</b>.',
258
+    'info_auteurs' => 'Autoren',
259
+    'info_auteurs_par_tri' => 'Autoren@partri@',
260
+    'info_auteurs_trouves' => 'Gefundene Autoren',
261
+    'info_authentification_externe' => 'Externe Authentifizierung',
262
+    'info_avertissement' => 'Warnung',
263
+    'info_barre_outils' => 'mit Symbolleiste?',
264
+    'info_base_installee' => 'Die Struktur Ihrer Datenbank wurde angelegt.',
265
+    'info_bio' => 'Biographie',
266
+    'info_cache_desactive' => 'Der Cache ist vorübergehend deaktiviert.',
267
+    'info_chapeau' => 'Kopf',
268
+    'info_chapeau_2' => 'Kopf:',
269
+    'info_chemin_acces_1' => 'Optionen: <b>Pfad im Verzeichnis</b>',
270
+    'info_chemin_acces_2' => 'Sie müssen jetzt den Pfad zu den Informationen im Verzeichnis angeben. Diese Information ist unbedingt erforderlich, um die Benutzerprofile im Verzeichnis lesen zu können.',
271
+    'info_chemin_acces_annuaire' => 'Optionen: <b>Pfad im Verzeichnis</b>',
272
+    'info_choix_base' => 'Schritt 3: ',
273
+    'info_classement_1' => ' von @liste@',
274
+    'info_classement_2' => 'von @liste@',
275
+    'info_code_acces' => 'Vergessen Sie ihre Zugangsdaten nicht!',
276
+    'info_config_suivi' => 'Wenn es sich bei dieser Adresse um eine Mailing-Liste handelt, können Sie unten die Adresse angeben, unter der sich Teilnehmer der Website anmelden können. Es kann sich um den URL einer Webseite handeln (die ein Anmeldeformular enthält) oder um eine E-Mail Adresse mit angehängtem Parameter (z.B. <tt>@adresse_suivi@?subject=subscribe</tt>):',
277
+    'info_config_suivi_explication' => 'Sie können die Mailing-Liste dieser Website abonnieren. Sie werden dann per E-Mail über neu zur Veröffentlichung vorgeschlagene Artikel informiert.',
278
+    'info_confirmer_passe' => 'Neues Passwort bestätigen:',
279
+    'info_conflit_edition_avis_non_sauvegarde' => 'Achtung, die folgenden Felder wurden von anderen geändert. Ihre Änderungen in diesen Feldern wurden deshalb nicht gespeichert.',
280
+    'info_conflit_edition_differences' => 'Unterschiede:',
281
+    'info_conflit_edition_version_enregistree' => 'Die gespeicherte Fassung:',
282
+    'info_conflit_edition_votre_version' => 'Ihre Fassung:',
283
+    'info_connexion_base' => 'Test der Verbindung zur Datenbank',
284
+    'info_connexion_base_donnee' => 'Verbindung mit Ihrer Datenbank',
285
+    'info_connexion_ldap_ok' => 'Die LDAP-Verbindung wurde hergestellt.</b><p> Sie können mit dem nächsten Schritt fortfahren.</p>',
286
+    'info_connexion_mysql' => 'Verbindung zur SQL-Datenbank',
287
+    'info_connexion_ok' => 'Die Verbindung wurde hergestellt.',
288
+    'info_contact' => 'Kontakt',
289
+    'info_contenu_articles' => 'Inhalt der Artikel',
290
+    'info_contributions' => 'Beiträge',
291
+    'info_creation_paragraphe' => 'Um einen Absatz einzufügen, lassen Sie einfach eine Zeile frei.',
292
+    'info_creation_rubrique' => 'Bevor Sie Artikel schreiben können,<br /> müssen Sie eine Rubrik anlegen.<br />',
293
+    'info_creation_tables' => 'Anlegen der Datentabellen',
294
+    'info_creer_base' => 'Neue Datenbank <b>anlegen</b>:',
295
+    'info_dans_rubrique' => 'In der Rubrik:',
296
+    'info_date_publication_anterieure' => 'Datum einer früheren Bearbeitung:',
297
+    'info_date_referencement' => 'DATUM DER VERLINKUNG DIESER WEBSITE:',
298
+    'info_derniere_etape' => 'Fertig!',
299
+    'info_descriptif' => 'Beschreibung:',
300
+    'info_desinstaller_plugin' => 'löscht die Daten und desktiviert das Plugin',
301
+    'info_discussion_cours' => 'Aktuelle Diskussionen',
302
+    'info_ecrire_article' => 'Bevor Sie Artikel schreiben könnnen, müssen Sie mindestens eine Rubrik anlegen.',
303
+    'info_email_envoi' => 'Absenderadresse (freiwillige Angabe)',
304
+    'info_email_envoi_txt' => 'Geben Sie hier die Absenderadresse der E-Mails an (ohne diese Angabe wird die Empfängeradresse als Absender eingetragen). ',
305
+    'info_email_webmestre' => 'E-Mail des Webmasters',
306
+    'info_envoi_email_automatique' => 'Automatischer Mailversand',
307
+    'info_envoyer_maintenant' => 'Jetzt schicken',
308
+    'info_etape_suivante' => 'Weiter',
309
+    'info_etape_suivante_1' => 'Sie können den nächsten Schritt ausführen.',
310
+    'info_etape_suivante_2' => 'Sie können den nächsten Schritt ausführen.',
311
+    'info_exceptions_proxy' => 'Ausnahmen für den Proxy',
312
+    'info_exportation_base' => 'Export der Datenbank nach @archive@',
313
+    'info_facilite_suivi_activite' => 'Um die editorische Arbeit zu erleichtern kann SPIP Veröffentlichungsvorschläge und Freischaltungen z.B. an eine Mailing-Liste der Redakteure schicken. Geben Sie eine oder mehrere Adressen an, die durch Kommata getrennt sind. ',
314
+    'info_fichiers_authent' => '“.htpasswd” Dateien',
315
+    'info_forums_abo_invites' => 'Ihre Website hat Foren für eingetragene Teilnehmer. Ihre Leser werden aus diesem Gund aufgefordert, sich bei Ihrer Website anzumelden.',
316
+    'info_gauche_admin_tech' => '<b>Diese Seite ist nur für den Verantwortlichen der Website zugänglich.</b><p>Sie erlaubt bestimmte technische Wartungsvorgänge auszulösen. Für manche Funktionen ist die Authentifizierung per FTP Voraussetzung.',
317
+    'info_gauche_admin_vider' => '<b>Diese Seite ist nur für den Verantwortlichen der Website zugänglich.</b><p>Sie erlaubt bestimmte technische Wartungsvorgänge auszulösen. Für manche Funktionen ist die Authentifizierung per FTP Voraussetzung.',
318
+    'info_gauche_auteurs' => 'Hier sehen Sie alle Autoren der Website.
319 319
 Ihr Status wird durch die Farbe ihres Symbols angezeigt (Redakteur = gelb; Administrator = grün). ',
320
-	'info_gauche_auteurs_exterieurs' => 'Externe Autoren ohne Zugang zum Redaktionssystem werden mit einem blauen Symbol gekennzeichnet, gelöschte Autoren haben eine Mülltonne als Symbol.',
321
-	'info_gauche_messagerie' => 'Nachrichtensystem: SPIP ermöglicht den Austausch von Nachrichten zwischen Redakteuren, persönliche Merkzettel und Ankündigungen im privaten Arbeitsbereich der Redakteure (nur Administratoren können diese verschicken).',
322
-	'info_gauche_statistiques_referers' => 'Diese Seite zeigt Ihnen <i>REFERER</i>, d.h. Webadressen mit Links zu Ihrer Website. Angezeigt werden nur Links von gestern und heute, diese Liste wird alle 24 Stunden auf Null gesetzt.',
323
-	'info_gauche_visiteurs_enregistres' => 'Hier sehen Sie die im öffentlichen Bereich der Website angemeldeten Besucher (Teilnahme an Foren nur mit gültiger E-Mail Adresse).',
324
-	'info_generation_miniatures_images' => 'Anlegen der Vorschaubilder',
325
-	'info_gerer_trad_objets' => '@objets@: Übersetzungslinks verwalten',
326
-	'info_hebergeur_desactiver_envoi_email' => 'Manche ISPs verhindern den Versand von Mails mit PHP. Die Mailfunktionen von SPIP funktionieren dann nicht.',
327
-	'info_hier' => 'Gestern:',
328
-	'info_identification_publique' => 'Ihre öffentliche Identität ...',
329
-	'info_image_process' => 'Bitte wählen Sie das beste Verfahren zum Generieren der Miniaturbilder, indem Sie auf ein Bild klicken.',
330
-	'info_image_process2' => 'Wenn kein Bild angezeigt wird, ist der Server ihrer Website nicht für die Verwendung solcher Werkzeuge eingerichtet. Wenn Sie diese Funktionen nutzen möchten, wenden Sie sich bitte an den verantwortlichen Techniker und bitten ihn, die Erweiterungen «GD» oder «Imagick» einzurichten.',
331
-	'info_images_auto' => 'automatisch berechnete Bilder',
332
-	'info_informations_personnelles' => 'Persönliche Informationen',
333
-	'info_inscription' => 'Angemeldet am',
334
-	'info_inscription_automatique' => 'Automatische Anmeldung neuer Redakteure',
335
-	'info_jeu_caractere' => 'Zeichensatz der Website',
336
-	'info_jours' => 'Tage',
337
-	'info_laisser_champs_vides' => 'diese Felder frei lassen)',
338
-	'info_langues' => 'Sprachen der Website',
339
-	'info_ldap_ok' => 'Die LDAP-Authentifizierung ist installiert.',
340
-	'info_lien_hypertexte' => 'Hyperlink:',
341
-	'info_liste_nouveautes_envoyee' => 'Die Liste der Neuerscheinungen wurde versand.',
342
-	'info_liste_redacteurs_connectes' => 'Liste der zur Zeit angemeldeten Redakteure',
343
-	'info_login_existant' => 'Dieses Login ist bereits vergeben.',
344
-	'info_login_trop_court' => 'Login zu kurz.',
345
-	'info_login_trop_court_car_pluriel' => 'Ihr Login muss mindestens @nb@ Zeichen haben.',
346
-	'info_logos' => 'Die Logos',
347
-	'info_maximum' => 'Maximum:',
348
-	'info_meme_rubrique' => 'In der gleichen Rubrik',
349
-	'info_message_en_redaction' => 'IHRE NACHRICHTEN IN BEARBEITUNG',
350
-	'info_message_technique' => 'Technische Nachricht:',
351
-	'info_messagerie_interne' => 'Interne Nachrichten',
352
-	'info_mise_a_niveau_base' => 'Update Ihrer SQL-Datenbank',
353
-	'info_mise_a_niveau_base_2' => '{{ACHTUNG!}} Sie haben eine {ältere} Version der SPIP-Dateien installiert als sich vorher auf Ihrem Server befand. Ihre Datenbank wird möglicherweise zerstört und Ihre Website wird nict mehr funktionieren.<br />{{Installieren Sie SPIP noch einmal.}}',
354
-	'info_modification_enregistree' => 'Ihre Änderung wurde gespeichert.',
355
-	'info_modifier_auteur' => 'Autor bearbeiten:',
356
-	'info_modifier_rubrique' => 'Rubrik bearbeiten:',
357
-	'info_modifier_titre' => 'Bearbeiten: @titre@',
358
-	'info_mon_site_spip' => 'Meine SPIP-Site',
359
-	'info_moyenne' => 'Durchschnitt: ',
360
-	'info_multi_cet_article' => 'Dieser Artikel ist auf: ',
361
-	'info_multi_langues_choisies' => 'Bitte wählen Sie hier die Sprachen aus, die den Redakteuren Ihrer Website zur Verfügung stehen sollen. Die Sprachen, welche bereits in Ihrer Website verwendet werden (oben auf der Liste), können nicht abgeschaltet werden.',
362
-	'info_multi_objets' => '@objets@: Sprachauswahlmenü aktivieren',
363
-	'info_multi_secteurs' => '... nur für Rubriken der obersten Ebene?',
364
-	'info_nb_articles' => '@nb@ Artikel',
365
-	'info_nb_auteurs' => '@nb@ Autoren',
366
-	'info_nb_messages' => '@nb@ Nachrichten',
367
-	'info_nb_mots_cles' => '@nb@ Schlagworte',
368
-	'info_nb_rubriques' => '@nb@ Rubriken',
369
-	'info_nb_visiteurs' => '@nb@ Besucher',
370
-	'info_nom' => 'Name',
371
-	'info_nom_destinataire' => 'Name des Empfängers',
372
-	'info_nom_pas_conforme' => 'HTNL-Tags sind nicht zugelassen.',
373
-	'info_nom_site' => 'Name Ihrer Website',
374
-	'info_nombre_articles' => '@nb_articles@ Artikel,',
375
-	'info_nombre_rubriques' => '@nb_rubriques@ Rubriken, ',
376
-	'info_nombre_sites' => '@nb_sites@ Websites, ',
377
-	'info_non_deplacer' => 'Bitte nicht verschieben...',
378
-	'info_non_envoi_annonce_dernieres_nouveautes' => 'SPIP kann regelmäßig die letzten Neuigkeiten der Website verschicken. (vor Kurzem erschienene Artikel und Meldungen).',
379
-	'info_non_envoi_liste_nouveautes' => 'Keine Liste der Neuigkeiten verschicken.',
380
-	'info_non_modifiable' => 'kann nicht geändert werden.',
381
-	'info_non_suppression_mot_cle' => 'ich möchte dieses Schlagwort nicht löschen.',
382
-	'info_notes' => 'Anmerkungen', # Fußnoten bzw. #NOTES werden besser als "Anmerkungen" denn als "Notizen" bezeichnet.
383
-	'info_nouvel_article' => 'Neuer Artikel',
384
-	'info_nouvelle_traduction' => 'Neue Übersetzung:',
385
-	'info_numero_article' => 'ARTIKEL NUMMER:',
386
-	'info_obligatoire_02' => ' (erforderlich)',
387
-	'info_option_accepter_visiteurs' => 'Besucher dürfen sich als Leser der Website anmelden.',
388
-	'info_option_ne_pas_accepter_visiteurs' => 'Anmeldung von Lesern verhindern',
389
-	'info_options_avancees' => 'SPEZIALFUNKTIONEN',
390
-	'info_ou' => 'oder ... ',
391
-	'info_page_interdite' => 'Seite gesperrt',
392
-	'info_par_nom' => 'nach Namen',
393
-	'info_par_nombre_article' => 'nach Anzahl der Artikel',
394
-	'info_par_statut' => 'nach Status',
395
-	'info_par_tri' => '’(nach @tri@)’',
396
-	'info_passe_trop_court' => 'Passwort zu kurz.',
397
-	'info_passe_trop_court_car_pluriel' => 'Das Passwort muss mindestens @nb@ Zeichen haben.',
398
-	'info_passes_identiques' => 'Die zwei Passworte stimmen nicht überein.',
399
-	'info_plus_cinq_car' => 'mehr als 5 Zeichen',
400
-	'info_plus_cinq_car_2' => '(mehr als 5 Zeichen)',
401
-	'info_plus_trois_car' => '(mehr als 3 Zeichen)',
402
-	'info_popularite' => 'Beliebtheit: @popularite@ ; Besuche: @visites@',
403
-	'info_post_scriptum' => 'Post-Scriptum',
404
-	'info_post_scriptum_2' => 'Post-scriptum:',
405
-	'info_pour' => 'für',
406
-	'info_preview_texte' => 'Man kann sich alle Elemente der Website so anzeigen lassen, als ob sie veröffentlicht wären, vorausgesetzt sie haben mindestens den Status « vorgeschlagen » oder man ist ihr Autor . Wem soll diese Möglichkeit zur Verfügung stehen (Adminsitratoren, Redakteure, niemand)?',
407
-	'info_procedez_par_etape' => 'gehen Sie Schritt für Schritt vor',
408
-	'info_procedure_maj_version' => 'Sie müssen die Update-Funktion starten, um Ihre Datenbank an die neue Version von SPIP anzupassen.',
409
-	'info_proxy_ok' => 'Proxytest erfolgreich.',
410
-	'info_ps' => 'P.S.',
411
-	'info_publier' => 'veröffentlichen',
412
-	'info_publies' => 'Ihre veröffentlichten Artikel',
413
-	'info_question_accepter_visiteurs' => 'Bitte aktivieren Sie die folgende Option, wenn sich Besucher Ihrer Website als <i>Leser ohne Zugang zum Redaktionssystem</i> anmelden können.',
414
-	'info_question_inscription_nouveaux_redacteurs' => 'Möchten Sie, dass sich neue Redakteure vom öffentlichen Bereich
320
+    'info_gauche_auteurs_exterieurs' => 'Externe Autoren ohne Zugang zum Redaktionssystem werden mit einem blauen Symbol gekennzeichnet, gelöschte Autoren haben eine Mülltonne als Symbol.',
321
+    'info_gauche_messagerie' => 'Nachrichtensystem: SPIP ermöglicht den Austausch von Nachrichten zwischen Redakteuren, persönliche Merkzettel und Ankündigungen im privaten Arbeitsbereich der Redakteure (nur Administratoren können diese verschicken).',
322
+    'info_gauche_statistiques_referers' => 'Diese Seite zeigt Ihnen <i>REFERER</i>, d.h. Webadressen mit Links zu Ihrer Website. Angezeigt werden nur Links von gestern und heute, diese Liste wird alle 24 Stunden auf Null gesetzt.',
323
+    'info_gauche_visiteurs_enregistres' => 'Hier sehen Sie die im öffentlichen Bereich der Website angemeldeten Besucher (Teilnahme an Foren nur mit gültiger E-Mail Adresse).',
324
+    'info_generation_miniatures_images' => 'Anlegen der Vorschaubilder',
325
+    'info_gerer_trad_objets' => '@objets@: Übersetzungslinks verwalten',
326
+    'info_hebergeur_desactiver_envoi_email' => 'Manche ISPs verhindern den Versand von Mails mit PHP. Die Mailfunktionen von SPIP funktionieren dann nicht.',
327
+    'info_hier' => 'Gestern:',
328
+    'info_identification_publique' => 'Ihre öffentliche Identität ...',
329
+    'info_image_process' => 'Bitte wählen Sie das beste Verfahren zum Generieren der Miniaturbilder, indem Sie auf ein Bild klicken.',
330
+    'info_image_process2' => 'Wenn kein Bild angezeigt wird, ist der Server ihrer Website nicht für die Verwendung solcher Werkzeuge eingerichtet. Wenn Sie diese Funktionen nutzen möchten, wenden Sie sich bitte an den verantwortlichen Techniker und bitten ihn, die Erweiterungen «GD» oder «Imagick» einzurichten.',
331
+    'info_images_auto' => 'automatisch berechnete Bilder',
332
+    'info_informations_personnelles' => 'Persönliche Informationen',
333
+    'info_inscription' => 'Angemeldet am',
334
+    'info_inscription_automatique' => 'Automatische Anmeldung neuer Redakteure',
335
+    'info_jeu_caractere' => 'Zeichensatz der Website',
336
+    'info_jours' => 'Tage',
337
+    'info_laisser_champs_vides' => 'diese Felder frei lassen)',
338
+    'info_langues' => 'Sprachen der Website',
339
+    'info_ldap_ok' => 'Die LDAP-Authentifizierung ist installiert.',
340
+    'info_lien_hypertexte' => 'Hyperlink:',
341
+    'info_liste_nouveautes_envoyee' => 'Die Liste der Neuerscheinungen wurde versand.',
342
+    'info_liste_redacteurs_connectes' => 'Liste der zur Zeit angemeldeten Redakteure',
343
+    'info_login_existant' => 'Dieses Login ist bereits vergeben.',
344
+    'info_login_trop_court' => 'Login zu kurz.',
345
+    'info_login_trop_court_car_pluriel' => 'Ihr Login muss mindestens @nb@ Zeichen haben.',
346
+    'info_logos' => 'Die Logos',
347
+    'info_maximum' => 'Maximum:',
348
+    'info_meme_rubrique' => 'In der gleichen Rubrik',
349
+    'info_message_en_redaction' => 'IHRE NACHRICHTEN IN BEARBEITUNG',
350
+    'info_message_technique' => 'Technische Nachricht:',
351
+    'info_messagerie_interne' => 'Interne Nachrichten',
352
+    'info_mise_a_niveau_base' => 'Update Ihrer SQL-Datenbank',
353
+    'info_mise_a_niveau_base_2' => '{{ACHTUNG!}} Sie haben eine {ältere} Version der SPIP-Dateien installiert als sich vorher auf Ihrem Server befand. Ihre Datenbank wird möglicherweise zerstört und Ihre Website wird nict mehr funktionieren.<br />{{Installieren Sie SPIP noch einmal.}}',
354
+    'info_modification_enregistree' => 'Ihre Änderung wurde gespeichert.',
355
+    'info_modifier_auteur' => 'Autor bearbeiten:',
356
+    'info_modifier_rubrique' => 'Rubrik bearbeiten:',
357
+    'info_modifier_titre' => 'Bearbeiten: @titre@',
358
+    'info_mon_site_spip' => 'Meine SPIP-Site',
359
+    'info_moyenne' => 'Durchschnitt: ',
360
+    'info_multi_cet_article' => 'Dieser Artikel ist auf: ',
361
+    'info_multi_langues_choisies' => 'Bitte wählen Sie hier die Sprachen aus, die den Redakteuren Ihrer Website zur Verfügung stehen sollen. Die Sprachen, welche bereits in Ihrer Website verwendet werden (oben auf der Liste), können nicht abgeschaltet werden.',
362
+    'info_multi_objets' => '@objets@: Sprachauswahlmenü aktivieren',
363
+    'info_multi_secteurs' => '... nur für Rubriken der obersten Ebene?',
364
+    'info_nb_articles' => '@nb@ Artikel',
365
+    'info_nb_auteurs' => '@nb@ Autoren',
366
+    'info_nb_messages' => '@nb@ Nachrichten',
367
+    'info_nb_mots_cles' => '@nb@ Schlagworte',
368
+    'info_nb_rubriques' => '@nb@ Rubriken',
369
+    'info_nb_visiteurs' => '@nb@ Besucher',
370
+    'info_nom' => 'Name',
371
+    'info_nom_destinataire' => 'Name des Empfängers',
372
+    'info_nom_pas_conforme' => 'HTNL-Tags sind nicht zugelassen.',
373
+    'info_nom_site' => 'Name Ihrer Website',
374
+    'info_nombre_articles' => '@nb_articles@ Artikel,',
375
+    'info_nombre_rubriques' => '@nb_rubriques@ Rubriken, ',
376
+    'info_nombre_sites' => '@nb_sites@ Websites, ',
377
+    'info_non_deplacer' => 'Bitte nicht verschieben...',
378
+    'info_non_envoi_annonce_dernieres_nouveautes' => 'SPIP kann regelmäßig die letzten Neuigkeiten der Website verschicken. (vor Kurzem erschienene Artikel und Meldungen).',
379
+    'info_non_envoi_liste_nouveautes' => 'Keine Liste der Neuigkeiten verschicken.',
380
+    'info_non_modifiable' => 'kann nicht geändert werden.',
381
+    'info_non_suppression_mot_cle' => 'ich möchte dieses Schlagwort nicht löschen.',
382
+    'info_notes' => 'Anmerkungen', # Fußnoten bzw. #NOTES werden besser als "Anmerkungen" denn als "Notizen" bezeichnet.
383
+    'info_nouvel_article' => 'Neuer Artikel',
384
+    'info_nouvelle_traduction' => 'Neue Übersetzung:',
385
+    'info_numero_article' => 'ARTIKEL NUMMER:',
386
+    'info_obligatoire_02' => ' (erforderlich)',
387
+    'info_option_accepter_visiteurs' => 'Besucher dürfen sich als Leser der Website anmelden.',
388
+    'info_option_ne_pas_accepter_visiteurs' => 'Anmeldung von Lesern verhindern',
389
+    'info_options_avancees' => 'SPEZIALFUNKTIONEN',
390
+    'info_ou' => 'oder ... ',
391
+    'info_page_interdite' => 'Seite gesperrt',
392
+    'info_par_nom' => 'nach Namen',
393
+    'info_par_nombre_article' => 'nach Anzahl der Artikel',
394
+    'info_par_statut' => 'nach Status',
395
+    'info_par_tri' => '’(nach @tri@)’',
396
+    'info_passe_trop_court' => 'Passwort zu kurz.',
397
+    'info_passe_trop_court_car_pluriel' => 'Das Passwort muss mindestens @nb@ Zeichen haben.',
398
+    'info_passes_identiques' => 'Die zwei Passworte stimmen nicht überein.',
399
+    'info_plus_cinq_car' => 'mehr als 5 Zeichen',
400
+    'info_plus_cinq_car_2' => '(mehr als 5 Zeichen)',
401
+    'info_plus_trois_car' => '(mehr als 3 Zeichen)',
402
+    'info_popularite' => 'Beliebtheit: @popularite@ ; Besuche: @visites@',
403
+    'info_post_scriptum' => 'Post-Scriptum',
404
+    'info_post_scriptum_2' => 'Post-scriptum:',
405
+    'info_pour' => 'für',
406
+    'info_preview_texte' => 'Man kann sich alle Elemente der Website so anzeigen lassen, als ob sie veröffentlicht wären, vorausgesetzt sie haben mindestens den Status « vorgeschlagen » oder man ist ihr Autor . Wem soll diese Möglichkeit zur Verfügung stehen (Adminsitratoren, Redakteure, niemand)?',
407
+    'info_procedez_par_etape' => 'gehen Sie Schritt für Schritt vor',
408
+    'info_procedure_maj_version' => 'Sie müssen die Update-Funktion starten, um Ihre Datenbank an die neue Version von SPIP anzupassen.',
409
+    'info_proxy_ok' => 'Proxytest erfolgreich.',
410
+    'info_ps' => 'P.S.',
411
+    'info_publier' => 'veröffentlichen',
412
+    'info_publies' => 'Ihre veröffentlichten Artikel',
413
+    'info_question_accepter_visiteurs' => 'Bitte aktivieren Sie die folgende Option, wenn sich Besucher Ihrer Website als <i>Leser ohne Zugang zum Redaktionssystem</i> anmelden können.',
414
+    'info_question_inscription_nouveaux_redacteurs' => 'Möchten Sie, dass sich neue Redakteure vom öffentlichen Bereich
415 415
  aus anmelden können? Wenn Sie es wollen, können sich Besucher über ein automatisch
416 416
  erstelltes Formular anmelden und Artikel vorschlagen.
417 417
  <div class="notice">Nach der Anmeldung erhalten die neuen Redakteure automatisch
418 418
  eine E-Mail mit ihren Zugangsdaten. Manche Webhoster unterbinden den Mailversand
419 419
  von ihren Webservern aus.
420 420
  In diesem Fall funktioniert die automatische Anmeldung nicht.</div>',
421
-	'info_qui_edite' => '@nom_auteur_modif@ hat vor  @date_diff@ Minuten an diesem Objekt gearbeitet.',
422
-	'info_racine_site' => 'OBERSTE EBENE DER WEBSITE',
423
-	'info_recharger_page' => 'Bitte laden Sie diese Seite in ein paar Augenblicken erneut.',
424
-	'info_recherche_auteur_zero' => 'Kein Ergebnis zu “@cherche_auteur@” gefunden.',
425
-	'info_recommencer' => 'Bitte wiederholen.',
426
-	'info_redacteur_1' => 'Redakteur',
427
-	'info_redacteur_2' => 'mit Zugang zum Redaktionssystem (<i>empfohlen</i>)',
428
-	'info_redacteurs' => 'Redakteure',
429
-	'info_redaction_en_cours' => 'IN BEARBEITUNG',
430
-	'info_redirection' => 'Umleitung',
431
-	'info_redirection_activee' => 'Die Weiterleitung ist aktiviert.',
432
-	'info_redirection_boucle' => 'Sie versuchen, den Artikel mit sich selber zu verlinken.',
433
-	'info_redirection_desactivee' => 'Die Weiterleitung wurde abgeschaltet.',
434
-	'info_refuses' => 'Ihre abgelehnten Artikel',
435
-	'info_reglage_ldap' => 'Optionen: <b>LDAP-Import Einstellungen</b>',
436
-	'info_renvoi_article' => '<b>Umleitung.</b> Dieser Artikel zeigt auf die Seite: ',
437
-	'info_reserve_admin' => 'Nur Administratoren können diese Seite ändern.',
438
-	'info_restreindre_rubrique' => 'Administrationsrechte auf diese Rubrik beschränken:',
439
-	'info_resultat_recherche' => 'Suchergebnisse:',
440
-	'info_rubriques' => 'Rubriken',
441
-	'info_rubriques_02' => 'Rubriken',
442
-	'info_rubriques_trouvees' => 'Rubriken gefunden',
443
-	'info_sans_titre' => 'Ohne Titel',
444
-	'info_selection_chemin_acces' => '<b>Wählen Sie</b> hier den Pfad zu Ihrem Verzeichnis:',
445
-	'info_signatures' => 'Unterschriften',
446
-	'info_site' => 'Website',
447
-	'info_site_2' => 'Website: ',
448
-	'info_site_min' => 'Website',
449
-	'info_site_reference_2' => 'Verlinkte Website',
450
-	'info_site_web' => 'Website:',
451
-	'info_sites' => 'Websites',
452
-	'info_sites_lies_mot' => 'Mit dieser Website verknüpfte Schlagworte',
453
-	'info_sites_proxy' => 'HTTP-Proxy verwenden',
454
-	'info_sites_trouves' => 'Gefundene Websites',
455
-	'info_sous_titre' => 'Untertitel:',
456
-	'info_statut_administrateur' => 'Administrator',
457
-	'info_statut_auteur' => 'Status des Autors:',
458
-	'info_statut_auteur_2' => 'Ich bin',
459
-	'info_statut_auteur_a_confirmer' => 'Anmeldung bestätigen',
460
-	'info_statut_auteur_autre' => 'Anderer Status:',
461
-	'info_statut_redacteur' => 'Redakteur',
462
-	'info_statut_utilisateurs_1' => 'Vorgegebener Status der importierten Benutzer',
463
-	'info_statut_utilisateurs_2' => 'Wählen Sie den Status, der Personen im LDAP-Verzeichnis zugeordnet wird, wenn sie sich zum ersten Mal anmelden. Sie können diesen Wert später für jeden Autor individuell einstellen.',
464
-	'info_suivi_activite' => 'Unterstützung der Redaktionsabläufe',
465
-	'info_surtitre' => 'Einleitender Titel:',
466
-	'info_syndication_integrale_1' => 'Ihre Website biete Backend-Dateien zur Syndikation an (siehe « <a href="@url@">@titre@</a> »).',
467
-	'info_syndication_integrale_2' => 'Möchten sie den gesamten Text der Artikel überragen oder nur eine Zusammenfassung von ein paar hundert Zeichen?',
468
-	'info_table_prefix' => 'Sie können den ersten Teil (das Prefix) der Datentabellen ändern. Das ist unerlässlich, wenn sie mehrere Websites in der selben Datenbank speichern möchten. Das Prefix besteht aus kleinen Buchstaben ohne Akzente, Sonder- oder Leerzeichen',
469
-	'info_taille_maximale_images' => 'SPIP wird die maximale Größe der Bilder (in Millionen Pixel) testen, die es bearbeiten kann.<br /> Größere Bilder werden nicht verkleinert.',
470
-	'info_taille_maximale_vignette' => 'Maximale Grösse der Icons des Systems:',
471
-	'info_terminer_installation' => 'Sie können jetzt die Standardinstallation abschliessen.',
472
-	'info_texte' => 'Text',
473
-	'info_texte_explicatif' => 'Beschreibung',
474
-	'info_texte_long' => '(Das ist ein langer Text. Er wird in mehreren Teilen angezeigt, die nach der Veröffentlichung zusammen gefügt werden.)',
475
-	'info_texte_message' => 'Text Ihrer Nachricht',
476
-	'info_texte_message_02' => 'Text Ihrer Nachricht',
477
-	'info_titre' => 'Titel:',
478
-	'info_total' => 'Gesamt: ',
479
-	'info_tous_articles_en_redaction' => 'Alle Artikel in Bearbeitung',
480
-	'info_tous_articles_presents' => 'Alle veröffentlichten Artikel dieser Rubrik',
481
-	'info_tous_articles_refuses' => 'Alle abgelehnten Artikel',
482
-	'info_tous_les' => 'alle',
483
-	'info_tout_site' => 'Ganze Website',
484
-	'info_tout_site2' => 'Der Artikel wurde nicht in diese Sprache übersetzt.',
485
-	'info_tout_site3' => 'Der Artikel wurde in diese Sprache übersetzt, aber der Originalartikel wurde erneut verändert. Die Übersetzung muss überarbeitet werden.',
486
-	'info_tout_site4' => 'Der Artikel wurde in diese Sprache übersetzt und die Übersetzung ist aktuel.',
487
-	'info_tout_site5' => 'Originalartikel.',
488
-	'info_tout_site6' => '<b>Achtung:</b> Nur die Originalartikel werden aufgelistet..
421
+    'info_qui_edite' => '@nom_auteur_modif@ hat vor  @date_diff@ Minuten an diesem Objekt gearbeitet.',
422
+    'info_racine_site' => 'OBERSTE EBENE DER WEBSITE',
423
+    'info_recharger_page' => 'Bitte laden Sie diese Seite in ein paar Augenblicken erneut.',
424
+    'info_recherche_auteur_zero' => 'Kein Ergebnis zu “@cherche_auteur@” gefunden.',
425
+    'info_recommencer' => 'Bitte wiederholen.',
426
+    'info_redacteur_1' => 'Redakteur',
427
+    'info_redacteur_2' => 'mit Zugang zum Redaktionssystem (<i>empfohlen</i>)',
428
+    'info_redacteurs' => 'Redakteure',
429
+    'info_redaction_en_cours' => 'IN BEARBEITUNG',
430
+    'info_redirection' => 'Umleitung',
431
+    'info_redirection_activee' => 'Die Weiterleitung ist aktiviert.',
432
+    'info_redirection_boucle' => 'Sie versuchen, den Artikel mit sich selber zu verlinken.',
433
+    'info_redirection_desactivee' => 'Die Weiterleitung wurde abgeschaltet.',
434
+    'info_refuses' => 'Ihre abgelehnten Artikel',
435
+    'info_reglage_ldap' => 'Optionen: <b>LDAP-Import Einstellungen</b>',
436
+    'info_renvoi_article' => '<b>Umleitung.</b> Dieser Artikel zeigt auf die Seite: ',
437
+    'info_reserve_admin' => 'Nur Administratoren können diese Seite ändern.',
438
+    'info_restreindre_rubrique' => 'Administrationsrechte auf diese Rubrik beschränken:',
439
+    'info_resultat_recherche' => 'Suchergebnisse:',
440
+    'info_rubriques' => 'Rubriken',
441
+    'info_rubriques_02' => 'Rubriken',
442
+    'info_rubriques_trouvees' => 'Rubriken gefunden',
443
+    'info_sans_titre' => 'Ohne Titel',
444
+    'info_selection_chemin_acces' => '<b>Wählen Sie</b> hier den Pfad zu Ihrem Verzeichnis:',
445
+    'info_signatures' => 'Unterschriften',
446
+    'info_site' => 'Website',
447
+    'info_site_2' => 'Website: ',
448
+    'info_site_min' => 'Website',
449
+    'info_site_reference_2' => 'Verlinkte Website',
450
+    'info_site_web' => 'Website:',
451
+    'info_sites' => 'Websites',
452
+    'info_sites_lies_mot' => 'Mit dieser Website verknüpfte Schlagworte',
453
+    'info_sites_proxy' => 'HTTP-Proxy verwenden',
454
+    'info_sites_trouves' => 'Gefundene Websites',
455
+    'info_sous_titre' => 'Untertitel:',
456
+    'info_statut_administrateur' => 'Administrator',
457
+    'info_statut_auteur' => 'Status des Autors:',
458
+    'info_statut_auteur_2' => 'Ich bin',
459
+    'info_statut_auteur_a_confirmer' => 'Anmeldung bestätigen',
460
+    'info_statut_auteur_autre' => 'Anderer Status:',
461
+    'info_statut_redacteur' => 'Redakteur',
462
+    'info_statut_utilisateurs_1' => 'Vorgegebener Status der importierten Benutzer',
463
+    'info_statut_utilisateurs_2' => 'Wählen Sie den Status, der Personen im LDAP-Verzeichnis zugeordnet wird, wenn sie sich zum ersten Mal anmelden. Sie können diesen Wert später für jeden Autor individuell einstellen.',
464
+    'info_suivi_activite' => 'Unterstützung der Redaktionsabläufe',
465
+    'info_surtitre' => 'Einleitender Titel:',
466
+    'info_syndication_integrale_1' => 'Ihre Website biete Backend-Dateien zur Syndikation an (siehe « <a href="@url@">@titre@</a> »).',
467
+    'info_syndication_integrale_2' => 'Möchten sie den gesamten Text der Artikel überragen oder nur eine Zusammenfassung von ein paar hundert Zeichen?',
468
+    'info_table_prefix' => 'Sie können den ersten Teil (das Prefix) der Datentabellen ändern. Das ist unerlässlich, wenn sie mehrere Websites in der selben Datenbank speichern möchten. Das Prefix besteht aus kleinen Buchstaben ohne Akzente, Sonder- oder Leerzeichen',
469
+    'info_taille_maximale_images' => 'SPIP wird die maximale Größe der Bilder (in Millionen Pixel) testen, die es bearbeiten kann.<br /> Größere Bilder werden nicht verkleinert.',
470
+    'info_taille_maximale_vignette' => 'Maximale Grösse der Icons des Systems:',
471
+    'info_terminer_installation' => 'Sie können jetzt die Standardinstallation abschliessen.',
472
+    'info_texte' => 'Text',
473
+    'info_texte_explicatif' => 'Beschreibung',
474
+    'info_texte_long' => '(Das ist ein langer Text. Er wird in mehreren Teilen angezeigt, die nach der Veröffentlichung zusammen gefügt werden.)',
475
+    'info_texte_message' => 'Text Ihrer Nachricht',
476
+    'info_texte_message_02' => 'Text Ihrer Nachricht',
477
+    'info_titre' => 'Titel:',
478
+    'info_total' => 'Gesamt: ',
479
+    'info_tous_articles_en_redaction' => 'Alle Artikel in Bearbeitung',
480
+    'info_tous_articles_presents' => 'Alle veröffentlichten Artikel dieser Rubrik',
481
+    'info_tous_articles_refuses' => 'Alle abgelehnten Artikel',
482
+    'info_tous_les' => 'alle',
483
+    'info_tout_site' => 'Ganze Website',
484
+    'info_tout_site2' => 'Der Artikel wurde nicht in diese Sprache übersetzt.',
485
+    'info_tout_site3' => 'Der Artikel wurde in diese Sprache übersetzt, aber der Originalartikel wurde erneut verändert. Die Übersetzung muss überarbeitet werden.',
486
+    'info_tout_site4' => 'Der Artikel wurde in diese Sprache übersetzt und die Übersetzung ist aktuel.',
487
+    'info_tout_site5' => 'Originalartikel.',
488
+    'info_tout_site6' => '<b>Achtung:</b> Nur die Originalartikel werden aufgelistet..
489 489
 Die Übersetzungen entsprechen dem Original,
490 490
 in einer Farbe, die den Status anzeigt :',
491
-	'info_traductions' => 'Übersetzungen',
492
-	'info_travail_colaboratif' => 'Gemeinsame Arbeit an den Artikeln',
493
-	'info_un_article' => ' ein Artikel, ',
494
-	'info_un_site' => ' eine Website, ',
495
-	'info_une_rubrique' => ' eine Rubrik, ',
496
-	'info_une_rubrique_02' => '1 Rubrik',
497
-	'info_url' => 'URL:',
498
-	'info_url_proxy' => 'URL des Proxy',
499
-	'info_url_proxy_pas_conforme' => 'ungültige Proxy-URL',
500
-	'info_url_site_pas_conforme' => 'Ungültiger Website-URL',
501
-	'info_url_test_proxy' => 'Test-URL',
502
-	'info_urlref' => 'Hyperlink:',
503
-	'info_utilisation_spip' => 'Sie können SPIP jetzt verwenden ...',
504
-	'info_visites_par_mois' => 'Anzeige pro Monat:',
505
-	'info_visiteur_1' => 'Besucher',
506
-	'info_visiteur_2' => 'des öffentlichen Bereichs',
507
-	'info_visiteurs' => 'Besucher',
508
-	'info_visiteurs_02' => 'Besucher des öffentlichen Bereichs',
509
-	'info_webmestre_forces' => 'Die Webmaster sind in der Datei <tt>@file_options@</tt> konfiguriert.',
510
-	'install_adresse_base_hebergeur' => 'Adresse der vom Provider zugewiesenen Datenbank',
511
-	'install_connect_ok' => 'Die neue Datenbank wurde unter dem Namen @connect@ deklariert.',
512
-	'install_echec_annonce' => 'Die Installation wird wahrscheinlich fehlschlagen oder eine nicht funktionierende Site ergeben.',
513
-	'install_extension_mbstring' => 'SPIP funktioniert nicht mit:',
514
-	'install_extension_php_obligatoire' => 'SPIP benötigt die Dateierweiterung php:',
515
-	'install_login_base_hebergeur' => 'Vom Provider zugeteiltes Login',
516
-	'install_nom_base_hebergeur' => 'Name der vom Provider zugewiesenen Datenbank:',
517
-	'install_pas_table' => 'Datenbank zur Zeit ohne Tabellen',
518
-	'install_pass_base_hebergeur' => 'Vom Provider zugeteiltes Passwort',
519
-	'install_php_extension' => 'Folgende Erweiterungen fehlen: @extensions@',
520
-	'install_php_version' => 'Die PHP-Version @version@ ist zu alt. (Mindestens erforderlich = @minimum@)',
521
-	'install_php_version_max' => 'PHP Version @version@ zu neu (maximum = @maximum@)',
522
-	'install_select_langue' => 'Wählen Sie eine Sprache aus und klicken Sie auf «Weiter», um die Installation zu starten.',
523
-	'install_select_type_db' => 'Geben Sie den Typ der Datenbank an:',
524
-	'install_select_type_mysql' => 'MySQL',
525
-	'install_select_type_pg' => 'PostgreSQL',
526
-	'install_select_type_sqlite2' => 'SQLite 2',
527
-	'install_select_type_sqlite3' => 'SQLite 3',
528
-	'install_serveur_hebergeur' => 'Vom Provider bereitgestellter Datenbankserver',
529
-	'install_table_prefix_hebergeur' => 'Prefix der vom Provider zugeteilten Tabelle',
530
-	'install_tables_base' => 'Tabellen der Datenbank',
531
-	'install_types_db_connus' => 'SPIP beherrscht <b>MySQL</b> (am weitesten verbreitet) und  <b>SQLite</b>.', # Geht PostGreSQL jetzt nicht mehr?
532
-	'install_types_db_connus_avertissement' => '<b>PostgreSQL</b> wird testweise unterstützt.',
533
-	'instituer_erreur_statut_a_change' => 'Der Status wurde bereits geändert.',
534
-	'instituer_erreur_statut_non_autorise' => 'Sie dürfen diesen Status nicht auswählen.',
535
-	'intem_redacteur' => 'Redakteur',
536
-	'intitule_licence' => 'Lizenz',
537
-	'item_accepter_inscriptions' => 'Anmeldungen erlauben',
538
-	'item_activer_messages_avertissement' => 'Aktuelle Benachrichtigungen einschalten',
539
-	'item_administrateur_2' => 'Administrator',
540
-	'item_afficher_calendrier' => 'Im Kalender anzeigen',
541
-	'item_autoriser_syndication_integrale' => 'Vollständige Artikel im Feed übertragen',
542
-	'item_choix_administrateurs' => 'Administratoren',
543
-	'item_choix_generation_miniature' => 'Vorschaubilder automatisch generieren.',
544
-	'item_choix_non_generation_miniature' => 'Keine Vorschaubilder generieren.',
545
-	'item_choix_redacteurs' => 'Redakteure',
546
-	'item_choix_visiteurs' => 'Besucher im öffentlichen Bereich',
547
-	'item_creer_fichiers_authent' => '.htpasswd-Dateien anlegen',
548
-	'item_login' => 'Login',
549
-	'item_messagerie_agenda' => 'Nachrichtenfunktion des Kalenders aktivieren',
550
-	'item_mots_cles_association_articles' => 'Artikeln zuordnen',
551
-	'item_mots_cles_association_rubriques' => 'Rubriken zuordnen',
552
-	'item_mots_cles_association_sites' => 'syndizierten Websites zuordnen.',
553
-	'item_non' => 'Nein',
554
-	'item_non_accepter_inscriptions' => 'Anmeldungen verhindern',
555
-	'item_non_activer_messages_avertissement' => 'Keine aktuellen Benachrichtigungen',
556
-	'item_non_afficher_calendrier' => 'Nicht im Kalender anzeigen',
557
-	'item_non_autoriser_syndication_integrale' => 'Nur Zusammenfassung übertragen',
558
-	'item_non_creer_fichiers_authent' => 'Diese Dateien nicht anlegen',
559
-	'item_non_messagerie_agenda' => 'Nachrichtenfunktion des Kalenders abschalten',
560
-	'item_non_publier_articles' => 'Artikel nicht vor dem eingestellten Datum veröffentlichen.',
561
-	'item_nouvel_auteur' => 'Neuer Autor',
562
-	'item_nouvelle_rubrique' => 'Neue Rubrik',
563
-	'item_oui' => 'Ja',
564
-	'item_publier_articles' => 'Sofort veröffentlichen, egal welches Datum ein Artikel trägt. ',
565
-	'item_reponse_article' => 'Antwort auf Artikel',
566
-	'item_visiteur' => 'Besucher',
491
+    'info_traductions' => 'Übersetzungen',
492
+    'info_travail_colaboratif' => 'Gemeinsame Arbeit an den Artikeln',
493
+    'info_un_article' => ' ein Artikel, ',
494
+    'info_un_site' => ' eine Website, ',
495
+    'info_une_rubrique' => ' eine Rubrik, ',
496
+    'info_une_rubrique_02' => '1 Rubrik',
497
+    'info_url' => 'URL:',
498
+    'info_url_proxy' => 'URL des Proxy',
499
+    'info_url_proxy_pas_conforme' => 'ungültige Proxy-URL',
500
+    'info_url_site_pas_conforme' => 'Ungültiger Website-URL',
501
+    'info_url_test_proxy' => 'Test-URL',
502
+    'info_urlref' => 'Hyperlink:',
503
+    'info_utilisation_spip' => 'Sie können SPIP jetzt verwenden ...',
504
+    'info_visites_par_mois' => 'Anzeige pro Monat:',
505
+    'info_visiteur_1' => 'Besucher',
506
+    'info_visiteur_2' => 'des öffentlichen Bereichs',
507
+    'info_visiteurs' => 'Besucher',
508
+    'info_visiteurs_02' => 'Besucher des öffentlichen Bereichs',
509
+    'info_webmestre_forces' => 'Die Webmaster sind in der Datei <tt>@file_options@</tt> konfiguriert.',
510
+    'install_adresse_base_hebergeur' => 'Adresse der vom Provider zugewiesenen Datenbank',
511
+    'install_connect_ok' => 'Die neue Datenbank wurde unter dem Namen @connect@ deklariert.',
512
+    'install_echec_annonce' => 'Die Installation wird wahrscheinlich fehlschlagen oder eine nicht funktionierende Site ergeben.',
513
+    'install_extension_mbstring' => 'SPIP funktioniert nicht mit:',
514
+    'install_extension_php_obligatoire' => 'SPIP benötigt die Dateierweiterung php:',
515
+    'install_login_base_hebergeur' => 'Vom Provider zugeteiltes Login',
516
+    'install_nom_base_hebergeur' => 'Name der vom Provider zugewiesenen Datenbank:',
517
+    'install_pas_table' => 'Datenbank zur Zeit ohne Tabellen',
518
+    'install_pass_base_hebergeur' => 'Vom Provider zugeteiltes Passwort',
519
+    'install_php_extension' => 'Folgende Erweiterungen fehlen: @extensions@',
520
+    'install_php_version' => 'Die PHP-Version @version@ ist zu alt. (Mindestens erforderlich = @minimum@)',
521
+    'install_php_version_max' => 'PHP Version @version@ zu neu (maximum = @maximum@)',
522
+    'install_select_langue' => 'Wählen Sie eine Sprache aus und klicken Sie auf «Weiter», um die Installation zu starten.',
523
+    'install_select_type_db' => 'Geben Sie den Typ der Datenbank an:',
524
+    'install_select_type_mysql' => 'MySQL',
525
+    'install_select_type_pg' => 'PostgreSQL',
526
+    'install_select_type_sqlite2' => 'SQLite 2',
527
+    'install_select_type_sqlite3' => 'SQLite 3',
528
+    'install_serveur_hebergeur' => 'Vom Provider bereitgestellter Datenbankserver',
529
+    'install_table_prefix_hebergeur' => 'Prefix der vom Provider zugeteilten Tabelle',
530
+    'install_tables_base' => 'Tabellen der Datenbank',
531
+    'install_types_db_connus' => 'SPIP beherrscht <b>MySQL</b> (am weitesten verbreitet) und  <b>SQLite</b>.', # Geht PostGreSQL jetzt nicht mehr?
532
+    'install_types_db_connus_avertissement' => '<b>PostgreSQL</b> wird testweise unterstützt.',
533
+    'instituer_erreur_statut_a_change' => 'Der Status wurde bereits geändert.',
534
+    'instituer_erreur_statut_non_autorise' => 'Sie dürfen diesen Status nicht auswählen.',
535
+    'intem_redacteur' => 'Redakteur',
536
+    'intitule_licence' => 'Lizenz',
537
+    'item_accepter_inscriptions' => 'Anmeldungen erlauben',
538
+    'item_activer_messages_avertissement' => 'Aktuelle Benachrichtigungen einschalten',
539
+    'item_administrateur_2' => 'Administrator',
540
+    'item_afficher_calendrier' => 'Im Kalender anzeigen',
541
+    'item_autoriser_syndication_integrale' => 'Vollständige Artikel im Feed übertragen',
542
+    'item_choix_administrateurs' => 'Administratoren',
543
+    'item_choix_generation_miniature' => 'Vorschaubilder automatisch generieren.',
544
+    'item_choix_non_generation_miniature' => 'Keine Vorschaubilder generieren.',
545
+    'item_choix_redacteurs' => 'Redakteure',
546
+    'item_choix_visiteurs' => 'Besucher im öffentlichen Bereich',
547
+    'item_creer_fichiers_authent' => '.htpasswd-Dateien anlegen',
548
+    'item_login' => 'Login',
549
+    'item_messagerie_agenda' => 'Nachrichtenfunktion des Kalenders aktivieren',
550
+    'item_mots_cles_association_articles' => 'Artikeln zuordnen',
551
+    'item_mots_cles_association_rubriques' => 'Rubriken zuordnen',
552
+    'item_mots_cles_association_sites' => 'syndizierten Websites zuordnen.',
553
+    'item_non' => 'Nein',
554
+    'item_non_accepter_inscriptions' => 'Anmeldungen verhindern',
555
+    'item_non_activer_messages_avertissement' => 'Keine aktuellen Benachrichtigungen',
556
+    'item_non_afficher_calendrier' => 'Nicht im Kalender anzeigen',
557
+    'item_non_autoriser_syndication_integrale' => 'Nur Zusammenfassung übertragen',
558
+    'item_non_creer_fichiers_authent' => 'Diese Dateien nicht anlegen',
559
+    'item_non_messagerie_agenda' => 'Nachrichtenfunktion des Kalenders abschalten',
560
+    'item_non_publier_articles' => 'Artikel nicht vor dem eingestellten Datum veröffentlichen.',
561
+    'item_nouvel_auteur' => 'Neuer Autor',
562
+    'item_nouvelle_rubrique' => 'Neue Rubrik',
563
+    'item_oui' => 'Ja',
564
+    'item_publier_articles' => 'Sofort veröffentlichen, egal welches Datum ein Artikel trägt. ',
565
+    'item_reponse_article' => 'Antwort auf Artikel',
566
+    'item_visiteur' => 'Besucher',
567 567
 
568
-	// J
569
-	'jour_non_connu_nc' => 'unbekannt',
568
+    // J
569
+    'jour_non_connu_nc' => 'unbekannt',
570 570
 
571
-	// L
572
-	'label_bando_outils' => 'Werkzeugleiste',
573
-	'label_bando_outils_afficher' => 'Werkzeuge anzeigen',
574
-	'label_bando_outils_masquer' => 'Werkzeuge ausblenden',
575
-	'label_choix_langue' => 'Ihre Sprache wählen',
576
-	'label_langue' => 'Sprache',
577
-	'label_nom_fichier_connect' => 'Geben Sie den für diesen Server verwendeten Namen an.',
578
-	'label_slogan_site' => 'Slogan der Website',
579
-	'label_taille_ecran' => 'Bildschirmbreite',
580
-	'label_texte_et_icones_navigation' => 'Navigationsmenü',
581
-	'label_texte_et_icones_page' => 'Auf der Seite anzeigen',
582
-	'ldap_correspondance' => 'Vererbung von Feld @champ@',
583
-	'ldap_correspondance_1' => 'Vererbung des LDAP Felds',
584
-	'ldap_correspondance_2' => 'Geben sie bitte für jedes der folgenden SPIP-Felder das entsprechende LDAP-Feld an. Leere Felder werden nicht genutzt, LDAP-Felder mit Leerzeichen oder Kommata trennen, um mehrere zu probieren. ',
585
-	'lien_ajouter_auteur' => 'Autor hinzufügen',
586
-	'lien_ajouter_une_rubrique' => 'Diese Rubrik hinzufügen',
587
-	'lien_email' => 'E-Mail',
588
-	'lien_nom_site' => 'NAME DER WEBSITE:',
589
-	'lien_rapide_contenu' => 'zum Inhalt',
590
-	'lien_rapide_navigation' => 'zur Navigation',
591
-	'lien_rapide_recherche' => 'zur Suche',
592
-	'lien_retirer_auteur' => 'Autor entfernen',
593
-	'lien_retirer_rubrique' => 'Rubrik entfernen',
594
-	'lien_retirer_tous_auteurs' => 'Alle Autoren entfernen',
595
-	'lien_retirer_toutes_rubriques' => 'Alle Rubriken entfernen ',
596
-	'lien_site' => 'Website',
597
-	'lien_tout_decocher' => 'Alles abwählen',
598
-	'lien_tout_deplier' => 'Alle anzeigen',
599
-	'lien_tout_replier' => 'Alle ausblenden',
600
-	'lien_tout_supprimer' => 'Alles löschen',
601
-	'lien_trier_nom' => 'Nach Namen sortieren',
602
-	'lien_trier_nombre_articles' => 'Nach Zahl der Artikel sortieren',
603
-	'lien_trier_statut' => 'Nach Status sortieren',
604
-	'lien_voir_en_ligne' => 'ONLINE ANZEIGEN:',
605
-	'logo_article' => 'Artikel-Logo',
606
-	'logo_auteur' => 'Autoren-Logo',
607
-	'logo_rubrique' => 'Rubrik-Logo',
608
-	'logo_site' => 'Website-Logo',
609
-	'logo_standard_rubrique' => 'Standardlogo für Rubriken',
610
-	'logo_survol' => 'Mouseover-Logo',
571
+    // L
572
+    'label_bando_outils' => 'Werkzeugleiste',
573
+    'label_bando_outils_afficher' => 'Werkzeuge anzeigen',
574
+    'label_bando_outils_masquer' => 'Werkzeuge ausblenden',
575
+    'label_choix_langue' => 'Ihre Sprache wählen',
576
+    'label_langue' => 'Sprache',
577
+    'label_nom_fichier_connect' => 'Geben Sie den für diesen Server verwendeten Namen an.',
578
+    'label_slogan_site' => 'Slogan der Website',
579
+    'label_taille_ecran' => 'Bildschirmbreite',
580
+    'label_texte_et_icones_navigation' => 'Navigationsmenü',
581
+    'label_texte_et_icones_page' => 'Auf der Seite anzeigen',
582
+    'ldap_correspondance' => 'Vererbung von Feld @champ@',
583
+    'ldap_correspondance_1' => 'Vererbung des LDAP Felds',
584
+    'ldap_correspondance_2' => 'Geben sie bitte für jedes der folgenden SPIP-Felder das entsprechende LDAP-Feld an. Leere Felder werden nicht genutzt, LDAP-Felder mit Leerzeichen oder Kommata trennen, um mehrere zu probieren. ',
585
+    'lien_ajouter_auteur' => 'Autor hinzufügen',
586
+    'lien_ajouter_une_rubrique' => 'Diese Rubrik hinzufügen',
587
+    'lien_email' => 'E-Mail',
588
+    'lien_nom_site' => 'NAME DER WEBSITE:',
589
+    'lien_rapide_contenu' => 'zum Inhalt',
590
+    'lien_rapide_navigation' => 'zur Navigation',
591
+    'lien_rapide_recherche' => 'zur Suche',
592
+    'lien_retirer_auteur' => 'Autor entfernen',
593
+    'lien_retirer_rubrique' => 'Rubrik entfernen',
594
+    'lien_retirer_tous_auteurs' => 'Alle Autoren entfernen',
595
+    'lien_retirer_toutes_rubriques' => 'Alle Rubriken entfernen ',
596
+    'lien_site' => 'Website',
597
+    'lien_tout_decocher' => 'Alles abwählen',
598
+    'lien_tout_deplier' => 'Alle anzeigen',
599
+    'lien_tout_replier' => 'Alle ausblenden',
600
+    'lien_tout_supprimer' => 'Alles löschen',
601
+    'lien_trier_nom' => 'Nach Namen sortieren',
602
+    'lien_trier_nombre_articles' => 'Nach Zahl der Artikel sortieren',
603
+    'lien_trier_statut' => 'Nach Status sortieren',
604
+    'lien_voir_en_ligne' => 'ONLINE ANZEIGEN:',
605
+    'logo_article' => 'Artikel-Logo',
606
+    'logo_auteur' => 'Autoren-Logo',
607
+    'logo_rubrique' => 'Rubrik-Logo',
608
+    'logo_site' => 'Website-Logo',
609
+    'logo_standard_rubrique' => 'Standardlogo für Rubriken',
610
+    'logo_survol' => 'Mouseover-Logo',
611 611
 
612
-	// M
613
-	'menu_aide_installation_choix_base' => 'Datenbank auswählen',
614
-	'module_fichier_langue' => 'Sprachdatei',
615
-	'module_raccourci' => 'Abkürzung',
616
-	'module_texte_affiche' => 'angezeigter Text',
617
-	'module_texte_explicatif' => 'Sie können die folgenden Abkürzungen in den HTML-Vorlagen Ihrer Website verwenden. Sie werden automatisch in den Sprachen angezeigt, für die eine Sprachdatei existiert.',
618
-	'module_texte_traduction' => 'Die Sprachdatei für « @module@ » liegt vor auf ',
619
-	'mois_non_connu' => 'unbekannt',
612
+    // M
613
+    'menu_aide_installation_choix_base' => 'Datenbank auswählen',
614
+    'module_fichier_langue' => 'Sprachdatei',
615
+    'module_raccourci' => 'Abkürzung',
616
+    'module_texte_affiche' => 'angezeigter Text',
617
+    'module_texte_explicatif' => 'Sie können die folgenden Abkürzungen in den HTML-Vorlagen Ihrer Website verwenden. Sie werden automatisch in den Sprachen angezeigt, für die eine Sprachdatei existiert.',
618
+    'module_texte_traduction' => 'Die Sprachdatei für « @module@ » liegt vor auf ',
619
+    'mois_non_connu' => 'unbekannt',
620 620
 
621
-	// N
622
-	'nouvelle_version_spip' => 'SPIP Version @version@ ist verfügbar.',
623
-	'nouvelle_version_spip_majeure' => 'Eine neue SPIP Version @version@ steht zur Verfügung.',
621
+    // N
622
+    'nouvelle_version_spip' => 'SPIP Version @version@ ist verfügbar.',
623
+    'nouvelle_version_spip_majeure' => 'Eine neue SPIP Version @version@ steht zur Verfügung.',
624 624
 
625
-	// O
626
-	'onglet_contenu' => 'Inhalt',
627
-	'onglet_declarer_une_autre_base' => 'Weitere Datenbank deklarieren',
628
-	'onglet_discuter' => 'Diskussionen',
629
-	'onglet_interactivite' => 'Interaktivität',
630
-	'onglet_proprietes' => 'Eigenschaften',
631
-	'onglet_repartition_actuelle' => 'zur Zeit',
632
-	'onglet_sous_rubriques' => 'Unterrubriken',
625
+    // O
626
+    'onglet_contenu' => 'Inhalt',
627
+    'onglet_declarer_une_autre_base' => 'Weitere Datenbank deklarieren',
628
+    'onglet_discuter' => 'Diskussionen',
629
+    'onglet_interactivite' => 'Interaktivität',
630
+    'onglet_proprietes' => 'Eigenschaften',
631
+    'onglet_repartition_actuelle' => 'zur Zeit',
632
+    'onglet_sous_rubriques' => 'Unterrubriken',
633 633
 
634
-	// P
635
-	'page_pas_proxy' => 'Diese Seite darf nicht durch den Proxy übertragen werden.',
636
-	'pas_de_proxy_pour' => 'Falls erforderlich, könne Sie die Rechner und Domainen angeben, die nicht über den Proxy angesprochen werden (z.B. @exemple@)',
637
-	'phpinfo' => 'PHP-Konfiguration',
638
-	'plugin_charge_paquet' => 'Paket @name@ wird geladen',
639
-	'plugin_charger' => 'Übertragen',
640
-	'plugin_erreur_charger' => 'Fehler: @zip@ kann nicht geladen werden',
641
-	'plugin_erreur_droit1' => 'In das Verzeichnis <code>@dest@</code> kann nicht geschrieben werden.',
642
-	'plugin_erreur_droit2' => 'Bitte überprüfen Sie die Schreibrechte für dieses Verzeichnis oder legen Sie es an, falls es noch nicht existiert, oder installieren Sie die Dateien per FTP.',
643
-	'plugin_erreur_zip' => 'Pclzip fehlgeschlagen: Fehler @status@',
644
-	'plugin_etat_developpement' => 'In Entwicklung',
645
-	'plugin_etat_experimental' => 'Experimentell',
646
-	'plugin_etat_stable' => 'Stabil',
647
-	'plugin_etat_test' => 'Im Test',
648
-	'plugin_impossible_activer' => 'Das Plugin @plugin@ kann nicht aktiviert werden.',
649
-	'plugin_info_automatique1' => 'Wenn Sie die automatische Installation von Plugins nutzen möchten, führen Sie bitte folgende Schritte aus:',
650
-	'plugin_info_automatique1_lib' => 'Wenn diese Bibliothek automatisch installiert werden soll, führen sie bitte diese Schritte aus:',
651
-	'plugin_info_automatique2' => 'Anlegen des Verzeichnis <code>@rep@</code> ;',
652
-	'plugin_info_automatique3' => 'überprüfen, ob der Server in das Verzeichnis schreiben kann.',
653
-	'plugin_info_automatique_creer' => 'im Wurzelverzeichnis der Website.',
654
-	'plugin_info_automatique_exemples' => 'Beispiele:',
655
-	'plugin_info_automatique_ftp' => 'Sie können Plugins per FTP in dem Vezeichnis <tt>@rep@</tt> installieren',
656
-	'plugin_info_automatique_lib' => 'Manche Plugins benötigen das Verzeichnis <code>lib/</code>, um Dateien downloaden zu können, das im Wurzelverzeichnis der Website angelegt werden muss.',
657
-	'plugin_info_automatique_liste' => 'Ihre Plugin-Listen:',
658
-	'plugin_info_automatique_liste_officielle' => 'Die offiziellen Plugins',
659
-	'plugin_info_automatique_liste_update' => 'Listen aktualisieren',
660
-	'plugin_info_automatique_ou' => 'oder...',
661
-	'plugin_info_automatique_select' => 'Wählen Sie ein Plugin aus. SPIP wird es herunterladen und im Verzeichnis <code>@rep@</code> installieren. Falls das Plugin bereits installiert ist, wird es auf den neuesten Stand gebracht.',
662
-	'plugin_info_credit' => 'Beteiligte',
663
-	'plugin_info_erreur_xml' => 'Die Deklaration dieses Plugins ist nicht korrekt.',
664
-	'plugin_info_install_ok' => 'Installation war erfolgreich.',
665
-	'plugin_info_necessite' => 'Erfordert:',
666
-	'plugin_info_non_compatible_spip' => 'Dieses Plugin ist nicht mit SPIP kompatibel.',
667
-	'plugin_info_plugins_dist_1' => 'Diese Erweiterungen liegen im Verzeichnis @plugins_dist@ und werden dort aktiviert.',
668
-	'plugin_info_plugins_dist_2' => 'Man kann sie nicht deaktivieren.',
669
-	'plugin_info_telecharger' => 'herunterladen von @url@ und in @rep@ installieren',
670
-	'plugin_info_upgrade_ok' => 'Upgrade erfolgreich',
671
-	'plugin_librairies_installees' => 'Installierte Bibliotheken',
672
-	'plugin_necessite_extension_php' => 'benötigt die PHP-Erweiterung @plugin@ Version @version@.',
673
-	'plugin_necessite_extension_php_sans_version' => 'benötigt die PHP-Erweiterung @plugin@',
674
-	'plugin_necessite_lib' => 'Dieses Plugin benötigt die Bibliothek @lib@',
675
-	'plugin_necessite_php' => 'benötigt @plugin@ Version @version@.',
676
-	'plugin_necessite_plugin' => 'Benötigt Version @version@ des Plugin @plugin@.',
677
-	'plugin_necessite_plugin_sans_version' => 'Benötigt das Plugin @plugin@',
678
-	'plugin_necessite_spip' => 'Benötigt mindestens Version @version@ von SPIP.',
679
-	'plugin_source' => 'Quelle: ',
680
-	'plugin_titre_automatique' => 'Automatische Installation',
681
-	'plugin_titre_automatique_ajouter' => 'Plugins hinzufügen',
682
-	'plugin_titre_installation' => 'Installation des Plugins @plugin@',
683
-	'plugin_titre_modifier' => 'Meine Plugins',
684
-	'plugin_utilise_extension_php' => 'PHP-Erweiterung @plugin@ muss Version @version@ sein.',
685
-	'plugin_utilise_php' => '@plugin@ muss Version @version@ sein.',
686
-	'plugin_utilise_plugin' => 'Das Plugin @plugin@ muss Version @version@ sein.',
687
-	'plugin_zip_active' => 'Weiter zum Aktivieren',
688
-	'plugin_zip_adresse' => 'Geben Sie hier die Adresse einer ZIP-Datei, die das Plugin enthält, oder die Adresse einer Plugin-Liste an.',
689
-	'plugin_zip_adresse_champ' => 'Adresse des Plugins oder der Liste ',
690
-	'plugin_zip_content' => 'Enthält die folgenden Dateien (@taille@),<br />die im Verzeichnis <code>@rep@</code> installiert werden können.',
691
-	'plugin_zip_installe_finie' => 'Die Datei @zip@ wurde entpackt und installiert.',
692
-	'plugin_zip_installe_rep_finie' => 'Die Datei @zip@ wurde entpackt und in das Verzeichnis @rep@ installiert.',
693
-	'plugin_zip_installer' => 'Sie können es jetzt installieren.',
694
-	'plugin_zip_telecharge' => 'Die Datei @zip@ wurde heruntergeladen',
695
-	'plugins_actif_aucun' => 'Kein aktives Plugin.',
696
-	'plugins_actif_un' => 'Ein aktives Plugin.',
697
-	'plugins_actifs' => '@count@ aktive Plugins.',
698
-	'plugins_actifs_liste' => 'Aktiv',
699
-	'plugins_compte' => '@count@ Plugins',
700
-	'plugins_disponible_un' => 'Ein Plugin verfügbar.',
701
-	'plugins_disponibles' => '@count@ verfügbare Plugins.',
702
-	'plugins_erreur' => 'Fehler in den Plugins: @plugins@',
703
-	'plugins_liste' => 'Installierte Plugins',
704
-	'plugins_liste_dist' => 'Gesicherte Plugins', # Das hat jetzt aber mit plugins_liste_dist nichts mehr zu tun.
705
-	'plugins_recents' => 'Neueste Plugins.',
706
-	'plugins_tous_liste' => 'Alle',
707
-	'plugins_vue_hierarchie' => 'Hierarchie',
708
-	'plugins_vue_liste' => 'Liste',
709
-	'protocole_ldap' => 'Version des Protokolls:',
634
+    // P
635
+    'page_pas_proxy' => 'Diese Seite darf nicht durch den Proxy übertragen werden.',
636
+    'pas_de_proxy_pour' => 'Falls erforderlich, könne Sie die Rechner und Domainen angeben, die nicht über den Proxy angesprochen werden (z.B. @exemple@)',
637
+    'phpinfo' => 'PHP-Konfiguration',
638
+    'plugin_charge_paquet' => 'Paket @name@ wird geladen',
639
+    'plugin_charger' => 'Übertragen',
640
+    'plugin_erreur_charger' => 'Fehler: @zip@ kann nicht geladen werden',
641
+    'plugin_erreur_droit1' => 'In das Verzeichnis <code>@dest@</code> kann nicht geschrieben werden.',
642
+    'plugin_erreur_droit2' => 'Bitte überprüfen Sie die Schreibrechte für dieses Verzeichnis oder legen Sie es an, falls es noch nicht existiert, oder installieren Sie die Dateien per FTP.',
643
+    'plugin_erreur_zip' => 'Pclzip fehlgeschlagen: Fehler @status@',
644
+    'plugin_etat_developpement' => 'In Entwicklung',
645
+    'plugin_etat_experimental' => 'Experimentell',
646
+    'plugin_etat_stable' => 'Stabil',
647
+    'plugin_etat_test' => 'Im Test',
648
+    'plugin_impossible_activer' => 'Das Plugin @plugin@ kann nicht aktiviert werden.',
649
+    'plugin_info_automatique1' => 'Wenn Sie die automatische Installation von Plugins nutzen möchten, führen Sie bitte folgende Schritte aus:',
650
+    'plugin_info_automatique1_lib' => 'Wenn diese Bibliothek automatisch installiert werden soll, führen sie bitte diese Schritte aus:',
651
+    'plugin_info_automatique2' => 'Anlegen des Verzeichnis <code>@rep@</code> ;',
652
+    'plugin_info_automatique3' => 'überprüfen, ob der Server in das Verzeichnis schreiben kann.',
653
+    'plugin_info_automatique_creer' => 'im Wurzelverzeichnis der Website.',
654
+    'plugin_info_automatique_exemples' => 'Beispiele:',
655
+    'plugin_info_automatique_ftp' => 'Sie können Plugins per FTP in dem Vezeichnis <tt>@rep@</tt> installieren',
656
+    'plugin_info_automatique_lib' => 'Manche Plugins benötigen das Verzeichnis <code>lib/</code>, um Dateien downloaden zu können, das im Wurzelverzeichnis der Website angelegt werden muss.',
657
+    'plugin_info_automatique_liste' => 'Ihre Plugin-Listen:',
658
+    'plugin_info_automatique_liste_officielle' => 'Die offiziellen Plugins',
659
+    'plugin_info_automatique_liste_update' => 'Listen aktualisieren',
660
+    'plugin_info_automatique_ou' => 'oder...',
661
+    'plugin_info_automatique_select' => 'Wählen Sie ein Plugin aus. SPIP wird es herunterladen und im Verzeichnis <code>@rep@</code> installieren. Falls das Plugin bereits installiert ist, wird es auf den neuesten Stand gebracht.',
662
+    'plugin_info_credit' => 'Beteiligte',
663
+    'plugin_info_erreur_xml' => 'Die Deklaration dieses Plugins ist nicht korrekt.',
664
+    'plugin_info_install_ok' => 'Installation war erfolgreich.',
665
+    'plugin_info_necessite' => 'Erfordert:',
666
+    'plugin_info_non_compatible_spip' => 'Dieses Plugin ist nicht mit SPIP kompatibel.',
667
+    'plugin_info_plugins_dist_1' => 'Diese Erweiterungen liegen im Verzeichnis @plugins_dist@ und werden dort aktiviert.',
668
+    'plugin_info_plugins_dist_2' => 'Man kann sie nicht deaktivieren.',
669
+    'plugin_info_telecharger' => 'herunterladen von @url@ und in @rep@ installieren',
670
+    'plugin_info_upgrade_ok' => 'Upgrade erfolgreich',
671
+    'plugin_librairies_installees' => 'Installierte Bibliotheken',
672
+    'plugin_necessite_extension_php' => 'benötigt die PHP-Erweiterung @plugin@ Version @version@.',
673
+    'plugin_necessite_extension_php_sans_version' => 'benötigt die PHP-Erweiterung @plugin@',
674
+    'plugin_necessite_lib' => 'Dieses Plugin benötigt die Bibliothek @lib@',
675
+    'plugin_necessite_php' => 'benötigt @plugin@ Version @version@.',
676
+    'plugin_necessite_plugin' => 'Benötigt Version @version@ des Plugin @plugin@.',
677
+    'plugin_necessite_plugin_sans_version' => 'Benötigt das Plugin @plugin@',
678
+    'plugin_necessite_spip' => 'Benötigt mindestens Version @version@ von SPIP.',
679
+    'plugin_source' => 'Quelle: ',
680
+    'plugin_titre_automatique' => 'Automatische Installation',
681
+    'plugin_titre_automatique_ajouter' => 'Plugins hinzufügen',
682
+    'plugin_titre_installation' => 'Installation des Plugins @plugin@',
683
+    'plugin_titre_modifier' => 'Meine Plugins',
684
+    'plugin_utilise_extension_php' => 'PHP-Erweiterung @plugin@ muss Version @version@ sein.',
685
+    'plugin_utilise_php' => '@plugin@ muss Version @version@ sein.',
686
+    'plugin_utilise_plugin' => 'Das Plugin @plugin@ muss Version @version@ sein.',
687
+    'plugin_zip_active' => 'Weiter zum Aktivieren',
688
+    'plugin_zip_adresse' => 'Geben Sie hier die Adresse einer ZIP-Datei, die das Plugin enthält, oder die Adresse einer Plugin-Liste an.',
689
+    'plugin_zip_adresse_champ' => 'Adresse des Plugins oder der Liste ',
690
+    'plugin_zip_content' => 'Enthält die folgenden Dateien (@taille@),<br />die im Verzeichnis <code>@rep@</code> installiert werden können.',
691
+    'plugin_zip_installe_finie' => 'Die Datei @zip@ wurde entpackt und installiert.',
692
+    'plugin_zip_installe_rep_finie' => 'Die Datei @zip@ wurde entpackt und in das Verzeichnis @rep@ installiert.',
693
+    'plugin_zip_installer' => 'Sie können es jetzt installieren.',
694
+    'plugin_zip_telecharge' => 'Die Datei @zip@ wurde heruntergeladen',
695
+    'plugins_actif_aucun' => 'Kein aktives Plugin.',
696
+    'plugins_actif_un' => 'Ein aktives Plugin.',
697
+    'plugins_actifs' => '@count@ aktive Plugins.',
698
+    'plugins_actifs_liste' => 'Aktiv',
699
+    'plugins_compte' => '@count@ Plugins',
700
+    'plugins_disponible_un' => 'Ein Plugin verfügbar.',
701
+    'plugins_disponibles' => '@count@ verfügbare Plugins.',
702
+    'plugins_erreur' => 'Fehler in den Plugins: @plugins@',
703
+    'plugins_liste' => 'Installierte Plugins',
704
+    'plugins_liste_dist' => 'Gesicherte Plugins', # Das hat jetzt aber mit plugins_liste_dist nichts mehr zu tun.
705
+    'plugins_recents' => 'Neueste Plugins.',
706
+    'plugins_tous_liste' => 'Alle',
707
+    'plugins_vue_hierarchie' => 'Hierarchie',
708
+    'plugins_vue_liste' => 'Liste',
709
+    'protocole_ldap' => 'Version des Protokolls:',
710 710
 
711
-	// Q
712
-	'queue_executer_maintenant' => 'Jetzt ausführen',
713
-	'queue_info_purger' => 'Sie können alle anstehenden Aufgaben löschen und so die Liste der regelmäßigen Aufgaben neu einlesen.',
714
-	'queue_nb_jobs_in_queue' => '@nb@ Aufgaben in der Warteschlange',
715
-	'queue_next_job_in_nb_sec' => 'Nächste Aufgabe in @nb@ s',
716
-	'queue_no_job_in_queue' => 'Keine Aufgaben in der Warteschlange',
717
-	'queue_one_job_in_queue' => '1 Aufgabe in der Warteschlange',
718
-	'queue_priorite_tache' => 'Rangfolge',
719
-	'queue_purger_queue' => 'Aufgabenliste löschen',
720
-	'queue_titre' => 'Hintergrundprozesse',
711
+    // Q
712
+    'queue_executer_maintenant' => 'Jetzt ausführen',
713
+    'queue_info_purger' => 'Sie können alle anstehenden Aufgaben löschen und so die Liste der regelmäßigen Aufgaben neu einlesen.',
714
+    'queue_nb_jobs_in_queue' => '@nb@ Aufgaben in der Warteschlange',
715
+    'queue_next_job_in_nb_sec' => 'Nächste Aufgabe in @nb@ s',
716
+    'queue_no_job_in_queue' => 'Keine Aufgaben in der Warteschlange',
717
+    'queue_one_job_in_queue' => '1 Aufgabe in der Warteschlange',
718
+    'queue_priorite_tache' => 'Rangfolge',
719
+    'queue_purger_queue' => 'Aufgabenliste löschen',
720
+    'queue_titre' => 'Hintergrundprozesse',
721 721
 
722
-	// R
723
-	'repertoire_plugins' => 'Verzeichnis:',
724
-	'required' => ' (erforderlich)',
722
+    // R
723
+    'repertoire_plugins' => 'Verzeichnis:',
724
+    'required' => ' (erforderlich)',
725 725
 
726
-	// S
727
-	'sans_heure' => 'Ohne Zeit',
728
-	'statut_admin_restreint' => 'Rubrik-Admin',
729
-	'statut_webmestre' => 'Webmaster',
726
+    // S
727
+    'sans_heure' => 'Ohne Zeit',
728
+    'statut_admin_restreint' => 'Rubrik-Admin',
729
+    'statut_webmestre' => 'Webmaster',
730 730
 
731
-	// T
732
-	'tache_cron_asap' => 'Cronjob @function@ (unverzüglich)',
733
-	'tache_cron_secondes' => 'Cronjob @function@ (alle @nb@ Sekunden)',
734
-	'taille_cache_image' => 'Die von SPIP automatisch berechneten Grafiken (Icons für Dokumente, als Grafiken gespeicherte Titel, mathematische Ausdrücke im Format TeX...) belegen insgesamt @taille@ im Verzeichnis @dir@.',
735
-	'taille_cache_moins_de' => 'Die Größe des Caches beträgt mindestens  @octets@.',
736
-	'taille_cache_octets' => 'Aktuelle Grösse des Cache: @octets@ Byte',
737
-	'taille_cache_vide' => 'Der Cache ist leer.',
738
-	'taille_repertoire_cache' => 'Grösse des Cache-Verzeichnis',
739
-	'text_article_propose_publication' => 'Dieser Artikel ist zur Veröffentlichung vorgeschlagen.',
740
-	'texte_acces_ldap_anonyme_1' => 'Manche LDAP-Server erlauben keinen anonymen Zugriff. In diesem Fall muss man Zugangsdaten für die erste Anmeldung eingeben, um Informationen im Verzeichnis suchen zu können. Meistens kann man hingegen die folgenden Felder frei lassen.',
741
-	'texte_admin_effacer_01' => 'Dieser Befehl löscht den <i>gesamten</i> Inhalt der Datenbank mit <i>allen</i> Redakteuren und Administratoren. Nach der Ausführung dieses Befehls müssen Sie SPIP neu installieren und einen ersten Administrator anlegen.',
742
-	'texte_adresse_annuaire_1' => '(Wenn Ihr Verzeichnis auf dem selben Rechner installiert ist wie diese Website, müssen Sie wahrscheinlich „localhost“ angeben.)',
743
-	'texte_ajout_auteur' => 'Folgender Autor ist diesem Artikel zugeordnet worden:',
744
-	'texte_annuaire_ldap_1' => 'Wenn Sie Zugang zu einem LDAP-Verzeichnis haben, können Sie es verwenden, um Benutzer automatisch nach SPIP zu importieren.',
745
-	'texte_article_statut' => 'Dieser Artikel ist:',
746
-	'texte_article_virtuel' => 'Virtueller Artikel',
747
-	'texte_article_virtuel_reference' => '<b>Virtueller Artikel:</b> Dieser Artikel ist Teil Ihrer Website, leitet Besucher aber zu einer anderen URL um. Sie können die Umleitung abschalten, indem Sie den URL oben löschen.',
748
-	'texte_aucun_resultat_auteur' => 'Kein Ergebnis für “@cherche_auteur@”',
749
-	'texte_auteur_messagerie' => 'Die Website kann Ihnen eine Liste aktuell eingelogter Redakteure anzeigen, so dass Sie sofort miteinander in Kontakt treten können (Wenn das Nachrichtensystem abgeschaltet ist, gibt es auch keine Liste angemeldeter Redakteure). Sie haben die Möglichkeit, nicht in diese Liste aufgenommen zu werden (damit sind Sie für andere Benutzer "unsichtbar").',
750
-	'texte_auteurs' => 'AUTOREN',
751
-	'texte_choix_base_1' => 'Wählen Sie die Datenbank:',
752
-	'texte_choix_base_2' => 'Der SQL-Server enthält mehrere Datenbanken.',
753
-	'texte_choix_base_3' => '<b>Wählen</b> Sie die von Ihrem Webhoster für Sie angelegte aus:',
754
-	'texte_choix_table_prefix' => 'Prefix der Tabellen:',
755
-	'texte_compte_element' => '@count@ Element',
756
-	'texte_compte_elements' => '@count@ Elemente',
757
-	'texte_conflit_edition_correction' => 'Bitte überprüfen sie hier die Unterschiede zwischen zwei Versionen des Textes. Sie können Ihre Änderungen kopieren und neu eingeben.',
758
-	'texte_connexion_mysql' => 'Sie erhalten die erforderlichen SQL-Zugangsdaten von Ihrem Provider: Name des Datenbankservers und persönliche Zugangsdaten.',
759
-	'texte_contenu_article' => '(Zusammenfassung des Artikels in wenigen Worten.)',
760
-	'texte_contenu_articles' => 'Ja nach Vorlage, die Sie für Ihre Website verwenden, können Sie Elemente von Artikeln aktivieren oder abschalten. Bitte bestimmen Sie mit dieser Liste, welche Elemente verfügbar sein sollen.',
761
-	'texte_crash_base' => 'Wenn Ihre Datenbank abgestürzt ist, können Sie eine automatische Reparatur versuchen.',
762
-	'texte_creer_rubrique' => 'Bevor Sie Artikel schreiben können,<br /> müssen Sie eine Rubrik anlegen.',
763
-	'texte_date_creation_article' => 'ARTIKEL ANGELEGT AM:',
764
-	'texte_date_creation_objet' => 'Erstellungsdatum:', # on ajoute le &quot;:&quot;
765
-	'texte_date_publication_anterieure' => 'DATUM EINER FRÜHEREN BEARBEITUNG',
766
-	'texte_date_publication_anterieure_nonaffichee' => 'Kein Datum einer früheren Bearbeitung anzeigen.',
767
-	'texte_date_publication_article' => 'ONLINE VERÖFFENTLICHT AM:',
768
-	'texte_date_publication_objet' => 'Veröffentlichungsdatum:',
769
-	'texte_definir_comme_traduction_rubrique' => 'Diese Rubrik ist eine Übersetzung der Rubik mit der Nummer',
770
-	'texte_descriptif_rapide' => 'Kurzbeschreibung',
771
-	'texte_effacer_base' => 'SPIP-Datenbank löschen',
772
-	'texte_effacer_statistiques' => 'Statistiken löschen',
773
-	'texte_en_cours_validation' => 'Die folgenden Einträge sind zur Veröffentlichung vorgeschlagen.',
774
-	'texte_enrichir_mise_a_jour' => 'Sie können Ihren Text ansprechend gestalten, indem Sie die „typografischen Abkürzungen“ verwenden.',
775
-	'texte_fichier_authent' => '<b>Soll SPIP die Dateien <tt>.htpasswd</tt> und <tt>.htpasswd-admin</tt> im Verzeichnis @dossier@ anlegen?</b><p>
731
+    // T
732
+    'tache_cron_asap' => 'Cronjob @function@ (unverzüglich)',
733
+    'tache_cron_secondes' => 'Cronjob @function@ (alle @nb@ Sekunden)',
734
+    'taille_cache_image' => 'Die von SPIP automatisch berechneten Grafiken (Icons für Dokumente, als Grafiken gespeicherte Titel, mathematische Ausdrücke im Format TeX...) belegen insgesamt @taille@ im Verzeichnis @dir@.',
735
+    'taille_cache_moins_de' => 'Die Größe des Caches beträgt mindestens  @octets@.',
736
+    'taille_cache_octets' => 'Aktuelle Grösse des Cache: @octets@ Byte',
737
+    'taille_cache_vide' => 'Der Cache ist leer.',
738
+    'taille_repertoire_cache' => 'Grösse des Cache-Verzeichnis',
739
+    'text_article_propose_publication' => 'Dieser Artikel ist zur Veröffentlichung vorgeschlagen.',
740
+    'texte_acces_ldap_anonyme_1' => 'Manche LDAP-Server erlauben keinen anonymen Zugriff. In diesem Fall muss man Zugangsdaten für die erste Anmeldung eingeben, um Informationen im Verzeichnis suchen zu können. Meistens kann man hingegen die folgenden Felder frei lassen.',
741
+    'texte_admin_effacer_01' => 'Dieser Befehl löscht den <i>gesamten</i> Inhalt der Datenbank mit <i>allen</i> Redakteuren und Administratoren. Nach der Ausführung dieses Befehls müssen Sie SPIP neu installieren und einen ersten Administrator anlegen.',
742
+    'texte_adresse_annuaire_1' => '(Wenn Ihr Verzeichnis auf dem selben Rechner installiert ist wie diese Website, müssen Sie wahrscheinlich „localhost“ angeben.)',
743
+    'texte_ajout_auteur' => 'Folgender Autor ist diesem Artikel zugeordnet worden:',
744
+    'texte_annuaire_ldap_1' => 'Wenn Sie Zugang zu einem LDAP-Verzeichnis haben, können Sie es verwenden, um Benutzer automatisch nach SPIP zu importieren.',
745
+    'texte_article_statut' => 'Dieser Artikel ist:',
746
+    'texte_article_virtuel' => 'Virtueller Artikel',
747
+    'texte_article_virtuel_reference' => '<b>Virtueller Artikel:</b> Dieser Artikel ist Teil Ihrer Website, leitet Besucher aber zu einer anderen URL um. Sie können die Umleitung abschalten, indem Sie den URL oben löschen.',
748
+    'texte_aucun_resultat_auteur' => 'Kein Ergebnis für “@cherche_auteur@”',
749
+    'texte_auteur_messagerie' => 'Die Website kann Ihnen eine Liste aktuell eingelogter Redakteure anzeigen, so dass Sie sofort miteinander in Kontakt treten können (Wenn das Nachrichtensystem abgeschaltet ist, gibt es auch keine Liste angemeldeter Redakteure). Sie haben die Möglichkeit, nicht in diese Liste aufgenommen zu werden (damit sind Sie für andere Benutzer "unsichtbar").',
750
+    'texte_auteurs' => 'AUTOREN',
751
+    'texte_choix_base_1' => 'Wählen Sie die Datenbank:',
752
+    'texte_choix_base_2' => 'Der SQL-Server enthält mehrere Datenbanken.',
753
+    'texte_choix_base_3' => '<b>Wählen</b> Sie die von Ihrem Webhoster für Sie angelegte aus:',
754
+    'texte_choix_table_prefix' => 'Prefix der Tabellen:',
755
+    'texte_compte_element' => '@count@ Element',
756
+    'texte_compte_elements' => '@count@ Elemente',
757
+    'texte_conflit_edition_correction' => 'Bitte überprüfen sie hier die Unterschiede zwischen zwei Versionen des Textes. Sie können Ihre Änderungen kopieren und neu eingeben.',
758
+    'texte_connexion_mysql' => 'Sie erhalten die erforderlichen SQL-Zugangsdaten von Ihrem Provider: Name des Datenbankservers und persönliche Zugangsdaten.',
759
+    'texte_contenu_article' => '(Zusammenfassung des Artikels in wenigen Worten.)',
760
+    'texte_contenu_articles' => 'Ja nach Vorlage, die Sie für Ihre Website verwenden, können Sie Elemente von Artikeln aktivieren oder abschalten. Bitte bestimmen Sie mit dieser Liste, welche Elemente verfügbar sein sollen.',
761
+    'texte_crash_base' => 'Wenn Ihre Datenbank abgestürzt ist, können Sie eine automatische Reparatur versuchen.',
762
+    'texte_creer_rubrique' => 'Bevor Sie Artikel schreiben können,<br /> müssen Sie eine Rubrik anlegen.',
763
+    'texte_date_creation_article' => 'ARTIKEL ANGELEGT AM:',
764
+    'texte_date_creation_objet' => 'Erstellungsdatum:', # on ajoute le &quot;:&quot;
765
+    'texte_date_publication_anterieure' => 'DATUM EINER FRÜHEREN BEARBEITUNG',
766
+    'texte_date_publication_anterieure_nonaffichee' => 'Kein Datum einer früheren Bearbeitung anzeigen.',
767
+    'texte_date_publication_article' => 'ONLINE VERÖFFENTLICHT AM:',
768
+    'texte_date_publication_objet' => 'Veröffentlichungsdatum:',
769
+    'texte_definir_comme_traduction_rubrique' => 'Diese Rubrik ist eine Übersetzung der Rubik mit der Nummer',
770
+    'texte_descriptif_rapide' => 'Kurzbeschreibung',
771
+    'texte_effacer_base' => 'SPIP-Datenbank löschen',
772
+    'texte_effacer_statistiques' => 'Statistiken löschen',
773
+    'texte_en_cours_validation' => 'Die folgenden Einträge sind zur Veröffentlichung vorgeschlagen.',
774
+    'texte_enrichir_mise_a_jour' => 'Sie können Ihren Text ansprechend gestalten, indem Sie die „typografischen Abkürzungen“ verwenden.',
775
+    'texte_fichier_authent' => '<b>Soll SPIP die Dateien <tt>.htpasswd</tt> und <tt>.htpasswd-admin</tt> im Verzeichnis @dossier@ anlegen?</b><p>
776 776
  Mit diesen Dateien können Sie den Zugang zu anderen Bereichen Ihrer Website (z.B. externe Logfile-Auswertungen) auf Redakteure und Administratoren beschränken.</p><p>Wenn Sie diese Möglickeit nicht nutzen, könnn Sie hier die Grundeinstellung (Dateien werden nicht angelegt) beibehalten.</p>',
777
-	'texte_informations_personnelles_1' => 'Das System wird nun persönliche Zugangsdaten für Sie anlegen.',
778
-	'texte_informations_personnelles_2' => '(Hinweis: Wenn Sie die Site erneut installieren, und Ihre Zugangsdaten funktionieren, können Sie',
779
-	'texte_introductif_article' => '(Einleitender Text des Artikels.)',
780
-	'texte_jeu_caractere' => 'Es empfiehlt sich, das Universalalphabet (<tt>utf-8</tt>) für ihre Website zu verwenden. Es ermöglicht die Darstellung der Zeichen aller Sprachen und wird nunmehr von allen modernen Webbrowsern unterstützt.',
781
-	'texte_jeu_caractere_3' => 'Ihre Website verwendet zur Zeit den Zeichensatz:',
782
-	'texte_jeu_caractere_4' => 'Wenn das nicht mit den Erfordernissen ihrer Daten übereinstimmt (z.B. nach der Wiederherstellung einer Datensicherung), oder wenn sie die Website neu einrichten und einen anderen Zeichernsatz verwenden möchten, stellen sie ihn bitte hier ein:',
783
-	'texte_login_ldap_1' => '(Keine Angabe bzw. vollständiger Pfad, z.B. „<tt>uid=meier, ou=mitglieder, dc=MeineDomäne, dc=com</tt>“.)',
784
-	'texte_login_precaution' => 'Achtung! Sie sind zur Zeit mit diesem Namen angemeldet. Bitte verwenden Sie diese Seite mit der erforderlichen Vorsicht.',
785
-	'texte_messagerie_agenda' => 'Mit dem Nachrichtensystem können Redakteure im Redaktionsbereich direkt miteinander kommunizieren. Es ist mit einem Kalender verbunden.',
786
-	'texte_mise_a_niveau_base_1' => 'Sie haben den Programmcode von SPIP aktualisiert. Jetzt muss die Datenbank aktualisiert werden.',
787
-	'texte_modifier_article' => 'Artikel bearbeiten:',
788
-	'texte_multilinguisme' => 'Wenn Sie Artikel in mehreren Sprachen mit entsprecher komplexer Navigation verwalten möchten, können Sie den Rubriken und/oder den Artikeln ein Menü zur Sprachauswahl hinzufügen. Diese Funktion ist abhängig von der Struktur Ihrer Website.',
789
-	'texte_multilinguisme_trad' => 'Sie können ein System zur automatischen Verlinkung der verschiedenen Sprachversionen von Objekten aktivieren.',
790
-	'texte_non_compresse' => '<i>unkomprimiert</i> (ihr Server unterstützt diese Funktion nicht)',
791
-	'texte_nouvelle_version_spip_1' => 'Sie haben eine neue Version von SPIP installiert.',
792
-	'texte_nouvelle_version_spip_2' => 'Diese neue Version erfordert eine weiter gehende Aktualisierung Ihres Systems als gewöhnlich. Wenn Sie Webmaster dieser Site sind, löschen Sie bitte die Datei @connect@ und setzen Sie die Installation fort, indem Sie die Verbindungsdaten zur Datenbank neu eingeben.<p>(Tipp: Sollten Sie Ihre Verbindungsdaten vergessen haben, schauen Sie in der Datei @connect@ nach, bevor Sie sie löschen ...)</p>',
793
-	'texte_operation_echec' => 'Gehen Sie zur vorigen Seite zurück und wählen Sie eine andere Datenbank aus bzw. legen Sie eine neue an. Überprüfen Sie die Angaben Ihres Providers.',
794
-	'texte_plus_trois_car' => 'mehr als 3 Zeichen',
795
-	'texte_plusieurs_articles' => 'Mehrere Autoren für „@cherche_auteur@“ gefunden:',
796
-	'texte_port_annuaire' => '(Der Standardwert kann meistens beibehalten werden.)',
797
-	'texte_presente_plugin' => 'Diese Seite zeigt eine Liste der auf dieser Website verfügbaren Plugins. Sie können sie aktivieren, indem sie die entsprechenden Einträge mit einem Häkchen merkieren.',
798
-	'texte_proposer_publication' => 'Wenn Ihr Artikel fertig ist,<br /> können Sie ihn zur Veröffentlichung vorschlagen.',
799
-	'texte_proxy' => 'In manchen Fällen (Intranet, Rechner hinter einer Firewall...),
777
+    'texte_informations_personnelles_1' => 'Das System wird nun persönliche Zugangsdaten für Sie anlegen.',
778
+    'texte_informations_personnelles_2' => '(Hinweis: Wenn Sie die Site erneut installieren, und Ihre Zugangsdaten funktionieren, können Sie',
779
+    'texte_introductif_article' => '(Einleitender Text des Artikels.)',
780
+    'texte_jeu_caractere' => 'Es empfiehlt sich, das Universalalphabet (<tt>utf-8</tt>) für ihre Website zu verwenden. Es ermöglicht die Darstellung der Zeichen aller Sprachen und wird nunmehr von allen modernen Webbrowsern unterstützt.',
781
+    'texte_jeu_caractere_3' => 'Ihre Website verwendet zur Zeit den Zeichensatz:',
782
+    'texte_jeu_caractere_4' => 'Wenn das nicht mit den Erfordernissen ihrer Daten übereinstimmt (z.B. nach der Wiederherstellung einer Datensicherung), oder wenn sie die Website neu einrichten und einen anderen Zeichernsatz verwenden möchten, stellen sie ihn bitte hier ein:',
783
+    'texte_login_ldap_1' => '(Keine Angabe bzw. vollständiger Pfad, z.B. „<tt>uid=meier, ou=mitglieder, dc=MeineDomäne, dc=com</tt>“.)',
784
+    'texte_login_precaution' => 'Achtung! Sie sind zur Zeit mit diesem Namen angemeldet. Bitte verwenden Sie diese Seite mit der erforderlichen Vorsicht.',
785
+    'texte_messagerie_agenda' => 'Mit dem Nachrichtensystem können Redakteure im Redaktionsbereich direkt miteinander kommunizieren. Es ist mit einem Kalender verbunden.',
786
+    'texte_mise_a_niveau_base_1' => 'Sie haben den Programmcode von SPIP aktualisiert. Jetzt muss die Datenbank aktualisiert werden.',
787
+    'texte_modifier_article' => 'Artikel bearbeiten:',
788
+    'texte_multilinguisme' => 'Wenn Sie Artikel in mehreren Sprachen mit entsprecher komplexer Navigation verwalten möchten, können Sie den Rubriken und/oder den Artikeln ein Menü zur Sprachauswahl hinzufügen. Diese Funktion ist abhängig von der Struktur Ihrer Website.',
789
+    'texte_multilinguisme_trad' => 'Sie können ein System zur automatischen Verlinkung der verschiedenen Sprachversionen von Objekten aktivieren.',
790
+    'texte_non_compresse' => '<i>unkomprimiert</i> (ihr Server unterstützt diese Funktion nicht)',
791
+    'texte_nouvelle_version_spip_1' => 'Sie haben eine neue Version von SPIP installiert.',
792
+    'texte_nouvelle_version_spip_2' => 'Diese neue Version erfordert eine weiter gehende Aktualisierung Ihres Systems als gewöhnlich. Wenn Sie Webmaster dieser Site sind, löschen Sie bitte die Datei @connect@ und setzen Sie die Installation fort, indem Sie die Verbindungsdaten zur Datenbank neu eingeben.<p>(Tipp: Sollten Sie Ihre Verbindungsdaten vergessen haben, schauen Sie in der Datei @connect@ nach, bevor Sie sie löschen ...)</p>',
793
+    'texte_operation_echec' => 'Gehen Sie zur vorigen Seite zurück und wählen Sie eine andere Datenbank aus bzw. legen Sie eine neue an. Überprüfen Sie die Angaben Ihres Providers.',
794
+    'texte_plus_trois_car' => 'mehr als 3 Zeichen',
795
+    'texte_plusieurs_articles' => 'Mehrere Autoren für „@cherche_auteur@“ gefunden:',
796
+    'texte_port_annuaire' => '(Der Standardwert kann meistens beibehalten werden.)',
797
+    'texte_presente_plugin' => 'Diese Seite zeigt eine Liste der auf dieser Website verfügbaren Plugins. Sie können sie aktivieren, indem sie die entsprechenden Einträge mit einem Häkchen merkieren.',
798
+    'texte_proposer_publication' => 'Wenn Ihr Artikel fertig ist,<br /> können Sie ihn zur Veröffentlichung vorschlagen.',
799
+    'texte_proxy' => 'In manchen Fällen (Intranet, Rechner hinter einer Firewall...),
800 800
 kann ein <i>HTTP-Proxy</i> erforderlich sein, um die syndizierten Websites zu erreichen.
801 801
  In diesem Fall geben Sie seine Adresse im Format
802 802
 <tt><html>http://proxy:8080</html></tt>. an.
803 803
 Meistens kann dieses Feld aber leer bleiben.',
804
-	'texte_publication_articles_post_dates' => 'Wie soll SPIP Artikel behandeln, deren Erscheinungsdatum in die Zukunft gelegt wurde?',
805
-	'texte_rappel_selection_champs' => '[Vergessen Sie nicht, dieses Feld korrekt auszufüllen.]',
806
-	'texte_recalcul_page' => 'Wenn Sie nur eine einzelne Seite aktualisieren wollen, verwenden Sie besser den Schalter „Seite aus Cache löschen“.',
807
-	'texte_recuperer_base' => 'Datenbank reparieren',
808
-	'texte_reference_mais_redirige' => 'Artikel Ihrer Website, der eine Umleitung zu einem anderen URL enthält.',
809
-	'texte_requetes_echouent' => '<b>Wenn manche SQL-Befehle ohne ersichtlichen Grund systematisch fehlschlagen, kann es an einer beschädigten Datenbank liegen.</b><p>
804
+    'texte_publication_articles_post_dates' => 'Wie soll SPIP Artikel behandeln, deren Erscheinungsdatum in die Zukunft gelegt wurde?',
805
+    'texte_rappel_selection_champs' => '[Vergessen Sie nicht, dieses Feld korrekt auszufüllen.]',
806
+    'texte_recalcul_page' => 'Wenn Sie nur eine einzelne Seite aktualisieren wollen, verwenden Sie besser den Schalter „Seite aus Cache löschen“.',
807
+    'texte_recuperer_base' => 'Datenbank reparieren',
808
+    'texte_reference_mais_redirige' => 'Artikel Ihrer Website, der eine Umleitung zu einem anderen URL enthält.',
809
+    'texte_requetes_echouent' => '<b>Wenn manche SQL-Befehle ohne ersichtlichen Grund systematisch fehlschlagen, kann es an einer beschädigten Datenbank liegen.</b><p>
810 810
 SQL kann Tabellen reparieren, die beschädigt worden sind. Starten Sie hier einen Reparaturversuch. Sollte das fehlschlagen, notieren Sie bitte die Fehlermeldung, die u.U. einen Hinweis auf die Ursache des Problems gibt ...<p>
811 811
 Wenn das Problem weiter besteht, nehmen Sie bitte Kontakt mit Ihrem Provider auf.<p>',
812
-	'texte_selection_langue_principale' => 'Hier können Sie die «Hauptsprache» der Website auswählen. Das zwingt Sie - zum Glück - nicht, Ihre Artikel in dieser Sprache zu schreiben, sondern ermöglicht:
812
+    'texte_selection_langue_principale' => 'Hier können Sie die «Hauptsprache» der Website auswählen. Das zwingt Sie - zum Glück - nicht, Ihre Artikel in dieser Sprache zu schreiben, sondern ermöglicht:
813 813
         <ul><li> das Format der Datumsanzeige einzustellen;</li>
814 814
         <li> die Art der typografischen Korrekturen von SPIP zu bestimmen;</li>
815 815
         <li> über die Sprachversion der eingebauten Formulare zu entscheiden;</li>
816 816
         <li> die Standardsprache des Redaktionssystems zu verändern.</li></ul>',
817
-	'texte_sous_titre' => 'Untertitel',
818
-	'texte_statistiques_visites' => '(dunkle Balken : Sonntag / dunkle Kurve : Entwicklung der Durchschnittswerte)',
819
-	'texte_statut_attente_validation' => 'vorgeschlagen',
820
-	'texte_statut_publies' => 'veröffentlicht',
821
-	'texte_statut_refuses' => 'abgelehnt',
822
-	'texte_suppression_fichiers' => 'Benutzen Sie diesen Befehl, um alle Dateien aus dem Zwischenspeicher von SPIP zu löschen. Damit können Sie eine erneute Berechnung aller Seiten erzwingen, wenn Sie z.B. wesentliche Änderungen am Inhalt und Layout Ihrer Site gemacht haben. ',
823
-	'texte_sur_titre' => 'Einleitender Titel',
824
-	'texte_table_ok' => ': Tabelle OK.',
825
-	'texte_tentative_recuperation' => 'Reparaturversuch',
826
-	'texte_tenter_reparation' => 'Reparatur der Datenbank versuchen',
827
-	'texte_test_proxy' => 'Um den Proxy zu testen, geben Sie hier die Adresse einer gewünschten Website ein.',
828
-	'texte_titre_02' => 'Titel:',
829
-	'texte_titre_obligatoire' => '<b>Titel</b> [obligatorisch]',
830
-	'texte_travail_article' => '@nom_auteur_modif@ hat diesen Artikel vor @date_diff@ Minuten bearbeitet',
831
-	'texte_travail_collaboratif' => 'Wenn es öfter vorkommt, dass mehrere Redakteure gemeinsam an Artikeln arbeiten, kann SPIP die vor kurzem „geöffneten“ Artikel anzeigen, um gleichzeitige Änderungen vorzubeugen. Diese Funktion ist normalerweise abgeschaltet, um störende Meldungen zu reduzieren.',
832
-	'texte_vide' => 'leer',
833
-	'texte_vider_cache' => 'Cache leeren',
834
-	'titre_admin_tech' => 'Wartung',
835
-	'titre_admin_vider' => 'Wartung',
836
-	'titre_ajouter_un_auteur' => 'Autor hinzufügen',
837
-	'titre_ajouter_un_mot' => 'Schlagwort hinzufügen',
838
-	'titre_cadre_afficher_article' => 'Artikel anzeigen',
839
-	'titre_cadre_afficher_traductions' => 'Stand der Übersetzungen für diese Sprachen anzeigen',
840
-	'titre_cadre_ajouter_auteur' => 'AUTOR HINZUFÜGEN: ',
841
-	'titre_cadre_interieur_rubrique' => 'In der Rubrik',
842
-	'titre_cadre_numero_auteur' => 'AUTOR NUMMER',
843
-	'titre_cadre_numero_objet' => '@objet@ Nummer:',
844
-	'titre_cadre_signature_obligatoire' => '<b>Unterschrift</b> [obligatorisch]<br />',
845
-	'titre_config_contenu_notifications' => 'Benachrichtigungen',
846
-	'titre_config_contenu_prive' => 'Im Redaktionsbereich',
847
-	'titre_config_contenu_public' => 'Auf der öffentlichen Website',
848
-	'titre_config_fonctions' => 'Website konfigurieren',
849
-	'titre_config_langage' => 'Sprache einstellen',
850
-	'titre_configuration' => 'Website konfigurieren',
851
-	'titre_configurer_preferences' => 'Ihre Einstellungen',
852
-	'titre_configurer_preferences_menus' => 'Konfigurieren Sie Ihre Menüeinstellungen',
853
-	'titre_conflit_edition' => 'Bearbeitungskonflikt',
854
-	'titre_connexion_ldap' => 'Optionen: <b>LDAP-Verbindung</b>',
855
-	'titre_groupe_mots' => 'KATEGORIE:',
856
-	'titre_identite_site' => 'Name der Website', # &quot;Identité du site&quot; war &quot;Identität der Website&quot;, jetzt &quot;Name der Website&quot;, auch möglich &quot;Websitebezeichnung&quot; o.ä.
857
-	'titre_langue_article' => 'Sprache des Artikels',
858
-	'titre_langue_rubrique' => 'Sprache der Rubrik',
859
-	'titre_langue_trad_article' => 'SPRACHE UND ÜBERSETZUNGEN DES ARTIKELS',
860
-	'titre_les_articles' => 'ARTIKEL',
861
-	'titre_messagerie_agenda' => 'Nachrichten und Kalender',
862
-	'titre_naviguer_dans_le_site' => 'Sitenavigation ...',
863
-	'titre_nouvelle_rubrique' => 'Neue Rubrik',
864
-	'titre_numero_rubrique' => 'RUBRIK NUMMER:',
865
-	'titre_page_articles_edit' => 'Bearbeiten: @titre@',
866
-	'titre_page_articles_page' => 'Artikel',
867
-	'titre_page_articles_tous' => 'Ganze Website',
868
-	'titre_page_calendrier' => 'Kalender @nom_mois@ @annee@',
869
-	'titre_page_config_contenu' => 'Website konfigurieren',
870
-	'titre_page_delete_all' => 'vollständig unwiderruflich löschen',
871
-	'titre_page_recherche' => 'Ergebnisse der Suche nach @recherche@',
872
-	'titre_page_statistiques_referers' => 'Statistik (Referer)',
873
-	'titre_page_upgrade' => 'Aktualisierung von SPIP',
874
-	'titre_preference_menus_favoris' => 'Lieblingsmenüs',
875
-	'titre_publication_articles_post_dates' => 'Veröffentlichung von vordatierten Artikeln',
876
-	'titre_reparation' => 'Reparatur',
877
-	'titre_suivi_petition' => 'Petitionen verwalten',
878
-	'tls_ldap' => 'Transport Layer Security:',
879
-	'trad_article_traduction' => 'Alle Fassungen dieses Artikels:',
880
-	'trad_delier' => 'Nicht mehr mit diesen Übersetzungen verbinden',
881
-	'trad_lier' => 'Dieser Artikel ist eine Übersetzung des Artikels Nummer ',
882
-	'trad_new' => 'Neue Übersetzung beginnen',
817
+    'texte_sous_titre' => 'Untertitel',
818
+    'texte_statistiques_visites' => '(dunkle Balken : Sonntag / dunkle Kurve : Entwicklung der Durchschnittswerte)',
819
+    'texte_statut_attente_validation' => 'vorgeschlagen',
820
+    'texte_statut_publies' => 'veröffentlicht',
821
+    'texte_statut_refuses' => 'abgelehnt',
822
+    'texte_suppression_fichiers' => 'Benutzen Sie diesen Befehl, um alle Dateien aus dem Zwischenspeicher von SPIP zu löschen. Damit können Sie eine erneute Berechnung aller Seiten erzwingen, wenn Sie z.B. wesentliche Änderungen am Inhalt und Layout Ihrer Site gemacht haben. ',
823
+    'texte_sur_titre' => 'Einleitender Titel',
824
+    'texte_table_ok' => ': Tabelle OK.',
825
+    'texte_tentative_recuperation' => 'Reparaturversuch',
826
+    'texte_tenter_reparation' => 'Reparatur der Datenbank versuchen',
827
+    'texte_test_proxy' => 'Um den Proxy zu testen, geben Sie hier die Adresse einer gewünschten Website ein.',
828
+    'texte_titre_02' => 'Titel:',
829
+    'texte_titre_obligatoire' => '<b>Titel</b> [obligatorisch]',
830
+    'texte_travail_article' => '@nom_auteur_modif@ hat diesen Artikel vor @date_diff@ Minuten bearbeitet',
831
+    'texte_travail_collaboratif' => 'Wenn es öfter vorkommt, dass mehrere Redakteure gemeinsam an Artikeln arbeiten, kann SPIP die vor kurzem „geöffneten“ Artikel anzeigen, um gleichzeitige Änderungen vorzubeugen. Diese Funktion ist normalerweise abgeschaltet, um störende Meldungen zu reduzieren.',
832
+    'texte_vide' => 'leer',
833
+    'texte_vider_cache' => 'Cache leeren',
834
+    'titre_admin_tech' => 'Wartung',
835
+    'titre_admin_vider' => 'Wartung',
836
+    'titre_ajouter_un_auteur' => 'Autor hinzufügen',
837
+    'titre_ajouter_un_mot' => 'Schlagwort hinzufügen',
838
+    'titre_cadre_afficher_article' => 'Artikel anzeigen',
839
+    'titre_cadre_afficher_traductions' => 'Stand der Übersetzungen für diese Sprachen anzeigen',
840
+    'titre_cadre_ajouter_auteur' => 'AUTOR HINZUFÜGEN: ',
841
+    'titre_cadre_interieur_rubrique' => 'In der Rubrik',
842
+    'titre_cadre_numero_auteur' => 'AUTOR NUMMER',
843
+    'titre_cadre_numero_objet' => '@objet@ Nummer:',
844
+    'titre_cadre_signature_obligatoire' => '<b>Unterschrift</b> [obligatorisch]<br />',
845
+    'titre_config_contenu_notifications' => 'Benachrichtigungen',
846
+    'titre_config_contenu_prive' => 'Im Redaktionsbereich',
847
+    'titre_config_contenu_public' => 'Auf der öffentlichen Website',
848
+    'titre_config_fonctions' => 'Website konfigurieren',
849
+    'titre_config_langage' => 'Sprache einstellen',
850
+    'titre_configuration' => 'Website konfigurieren',
851
+    'titre_configurer_preferences' => 'Ihre Einstellungen',
852
+    'titre_configurer_preferences_menus' => 'Konfigurieren Sie Ihre Menüeinstellungen',
853
+    'titre_conflit_edition' => 'Bearbeitungskonflikt',
854
+    'titre_connexion_ldap' => 'Optionen: <b>LDAP-Verbindung</b>',
855
+    'titre_groupe_mots' => 'KATEGORIE:',
856
+    'titre_identite_site' => 'Name der Website', # &quot;Identité du site&quot; war &quot;Identität der Website&quot;, jetzt &quot;Name der Website&quot;, auch möglich &quot;Websitebezeichnung&quot; o.ä.
857
+    'titre_langue_article' => 'Sprache des Artikels',
858
+    'titre_langue_rubrique' => 'Sprache der Rubrik',
859
+    'titre_langue_trad_article' => 'SPRACHE UND ÜBERSETZUNGEN DES ARTIKELS',
860
+    'titre_les_articles' => 'ARTIKEL',
861
+    'titre_messagerie_agenda' => 'Nachrichten und Kalender',
862
+    'titre_naviguer_dans_le_site' => 'Sitenavigation ...',
863
+    'titre_nouvelle_rubrique' => 'Neue Rubrik',
864
+    'titre_numero_rubrique' => 'RUBRIK NUMMER:',
865
+    'titre_page_articles_edit' => 'Bearbeiten: @titre@',
866
+    'titre_page_articles_page' => 'Artikel',
867
+    'titre_page_articles_tous' => 'Ganze Website',
868
+    'titre_page_calendrier' => 'Kalender @nom_mois@ @annee@',
869
+    'titre_page_config_contenu' => 'Website konfigurieren',
870
+    'titre_page_delete_all' => 'vollständig unwiderruflich löschen',
871
+    'titre_page_recherche' => 'Ergebnisse der Suche nach @recherche@',
872
+    'titre_page_statistiques_referers' => 'Statistik (Referer)',
873
+    'titre_page_upgrade' => 'Aktualisierung von SPIP',
874
+    'titre_preference_menus_favoris' => 'Lieblingsmenüs',
875
+    'titre_publication_articles_post_dates' => 'Veröffentlichung von vordatierten Artikeln',
876
+    'titre_reparation' => 'Reparatur',
877
+    'titre_suivi_petition' => 'Petitionen verwalten',
878
+    'tls_ldap' => 'Transport Layer Security:',
879
+    'trad_article_traduction' => 'Alle Fassungen dieses Artikels:',
880
+    'trad_delier' => 'Nicht mehr mit diesen Übersetzungen verbinden',
881
+    'trad_lier' => 'Dieser Artikel ist eine Übersetzung des Artikels Nummer ',
882
+    'trad_new' => 'Neue Übersetzung beginnen',
883 883
 
884
-	// U
885
-	'utf8_convert_erreur_orig' => 'Fehler: Der Zeichensatz @charset@ wird nicht unterstützt.',
884
+    // U
885
+    'utf8_convert_erreur_orig' => 'Fehler: Der Zeichensatz @charset@ wird nicht unterstützt.',
886 886
 
887
-	// V
888
-	'version' => 'Version:'
887
+    // V
888
+    'version' => 'Version:'
889 889
 );
Please login to merge, or discard this patch.
prive/themes/spip/vars.css_fonctions.php 1 patch
Indentation   +144 added lines, -144 removed lines patch added patch discarded remove patch
@@ -8,59 +8,59 @@  discard block
 block discarded – undo
8 8
  * @param Pile $pile Pile
9 9
  */
10 10
 function spip_generer_variables_css_typo(array $Pile): Collection {
11
-	$vars = new Collection();
12
-
13
-	// Direction
14
-	$vars->add('--spip-dir', $Pile[0]['dir']);
15
-	$vars->add('--spip-left', $Pile[0]['left']);
16
-	$vars->add('--spip-right', $Pile[0]['right']);
17
-
18
-	// Typographie
19
-	$vars->add('--spip-font-size', $Pile[0]['font-size']);
20
-	$vars->add('--spip-line-height', $Pile[0]['line-height']);
21
-	$vars->add('--spip-text-indent', $Pile[0]['text-indent']);
22
-	$vars->add('--spip-font-family', $Pile[0]['font-family']);
23
-
24
-	// Couleurs hors thème
25
-	$vars->add('--spip-background-color', $Pile[0]['background-color']);
26
-	$vars->add('--spip-color', $Pile[0]['color']);
27
-
28
-	// Espacements pour le rythme vertical et les gouttières
29
-	// Basés sur la hauteur d'une ligne de texte à la racine du document
30
-	$vars->add('--spip-spacing-y', round(strmult($Pile[0]['font-size'], $Pile[0]['line-height']), 4) . 'rem');
31
-	$vars->add('--spip-spacing-x', round(strmult($Pile[0]['font-size'], $Pile[0]['line-height']), 4) . 'rem');
32
-	$vars->add('--spip-margin-bottom', $Pile[0]['margin-bottom']); // À déprécier
33
-
34
-	// Bordures
35
-	$vars->add('--spip-border-radius-mini', '0.2rem');
36
-	$vars->add('--spip-border-radius', '0.33rem');
37
-	$vars->add('--spip-border-radius-large', '0.66rem');
38
-
39
-	// Ombres portées
40
-	$shadow_mini =
41
-		'0 0.05em 0.1em hsla(0, 0%, 0%, 0.33),' .
42
-		'0 0.1em  0.15em hsla(0, 0%, 0%, 0.05),' .
43
-		'0 0.1em  0.25em  hsla(0, 0%, 0%, 0.05)';
44
-	$shadow =
45
-		'0 0.05em 0.15em hsla(0, 0%, 0%, 0.33),' .
46
-		'0 0.1em  0.25em hsla(0, 0%, 0%, 0.05),' .
47
-		'0 0.1em  0.5em  hsla(0, 0%, 0%, 0.05)';
48
-	$shadow_large =
49
-		'0 0.05em 0.15em hsla(0, 0%, 0%, 0.1),' .
50
-		'0 0.2em  0.5em  hsla(0, 0%, 0%, 0.1),' .
51
-		'0 0.2em  1em    hsla(0, 0%, 0%, 0.075)';
52
-	$shadow_huge =
53
-		'0 0.1em 0.25em hsla(0, 0%, 0%, 0.1),' .
54
-		'0 0.25em  1em  hsla(0, 0%, 0%, 0.1),' .
55
-		'0 0.5em  2em    hsla(0, 0%, 0%, 0.075)';
56
-	$vars->add('--spip-box-shadow-mini', $shadow_mini);
57
-	$vars->add('--spip-box-shadow-mini-hover', $shadow);
58
-	$vars->add('--spip-box-shadow', $shadow);
59
-	$vars->add('--spip-box-shadow-hover', $shadow_large);
60
-	$vars->add('--spip-box-shadow-large', $shadow_large);
61
-	$vars->add('--spip-box-shadow-large-hover', $shadow_huge);
62
-
63
-	return $vars;
11
+    $vars = new Collection();
12
+
13
+    // Direction
14
+    $vars->add('--spip-dir', $Pile[0]['dir']);
15
+    $vars->add('--spip-left', $Pile[0]['left']);
16
+    $vars->add('--spip-right', $Pile[0]['right']);
17
+
18
+    // Typographie
19
+    $vars->add('--spip-font-size', $Pile[0]['font-size']);
20
+    $vars->add('--spip-line-height', $Pile[0]['line-height']);
21
+    $vars->add('--spip-text-indent', $Pile[0]['text-indent']);
22
+    $vars->add('--spip-font-family', $Pile[0]['font-family']);
23
+
24
+    // Couleurs hors thème
25
+    $vars->add('--spip-background-color', $Pile[0]['background-color']);
26
+    $vars->add('--spip-color', $Pile[0]['color']);
27
+
28
+    // Espacements pour le rythme vertical et les gouttières
29
+    // Basés sur la hauteur d'une ligne de texte à la racine du document
30
+    $vars->add('--spip-spacing-y', round(strmult($Pile[0]['font-size'], $Pile[0]['line-height']), 4) . 'rem');
31
+    $vars->add('--spip-spacing-x', round(strmult($Pile[0]['font-size'], $Pile[0]['line-height']), 4) . 'rem');
32
+    $vars->add('--spip-margin-bottom', $Pile[0]['margin-bottom']); // À déprécier
33
+
34
+    // Bordures
35
+    $vars->add('--spip-border-radius-mini', '0.2rem');
36
+    $vars->add('--spip-border-radius', '0.33rem');
37
+    $vars->add('--spip-border-radius-large', '0.66rem');
38
+
39
+    // Ombres portées
40
+    $shadow_mini =
41
+        '0 0.05em 0.1em hsla(0, 0%, 0%, 0.33),' .
42
+        '0 0.1em  0.15em hsla(0, 0%, 0%, 0.05),' .
43
+        '0 0.1em  0.25em  hsla(0, 0%, 0%, 0.05)';
44
+    $shadow =
45
+        '0 0.05em 0.15em hsla(0, 0%, 0%, 0.33),' .
46
+        '0 0.1em  0.25em hsla(0, 0%, 0%, 0.05),' .
47
+        '0 0.1em  0.5em  hsla(0, 0%, 0%, 0.05)';
48
+    $shadow_large =
49
+        '0 0.05em 0.15em hsla(0, 0%, 0%, 0.1),' .
50
+        '0 0.2em  0.5em  hsla(0, 0%, 0%, 0.1),' .
51
+        '0 0.2em  1em    hsla(0, 0%, 0%, 0.075)';
52
+    $shadow_huge =
53
+        '0 0.1em 0.25em hsla(0, 0%, 0%, 0.1),' .
54
+        '0 0.25em  1em  hsla(0, 0%, 0%, 0.1),' .
55
+        '0 0.5em  2em    hsla(0, 0%, 0%, 0.075)';
56
+    $vars->add('--spip-box-shadow-mini', $shadow_mini);
57
+    $vars->add('--spip-box-shadow-mini-hover', $shadow);
58
+    $vars->add('--spip-box-shadow', $shadow);
59
+    $vars->add('--spip-box-shadow-hover', $shadow_large);
60
+    $vars->add('--spip-box-shadow-large', $shadow_large);
61
+    $vars->add('--spip-box-shadow-large-hover', $shadow_huge);
62
+
63
+    return $vars;
64 64
 }
65 65
 
66 66
 /**
@@ -69,101 +69,101 @@  discard block
 block discarded – undo
69 69
  * @param string $couleur Couleur hex
70 70
  */
71 71
 function spip_generer_variables_css_couleurs_theme(string $couleur): Collection {
72
-	$vars = new Collection();
73
-
74
-	#$vars->add('--spip-color-theme--hsl', couleur_hex_to_hsl($couleur, 'h, s, l')); // redéfini ensuite
75
-	$vars->add('--spip-color-theme--h', couleur_hex_to_hsl($couleur, 'h'));
76
-	$vars->add('--spip-color-theme--s', couleur_hex_to_hsl($couleur, 's'));
77
-	$vars->add('--spip-color-theme--l', couleur_hex_to_hsl($couleur, 'l'));
78
-
79
-	// un joli dégradé coloré de presque blanc à presque noir…
80
-	$vars->add('--spip-color-theme--100', couleur_hex_to_hsl(couleur_eclaircir($couleur, .99), 'h, s, l'));
81
-	$vars->add('--spip-color-theme--98', couleur_hex_to_hsl(couleur_eclaircir($couleur, .95), 'h, s, l'));
82
-	$vars->add('--spip-color-theme--95', couleur_hex_to_hsl(couleur_eclaircir($couleur, .90), 'h, s, l'));
83
-	$vars->add('--spip-color-theme--90', couleur_hex_to_hsl(couleur_eclaircir($couleur, .75), 'h, s, l'));
84
-	$vars->add('--spip-color-theme--80', couleur_hex_to_hsl(couleur_eclaircir($couleur, .50), 'h, s, l'));
85
-	$vars->add('--spip-color-theme--70', couleur_hex_to_hsl(couleur_eclaircir($couleur, .25), 'h, s, l'));
86
-	$vars->add('--spip-color-theme--60', couleur_hex_to_hsl($couleur, 'h, s, l'));
87
-	$vars->add('--spip-color-theme--50', couleur_hex_to_hsl(couleur_foncer($couleur, .125), 'h, s, l'));
88
-	$vars->add('--spip-color-theme--40', couleur_hex_to_hsl(couleur_foncer($couleur, .25), 'h, s, l'));
89
-	$vars->add('--spip-color-theme--30', couleur_hex_to_hsl(couleur_foncer($couleur, .375), 'h, s, l'));
90
-	$vars->add('--spip-color-theme--20', couleur_hex_to_hsl(couleur_foncer($couleur, .50), 'h, s, l'));
91
-	$vars->add('--spip-color-theme--10', couleur_hex_to_hsl(couleur_foncer($couleur, .75), 'h, s, l'));
92
-	$vars->add('--spip-color-theme--00', couleur_hex_to_hsl(couleur_foncer($couleur, .98), 'h, s, l'));
93
-
94
-	return $vars;
72
+    $vars = new Collection();
73
+
74
+    #$vars->add('--spip-color-theme--hsl', couleur_hex_to_hsl($couleur, 'h, s, l')); // redéfini ensuite
75
+    $vars->add('--spip-color-theme--h', couleur_hex_to_hsl($couleur, 'h'));
76
+    $vars->add('--spip-color-theme--s', couleur_hex_to_hsl($couleur, 's'));
77
+    $vars->add('--spip-color-theme--l', couleur_hex_to_hsl($couleur, 'l'));
78
+
79
+    // un joli dégradé coloré de presque blanc à presque noir…
80
+    $vars->add('--spip-color-theme--100', couleur_hex_to_hsl(couleur_eclaircir($couleur, .99), 'h, s, l'));
81
+    $vars->add('--spip-color-theme--98', couleur_hex_to_hsl(couleur_eclaircir($couleur, .95), 'h, s, l'));
82
+    $vars->add('--spip-color-theme--95', couleur_hex_to_hsl(couleur_eclaircir($couleur, .90), 'h, s, l'));
83
+    $vars->add('--spip-color-theme--90', couleur_hex_to_hsl(couleur_eclaircir($couleur, .75), 'h, s, l'));
84
+    $vars->add('--spip-color-theme--80', couleur_hex_to_hsl(couleur_eclaircir($couleur, .50), 'h, s, l'));
85
+    $vars->add('--spip-color-theme--70', couleur_hex_to_hsl(couleur_eclaircir($couleur, .25), 'h, s, l'));
86
+    $vars->add('--spip-color-theme--60', couleur_hex_to_hsl($couleur, 'h, s, l'));
87
+    $vars->add('--spip-color-theme--50', couleur_hex_to_hsl(couleur_foncer($couleur, .125), 'h, s, l'));
88
+    $vars->add('--spip-color-theme--40', couleur_hex_to_hsl(couleur_foncer($couleur, .25), 'h, s, l'));
89
+    $vars->add('--spip-color-theme--30', couleur_hex_to_hsl(couleur_foncer($couleur, .375), 'h, s, l'));
90
+    $vars->add('--spip-color-theme--20', couleur_hex_to_hsl(couleur_foncer($couleur, .50), 'h, s, l'));
91
+    $vars->add('--spip-color-theme--10', couleur_hex_to_hsl(couleur_foncer($couleur, .75), 'h, s, l'));
92
+    $vars->add('--spip-color-theme--00', couleur_hex_to_hsl(couleur_foncer($couleur, .98), 'h, s, l'));
93
+
94
+    return $vars;
95 95
 }
96 96
 
97 97
 /**
98 98
  * Génère les variables CSS de couleurs, dont celles dépendantes des couleurs du thème actif.
99 99
  */
100 100
 function spip_generer_variables_css_couleurs(): Collection {
101
-	$vars = new Collection();
102
-
103
-	// nos déclinaisons de couleur (basées sur le dégradé précedent, où 60 est là couleur du thème)
104
-	$vars->add('--spip-color-theme-white--hsl', 'var(--spip-color-theme--100)');
105
-	$vars->add('--spip-color-theme-lightest--hsl', 'var(--spip-color-theme--95)');
106
-	$vars->add('--spip-color-theme-lighter--hsl', 'var(--spip-color-theme--90)');
107
-	$vars->add('--spip-color-theme-light--hsl', 'var(--spip-color-theme--80)');
108
-	$vars->add('--spip-color-theme--hsl', 'var(--spip-color-theme--60)');
109
-	$vars->add('--spip-color-theme-dark--hsl', 'var(--spip-color-theme--40)');
110
-	$vars->add('--spip-color-theme-darker--hsl', 'var(--spip-color-theme--20)');
111
-	$vars->add('--spip-color-theme-darkest--hsl', 'var(--spip-color-theme--10)');
112
-	$vars->add('--spip-color-theme-black--hsl', 'var(--spip-color-theme--00)');
113
-
114
-	$vars->add('--spip-color-theme-white', 'hsl(var(--spip-color-theme-white--hsl))');
115
-	$vars->add('--spip-color-theme-lightest', 'hsl(var(--spip-color-theme-lightest--hsl))');
116
-	$vars->add('--spip-color-theme-lighter', 'hsl(var(--spip-color-theme-lighter--hsl))');
117
-	$vars->add('--spip-color-theme-light', 'hsl(var(--spip-color-theme-light--hsl))');
118
-	$vars->add('--spip-color-theme', 'hsl(var(--spip-color-theme--hsl))');
119
-	$vars->add('--spip-color-theme-dark', 'hsl(var(--spip-color-theme-dark--hsl))');
120
-	$vars->add('--spip-color-theme-darker', 'hsl(var(--spip-color-theme-darker--hsl))');
121
-	$vars->add('--spip-color-theme-darkest', 'hsl(var(--spip-color-theme-darkest--hsl))');
122
-	$vars->add('--spip-color-theme-black', 'hsl(var(--spip-color-theme-black--hsl))');
123
-
124
-	// déclinaisons de gris (luminosité calquée sur le dégradé de couleur)
125
-	$vars->add('--spip-color-white--hsl', '0, 0%, 100%');
126
-	$vars->add('--spip-color-gray-lightest--hsl', '0, 0%, 96%');
127
-	$vars->add('--spip-color-gray-lighter--hsl', '0, 0%, 90%');
128
-	$vars->add('--spip-color-gray-light--hsl', '0, 0%, 80%');
129
-	$vars->add('--spip-color-gray--hsl', '0, 0%, 60%');
130
-	$vars->add('--spip-color-gray-dark--hsl', '0, 0%, 40%');
131
-	$vars->add('--spip-color-gray-darker--hsl', '0, 0%, 20%');
132
-	$vars->add('--spip-color-gray-darkest--hsl', '0, 0%, 10%');
133
-	$vars->add('--spip-color-black--hsl', '0, 0%, 0%');
134
-
135
-	$vars->add('--spip-color-white', 'hsl(var(--spip-color-white--hsl))');
136
-	$vars->add('--spip-color-gray-lightest', 'hsl(var(--spip-color-gray-lightest--hsl))');
137
-	$vars->add('--spip-color-gray-lighter', 'hsl(var(--spip-color-gray-lighter--hsl))');
138
-	$vars->add('--spip-color-gray-light', 'hsl(var(--spip-color-gray-light--hsl))');
139
-	$vars->add('--spip-color-gray', 'hsl(var(--spip-color-gray--hsl))');
140
-	$vars->add('--spip-color-gray-dark', 'hsl(var(--spip-color-gray-dark--hsl))');
141
-	$vars->add('--spip-color-gray-darker', 'hsl(var(--spip-color-gray-darker--hsl))');
142
-	$vars->add('--spip-color-gray-darkest', 'hsl(var(--spip-color-gray-darkest--hsl))');
143
-	$vars->add('--spip-color-black', 'hsl(var(--spip-color-black--hsl))');
144
-
145
-	// Différents états : erreur, etc.
146
-	$vars->add('--spip-color-success--hsl', '72, 66%, 62%');
147
-	$vars->add('--spip-color-success--h', '72');
148
-	$vars->add('--spip-color-success--s', '66%');
149
-	$vars->add('--spip-color-success--l', '62%');
150
-	$vars->add('--spip-color-error--hsl', '356, 70%, 57%');
151
-	$vars->add('--spip-color-error--h', '356');
152
-	$vars->add('--spip-color-error--s', '70%');
153
-	$vars->add('--spip-color-error--l', '57%');
154
-	$vars->add('--spip-color-notice--hsl', '47, 100%, 62%');
155
-	$vars->add('--spip-color-notice--h', '47');
156
-	$vars->add('--spip-color-notice--s', '100%');
157
-	$vars->add('--spip-color-notice--l', '62%');
158
-	$vars->add('--spip-color-info--hsl', '197, 56%, 27%');
159
-	$vars->add('--spip-color-info--h', '197');
160
-	$vars->add('--spip-color-info--s', '56%');
161
-	$vars->add('--spip-color-info--l', '27%');
162
-
163
-	$vars->add('--spip-color-success', 'hsl(var(--spip-color-success--hsl))');
164
-	$vars->add('--spip-color-error', 'hsl(var(--spip-color-error--hsl))');
165
-	$vars->add('--spip-color-notice', 'hsl(var(--spip-color-notice--hsl))');
166
-	$vars->add('--spip-color-info', 'hsl(var(--spip-color-info--hsl))');
167
-
168
-	return $vars;
101
+    $vars = new Collection();
102
+
103
+    // nos déclinaisons de couleur (basées sur le dégradé précedent, où 60 est là couleur du thème)
104
+    $vars->add('--spip-color-theme-white--hsl', 'var(--spip-color-theme--100)');
105
+    $vars->add('--spip-color-theme-lightest--hsl', 'var(--spip-color-theme--95)');
106
+    $vars->add('--spip-color-theme-lighter--hsl', 'var(--spip-color-theme--90)');
107
+    $vars->add('--spip-color-theme-light--hsl', 'var(--spip-color-theme--80)');
108
+    $vars->add('--spip-color-theme--hsl', 'var(--spip-color-theme--60)');
109
+    $vars->add('--spip-color-theme-dark--hsl', 'var(--spip-color-theme--40)');
110
+    $vars->add('--spip-color-theme-darker--hsl', 'var(--spip-color-theme--20)');
111
+    $vars->add('--spip-color-theme-darkest--hsl', 'var(--spip-color-theme--10)');
112
+    $vars->add('--spip-color-theme-black--hsl', 'var(--spip-color-theme--00)');
113
+
114
+    $vars->add('--spip-color-theme-white', 'hsl(var(--spip-color-theme-white--hsl))');
115
+    $vars->add('--spip-color-theme-lightest', 'hsl(var(--spip-color-theme-lightest--hsl))');
116
+    $vars->add('--spip-color-theme-lighter', 'hsl(var(--spip-color-theme-lighter--hsl))');
117
+    $vars->add('--spip-color-theme-light', 'hsl(var(--spip-color-theme-light--hsl))');
118
+    $vars->add('--spip-color-theme', 'hsl(var(--spip-color-theme--hsl))');
119
+    $vars->add('--spip-color-theme-dark', 'hsl(var(--spip-color-theme-dark--hsl))');
120
+    $vars->add('--spip-color-theme-darker', 'hsl(var(--spip-color-theme-darker--hsl))');
121
+    $vars->add('--spip-color-theme-darkest', 'hsl(var(--spip-color-theme-darkest--hsl))');
122
+    $vars->add('--spip-color-theme-black', 'hsl(var(--spip-color-theme-black--hsl))');
123
+
124
+    // déclinaisons de gris (luminosité calquée sur le dégradé de couleur)
125
+    $vars->add('--spip-color-white--hsl', '0, 0%, 100%');
126
+    $vars->add('--spip-color-gray-lightest--hsl', '0, 0%, 96%');
127
+    $vars->add('--spip-color-gray-lighter--hsl', '0, 0%, 90%');
128
+    $vars->add('--spip-color-gray-light--hsl', '0, 0%, 80%');
129
+    $vars->add('--spip-color-gray--hsl', '0, 0%, 60%');
130
+    $vars->add('--spip-color-gray-dark--hsl', '0, 0%, 40%');
131
+    $vars->add('--spip-color-gray-darker--hsl', '0, 0%, 20%');
132
+    $vars->add('--spip-color-gray-darkest--hsl', '0, 0%, 10%');
133
+    $vars->add('--spip-color-black--hsl', '0, 0%, 0%');
134
+
135
+    $vars->add('--spip-color-white', 'hsl(var(--spip-color-white--hsl))');
136
+    $vars->add('--spip-color-gray-lightest', 'hsl(var(--spip-color-gray-lightest--hsl))');
137
+    $vars->add('--spip-color-gray-lighter', 'hsl(var(--spip-color-gray-lighter--hsl))');
138
+    $vars->add('--spip-color-gray-light', 'hsl(var(--spip-color-gray-light--hsl))');
139
+    $vars->add('--spip-color-gray', 'hsl(var(--spip-color-gray--hsl))');
140
+    $vars->add('--spip-color-gray-dark', 'hsl(var(--spip-color-gray-dark--hsl))');
141
+    $vars->add('--spip-color-gray-darker', 'hsl(var(--spip-color-gray-darker--hsl))');
142
+    $vars->add('--spip-color-gray-darkest', 'hsl(var(--spip-color-gray-darkest--hsl))');
143
+    $vars->add('--spip-color-black', 'hsl(var(--spip-color-black--hsl))');
144
+
145
+    // Différents états : erreur, etc.
146
+    $vars->add('--spip-color-success--hsl', '72, 66%, 62%');
147
+    $vars->add('--spip-color-success--h', '72');
148
+    $vars->add('--spip-color-success--s', '66%');
149
+    $vars->add('--spip-color-success--l', '62%');
150
+    $vars->add('--spip-color-error--hsl', '356, 70%, 57%');
151
+    $vars->add('--spip-color-error--h', '356');
152
+    $vars->add('--spip-color-error--s', '70%');
153
+    $vars->add('--spip-color-error--l', '57%');
154
+    $vars->add('--spip-color-notice--hsl', '47, 100%, 62%');
155
+    $vars->add('--spip-color-notice--h', '47');
156
+    $vars->add('--spip-color-notice--s', '100%');
157
+    $vars->add('--spip-color-notice--l', '62%');
158
+    $vars->add('--spip-color-info--hsl', '197, 56%, 27%');
159
+    $vars->add('--spip-color-info--h', '197');
160
+    $vars->add('--spip-color-info--s', '56%');
161
+    $vars->add('--spip-color-info--l', '27%');
162
+
163
+    $vars->add('--spip-color-success', 'hsl(var(--spip-color-success--hsl))');
164
+    $vars->add('--spip-color-error', 'hsl(var(--spip-color-error--hsl))');
165
+    $vars->add('--spip-color-notice', 'hsl(var(--spip-color-notice--hsl))');
166
+    $vars->add('--spip-color-info', 'hsl(var(--spip-color-info--hsl))');
167
+
168
+    return $vars;
169 169
 }
Please login to merge, or discard this patch.
ecrire/public/compiler.php 1 patch
Indentation   +1212 added lines, -1212 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
  **/
22 22
 
23 23
 if (!defined('_ECRIRE_INC_VERSION')) {
24
-	return;
24
+    return;
25 25
 }
26 26
 
27 27
 /** Repérer un code ne calculant rien, meme avec commentaire */
@@ -62,92 +62,92 @@  discard block
 block discarded – undo
62 62
 
63 63
 
64 64
 function argumenter_inclure(
65
-	$params,
66
-	$rejet_filtres,
67
-	$p,
68
-	&$boucles,
69
-	$id_boucle,
70
-	$echap = true,
71
-	$lang = '',
72
-	$fond1 = false
65
+    $params,
66
+    $rejet_filtres,
67
+    $p,
68
+    &$boucles,
69
+    $id_boucle,
70
+    $echap = true,
71
+    $lang = '',
72
+    $fond1 = false
73 73
 ) {
74
-	$l = [];
75
-	$erreur_p_i_i = '';
76
-	if (!is_array($params)) {
77
-		return $l;
78
-	}
79
-	foreach ($params as $k => $couple) {
80
-		// la liste d'arguments d'inclusion peut se terminer par un filtre
81
-		$filtre = array_shift($couple);
82
-		if ($filtre) {
83
-			break;
84
-		}
85
-		foreach ($couple as $n => $val) {
86
-			$var = $val[0];
87
-			if ($var->type != 'texte') {
88
-				if ($n or $k or $fond1) {
89
-					$erreur_p_i_i = [
90
-						'zbug_parametres_inclus_incorrects',
91
-						['param' => $var->nom_champ]
92
-					];
93
-					erreur_squelette($erreur_p_i_i, $p);
94
-					break;
95
-				} else {
96
-					$l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
97
-				}
98
-			} else {
99
-				preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
100
-				$m = array_pad($m, 3, null);
101
-				$var = $m[1];
102
-				$auto = false;
103
-
104
-				if ($m[2]) {
105
-					$v = $m[3];
106
-					if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
107
-						$v = $m[1];
108
-					}
109
-					$val[0] = new Texte();
110
-					$val[0]->texte = $v;
111
-				} elseif ($k or $n or $fond1) {
112
-					$auto = true;
113
-				} else {
114
-					$var = 1;
115
-				}
116
-
117
-				if ($var == 'lang') {
118
-					$lang = !$auto
119
-						? calculer_liste($val, $p->descr, $boucles, $id_boucle)
120
-						: '$GLOBALS["spip_lang"]';
121
-				} else {
122
-					$val = $auto
123
-						? index_pile($id_boucle, $var, $boucles)
124
-						: calculer_liste($val, $p->descr, $boucles, $id_boucle);
125
-					if ($var !== 1) {
126
-						$val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
127
-							. $val . ($echap ? ") . '" : ' ');
128
-					} else {
129
-						$val = $echap ? "'.$val.'" : $val;
130
-					}
131
-					$l[$var] = $val;
132
-				}
133
-			}
134
-		}
135
-	}
136
-	if ($erreur_p_i_i) {
137
-		return false;
138
-	}
139
-	// Cas particulier de la langue : si {lang=xx} est definie, on
140
-	// la passe, sinon on passe la langue courante au moment du calcul
141
-	// sauf si on n'en veut pas
142
-	if ($lang === false) {
143
-		return $l;
144
-	}
145
-	if (!$lang) {
146
-		$lang = '$GLOBALS["spip_lang"]';
147
-	}
148
-	$l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
149
-
150
-	return $l;
74
+    $l = [];
75
+    $erreur_p_i_i = '';
76
+    if (!is_array($params)) {
77
+        return $l;
78
+    }
79
+    foreach ($params as $k => $couple) {
80
+        // la liste d'arguments d'inclusion peut se terminer par un filtre
81
+        $filtre = array_shift($couple);
82
+        if ($filtre) {
83
+            break;
84
+        }
85
+        foreach ($couple as $n => $val) {
86
+            $var = $val[0];
87
+            if ($var->type != 'texte') {
88
+                if ($n or $k or $fond1) {
89
+                    $erreur_p_i_i = [
90
+                        'zbug_parametres_inclus_incorrects',
91
+                        ['param' => $var->nom_champ]
92
+                    ];
93
+                    erreur_squelette($erreur_p_i_i, $p);
94
+                    break;
95
+                } else {
96
+                    $l[1] = calculer_liste($val, $p->descr, $boucles, $id_boucle);
97
+                }
98
+            } else {
99
+                preg_match(',^([^=]*)(=?)(.*)$,m', $var->texte, $m);
100
+                $m = array_pad($m, 3, null);
101
+                $var = $m[1];
102
+                $auto = false;
103
+
104
+                if ($m[2]) {
105
+                    $v = $m[3];
106
+                    if (preg_match(',^[\'"](.*)[\'"]$,', $v, $m)) {
107
+                        $v = $m[1];
108
+                    }
109
+                    $val[0] = new Texte();
110
+                    $val[0]->texte = $v;
111
+                } elseif ($k or $n or $fond1) {
112
+                    $auto = true;
113
+                } else {
114
+                    $var = 1;
115
+                }
116
+
117
+                if ($var == 'lang') {
118
+                    $lang = !$auto
119
+                        ? calculer_liste($val, $p->descr, $boucles, $id_boucle)
120
+                        : '$GLOBALS["spip_lang"]';
121
+                } else {
122
+                    $val = $auto
123
+                        ? index_pile($id_boucle, $var, $boucles)
124
+                        : calculer_liste($val, $p->descr, $boucles, $id_boucle);
125
+                    if ($var !== 1) {
126
+                        $val = ($echap ? "\'$var\' => ' . argumenter_squelette(" : "'$var' => ")
127
+                            . $val . ($echap ? ") . '" : ' ');
128
+                    } else {
129
+                        $val = $echap ? "'.$val.'" : $val;
130
+                    }
131
+                    $l[$var] = $val;
132
+                }
133
+            }
134
+        }
135
+    }
136
+    if ($erreur_p_i_i) {
137
+        return false;
138
+    }
139
+    // Cas particulier de la langue : si {lang=xx} est definie, on
140
+    // la passe, sinon on passe la langue courante au moment du calcul
141
+    // sauf si on n'en veut pas
142
+    if ($lang === false) {
143
+        return $l;
144
+    }
145
+    if (!$lang) {
146
+        $lang = '$GLOBALS["spip_lang"]';
147
+    }
148
+    $l['lang'] = ($echap ? "\'lang\' => ' . argumenter_squelette(" : "'lang' => ") . $lang . ($echap ? ") . '" : ' ');
149
+
150
+    return $l;
151 151
 }
152 152
 
153 153
 /**
@@ -171,84 +171,84 @@  discard block
 block discarded – undo
171 171
  **/
172 172
 function calculer_inclure($p, &$boucles, $id_boucle) {
173 173
 
174
-	$_options = [];
175
-	$_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
176
-	if (is_string($p->texte)) {
177
-		$fichier = $p->texte;
178
-		$code = '"' . str_replace('"', '\"', $fichier) . '"';
179
-	} else {
180
-		$code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
181
-		if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
182
-			$fichier = $r[1];
183
-		} else {
184
-			$fichier = '';
185
-		}
186
-	}
187
-	if (!$code or $code === '""' or $code === "''") {
188
-		$trace = $p->fonctions;
189
-		while (
190
-			is_array($trace)
191
-			and $trace = array_filter($trace)
192
-			and count($trace) == 1
193
-		) {
194
-			$trace = reset($trace);
195
-		}
196
-		$erreur_p_i_i = [
197
-			'zbug_parametres_inclus_incorrects',
198
-			['param' => print_r($trace, true)]
199
-		];
200
-		erreur_squelette($erreur_p_i_i, $p);
201
-
202
-		return "''";
203
-	}
204
-	$compil = texte_script(memoriser_contexte_compil($p));
205
-
206
-	if (is_array($_contexte)) {
207
-		// Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
208
-		if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
209
-			unset($_contexte['env']);
210
-		}
211
-
212
-		// noter les doublons dans l'appel a public.php
213
-		if (isset($_contexte['doublons'])) {
214
-			$_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
215
-		}
216
-
217
-		if ($ajax = isset($_contexte['ajax'])) {
218
-			$ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
219
-			unset($_contexte['ajax']);
220
-		}
221
-
222
-		$_contexte = join(",\n\t", $_contexte);
223
-	} else {
224
-		return false;
225
-	} // j'aurais voulu toucher le fond ...
226
-
227
-	$contexte = 'array(' . $_contexte . ')';
228
-
229
-	if ($env) {
230
-		$contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
231
-	}
232
-
233
-	// s'il y a une extension .php, ce n'est pas un squelette
234
-	if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
235
-		$code = sandbox_composer_inclure_php($fichier, $p, $contexte);
236
-	} else {
237
-		$_options[] = "\"compil\"=>array($compil)";
238
-		if ($ajax) {
239
-			$_options[] = $ajax;
240
-		}
241
-		$code = " ' . argumenter_squelette($code) . '";
242
-		$code = 'echo ' . sprintf(
243
-			CODE_RECUPERER_FOND,
244
-			$code,
245
-			$contexte,
246
-			implode(',', $_options),
247
-			"_request(\\'connect\\') ?? \\'\\'"
248
-		) . ';';
249
-	}
250
-
251
-	return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
174
+    $_options = [];
175
+    $_contexte = argumenter_inclure($p->param, false, $p, $boucles, $id_boucle, true, '', true);
176
+    if (is_string($p->texte)) {
177
+        $fichier = $p->texte;
178
+        $code = '"' . str_replace('"', '\"', $fichier) . '"';
179
+    } else {
180
+        $code = calculer_liste($p->texte, $p->descr, $boucles, $id_boucle);
181
+        if ($code and preg_match("/^'([^']*)'/s", $code, $r)) {
182
+            $fichier = $r[1];
183
+        } else {
184
+            $fichier = '';
185
+        }
186
+    }
187
+    if (!$code or $code === '""' or $code === "''") {
188
+        $trace = $p->fonctions;
189
+        while (
190
+            is_array($trace)
191
+            and $trace = array_filter($trace)
192
+            and count($trace) == 1
193
+        ) {
194
+            $trace = reset($trace);
195
+        }
196
+        $erreur_p_i_i = [
197
+            'zbug_parametres_inclus_incorrects',
198
+            ['param' => print_r($trace, true)]
199
+        ];
200
+        erreur_squelette($erreur_p_i_i, $p);
201
+
202
+        return "''";
203
+    }
204
+    $compil = texte_script(memoriser_contexte_compil($p));
205
+
206
+    if (is_array($_contexte)) {
207
+        // Critere d'inclusion {env} (et {self} pour compatibilite ascendante)
208
+        if ($env = (isset($_contexte['env']) || isset($_contexte['self']))) {
209
+            unset($_contexte['env']);
210
+        }
211
+
212
+        // noter les doublons dans l'appel a public.php
213
+        if (isset($_contexte['doublons'])) {
214
+            $_contexte['doublons'] = "\\'doublons\\' => '.var_export(\$doublons,true).'";
215
+        }
216
+
217
+        if ($ajax = isset($_contexte['ajax'])) {
218
+            $ajax = preg_replace(',=>(.*)$,ims', '=> ($v=(\\1))?$v:true', $_contexte['ajax']);
219
+            unset($_contexte['ajax']);
220
+        }
221
+
222
+        $_contexte = join(",\n\t", $_contexte);
223
+    } else {
224
+        return false;
225
+    } // j'aurais voulu toucher le fond ...
226
+
227
+    $contexte = 'array(' . $_contexte . ')';
228
+
229
+    if ($env) {
230
+        $contexte = "array_merge('.var_export(\$Pile[0],1).',$contexte)";
231
+    }
232
+
233
+    // s'il y a une extension .php, ce n'est pas un squelette
234
+    if ($fichier and preg_match('/^.+[.]php$/s', $fichier)) {
235
+        $code = sandbox_composer_inclure_php($fichier, $p, $contexte);
236
+    } else {
237
+        $_options[] = "\"compil\"=>array($compil)";
238
+        if ($ajax) {
239
+            $_options[] = $ajax;
240
+        }
241
+        $code = " ' . argumenter_squelette($code) . '";
242
+        $code = 'echo ' . sprintf(
243
+            CODE_RECUPERER_FOND,
244
+            $code,
245
+            $contexte,
246
+            implode(',', $_options),
247
+            "_request(\\'connect\\') ?? \\'\\'"
248
+        ) . ';';
249
+    }
250
+
251
+    return "\n'<'.'" . '?php ' . $code . "\n?'." . "'>'";
252 252
 }
253 253
 
254 254
 
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
  *     true pour ne tester que le cas publie et ignorer l'eventuel var_mode=preview de la page
267 267
  */
268 268
 function instituer_boucle(&$boucle, $echapper = true, $ignore_previsu = false) {
269
-	/*
269
+    /*
270 270
 	$show['statut'][] = array(
271 271
 		'champ'=>'statut',  // champ de la table sur lequel porte le filtrage par le statut
272 272
 		'publie'=>'publie', // valeur ou liste de valeurs, qui definissent l'objet comme publie.
@@ -290,74 +290,74 @@  discard block
 block discarded – undo
290 290
 	champstatut est alors le champ statut sur la tablen
291 291
 	dans les jointures, clen peut etre un tableau pour une jointure complexe : array('id_objet','id_article','objet','article')
292 292
 	*/
293
-	$id_table = $boucle->id_table;
294
-	$show = $boucle->show;
295
-	if (isset($show['statut']) and $show['statut']) {
296
-		foreach ($show['statut'] as $k => $s) {
297
-			// Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
298
-			$filtrer = true;
299
-			if (isset($s['exception'])) {
300
-				foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
301
-					if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
302
-						$filtrer = false;
303
-						break;
304
-					}
305
-				}
306
-			}
307
-
308
-			if ($filtrer) {
309
-				if (is_array($s['champ'])) {
310
-					$statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
311
-					$jointures = [];
312
-					// indiquer la description de chaque table dans le tableau de jointures,
313
-					// ce qui permet d'eviter certains GROUP BY inutiles.
314
-					$trouver_table = charger_fonction('trouver_table', 'base');
315
-					foreach ($s['champ'] as $j) {
316
-						$id = reset($j);
317
-						$def = $trouver_table($id);
318
-						$jointures[] = ['', [$id, $def], end($j)];
319
-					}
320
-					$jointures[0][0] = $id_table;
321
-					if (!array_search($id, $boucle->from)) {
322
-						include_spip('public/jointures');
323
-						fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
324
-					}
325
-					// trouver l'alias de la table d'arrivee qui porte le statut
326
-					$id = array_search($id, $boucle->from);
327
-				} else {
328
-					$id = $id_table;
329
-					$statut = preg_replace(',\W,', '', $s['champ']); // securite
330
-				}
331
-				$mstatut = $id . '.' . $statut;
332
-
333
-				$arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
334
-				include_spip('public/quete');
335
-				if (
336
-					isset($s['post_date']) and $s['post_date']
337
-					and $GLOBALS['meta']['post_dates'] == 'non'
338
-				) {
339
-					$date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
-					array_unshift(
341
-						$boucle->where,
342
-						$echapper ?
343
-							"\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
-							:
345
-							quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
-					);
347
-				}
348
-				array_unshift(
349
-					$boucle->where,
350
-					$echapper ?
351
-						"\nquete_condition_statut('$mstatut',"
352
-						. _q($s['previsu']) . ','
353
-						. _q($s['publie']) . ','
354
-						. _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
-						:
356
-						quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
-				);
358
-			}
359
-		}
360
-	}
293
+    $id_table = $boucle->id_table;
294
+    $show = $boucle->show;
295
+    if (isset($show['statut']) and $show['statut']) {
296
+        foreach ($show['statut'] as $k => $s) {
297
+            // Restreindre aux elements publies si pas de {statut} ou autre dans les criteres
298
+            $filtrer = true;
299
+            if (isset($s['exception'])) {
300
+                foreach (is_array($s['exception']) ? $s['exception'] : [$s['exception']] as $m) {
301
+                    if (isset($boucle->modificateur[$m]) or isset($boucle->modificateur['criteres'][$m])) {
302
+                        $filtrer = false;
303
+                        break;
304
+                    }
305
+                }
306
+            }
307
+
308
+            if ($filtrer) {
309
+                if (is_array($s['champ'])) {
310
+                    $statut = preg_replace(',\W,', '', array_pop($s['champ'])); // securite
311
+                    $jointures = [];
312
+                    // indiquer la description de chaque table dans le tableau de jointures,
313
+                    // ce qui permet d'eviter certains GROUP BY inutiles.
314
+                    $trouver_table = charger_fonction('trouver_table', 'base');
315
+                    foreach ($s['champ'] as $j) {
316
+                        $id = reset($j);
317
+                        $def = $trouver_table($id);
318
+                        $jointures[] = ['', [$id, $def], end($j)];
319
+                    }
320
+                    $jointures[0][0] = $id_table;
321
+                    if (!array_search($id, $boucle->from)) {
322
+                        include_spip('public/jointures');
323
+                        fabrique_jointures($boucle, $jointures, true, $boucle->show, $id_table, '', $echapper);
324
+                    }
325
+                    // trouver l'alias de la table d'arrivee qui porte le statut
326
+                    $id = array_search($id, $boucle->from);
327
+                } else {
328
+                    $id = $id_table;
329
+                    $statut = preg_replace(',\W,', '', $s['champ']); // securite
330
+                }
331
+                $mstatut = $id . '.' . $statut;
332
+
333
+                $arg_ignore_previsu = ($ignore_previsu ? ',true' : '');
334
+                include_spip('public/quete');
335
+                if (
336
+                    isset($s['post_date']) and $s['post_date']
337
+                    and $GLOBALS['meta']['post_dates'] == 'non'
338
+                ) {
339
+                    $date = $id . '.' . preg_replace(',\W,', '', $s['post_date']); // securite
340
+                    array_unshift(
341
+                        $boucle->where,
342
+                        $echapper ?
343
+                            "\nquete_condition_postdates('$date'," . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
344
+                            :
345
+                            quete_condition_postdates($date, $boucle->sql_serveur, $ignore_previsu)
346
+                    );
347
+                }
348
+                array_unshift(
349
+                    $boucle->where,
350
+                    $echapper ?
351
+                        "\nquete_condition_statut('$mstatut',"
352
+                        . _q($s['previsu']) . ','
353
+                        . _q($s['publie']) . ','
354
+                        . _q($boucle->sql_serveur) . "$arg_ignore_previsu)"
355
+                        :
356
+                        quete_condition_statut($mstatut, $s['previsu'], $s['publie'], $boucle->sql_serveur, $ignore_previsu)
357
+                );
358
+            }
359
+        }
360
+    }
361 361
 }
362 362
 
363 363
 /**
@@ -376,29 +376,29 @@  discard block
 block discarded – undo
376 376
  */
377 377
 function calculer_boucle($id_boucle, &$boucles) {
378 378
 
379
-	$boucle = &$boucles[$id_boucle];
380
-	instituer_boucle($boucle);
381
-	$boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
-
383
-	// en mode debug memoriser les premiers passages dans la boucle,
384
-	// mais pas tous, sinon ca pete.
385
-	if (_request('var_mode_affiche') != 'resultat') {
386
-		$trace = '';
387
-	} else {
388
-		$_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
-		$_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
-		$trace = "
379
+    $boucle = &$boucles[$id_boucle];
380
+    instituer_boucle($boucle);
381
+    $boucles[$id_boucle] = pipeline('post_boucle', $boucles[$id_boucle]);
382
+
383
+    // en mode debug memoriser les premiers passages dans la boucle,
384
+    // mais pas tous, sinon ca pete.
385
+    if (_request('var_mode_affiche') != 'resultat') {
386
+        $trace = '';
387
+    } else {
388
+        $_trace = $boucles[$id_boucle]->descr['nom'] . $id_boucle;
389
+        $_trace = "\$GLOBALS['debug_objets']['resultat']['$_trace']";
390
+        $trace = "
391 391
 		if (empty($_trace)) {
392 392
 			$_trace = [];
393 393
 		}
394 394
 		if (count($_trace) < 3) {
395 395
 			$_trace" . '[] = $t0;
396 396
 		}';
397
-	}
397
+    }
398 398
 
399
-	return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
-		? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
-		: calculer_boucle_nonrec($id_boucle, $boucles, $trace);
399
+    return ($boucles[$id_boucle]->type_requete == TYPE_RECURSIF)
400
+        ? calculer_boucle_rec($id_boucle, $boucles, $trace)
401
+        : calculer_boucle_nonrec($id_boucle, $boucles, $trace);
402 402
 }
403 403
 
404 404
 
@@ -421,15 +421,15 @@  discard block
 block discarded – undo
421 421
  *    Code PHP compilé de la boucle récursive
422 422
  **/
423 423
 function calculer_boucle_rec($id_boucle, &$boucles, $trace) {
424
-	$nom = $boucles[$id_boucle]->param[0];
425
-
426
-	return
427
-		// Numrows[$nom] peut ne pas être encore defini
428
-		"\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
-		. "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
-		. "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
-		. $trace
432
-		. "\n\treturn \$t0;";
424
+    $nom = $boucles[$id_boucle]->param[0];
425
+
426
+    return
427
+        // Numrows[$nom] peut ne pas être encore defini
428
+        "\n\t\$save_numrows = (isset(\$Numrows['$nom']) ? \$Numrows['$nom'] : array());"
429
+        . "\n\t\$t0 = " . $boucles[$id_boucle]->return . ';'
430
+        . "\n\t\$Numrows['$nom'] = (\$save_numrows);"
431
+        . $trace
432
+        . "\n\treturn \$t0;";
433 433
 }
434 434
 
435 435
 /**
@@ -482,173 +482,173 @@  discard block
 block discarded – undo
482 482
  **/
483 483
 function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) {
484 484
 
485
-	$code_sep = null;
486
-	$boucle = &$boucles[$id_boucle];
487
-	$return = $boucle->return;
488
-	$type_boucle = $boucle->type_requete;
489
-	$primary = $boucle->primary;
490
-	$constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
-	$flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
-	$corps = '';
493
-
494
-	// faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
-	// et puis faire un [] plutot qu'un "','."
496
-	if ($boucle->doublons) {
497
-		$corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
-			index_pile($id_boucle, $primary, $boucles)
499
-			. "; // doublons\n";
500
-	}
501
-
502
-	// La boucle doit-elle selectionner la langue ?
503
-	// - par defaut, les boucles suivantes le font
504
-	//    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
-	// - a moins d'une demande explicite via {!lang_select}
506
-	if (
507
-		!$constant && $boucle->lang_select != 'non' &&
508
-		(($boucle->lang_select == 'oui') ||
509
-			in_array($type_boucle, [
510
-				'articles',
511
-				'rubriques',
512
-				'hierarchie',
513
-				'breves'
514
-			]))
515
-	) {
516
-		// Memoriser la langue avant la boucle et la restituer apres
517
-		// afin que le corps de boucle affecte la globale directement
518
-		$init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
-		$fin_lang = "lang_select();\n\t";
520
-		$fin_lang_select_public = "\n\t\tlang_select();";
521
-
522
-		$corps .=
523
-			"\n\t\tlang_select_public("
524
-			. index_pile($id_boucle, 'lang', $boucles)
525
-			. ", '" . $boucle->lang_select . "'"
526
-			. (in_array($type_boucle, [
527
-				'articles',
528
-				'rubriques',
529
-				'hierarchie',
530
-				'breves'
531
-			]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
-			. ');';
533
-	} else {
534
-		$init_lang = '';
535
-		$fin_lang = '';
536
-		$fin_lang_select_public = '';
537
-		// sortir les appels au traducteur (invariants de boucle)
538
-		if (
539
-			strpos($return, '?php') === false
540
-			and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
-		) {
542
-			$i = 1;
543
-			foreach ($r[1] as $t) {
544
-				$init_lang .= "\n\t\$l$i = $t;";
545
-				$return = str_replace($t, "\$l$i", $return);
546
-				$i++;
547
-			}
548
-		}
549
-	}
550
-
551
-	// gestion optimale des separateurs et des boucles constantes
552
-	if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
-		$code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
-	}
555
-
556
-	$corps .=
557
-		((!$boucle->separateur) ?
558
-			(($constant && !$corps && !$flag_cpt) ? $return :
559
-				(($return === "''") ? '' :
560
-					("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
-			("\n\t\t\$t1 " .
562
-				((strpos($return, '$t1.') === 0) ?
563
-					('.=' . substr($return, 4)) :
564
-					('= ' . $return)) .
565
-				";\n\t\t" .
566
-				'$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
-
568
-	// Calculer les invalideurs si c'est une boucle non constante et si on
569
-	// souhaite invalider ces elements
570
-	if (!$constant and $primary) {
571
-		include_spip('inc/invalideur');
572
-		$corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
-	}
574
-
575
-	// gerer le compteur de boucle
576
-	// avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
-
578
-	if ($boucle->partie or $boucle->cptrows) {
579
-		$corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
-			. $boucle->partie
581
-			. $corps;
582
-	}
583
-
584
-	// depiler la lang de la boucle si besoin
585
-	$corps .= $fin_lang_select_public;
586
-
587
-	// si le corps est une constante, ne pas appeler le serveur N fois!
588
-
589
-	if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
-		if (!isset($r[2]) or (!$r[2])) {
591
-			if (!$boucle->numrows) {
592
-				return "\n\t\$t0 = '';";
593
-			} else {
594
-				$corps = '';
595
-			}
596
-		} else {
597
-			$boucle->numrows = true;
598
-			$corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
-		}
600
-	} else {
601
-		$corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
-	}
603
-
604
-	$count = '';
605
-	if (!$boucle->select) {
606
-		if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
607
-			$count = '1';
608
-		} else {
609
-			$count = 'count(*)';
610
-		}
611
-		$boucles[$id_boucle]->select[] = $count;
612
-	}
613
-
614
-	if ($flag_cpt) {
615
-		$nums = "\n\t// COMPTEUR\n\t"
616
-			. "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
-	} else {
618
-		$nums = '';
619
-	}
620
-
621
-	if ($boucle->numrows or $boucle->mode_partie) {
622
-		$nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
-			. "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
-			. $boucle->mode_partie
625
-			. "\n\t";
626
-	}
627
-
628
-	// Ne calculer la requete que maintenant
629
-	// car ce qui precede appelle index_pile qui influe dessus
630
-
631
-	$init = (($init = $boucles[$id_boucle]->doublons)
632
-			? ("\n\t$init = array();") : '')
633
-		. calculer_requete_sql($boucles[$id_boucle]);
634
-
635
-	$contexte = memoriser_contexte_compil($boucle);
636
-
637
-	$a = sprintf(
638
-		CODE_CORPS_BOUCLE,
639
-		$init,
640
-		$boucle->iterateur,
641
-		'$command',
642
-		$contexte,
643
-		$nums,
644
-		$init_lang,
645
-		$corps,
646
-		$fin_lang,
647
-		$trace,
648
-		'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
-	);
650
-
651
-	return $a;
485
+    $code_sep = null;
486
+    $boucle = &$boucles[$id_boucle];
487
+    $return = $boucle->return;
488
+    $type_boucle = $boucle->type_requete;
489
+    $primary = $boucle->primary;
490
+    $constant = preg_match(CODE_MONOTONE, str_replace("\\'", '', $return));
491
+    $flag_cpt = $boucle->mode_partie || $boucle->cptrows;
492
+    $corps = '';
493
+
494
+    // faudrait expanser le foreach a la compil, car y en a souvent qu'un
495
+    // et puis faire un [] plutot qu'un "','."
496
+    if ($boucle->doublons) {
497
+        $corps .= "\n\t\t\tforeach(" . $boucle->doublons . ' as $k) $doublons[$k] .= "," . ' .
498
+            index_pile($id_boucle, $primary, $boucles)
499
+            . "; // doublons\n";
500
+    }
501
+
502
+    // La boucle doit-elle selectionner la langue ?
503
+    // - par defaut, les boucles suivantes le font
504
+    //    (sauf si forcer_lang==true ou si le titre contient <multi>).
505
+    // - a moins d'une demande explicite via {!lang_select}
506
+    if (
507
+        !$constant && $boucle->lang_select != 'non' &&
508
+        (($boucle->lang_select == 'oui') ||
509
+            in_array($type_boucle, [
510
+                'articles',
511
+                'rubriques',
512
+                'hierarchie',
513
+                'breves'
514
+            ]))
515
+    ) {
516
+        // Memoriser la langue avant la boucle et la restituer apres
517
+        // afin que le corps de boucle affecte la globale directement
518
+        $init_lang = "lang_select(\$GLOBALS['spip_lang']);\n\t";
519
+        $fin_lang = "lang_select();\n\t";
520
+        $fin_lang_select_public = "\n\t\tlang_select();";
521
+
522
+        $corps .=
523
+            "\n\t\tlang_select_public("
524
+            . index_pile($id_boucle, 'lang', $boucles)
525
+            . ", '" . $boucle->lang_select . "'"
526
+            . (in_array($type_boucle, [
527
+                'articles',
528
+                'rubriques',
529
+                'hierarchie',
530
+                'breves'
531
+            ]) ? ', ' . index_pile($id_boucle, 'titre', $boucles) : '')
532
+            . ');';
533
+    } else {
534
+        $init_lang = '';
535
+        $fin_lang = '';
536
+        $fin_lang_select_public = '';
537
+        // sortir les appels au traducteur (invariants de boucle)
538
+        if (
539
+            strpos($return, '?php') === false
540
+            and preg_match_all("/\W(_T[(]'[^']*'[)])/", $return, $r)
541
+        ) {
542
+            $i = 1;
543
+            foreach ($r[1] as $t) {
544
+                $init_lang .= "\n\t\$l$i = $t;";
545
+                $return = str_replace($t, "\$l$i", $return);
546
+                $i++;
547
+            }
548
+        }
549
+    }
550
+
551
+    // gestion optimale des separateurs et des boucles constantes
552
+    if (is_countable($boucle->separateur) ? count($boucle->separateur) : 0) {
553
+        $code_sep = ("'" . str_replace("'", "\'", join('', $boucle->separateur)) . "'");
554
+    }
555
+
556
+    $corps .=
557
+        ((!$boucle->separateur) ?
558
+            (($constant && !$corps && !$flag_cpt) ? $return :
559
+                (($return === "''") ? '' :
560
+                    ("\n\t\t" . '$t0 .= ' . $return . ';'))) :
561
+            ("\n\t\t\$t1 " .
562
+                ((strpos($return, '$t1.') === 0) ?
563
+                    ('.=' . substr($return, 4)) :
564
+                    ('= ' . $return)) .
565
+                ";\n\t\t" .
566
+                '$t0 .= ((strlen($t1) && strlen($t0)) ? ' . $code_sep . " : '') . \$t1;"));
567
+
568
+    // Calculer les invalideurs si c'est une boucle non constante et si on
569
+    // souhaite invalider ces elements
570
+    if (!$constant and $primary) {
571
+        include_spip('inc/invalideur');
572
+        $corps = calcul_invalideurs($corps, $primary, $boucles, $id_boucle);
573
+    }
574
+
575
+    // gerer le compteur de boucle
576
+    // avec ou sans son utilisation par les criteres {1/3} {1,4} {n-2,1}...
577
+
578
+    if ($boucle->partie or $boucle->cptrows) {
579
+        $corps = "\n\t\t\$Numrows['$id_boucle']['compteur_boucle']++;"
580
+            . $boucle->partie
581
+            . $corps;
582
+    }
583
+
584
+    // depiler la lang de la boucle si besoin
585
+    $corps .= $fin_lang_select_public;
586
+
587
+    // si le corps est une constante, ne pas appeler le serveur N fois!
588
+
589
+    if (preg_match(CODE_MONOTONE, str_replace("\\'", '', $corps), $r)) {
590
+        if (!isset($r[2]) or (!$r[2])) {
591
+            if (!$boucle->numrows) {
592
+                return "\n\t\$t0 = '';";
593
+            } else {
594
+                $corps = '';
595
+            }
596
+        } else {
597
+            $boucle->numrows = true;
598
+            $corps = "\n\t\$t0 = str_repeat($corps, \$Numrows['$id_boucle']['total']);";
599
+        }
600
+    } else {
601
+        $corps = "while (\$Pile[\$SP]=\$iter->fetch()) {\n$corps\n	}";
602
+    }
603
+
604
+    $count = '';
605
+    if (!$boucle->select) {
606
+        if (!$boucle->numrows or $boucle->limit or $boucle->mode_partie or $boucle->group) {
607
+            $count = '1';
608
+        } else {
609
+            $count = 'count(*)';
610
+        }
611
+        $boucles[$id_boucle]->select[] = $count;
612
+    }
613
+
614
+    if ($flag_cpt) {
615
+        $nums = "\n\t// COMPTEUR\n\t"
616
+            . "\$Numrows['$id_boucle']['compteur_boucle'] = 0;\n\t";
617
+    } else {
618
+        $nums = '';
619
+    }
620
+
621
+    if ($boucle->numrows or $boucle->mode_partie) {
622
+        $nums .= "\$Numrows['$id_boucle']['command'] = \$command;\n\t"
623
+            . "\$Numrows['$id_boucle']['total'] = @intval(\$iter->count());"
624
+            . $boucle->mode_partie
625
+            . "\n\t";
626
+    }
627
+
628
+    // Ne calculer la requete que maintenant
629
+    // car ce qui precede appelle index_pile qui influe dessus
630
+
631
+    $init = (($init = $boucles[$id_boucle]->doublons)
632
+            ? ("\n\t$init = array();") : '')
633
+        . calculer_requete_sql($boucles[$id_boucle]);
634
+
635
+    $contexte = memoriser_contexte_compil($boucle);
636
+
637
+    $a = sprintf(
638
+        CODE_CORPS_BOUCLE,
639
+        $init,
640
+        $boucle->iterateur,
641
+        '$command',
642
+        $contexte,
643
+        $nums,
644
+        $init_lang,
645
+        $corps,
646
+        $fin_lang,
647
+        $trace,
648
+        'BOUCLE' . $id_boucle . ' @ ' . ($boucle->descr['sourcefile'])
649
+    );
650
+
651
+    return $a;
652 652
 }
653 653
 
654 654
 
@@ -664,48 +664,48 @@  discard block
 block discarded – undo
664 664
  *     Code PHP compilé définissant les informations de requête
665 665
  **/
666 666
 function calculer_requete_sql($boucle) {
667
-	$init = [];
668
-	$init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
-	$init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
-	# En absence de champ c'est un decompte :
671
-	$init[] = calculer_dec('from', calculer_from($boucle));
672
-	$init[] = calculer_dec('type', calculer_from_type($boucle));
673
-	$init[] = calculer_dec(
674
-		'groupby',
675
-		'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
-	);
677
-	$init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
-	$init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
-	$init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
-	$init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
-	$init[] = calculer_dec(
682
-		'limit',
683
-		(
684
-			strpos($boucle->limit, 'intval') === false ?
685
-			"'" . ($boucle->limit) . "'" :
686
-			$boucle->limit
687
-		)
688
-	);
689
-	$init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
-	$s = $d = '';
691
-	// l'index 0 de $i indique si l'affectation est statique (contenu)
692
-	// ou recalculée à chaque passage (vide)
693
-	foreach ($init as $i) {
694
-		if (reset($i)) {
695
-			$s .= "\n\t\t" . end($i);
696
-		} # statique
697
-		else {
698
-			$d .= "\n\t" . end($i);
699
-		} # dynamique
700
-	}
701
-
702
-	return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
-	. $boucle->in
704
-	. $boucle->hash
705
-	. "\n\t" . 'if (!isset($command[\'table\'])) {'
706
-	. $s
707
-	. "\n\t}"
708
-	. $d;
667
+    $init = [];
668
+    $init[] = calculer_dec('table', "'" . $boucle->id_table . "'");
669
+    $init[] = calculer_dec('id', "'" . $boucle->id_boucle . "'");
670
+    # En absence de champ c'est un decompte :
671
+    $init[] = calculer_dec('from', calculer_from($boucle));
672
+    $init[] = calculer_dec('type', calculer_from_type($boucle));
673
+    $init[] = calculer_dec(
674
+        'groupby',
675
+        'array(' . (($g = join("\",\n\t\t\"", $boucle->group)) ? '"' . $g . '"' : '') . ')'
676
+    );
677
+    $init[] = calculer_dec('select', 'array("' . join("\",\n\t\t\"", $boucle->select) . '")');
678
+    $init[] = calculer_dec('orderby', 'array(' . calculer_order($boucle) . ')');
679
+    $init[] = calculer_dec('where', calculer_dump_array($boucle->where));
680
+    $init[] = calculer_dec('join', calculer_dump_join($boucle->join));
681
+    $init[] = calculer_dec(
682
+        'limit',
683
+        (
684
+            strpos($boucle->limit, 'intval') === false ?
685
+            "'" . ($boucle->limit) . "'" :
686
+            $boucle->limit
687
+        )
688
+    );
689
+    $init[] = calculer_dec('having', calculer_dump_array($boucle->having));
690
+    $s = $d = '';
691
+    // l'index 0 de $i indique si l'affectation est statique (contenu)
692
+    // ou recalculée à chaque passage (vide)
693
+    foreach ($init as $i) {
694
+        if (reset($i)) {
695
+            $s .= "\n\t\t" . end($i);
696
+        } # statique
697
+        else {
698
+            $d .= "\n\t" . end($i);
699
+        } # dynamique
700
+    }
701
+
702
+    return ($boucle->hierarchie ? "\n\t$boucle->hierarchie" : '')
703
+    . $boucle->in
704
+    . $boucle->hash
705
+    . "\n\t" . 'if (!isset($command[\'table\'])) {'
706
+    . $s
707
+    . "\n\t}"
708
+    . $d;
709 709
 }
710 710
 
711 711
 /**
@@ -723,13 +723,13 @@  discard block
 block discarded – undo
723 723
  *     qui peut être utilisé pour la production d'un tableau array()
724 724
  **/
725 725
 function memoriser_contexte_compil($p) {
726
-	return join(',', [
727
-		_q($p->descr['sourcefile'] ?? ''),
728
-		_q($p->descr['nom'] ?? ''),
729
-		_q($p->id_boucle ?? ''),
730
-		intval($p->ligne),
731
-		'$GLOBALS[\'spip_lang\']'
732
-	]);
726
+    return join(',', [
727
+        _q($p->descr['sourcefile'] ?? ''),
728
+        _q($p->descr['nom'] ?? ''),
729
+        _q($p->id_boucle ?? ''),
730
+        intval($p->ligne),
731
+        '$GLOBALS[\'spip_lang\']'
732
+    ]);
733 733
 }
734 734
 
735 735
 /**
@@ -747,20 +747,20 @@  discard block
 block discarded – undo
747 747
  *     Objet Contexte
748 748
  **/
749 749
 function reconstruire_contexte_compil($context_compil) {
750
-	if (!is_array($context_compil)) {
751
-		return $context_compil;
752
-	}
753
-	$p = new Contexte();
754
-	$p->descr = [
755
-		'sourcefile' => $context_compil[0] ?? '',
756
-		'nom' => $context_compil[1] ?? '',
757
-	];
758
-
759
-	$p->id_boucle = $context_compil[2] ?? '';
760
-	$p->ligne = (int)($context_compil[3] ?? 0);
761
-	$p->lang = $context_compil[4] ?? '';
762
-
763
-	return $p;
750
+    if (!is_array($context_compil)) {
751
+        return $context_compil;
752
+    }
753
+    $p = new Contexte();
754
+    $p->descr = [
755
+        'sourcefile' => $context_compil[0] ?? '',
756
+        'nom' => $context_compil[1] ?? '',
757
+    ];
758
+
759
+    $p->id_boucle = $context_compil[2] ?? '';
760
+    $p->ligne = (int)($context_compil[3] ?? 0);
761
+    $p->lang = $context_compil[4] ?? '';
762
+
763
+    return $p;
764 764
 }
765 765
 
766 766
 /**
@@ -786,12 +786,12 @@  discard block
 block discarded – undo
786 786
  *    - index 1 : Code de l'affectation
787 787
  **/
788 788
 function calculer_dec($nom, $val) {
789
-	$static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
-	// si une variable apparait dans le calcul de la clause
791
-	// il faut la re-evaluer a chaque passage
792
-	if (
793
-		str_contains($val, '$')
794
-		/*
789
+    $static = 'if (!isset($command[\'' . $nom . '\'])) ';
790
+    // si une variable apparait dans le calcul de la clause
791
+    // il faut la re-evaluer a chaque passage
792
+    if (
793
+        str_contains($val, '$')
794
+        /*
795 795
 		OR str_contains($val, 'sql_')
796 796
 		OR (
797 797
 			$test = str_replace(array("array(",'\"',"\'"),array("","",""),$val) // supprimer les array( et les echappements de guillemets
@@ -799,11 +799,11 @@  discard block
 block discarded – undo
799 799
 			AND $test = preg_replace(",'[^']*',UimsS","",$test) // supprimer les chaines qui peuvent contenir des fonctions SQL qui ne genent pas
800 800
 			AND preg_match(",\w+\s*\(,UimsS",$test,$regs) // tester la presence de fonctions restantes
801 801
 		)*/
802
-	) {
803
-		$static = '';
804
-	}
802
+    ) {
803
+        $static = '';
804
+    }
805 805
 
806
-	return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
806
+    return [$static, '$command[\'' . $nom . '\'] = ' . $val . ';'];
807 807
 }
808 808
 
809 809
 /**
@@ -823,32 +823,32 @@  discard block
 block discarded – undo
823 823
  *     Expression PHP décrivant un texte ou un tableau
824 824
  **/
825 825
 function calculer_dump_array($a) {
826
-	if (!is_array($a)) {
827
-		return $a;
828
-	}
829
-	$res = '';
830
-	if ($a and $a[0] == "'?'") {
831
-		return ('(' . calculer_dump_array($a[1]) .
832
-			' ? ' . calculer_dump_array($a[2]) .
833
-			' : ' . calculer_dump_array($a[3]) .
834
-			')');
835
-	} else {
836
-		foreach ($a as $k => $v) {
837
-			$showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
-			$res .= ', ' . $showk . calculer_dump_array($v);
839
-		}
840
-
841
-		return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
-	}
826
+    if (!is_array($a)) {
827
+        return $a;
828
+    }
829
+    $res = '';
830
+    if ($a and $a[0] == "'?'") {
831
+        return ('(' . calculer_dump_array($a[1]) .
832
+            ' ? ' . calculer_dump_array($a[2]) .
833
+            ' : ' . calculer_dump_array($a[3]) .
834
+            ')');
835
+    } else {
836
+        foreach ($a as $k => $v) {
837
+            $showk = (is_numeric($k) ? '' : sql_quote($k) . ' => ');
838
+            $res .= ', ' . $showk . calculer_dump_array($v);
839
+        }
840
+
841
+        return "\n\t\t\tarray(" . substr($res, 2) . ')';
842
+    }
843 843
 }
844 844
 
845 845
 function calculer_dump_join($a) {
846
-	$res = '';
847
-	foreach ($a as $k => $v) {
848
-		$res .= ", '$k' => array(" . implode(',', $v) . ')';
849
-	}
846
+    $res = '';
847
+    foreach ($a as $k => $v) {
848
+        $res .= ", '$k' => array(" . implode(',', $v) . ')';
849
+    }
850 850
 
851
-	return 'array(' . substr($res, 2) . ')';
851
+    return 'array(' . substr($res, 2) . ')';
852 852
 }
853 853
 
854 854
 /**
@@ -860,12 +860,12 @@  discard block
 block discarded – undo
860 860
  *     Code PHP construisant un tableau des alias et noms des tables du FROM
861 861
  **/
862 862
 function calculer_from(&$boucle) {
863
-	$res = '';
864
-	foreach ($boucle->from as $k => $v) {
865
-		$res .= ",'$k' => '$v'";
866
-	}
863
+    $res = '';
864
+    foreach ($boucle->from as $k => $v) {
865
+        $res .= ",'$k' => '$v'";
866
+    }
867 867
 
868
-	return 'array(' . substr($res, 1) . ')';
868
+    return 'array(' . substr($res, 1) . ')';
869 869
 }
870 870
 
871 871
 /**
@@ -878,30 +878,30 @@  discard block
 block discarded – undo
878 878
  *     Code PHP construisant un tableau des alias et type de jointure du FROM
879 879
  **/
880 880
 function calculer_from_type(&$boucle) {
881
-	$res = '';
882
-	foreach ($boucle->from_type as $k => $v) {
883
-		$res .= ",'$k' => '$v'";
884
-	}
881
+    $res = '';
882
+    foreach ($boucle->from_type as $k => $v) {
883
+        $res .= ",'$k' => '$v'";
884
+    }
885 885
 
886
-	return 'array(' . substr($res, 1) . ')';
886
+    return 'array(' . substr($res, 1) . ')';
887 887
 }
888 888
 
889 889
 function calculer_order(&$boucle) {
890
-	if (
891
-		!$order = $boucle->order
892
-		and !$order = $boucle->default_order
893
-	) {
894
-		$order = [];
895
-	}
896
-
897
-	/*if (isset($boucle->modificateur['collate'])){
890
+    if (
891
+        !$order = $boucle->order
892
+        and !$order = $boucle->default_order
893
+    ) {
894
+        $order = [];
895
+    }
896
+
897
+    /*if (isset($boucle->modificateur['collate'])){
898 898
 		$col = "." . $boucle->modificateur['collate'];
899 899
 		foreach($order as $k=>$o)
900 900
 			if (strpos($order[$k],'COLLATE')===false)
901 901
 				$order[$k].= $col;
902 902
 	}*/
903 903
 
904
-	return join(', ', $order);
904
+    return join(', ', $order);
905 905
 }
906 906
 
907 907
 // Production du code PHP a partir de la sequence livree par le phraseur
@@ -910,62 +910,62 @@  discard block
 block discarded – undo
910 910
 // (qui sera argument d'un Return ou la partie droite d'une affectation).
911 911
 
912 912
 function calculer_liste($tableau, $descr, &$boucles, $id_boucle = '') {
913
-	if (!$tableau) {
914
-		return "''";
915
-	}
916
-	if (is_string($descr)) {
917
-		if (isset($boucles[$descr])) {
918
-			$idb = $descr;
919
-			$descr = [];
920
-			if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
-				$descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
-			}
923
-			if (isset($boucles[$idb]->descr['sourcefile'])) {
924
-				$descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
-			}
926
-		}
927
-		else {
928
-			$descr = [];
929
-		}
930
-	}
931
-	if (!isset($descr['niv'])) {
932
-		$descr['niv'] = 0;
933
-	}
934
-	$codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
-	if ($codes === false) {
936
-		return false;
937
-	}
938
-	$n = is_countable($codes) ? count($codes) : 0;
939
-	if (!$n) {
940
-		return "''";
941
-	}
942
-	$tab = str_repeat("\t", $descr['niv']);
943
-	if (_request('var_mode_affiche') != 'validation') {
944
-		if ($n == 1) {
945
-			return $codes[0];
946
-		} else {
947
-			$res = '';
948
-			foreach ($codes as $code) {
949
-				if (
950
-					!preg_match("/^'[^']*'$/", $code)
951
-					or substr($res, -1, 1) !== "'"
952
-				) {
953
-					$res .= " .\n$tab$code";
954
-				} else {
955
-					$res = substr($res, 0, -1) . substr($code, 1);
956
-				}
957
-			}
958
-
959
-			return '(' . substr($res, 2 + $descr['niv']) . ')';
960
-		}
961
-	} else {
962
-		$nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
-
964
-		return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
-			" ,\n$tab",
966
-			$codes
967
-		) . ')))';
968
-	}
913
+    if (!$tableau) {
914
+        return "''";
915
+    }
916
+    if (is_string($descr)) {
917
+        if (isset($boucles[$descr])) {
918
+            $idb = $descr;
919
+            $descr = [];
920
+            if (isset($boucles[$idb]->descr['id_mere_contexte'])) {
921
+                $descr['id_mere'] = $boucles[$idb]->descr['id_mere_contexte'];
922
+            }
923
+            if (isset($boucles[$idb]->descr['sourcefile'])) {
924
+                $descr['sourcefile'] = $boucles[$idb]->descr['sourcefile'];
925
+            }
926
+        }
927
+        else {
928
+            $descr = [];
929
+        }
930
+    }
931
+    if (!isset($descr['niv'])) {
932
+        $descr['niv'] = 0;
933
+    }
934
+    $codes = compile_cas($tableau, $descr, $boucles, $id_boucle);
935
+    if ($codes === false) {
936
+        return false;
937
+    }
938
+    $n = is_countable($codes) ? count($codes) : 0;
939
+    if (!$n) {
940
+        return "''";
941
+    }
942
+    $tab = str_repeat("\t", $descr['niv']);
943
+    if (_request('var_mode_affiche') != 'validation') {
944
+        if ($n == 1) {
945
+            return $codes[0];
946
+        } else {
947
+            $res = '';
948
+            foreach ($codes as $code) {
949
+                if (
950
+                    !preg_match("/^'[^']*'$/", $code)
951
+                    or substr($res, -1, 1) !== "'"
952
+                ) {
953
+                    $res .= " .\n$tab$code";
954
+                } else {
955
+                    $res = substr($res, 0, -1) . substr($code, 1);
956
+                }
957
+            }
958
+
959
+            return '(' . substr($res, 2 + $descr['niv']) . ')';
960
+        }
961
+    } else {
962
+        $nom = $descr['nom'] . $id_boucle . ($descr['niv'] ?: '');
963
+
964
+        return "join('', array_map('array_shift', \$GLOBALS['debug_objets']['sequence']['$nom'] = array(" . join(
965
+            " ,\n$tab",
966
+            $codes
967
+        ) . ')))';
968
+    }
969 969
 }
970 970
 
971 971
 
@@ -984,213 +984,213 @@  discard block
 block discarded – undo
984 984
  */
985 985
 function compile_cas($tableau, $descr, &$boucles, $id_boucle) {
986 986
 
987
-	$codes = [];
988
-	// cas de la boucle recursive
989
-	if (is_array($id_boucle)) {
990
-		$id_boucle = $id_boucle[0];
991
-	}
992
-	$type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
-	$tab = str_repeat("\t", ++$descr['niv']);
994
-	$mode = _request('var_mode_affiche');
995
-	$err_e_c = '';
996
-	// chaque commentaire introduit dans le code doit commencer
997
-	// par un caractere distinguant le cas, pour exploitation par debug.
998
-	foreach ($tableau as $p) {
999
-		switch ($p->type) {
1000
-			// texte seul
1001
-			case 'texte':
1002
-				$code = sandbox_composer_texte($p->texte, $p);
1003
-				$commentaire = strlen($p->texte) . ' signes';
1004
-				$avant = '';
1005
-				$apres = '';
1006
-				$altern = "''";
1007
-				break;
1008
-
1009
-			case 'polyglotte':
1010
-				$code = '';
1011
-				foreach ($p->traductions as $k => $v) {
1012
-					$code .= ",'" .
1013
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
-						"' => '" .
1015
-						str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
-						"'";
1017
-				}
1018
-				$code = 'choisir_traduction(array(' .
1019
-					substr($code, 1) .
1020
-					'))';
1021
-				$commentaire = '&';
1022
-				$avant = '';
1023
-				$apres = '';
1024
-				$altern = "''";
1025
-				break;
1026
-
1027
-			// inclure
1028
-			case 'include':
1029
-				$p->descr = $descr;
1030
-				$code = calculer_inclure($p, $boucles, $id_boucle);
1031
-				if ($code === false) {
1032
-					$err_e_c = true;
1033
-					$code = "''";
1034
-				} else {
1035
-					$commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
-					$avant = '';
1037
-					$apres = '';
1038
-					$altern = "''";
1039
-				}
1040
-				break;
1041
-
1042
-			// boucle
1043
-			case TYPE_RECURSIF:
1044
-				$nom = $p->id_boucle;
1045
-				$newdescr = $descr;
1046
-				$newdescr['id_mere'] = $nom;
1047
-				$newdescr['niv']++;
1048
-				$preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
-				$avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
-				$apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
-				$postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
-				$newdescr['niv']--;
1053
-				$altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
-				if (
1055
-					$preaff === false
1056
-					or $avant === false
1057
-					or $apres === false
1058
-					or $altern === false
1059
-					or $postaff === false
1060
-				) {
1061
-					$err_e_c = true;
1062
-					$code = "''";
1063
-				} else {
1064
-					$code = 'BOUCLE' .
1065
-						str_replace('-', '_', $nom) . $descr['nom'] .
1066
-						'($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
-					$commentaire = "?$nom";
1068
-					if (
1069
-						!$boucles[$nom]->milieu
1070
-						and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
-					) {
1072
-						if ($preaff != "''") {
1073
-							$code .= "\n. $preaff";
1074
-						}
1075
-						if ($altern != "''") {
1076
-							$code .= "\n. $altern";
1077
-						}
1078
-						if ($postaff != "''") {
1079
-							$code .= "\n. $postaff";
1080
-						}
1081
-						if ($avant <> "''" or $apres <> "''") {
1082
-							spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
-						}
1084
-						$avant = $apres = $altern = "''";
1085
-					} else {
1086
-						if ($preaff != "''") {
1087
-							$avant = compile_concatene_parties_codes($preaff, $avant);
1088
-							$altern = compile_concatene_parties_codes($preaff, $altern);
1089
-						}
1090
-						if ($postaff != "''") {
1091
-							$apres = compile_concatene_parties_codes($apres, $postaff);
1092
-							$altern = compile_concatene_parties_codes($altern, $postaff);
1093
-						}
1094
-						if ($altern != "''") {
1095
-							$altern = "($altern)";
1096
-						}
1097
-					}
1098
-				}
1099
-				break;
1100
-
1101
-			case 'idiome':
1102
-				$l = [];
1103
-				$code = '';
1104
-				foreach ($p->arg as $k => $v) {
1105
-					$_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
-					if ($k) {
1107
-						$l[] = _q($k) . ' => ' . $_v;
1108
-					} else {
1109
-						$code = $_v;
1110
-					}
1111
-				}
1112
-				// Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
-				if ($p->module) {
1114
-					$m = $p->module . ':' . $p->nom_champ;
1115
-				} elseif ($p->nom_champ) {
1116
-					$m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
-				} else {
1118
-					$m = '';
1119
-				}
1120
-
1121
-				$code = (!$code ? "'$m'" :
1122
-						($m ? "'$m' . $code" :
1123
-							("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
-					. (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
-				$code = "_T($code)";
1126
-				if ($p->param) {
1127
-					$p->id_boucle = $id_boucle;
1128
-					$p->boucles = &$boucles;
1129
-					$code = compose_filtres($p, $code);
1130
-				}
1131
-				$commentaire = ':';
1132
-				$avant = '';
1133
-				$apres = '';
1134
-				$altern = "''";
1135
-				break;
1136
-
1137
-			case 'champ':
1138
-				// cette structure pourrait etre completee des le phrase' (a faire)
1139
-				$p->id_boucle = $id_boucle;
1140
-				$p->boucles = &$boucles;
1141
-				$p->descr = $descr;
1142
-				#$p->interdire_scripts = true;
1143
-				$p->type_requete = $type;
1144
-
1145
-				$code = calculer_champ($p);
1146
-				$commentaire = '#' . $p->nom_champ . $p->etoile;
1147
-				$avant = calculer_liste(
1148
-					$p->avant,
1149
-					$descr,
1150
-					$boucles,
1151
-					$id_boucle
1152
-				);
1153
-				$apres = calculer_liste(
1154
-					$p->apres,
1155
-					$descr,
1156
-					$boucles,
1157
-					$id_boucle
1158
-				);
1159
-				$altern = "''";
1160
-				// Si la valeur est destinee a une comparaison a ''
1161
-				// forcer la conversion en une chaine par strval
1162
-				// si ca peut etre autre chose qu'une chaine
1163
-				if (
1164
-					($avant != "''" or $apres != "''")
1165
-					and $code[0] != "'"
1166
-					# AND (strpos($code,'interdire_scripts') !== 0)
1167
-					and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1168
-					and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1169
-					and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1170
-				) {
1171
-					$code = "strval($code)";
1172
-				}
1173
-				break;
1174
-
1175
-			default:
1176
-				// Erreur de construction de l'arbre de syntaxe abstraite
1177
-				$code = "''";
1178
-				$p->descr = $descr;
1179
-				$err_e_c = _T('zbug_erreur_compilation');
1180
-				erreur_squelette($err_e_c, $p);
1181
-		} // switch
1182
-
1183
-		if ($code != "''") {
1184
-			$code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1185
-			$codes[] = (($mode == 'validation') ?
1186
-				"array($code, '$commentaire', " . $p->ligne . ')'
1187
-				: (($mode == 'code') ?
1188
-					"\n// $commentaire\n$code" :
1189
-					$code));
1190
-		}
1191
-	} // foreach
1192
-
1193
-	return $err_e_c ? false : $codes;
987
+    $codes = [];
988
+    // cas de la boucle recursive
989
+    if (is_array($id_boucle)) {
990
+        $id_boucle = $id_boucle[0];
991
+    }
992
+    $type = !$id_boucle ? '' : $boucles[$id_boucle]->type_requete;
993
+    $tab = str_repeat("\t", ++$descr['niv']);
994
+    $mode = _request('var_mode_affiche');
995
+    $err_e_c = '';
996
+    // chaque commentaire introduit dans le code doit commencer
997
+    // par un caractere distinguant le cas, pour exploitation par debug.
998
+    foreach ($tableau as $p) {
999
+        switch ($p->type) {
1000
+            // texte seul
1001
+            case 'texte':
1002
+                $code = sandbox_composer_texte($p->texte, $p);
1003
+                $commentaire = strlen($p->texte) . ' signes';
1004
+                $avant = '';
1005
+                $apres = '';
1006
+                $altern = "''";
1007
+                break;
1008
+
1009
+            case 'polyglotte':
1010
+                $code = '';
1011
+                foreach ($p->traductions as $k => $v) {
1012
+                    $code .= ",'" .
1013
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $k) .
1014
+                        "' => '" .
1015
+                        str_replace(['\\', "'"], ['\\\\', "\\'"], $v) .
1016
+                        "'";
1017
+                }
1018
+                $code = 'choisir_traduction(array(' .
1019
+                    substr($code, 1) .
1020
+                    '))';
1021
+                $commentaire = '&';
1022
+                $avant = '';
1023
+                $apres = '';
1024
+                $altern = "''";
1025
+                break;
1026
+
1027
+            // inclure
1028
+            case 'include':
1029
+                $p->descr = $descr;
1030
+                $code = calculer_inclure($p, $boucles, $id_boucle);
1031
+                if ($code === false) {
1032
+                    $err_e_c = true;
1033
+                    $code = "''";
1034
+                } else {
1035
+                    $commentaire = '<INCLURE ' . addslashes(str_replace("\n", ' ', $code)) . '>';
1036
+                    $avant = '';
1037
+                    $apres = '';
1038
+                    $altern = "''";
1039
+                }
1040
+                break;
1041
+
1042
+            // boucle
1043
+            case TYPE_RECURSIF:
1044
+                $nom = $p->id_boucle;
1045
+                $newdescr = $descr;
1046
+                $newdescr['id_mere'] = $nom;
1047
+                $newdescr['niv']++;
1048
+                $preaff = calculer_liste($p->preaff, $newdescr, $boucles, $id_boucle);
1049
+                $avant = calculer_liste($p->avant, $newdescr, $boucles, $id_boucle);
1050
+                $apres = calculer_liste($p->apres, $newdescr, $boucles, $id_boucle);
1051
+                $postaff = calculer_liste($p->postaff, $newdescr, $boucles, $id_boucle);
1052
+                $newdescr['niv']--;
1053
+                $altern = calculer_liste($p->altern, $newdescr, $boucles, $id_boucle);
1054
+                if (
1055
+                    $preaff === false
1056
+                    or $avant === false
1057
+                    or $apres === false
1058
+                    or $altern === false
1059
+                    or $postaff === false
1060
+                ) {
1061
+                    $err_e_c = true;
1062
+                    $code = "''";
1063
+                } else {
1064
+                    $code = 'BOUCLE' .
1065
+                        str_replace('-', '_', $nom) . $descr['nom'] .
1066
+                        '($Cache, $Pile, $doublons, $Numrows, $SP)';
1067
+                    $commentaire = "?$nom";
1068
+                    if (
1069
+                        !$boucles[$nom]->milieu
1070
+                        and $boucles[$nom]->type_requete <> TYPE_RECURSIF
1071
+                    ) {
1072
+                        if ($preaff != "''") {
1073
+                            $code .= "\n. $preaff";
1074
+                        }
1075
+                        if ($altern != "''") {
1076
+                            $code .= "\n. $altern";
1077
+                        }
1078
+                        if ($postaff != "''") {
1079
+                            $code .= "\n. $postaff";
1080
+                        }
1081
+                        if ($avant <> "''" or $apres <> "''") {
1082
+                            spip_log("boucle $nom toujours vide, code superflu dans $descr[sourcefile]");
1083
+                        }
1084
+                        $avant = $apres = $altern = "''";
1085
+                    } else {
1086
+                        if ($preaff != "''") {
1087
+                            $avant = compile_concatene_parties_codes($preaff, $avant);
1088
+                            $altern = compile_concatene_parties_codes($preaff, $altern);
1089
+                        }
1090
+                        if ($postaff != "''") {
1091
+                            $apres = compile_concatene_parties_codes($apres, $postaff);
1092
+                            $altern = compile_concatene_parties_codes($altern, $postaff);
1093
+                        }
1094
+                        if ($altern != "''") {
1095
+                            $altern = "($altern)";
1096
+                        }
1097
+                    }
1098
+                }
1099
+                break;
1100
+
1101
+            case 'idiome':
1102
+                $l = [];
1103
+                $code = '';
1104
+                foreach ($p->arg as $k => $v) {
1105
+                    $_v = calculer_liste($v, $descr, $boucles, $id_boucle);
1106
+                    if ($k) {
1107
+                        $l[] = _q($k) . ' => ' . $_v;
1108
+                    } else {
1109
+                        $code = $_v;
1110
+                    }
1111
+                }
1112
+                // Si le module n'est pas fourni, l'expliciter sauf si calculé
1113
+                if ($p->module) {
1114
+                    $m = $p->module . ':' . $p->nom_champ;
1115
+                } elseif ($p->nom_champ) {
1116
+                    $m = MODULES_IDIOMES . ':' . $p->nom_champ;
1117
+                } else {
1118
+                    $m = '';
1119
+                }
1120
+
1121
+                $code = (!$code ? "'$m'" :
1122
+                        ($m ? "'$m' . $code" :
1123
+                            ("(strpos(\$x=$code, ':') ? \$x : ('" . MODULES_IDIOMES . ":' . \$x))")))
1124
+                    . (!$l ? '' : (', array(' . implode(",\n", $l) . ')'));
1125
+                $code = "_T($code)";
1126
+                if ($p->param) {
1127
+                    $p->id_boucle = $id_boucle;
1128
+                    $p->boucles = &$boucles;
1129
+                    $code = compose_filtres($p, $code);
1130
+                }
1131
+                $commentaire = ':';
1132
+                $avant = '';
1133
+                $apres = '';
1134
+                $altern = "''";
1135
+                break;
1136
+
1137
+            case 'champ':
1138
+                // cette structure pourrait etre completee des le phrase' (a faire)
1139
+                $p->id_boucle = $id_boucle;
1140
+                $p->boucles = &$boucles;
1141
+                $p->descr = $descr;
1142
+                #$p->interdire_scripts = true;
1143
+                $p->type_requete = $type;
1144
+
1145
+                $code = calculer_champ($p);
1146
+                $commentaire = '#' . $p->nom_champ . $p->etoile;
1147
+                $avant = calculer_liste(
1148
+                    $p->avant,
1149
+                    $descr,
1150
+                    $boucles,
1151
+                    $id_boucle
1152
+                );
1153
+                $apres = calculer_liste(
1154
+                    $p->apres,
1155
+                    $descr,
1156
+                    $boucles,
1157
+                    $id_boucle
1158
+                );
1159
+                $altern = "''";
1160
+                // Si la valeur est destinee a une comparaison a ''
1161
+                // forcer la conversion en une chaine par strval
1162
+                // si ca peut etre autre chose qu'une chaine
1163
+                if (
1164
+                    ($avant != "''" or $apres != "''")
1165
+                    and $code[0] != "'"
1166
+                    # AND (strpos($code,'interdire_scripts') !== 0)
1167
+                    and !preg_match(_REGEXP_COND_VIDE_NONVIDE, $code)
1168
+                    and !preg_match(_REGEXP_COND_NONVIDE_VIDE, $code)
1169
+                    and !preg_match(_REGEXP_CONCAT_NON_VIDE, $code)
1170
+                ) {
1171
+                    $code = "strval($code)";
1172
+                }
1173
+                break;
1174
+
1175
+            default:
1176
+                // Erreur de construction de l'arbre de syntaxe abstraite
1177
+                $code = "''";
1178
+                $p->descr = $descr;
1179
+                $err_e_c = _T('zbug_erreur_compilation');
1180
+                erreur_squelette($err_e_c, $p);
1181
+        } // switch
1182
+
1183
+        if ($code != "''") {
1184
+            $code = compile_retour($code, $avant, $apres, $altern, $tab, $descr['niv']);
1185
+            $codes[] = (($mode == 'validation') ?
1186
+                "array($code, '$commentaire', " . $p->ligne . ')'
1187
+                : (($mode == 'code') ?
1188
+                    "\n// $commentaire\n$code" :
1189
+                    $code));
1190
+        }
1191
+    } // foreach
1192
+
1193
+    return $err_e_c ? false : $codes;
1194 1194
 }
1195 1195
 
1196 1196
 /**
@@ -1200,13 +1200,13 @@  discard block
 block discarded – undo
1200 1200
  * @return string
1201 1201
  */
1202 1202
 function compile_concatene_parties_codes($partie1, $partie2) {
1203
-	if ($partie1 === "''") {
1204
-		return $partie2;
1205
-	}
1206
-	if ($partie2 === "''") {
1207
-		return $partie1;
1208
-	}
1209
-	return "$partie1\n. $partie2";
1203
+    if ($partie1 === "''") {
1204
+        return $partie2;
1205
+    }
1206
+    if ($partie2 === "''") {
1207
+        return $partie1;
1208
+    }
1209
+    return "$partie1\n. $partie2";
1210 1210
 }
1211 1211
 
1212 1212
 
@@ -1230,56 +1230,56 @@  discard block
 block discarded – undo
1230 1230
  * @return mixed|string
1231 1231
  */
1232 1232
 function compile_retour($code, $avant, $apres, $altern, $tab, $n) {
1233
-	if ($avant === "''") {
1234
-		$avant = '';
1235
-	}
1236
-	if ($apres === "''") {
1237
-		$apres = '';
1238
-	}
1239
-	if ($avant or $apres or ($altern !== "''")) {
1240
-		if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1241
-			$t = $code;
1242
-			$cond = '';
1243
-		} elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1244
-			$t = $r[2];
1245
-			$cond = '!' . $r[1];
1246
-		} else {
1247
-			if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1248
-				$t = $r[2];
1249
-				$cond = $r[1];
1250
-			} else {
1251
-				$t = '$t' . $n;
1252
-				$cond = "($t = $code)!==''";
1253
-			}
1254
-		}
1255
-
1256
-		$res = (!$avant ? '' : "$avant . ") .
1257
-			$t .
1258
-			(!$apres ? '' : " . $apres");
1259
-
1260
-		if ($res !== $t) {
1261
-			$res = "($res)";
1262
-		}
1263
-
1264
-		$code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1265
-	}
1266
-
1267
-	return $code;
1233
+    if ($avant === "''") {
1234
+        $avant = '';
1235
+    }
1236
+    if ($apres === "''") {
1237
+        $apres = '';
1238
+    }
1239
+    if ($avant or $apres or ($altern !== "''")) {
1240
+        if (preg_match(_REGEXP_CONCAT_NON_VIDE, $code)) {
1241
+            $t = $code;
1242
+            $cond = '';
1243
+        } elseif (preg_match(_REGEXP_COND_VIDE_NONVIDE, $code, $r)) {
1244
+            $t = $r[2];
1245
+            $cond = '!' . $r[1];
1246
+        } else {
1247
+            if (preg_match(_REGEXP_COND_NONVIDE_VIDE, $code, $r)) {
1248
+                $t = $r[2];
1249
+                $cond = $r[1];
1250
+            } else {
1251
+                $t = '$t' . $n;
1252
+                $cond = "($t = $code)!==''";
1253
+            }
1254
+        }
1255
+
1256
+        $res = (!$avant ? '' : "$avant . ") .
1257
+            $t .
1258
+            (!$apres ? '' : " . $apres");
1259
+
1260
+        if ($res !== $t) {
1261
+            $res = "($res)";
1262
+        }
1263
+
1264
+        $code = (!$cond ? $res : "($cond ?\n\t$tab$res :\n\t$tab$altern)");
1265
+    }
1266
+
1267
+    return $code;
1268 1268
 }
1269 1269
 
1270 1270
 
1271 1271
 function compile_inclure_doublons($lexemes) {
1272
-	foreach ($lexemes as $v) {
1273
-		if ($v->type === 'include' and $v->param) {
1274
-			foreach ($v->param as $r) {
1275
-				if (trim($r[0]) === 'doublons') {
1276
-					return true;
1277
-				}
1278
-			}
1279
-		}
1280
-	}
1281
-
1282
-	return false;
1272
+    foreach ($lexemes as $v) {
1273
+        if ($v->type === 'include' and $v->param) {
1274
+            foreach ($v->param as $r) {
1275
+                if (trim($r[0]) === 'doublons') {
1276
+                    return true;
1277
+                }
1278
+            }
1279
+        }
1280
+    }
1281
+
1282
+    return false;
1283 1283
 }
1284 1284
 
1285 1285
 // Prend en argument le texte d'un squelette, le nom de son fichier d'origine,
@@ -1298,354 +1298,354 @@  discard block
 block discarded – undo
1298 1298
 // En cas d'erreur, elle retournera un tableau des 2 premiers elements seulement
1299 1299
 
1300 1300
 function public_compiler_dist($squelette, $nom, $gram, $sourcefile, string $connect = '') {
1301
-	// Pre-traitement : reperer le charset du squelette, et le convertir
1302
-	// Bonus : supprime le BOM
1303
-	include_spip('inc/charsets');
1304
-	$squelette = transcoder_page($squelette);
1305
-
1306
-	// rendre inertes les echappements de #[](){}<>
1307
-	$i = 0;
1308
-	while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1309
-		$i++;
1310
-	}
1311
-	$squelette = preg_replace_callback(
1312
-		',\\\\([#[()\]{}<>]),',
1313
-		fn($a) => "$inerte-" . ord($a[1]) . '-',
1314
-		$squelette,
1315
-		-1,
1316
-		$esc
1317
-	);
1318
-
1319
-	$descr = [
1320
-		'nom' => $nom,
1321
-		'gram' => $gram,
1322
-		'sourcefile' => $sourcefile,
1323
-		'squelette' => $squelette
1324
-	];
1325
-
1326
-	// Phraser le squelette, selon sa grammaire
1327
-
1328
-	$boucles = [];
1329
-	$f = charger_fonction('phraser_' . $gram, 'public');
1330
-
1331
-	$squelette = $f($squelette, '', $boucles, $descr);
1332
-
1333
-	$boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1334
-
1335
-	// restituer les echappements
1336
-	if ($esc) {
1337
-		foreach ($boucles as $i => $boucle) {
1338
-			$boucles[$i]->return = preg_replace_callback(
1339
-				",$inerte-(\d+)-,",
1340
-				fn($a) => chr($a[1]),
1341
-				$boucle->return
1342
-			);
1343
-			$boucles[$i]->descr['squelette'] = preg_replace_callback(
1344
-				",$inerte-(\d+)-,",
1345
-				fn($a) => '\\\\' . chr($a[1]),
1346
-				$boucle->descr['squelette']
1347
-			);
1348
-		}
1349
-	}
1350
-
1351
-	$debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1352
-	if ($debug) {
1353
-		include_spip('public/decompiler');
1354
-		foreach ($boucles as $id => $boucle) {
1355
-			if ($id) {
1356
-				$decomp = "\n/* BOUCLE " .
1357
-					$boucle->type_requete .
1358
-					' ' .
1359
-					str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1360
-					($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1361
-					" */\n";
1362
-			} else {
1363
-				$decomp = ("\n/*\n" .
1364
-					str_replace('*/', '* /', public_decompiler($squelette, $gram))
1365
-					. "\n*/");
1366
-			}
1367
-			$boucles[$id]->return = $decomp . $boucle->return;
1368
-			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1369
-		}
1370
-	}
1371
-
1372
-	return $boucles;
1301
+    // Pre-traitement : reperer le charset du squelette, et le convertir
1302
+    // Bonus : supprime le BOM
1303
+    include_spip('inc/charsets');
1304
+    $squelette = transcoder_page($squelette);
1305
+
1306
+    // rendre inertes les echappements de #[](){}<>
1307
+    $i = 0;
1308
+    while (str_contains($squelette, $inerte = '-INERTE' . $i)) {
1309
+        $i++;
1310
+    }
1311
+    $squelette = preg_replace_callback(
1312
+        ',\\\\([#[()\]{}<>]),',
1313
+        fn($a) => "$inerte-" . ord($a[1]) . '-',
1314
+        $squelette,
1315
+        -1,
1316
+        $esc
1317
+    );
1318
+
1319
+    $descr = [
1320
+        'nom' => $nom,
1321
+        'gram' => $gram,
1322
+        'sourcefile' => $sourcefile,
1323
+        'squelette' => $squelette
1324
+    ];
1325
+
1326
+    // Phraser le squelette, selon sa grammaire
1327
+
1328
+    $boucles = [];
1329
+    $f = charger_fonction('phraser_' . $gram, 'public');
1330
+
1331
+    $squelette = $f($squelette, '', $boucles, $descr);
1332
+
1333
+    $boucles = compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect);
1334
+
1335
+    // restituer les echappements
1336
+    if ($esc) {
1337
+        foreach ($boucles as $i => $boucle) {
1338
+            $boucles[$i]->return = preg_replace_callback(
1339
+                ",$inerte-(\d+)-,",
1340
+                fn($a) => chr($a[1]),
1341
+                $boucle->return
1342
+            );
1343
+            $boucles[$i]->descr['squelette'] = preg_replace_callback(
1344
+                ",$inerte-(\d+)-,",
1345
+                fn($a) => '\\\\' . chr($a[1]),
1346
+                $boucle->descr['squelette']
1347
+            );
1348
+        }
1349
+    }
1350
+
1351
+    $debug = ($boucles and defined('_VAR_MODE') and _VAR_MODE == 'debug');
1352
+    if ($debug) {
1353
+        include_spip('public/decompiler');
1354
+        foreach ($boucles as $id => $boucle) {
1355
+            if ($id) {
1356
+                $decomp = "\n/* BOUCLE " .
1357
+                    $boucle->type_requete .
1358
+                    ' ' .
1359
+                    str_replace('*/', '* /', public_decompiler($boucle, $gram, 0, 'criteres')) .
1360
+                    ($boucle->debug ? "\n *\n * " . implode("\n * ", $boucle->debug) . "\n" : '') .
1361
+                    " */\n";
1362
+            } else {
1363
+                $decomp = ("\n/*\n" .
1364
+                    str_replace('*/', '* /', public_decompiler($squelette, $gram))
1365
+                    . "\n*/");
1366
+            }
1367
+            $boucles[$id]->return = $decomp . $boucle->return;
1368
+            $GLOBALS['debug_objets']['code'][$nom . $id] = $boucle->return;
1369
+        }
1370
+    }
1371
+
1372
+    return $boucles;
1373 1373
 }
1374 1374
 
1375 1375
 // Point d'entree pour arbre de syntaxe abstraite fourni en premier argument
1376 1376
 // Autres specifications comme ci-dessus
1377 1377
 
1378 1378
 function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, string $connect = '') {
1379
-	static $trouver_table;
1380
-	spip_timer('calcul_skel');
1381
-
1382
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1383
-		$GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1384
-		$GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1385
-
1386
-		if (!isset($GLOBALS['debug_objets']['principal'])) {
1387
-			$GLOBALS['debug_objets']['principal'] = $nom;
1388
-		}
1389
-	}
1390
-	foreach ($boucles as $id => $boucle) {
1391
-		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1392
-	}
1393
-	$descr['documents'] = compile_inclure_doublons($squelette);
1394
-
1395
-	// Demander la description des tables une fois pour toutes
1396
-	if (!$trouver_table) {
1397
-		$trouver_table = charger_fonction('trouver_table', 'base');
1398
-	}
1399
-
1400
-	// reperer si les doublons sont demandes
1401
-	// pour un inclure ou une boucle document
1402
-	// c'est utile a la fonction champs_traitements
1403
-	foreach ($boucles as $id => $boucle) {
1404
-		if (!($type = $boucle->type_requete)) {
1405
-			continue;
1406
-		}
1407
-		if (
1408
-			!$descr['documents'] and (
1409
-				(($type == 'documents') and $boucle->doublons) or
1410
-				compile_inclure_doublons($boucle->avant) or
1411
-				compile_inclure_doublons($boucle->apres) or
1412
-				compile_inclure_doublons($boucle->milieu) or
1413
-				compile_inclure_doublons($boucle->altern))
1414
-		) {
1415
-			$descr['documents'] = true;
1416
-		}
1417
-		if ($type != TYPE_RECURSIF) {
1418
-			if (!$boucles[$id]->sql_serveur and $connect) {
1419
-				$boucles[$id]->sql_serveur = $connect;
1420
-			}
1421
-
1422
-			// chercher dans les iterateurs du repertoire iterateur/
1423
-			if (
1424
-				$g = charger_fonction(
1425
-					preg_replace('/\W/', '_', $boucle->type_requete),
1426
-					'iterateur',
1427
-					true
1428
-				)
1429
-			) {
1430
-				$boucles[$id] = $g($boucle);
1431
-
1432
-				// sinon, en cas de requeteur d'un type predefini,
1433
-				// utiliser les informations donnees par le requeteur
1434
-				// cas "php:xx" et "data:xx".
1435
-			} else {
1436
-				if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1437
-					$requeteur($boucles, $boucle, $id);
1438
-
1439
-					// utiliser la description des champs transmis
1440
-				} else {
1441
-					$show = $trouver_table($type, $boucles[$id]->sql_serveur);
1442
-					// si la table n'existe pas avec le connecteur par defaut,
1443
-					// c'est peut etre une table qui necessite son connecteur dedie fourni
1444
-					// permet une ecriture allegee (GEO) -> (geo:GEO)
1445
-					if (
1446
-						!$show
1447
-						and $show = $trouver_table($type, strtolower($type))
1448
-					) {
1449
-						$boucles[$id]->sql_serveur = strtolower($type);
1450
-					}
1451
-					if ($show) {
1452
-						$boucles[$id]->show = $show;
1453
-						// recopie les infos les plus importantes
1454
-						$boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1455
-						$boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1456
-						$boucles[$id]->from[$x] = $nom_table = $show['table'];
1457
-						$boucles[$id]->iterateur = 'SQL';
1458
-
1459
-						if (empty($boucles[$id]->descr)) {
1460
-							$boucles[$id]->descr = &$descr;
1461
-						}
1462
-						if (
1463
-							(!$boucles[$id]->jointures)
1464
-							and is_array($show['tables_jointures'])
1465
-							and count($x = $show['tables_jointures'])
1466
-						) {
1467
-							$boucles[$id]->jointures = $x;
1468
-						}
1469
-						if ($boucles[$id]->jointures_explicites) {
1470
-							$jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1471
-							while ($j = array_pop($jointures)) {
1472
-								array_unshift($boucles[$id]->jointures, $j);
1473
-							}
1474
-						}
1475
-					} else {
1476
-						// Pas une erreur si la table est optionnelle
1477
-						if ($boucles[$id]->table_optionnelle) {
1478
-							$boucles[$id]->type_requete = '';
1479
-						} else {
1480
-							$boucles[$id]->type_requete = false;
1481
-							$boucle = $boucles[$id];
1482
-							$x = (!$boucle->sql_serveur ? '' :
1483
-									($boucle->sql_serveur . ':')) .
1484
-								$type;
1485
-							$msg = [
1486
-								'zbug_table_inconnue',
1487
-								['table' => $x]
1488
-							];
1489
-							erreur_squelette($msg, $boucle);
1490
-						}
1491
-					}
1492
-				}
1493
-			}
1494
-		}
1495
-	}
1496
-
1497
-	// Commencer par reperer les boucles appelees explicitement
1498
-	// car elles indexent les arguments de maniere derogatoire
1499
-	foreach ($boucles as $id => $boucle) {
1500
-		if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1501
-			$boucles[$id]->descr = &$descr;
1502
-			$rec = &$boucles[$boucle->param[0]];
1503
-			if (!$rec) {
1504
-				$msg = [
1505
-					'zbug_boucle_recursive_undef',
1506
-					['nom' => $boucle->param[0]]
1507
-				];
1508
-				erreur_squelette($msg, $boucle);
1509
-				$boucles[$id]->type_requete = false;
1510
-			} else {
1511
-				$rec->externe = $id;
1512
-				$descr['id_mere'] = $id;
1513
-				$boucles[$id]->return =
1514
-					calculer_liste(
1515
-						[$rec],
1516
-						$descr,
1517
-						$boucles,
1518
-						$boucle->param
1519
-					);
1520
-			}
1521
-		}
1522
-	}
1523
-	foreach ($boucles as $id => $boucle) {
1524
-		$id = strval($id); // attention au type dans index_pile
1525
-		$type = $boucle->type_requete;
1526
-		if ($type and $type != TYPE_RECURSIF) {
1527
-			$res = '';
1528
-			if ($boucle->param) {
1529
-				// retourne un tableau en cas d'erreur
1530
-				$res = calculer_criteres($id, $boucles);
1531
-			}
1532
-			$descr['id_mere'] = $id;
1533
-			$boucles[$id]->return =
1534
-				calculer_liste(
1535
-					$boucle->milieu,
1536
-					$descr,
1537
-					$boucles,
1538
-					$id
1539
-				);
1540
-			// Si les criteres se sont mal compiles
1541
-			// ne pas tenter d'assembler le code final
1542
-			// (mais compiler le corps pour detection d'erreurs)
1543
-			if (is_array($res)) {
1544
-				$boucles[$id]->type_requete = false;
1545
-			}
1546
-		}
1547
-	}
1548
-
1549
-	// idem pour la racine
1550
-	$descr['id_mere'] = '';
1551
-	$corps = calculer_liste($squelette, $descr, $boucles);
1552
-
1553
-
1554
-	// Calcul du corps de toutes les fonctions PHP,
1555
-	// en particulier les requetes SQL et TOTAL_BOUCLE
1556
-	// de'terminables seulement maintenant
1557
-
1558
-	foreach ($boucles as $id => $boucle) {
1559
-		$boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1560
-		if ($boucle->return === false) {
1561
-			$corps = false;
1562
-			continue;
1563
-		}
1564
-		// appeler la fonction de definition de la boucle
1565
-
1566
-		if ($req = $boucle->type_requete) {
1567
-			// boucle personnalisée ?
1568
-			$table = strtoupper($boucle->type_requete);
1569
-			$serveur = strtolower($boucle->sql_serveur);
1570
-			if (
1571
-				// fonction de boucle avec serveur & table
1572
-				(!$serveur or
1573
-					((!function_exists($f = 'boucle_' . $serveur . '_' . $table))
1574
-						and (!function_exists($f = $f . '_dist'))
1575
-					)
1576
-				)
1577
-				// fonction de boucle avec table
1578
-				and (!function_exists($f = 'boucle_' . $table))
1579
-				and (!function_exists($f = $f . '_dist'))
1580
-			) {
1581
-				// fonction de boucle standard
1582
-				if (!function_exists($f = 'boucle_DEFAUT')) {
1583
-					$f = 'boucle_DEFAUT_dist';
1584
-				}
1585
-			}
1586
-
1587
-			$req = "\n\n\tstatic \$command = array();\n\t" .
1588
-				"static \$connect;\n\t" .
1589
-				"\$command['connect'] = \$connect = " .
1590
-				_q($boucle->sql_serveur) .
1591
-				';' .
1592
-				$f($id, $boucles);
1593
-		} else {
1594
-			$req = ("\n\treturn '';");
1595
-		}
1596
-
1597
-		$boucles[$id]->return =
1598
-			"\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
-			'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
-			$req .
1601
-			"\n}\n";
1602
-	}
1603
-
1604
-	// Au final, si le corps ou un critere au moins s'est mal compile
1605
-	// retourner False, sinon inserer leur decompilation
1606
-	if (is_bool($corps)) {
1607
-		return false;
1608
-	}
1609
-
1610
-	$principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1379
+    static $trouver_table;
1380
+    spip_timer('calcul_skel');
1381
+
1382
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
1383
+        $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
1384
+        $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
1385
+
1386
+        if (!isset($GLOBALS['debug_objets']['principal'])) {
1387
+            $GLOBALS['debug_objets']['principal'] = $nom;
1388
+        }
1389
+    }
1390
+    foreach ($boucles as $id => $boucle) {
1391
+        $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
1392
+    }
1393
+    $descr['documents'] = compile_inclure_doublons($squelette);
1394
+
1395
+    // Demander la description des tables une fois pour toutes
1396
+    if (!$trouver_table) {
1397
+        $trouver_table = charger_fonction('trouver_table', 'base');
1398
+    }
1399
+
1400
+    // reperer si les doublons sont demandes
1401
+    // pour un inclure ou une boucle document
1402
+    // c'est utile a la fonction champs_traitements
1403
+    foreach ($boucles as $id => $boucle) {
1404
+        if (!($type = $boucle->type_requete)) {
1405
+            continue;
1406
+        }
1407
+        if (
1408
+            !$descr['documents'] and (
1409
+                (($type == 'documents') and $boucle->doublons) or
1410
+                compile_inclure_doublons($boucle->avant) or
1411
+                compile_inclure_doublons($boucle->apres) or
1412
+                compile_inclure_doublons($boucle->milieu) or
1413
+                compile_inclure_doublons($boucle->altern))
1414
+        ) {
1415
+            $descr['documents'] = true;
1416
+        }
1417
+        if ($type != TYPE_RECURSIF) {
1418
+            if (!$boucles[$id]->sql_serveur and $connect) {
1419
+                $boucles[$id]->sql_serveur = $connect;
1420
+            }
1421
+
1422
+            // chercher dans les iterateurs du repertoire iterateur/
1423
+            if (
1424
+                $g = charger_fonction(
1425
+                    preg_replace('/\W/', '_', $boucle->type_requete),
1426
+                    'iterateur',
1427
+                    true
1428
+                )
1429
+            ) {
1430
+                $boucles[$id] = $g($boucle);
1431
+
1432
+                // sinon, en cas de requeteur d'un type predefini,
1433
+                // utiliser les informations donnees par le requeteur
1434
+                // cas "php:xx" et "data:xx".
1435
+            } else {
1436
+                if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
1437
+                    $requeteur($boucles, $boucle, $id);
1438
+
1439
+                    // utiliser la description des champs transmis
1440
+                } else {
1441
+                    $show = $trouver_table($type, $boucles[$id]->sql_serveur);
1442
+                    // si la table n'existe pas avec le connecteur par defaut,
1443
+                    // c'est peut etre une table qui necessite son connecteur dedie fourni
1444
+                    // permet une ecriture allegee (GEO) -> (geo:GEO)
1445
+                    if (
1446
+                        !$show
1447
+                        and $show = $trouver_table($type, strtolower($type))
1448
+                    ) {
1449
+                        $boucles[$id]->sql_serveur = strtolower($type);
1450
+                    }
1451
+                    if ($show) {
1452
+                        $boucles[$id]->show = $show;
1453
+                        // recopie les infos les plus importantes
1454
+                        $boucles[$id]->primary = $show['key']['PRIMARY KEY'] ?? '';
1455
+                        $boucles[$id]->id_table = $x = preg_replace(',^spip_,', '', $show['id_table']);
1456
+                        $boucles[$id]->from[$x] = $nom_table = $show['table'];
1457
+                        $boucles[$id]->iterateur = 'SQL';
1458
+
1459
+                        if (empty($boucles[$id]->descr)) {
1460
+                            $boucles[$id]->descr = &$descr;
1461
+                        }
1462
+                        if (
1463
+                            (!$boucles[$id]->jointures)
1464
+                            and is_array($show['tables_jointures'])
1465
+                            and count($x = $show['tables_jointures'])
1466
+                        ) {
1467
+                            $boucles[$id]->jointures = $x;
1468
+                        }
1469
+                        if ($boucles[$id]->jointures_explicites) {
1470
+                            $jointures = preg_split('/\s+/', $boucles[$id]->jointures_explicites);
1471
+                            while ($j = array_pop($jointures)) {
1472
+                                array_unshift($boucles[$id]->jointures, $j);
1473
+                            }
1474
+                        }
1475
+                    } else {
1476
+                        // Pas une erreur si la table est optionnelle
1477
+                        if ($boucles[$id]->table_optionnelle) {
1478
+                            $boucles[$id]->type_requete = '';
1479
+                        } else {
1480
+                            $boucles[$id]->type_requete = false;
1481
+                            $boucle = $boucles[$id];
1482
+                            $x = (!$boucle->sql_serveur ? '' :
1483
+                                    ($boucle->sql_serveur . ':')) .
1484
+                                $type;
1485
+                            $msg = [
1486
+                                'zbug_table_inconnue',
1487
+                                ['table' => $x]
1488
+                            ];
1489
+                            erreur_squelette($msg, $boucle);
1490
+                        }
1491
+                    }
1492
+                }
1493
+            }
1494
+        }
1495
+    }
1496
+
1497
+    // Commencer par reperer les boucles appelees explicitement
1498
+    // car elles indexent les arguments de maniere derogatoire
1499
+    foreach ($boucles as $id => $boucle) {
1500
+        if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
1501
+            $boucles[$id]->descr = &$descr;
1502
+            $rec = &$boucles[$boucle->param[0]];
1503
+            if (!$rec) {
1504
+                $msg = [
1505
+                    'zbug_boucle_recursive_undef',
1506
+                    ['nom' => $boucle->param[0]]
1507
+                ];
1508
+                erreur_squelette($msg, $boucle);
1509
+                $boucles[$id]->type_requete = false;
1510
+            } else {
1511
+                $rec->externe = $id;
1512
+                $descr['id_mere'] = $id;
1513
+                $boucles[$id]->return =
1514
+                    calculer_liste(
1515
+                        [$rec],
1516
+                        $descr,
1517
+                        $boucles,
1518
+                        $boucle->param
1519
+                    );
1520
+            }
1521
+        }
1522
+    }
1523
+    foreach ($boucles as $id => $boucle) {
1524
+        $id = strval($id); // attention au type dans index_pile
1525
+        $type = $boucle->type_requete;
1526
+        if ($type and $type != TYPE_RECURSIF) {
1527
+            $res = '';
1528
+            if ($boucle->param) {
1529
+                // retourne un tableau en cas d'erreur
1530
+                $res = calculer_criteres($id, $boucles);
1531
+            }
1532
+            $descr['id_mere'] = $id;
1533
+            $boucles[$id]->return =
1534
+                calculer_liste(
1535
+                    $boucle->milieu,
1536
+                    $descr,
1537
+                    $boucles,
1538
+                    $id
1539
+                );
1540
+            // Si les criteres se sont mal compiles
1541
+            // ne pas tenter d'assembler le code final
1542
+            // (mais compiler le corps pour detection d'erreurs)
1543
+            if (is_array($res)) {
1544
+                $boucles[$id]->type_requete = false;
1545
+            }
1546
+        }
1547
+    }
1548
+
1549
+    // idem pour la racine
1550
+    $descr['id_mere'] = '';
1551
+    $corps = calculer_liste($squelette, $descr, $boucles);
1552
+
1553
+
1554
+    // Calcul du corps de toutes les fonctions PHP,
1555
+    // en particulier les requetes SQL et TOTAL_BOUCLE
1556
+    // de'terminables seulement maintenant
1557
+
1558
+    foreach ($boucles as $id => $boucle) {
1559
+        $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
1560
+        if ($boucle->return === false) {
1561
+            $corps = false;
1562
+            continue;
1563
+        }
1564
+        // appeler la fonction de definition de la boucle
1565
+
1566
+        if ($req = $boucle->type_requete) {
1567
+            // boucle personnalisée ?
1568
+            $table = strtoupper($boucle->type_requete);
1569
+            $serveur = strtolower($boucle->sql_serveur);
1570
+            if (
1571
+                // fonction de boucle avec serveur & table
1572
+                (!$serveur or
1573
+                    ((!function_exists($f = 'boucle_' . $serveur . '_' . $table))
1574
+                        and (!function_exists($f = $f . '_dist'))
1575
+                    )
1576
+                )
1577
+                // fonction de boucle avec table
1578
+                and (!function_exists($f = 'boucle_' . $table))
1579
+                and (!function_exists($f = $f . '_dist'))
1580
+            ) {
1581
+                // fonction de boucle standard
1582
+                if (!function_exists($f = 'boucle_DEFAUT')) {
1583
+                    $f = 'boucle_DEFAUT_dist';
1584
+                }
1585
+            }
1586
+
1587
+            $req = "\n\n\tstatic \$command = array();\n\t" .
1588
+                "static \$connect;\n\t" .
1589
+                "\$command['connect'] = \$connect = " .
1590
+                _q($boucle->sql_serveur) .
1591
+                ';' .
1592
+                $f($id, $boucles);
1593
+        } else {
1594
+            $req = ("\n\treturn '';");
1595
+        }
1596
+
1597
+        $boucles[$id]->return =
1598
+            "\n\nfunction BOUCLE" . strtr($id, '-', '_') . $nom .
1599
+            '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
1600
+            $req .
1601
+            "\n}\n";
1602
+    }
1603
+
1604
+    // Au final, si le corps ou un critere au moins s'est mal compile
1605
+    // retourner False, sinon inserer leur decompilation
1606
+    if (is_bool($corps)) {
1607
+        return false;
1608
+    }
1609
+
1610
+    $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons = array(), $Numrows = array(), $SP = 0) {
1611 1611
 '
1612
-		// reporter de maniere securisee les doublons inclus
1613
-		. '
1612
+        // reporter de maniere securisee les doublons inclus
1613
+        . '
1614 1614
 	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
1615 1615
 		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);
1616 1616
 
1617 1617
 	$connect = ' .
1618
-		_q($connect) . ';
1618
+        _q($connect) . ';
1619 1619
 	$page = ' .
1620
-		// ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
-		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
-		// avant de referencer $Cache
1623
-		$corps . ';
1620
+        // ATTENTION, le calcul de l'expression $corps affectera $Cache
1621
+        // c'est pourquoi on l'affecte a la variable auxiliaire $page.
1622
+        // avant de referencer $Cache
1623
+        $corps . ';
1624 1624
 
1625 1625
 	return analyse_resultat_skel(' . var_export($nom, true)
1626
-		. ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1626
+        . ', $Cache, $page, ' . var_export($sourcefile, true) . ');
1627 1627
 }';
1628 1628
 
1629
-	$secondes = spip_timer('calcul_skel');
1630
-	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
-	// $connect n'est pas sûr : on nettoie
1632
-	$connect = preg_replace(',[^\w],', '', $connect);
1629
+    $secondes = spip_timer('calcul_skel');
1630
+    spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
1631
+    // $connect n'est pas sûr : on nettoie
1632
+    $connect = preg_replace(',[^\w],', '', $connect);
1633 1633
 
1634
-	// Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
-	$code = new Boucle();
1636
-	$code->descr = $descr;
1637
-	$code->return = '
1634
+    // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
1635
+    $code = new Boucle();
1636
+    $code->descr = $descr;
1637
+    $code->return = '
1638 1638
 //
1639 1639
 // Fonction principale du squelette ' .
1640
-		$sourcefile .
1641
-		($connect ? " pour $connect" : '') .
1642
-		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
-		"\n//\n" .
1644
-		$principal;
1640
+        $sourcefile .
1641
+        ($connect ? " pour $connect" : '') .
1642
+        (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
1643
+        "\n//\n" .
1644
+        $principal;
1645 1645
 
1646
-	$boucles[''] = $code;
1646
+    $boucles[''] = $code;
1647 1647
 
1648
-	return $boucles;
1648
+    return $boucles;
1649 1649
 }
1650 1650
 
1651 1651
 
@@ -1662,18 +1662,18 @@  discard block
 block discarded – undo
1662 1662
  *
1663 1663
  **/
1664 1664
 function requeteur_php_dist(&$boucles, &$boucle, &$id) {
1665
-	if (class_exists($boucle->type_requete)) {
1666
-		$g = charger_fonction('php', 'iterateur');
1667
-		$boucles[$id] = $g($boucle, $boucle->type_requete);
1668
-	} else {
1669
-		$x = $boucle->type_requete;
1670
-		$boucle->type_requete = false;
1671
-		$msg = [
1672
-			'zbug_iterateur_inconnu',
1673
-			['iterateur' => $x]
1674
-		];
1675
-		erreur_squelette($msg, $boucle);
1676
-	}
1665
+    if (class_exists($boucle->type_requete)) {
1666
+        $g = charger_fonction('php', 'iterateur');
1667
+        $boucles[$id] = $g($boucle, $boucle->type_requete);
1668
+    } else {
1669
+        $x = $boucle->type_requete;
1670
+        $boucle->type_requete = false;
1671
+        $msg = [
1672
+            'zbug_iterateur_inconnu',
1673
+            ['iterateur' => $x]
1674
+        ];
1675
+        erreur_squelette($msg, $boucle);
1676
+    }
1677 1677
 }
1678 1678
 
1679 1679
 
@@ -1691,22 +1691,22 @@  discard block
 block discarded – undo
1691 1691
  *
1692 1692
  **/
1693 1693
 function requeteur_data_dist(&$boucles, &$boucle, &$id) {
1694
-	include_spip('iterateur/data');
1695
-	if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
-		$g = charger_fonction('data', 'iterateur');
1697
-		$boucles[$id] = $g($boucle);
1698
-		// from[0] stocke le type de data (rss, yql, ...)
1699
-		$boucles[$id]->from[] = $boucle->type_requete;
1700
-	} else {
1701
-		$x = $boucle->type_requete;
1702
-		$boucle->type_requete = false;
1703
-		$msg = [
1704
-			'zbug_requeteur_inconnu',
1705
-			[
1706
-				'requeteur' => 'data',
1707
-				'type' => $x
1708
-			]
1709
-		];
1710
-		erreur_squelette($msg, $boucle);
1711
-	}
1694
+    include_spip('iterateur/data');
1695
+    if ($h = charger_fonction($boucle->type_requete . '_to_array', 'inc', true)) {
1696
+        $g = charger_fonction('data', 'iterateur');
1697
+        $boucles[$id] = $g($boucle);
1698
+        // from[0] stocke le type de data (rss, yql, ...)
1699
+        $boucles[$id]->from[] = $boucle->type_requete;
1700
+    } else {
1701
+        $x = $boucle->type_requete;
1702
+        $boucle->type_requete = false;
1703
+        $msg = [
1704
+            'zbug_requeteur_inconnu',
1705
+            [
1706
+                'requeteur' => 'data',
1707
+                'type' => $x
1708
+            ]
1709
+        ];
1710
+        erreur_squelette($msg, $boucle);
1711
+    }
1712 1712
 }
Please login to merge, or discard this patch.
ecrire/public/references.php 1 patch
Indentation   +561 added lines, -561 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
  * @package SPIP\Core\Compilateur\References
20 20
  **/
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 /**
@@ -44,14 +44,14 @@  discard block
 block discarded – undo
44 44
  *     - '' si une référence explicite incorrecte est envoyée
45 45
  */
46 46
 function index_boucle($p) {
47
-	if (strlen($p->nom_boucle)) {
48
-		// retourne l’index explicite demandé s’il existe
49
-		if (!empty($p->boucles[$p->nom_boucle])) {
50
-			return $p->nom_boucle;
51
-		}
52
-		return '';
53
-	}
54
-	return $p->id_boucle;
47
+    if (strlen($p->nom_boucle)) {
48
+        // retourne l’index explicite demandé s’il existe
49
+        if (!empty($p->boucles[$p->nom_boucle])) {
50
+            return $p->nom_boucle;
51
+        }
52
+        return '';
53
+    }
54
+    return $p->id_boucle;
55 55
 }
56 56
 
57 57
 
@@ -74,17 +74,17 @@  discard block
 block discarded – undo
74 74
  *     - '' si une référence explicite incorrecte est envoyée
75 75
  */
76 76
 function index_boucle_mere($p) {
77
-	if (strlen($p->nom_boucle)) {
78
-		// retourne l’index explicite demandé s’il existe
79
-		if (!empty($p->boucles[$p->nom_boucle])) {
80
-			return $p->nom_boucle;
81
-		}
82
-		return '';
83
-	}
84
-	if (!empty($p->descr['id_mere'])) {
85
-		return $p->descr['id_mere'];
86
-	}
87
-	return '';
77
+    if (strlen($p->nom_boucle)) {
78
+        // retourne l’index explicite demandé s’il existe
79
+        if (!empty($p->boucles[$p->nom_boucle])) {
80
+            return $p->nom_boucle;
81
+        }
82
+        return '';
83
+    }
84
+    if (!empty($p->descr['id_mere'])) {
85
+        return $p->descr['id_mere'];
86
+    }
87
+    return '';
88 88
 }
89 89
 
90 90
 /**
@@ -118,74 +118,74 @@  discard block
 block discarded – undo
118 118
  *     Code PHP pour obtenir le champ SQL
119 119
  */
120 120
 function index_pile(
121
-	$idb,
122
-	$nom_champ,
123
-	&$boucles,
124
-	$explicite = '',
125
-	$defaut = null,
126
-	$remonte_pile = true,
127
-	$select = true
121
+    $idb,
122
+    $nom_champ,
123
+    &$boucles,
124
+    $explicite = '',
125
+    $defaut = null,
126
+    $remonte_pile = true,
127
+    $select = true
128 128
 ) {
129
-	if (!is_string($defaut)) {
130
-		$defaut = '($Pile[0][\'' . strtolower($nom_champ) . '\'] ?? null)';
131
-	}
132
-
133
-	$idb_origine = $idb;
134
-	$nom_champ_origine = $nom_champ;
135
-
136
-	$i = 0;
137
-	if (strlen($explicite)) {
138
-		// Recherche d'un champ dans un etage superieur
139
-		while (($idb !== $explicite) && ($idb !== '')) {
140
-			#	spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'");
141
-			$i++;
142
-			$idb = $boucles[$idb]->id_parent;
143
-		}
144
-	}
145
-
146
-	#	spip_log("Cherche: $nom_champ a partir de '$idb'");
147
-	$nom_champ = strtolower($nom_champ);
148
-	$conditionnel = [];
149
-	// attention: entre la boucle nommee 0, "" et le tableau vide,
150
-	// il y a incoherences qu'il vaut mieux eviter
151
-	while (isset($boucles[$idb])) {
152
-		$joker = true;
153
-		// modifie $joker si tous les champs sont autorisés.
154
-		// $t = le select pour le champ, si on l'a trouvé (ou si joker)
155
-		// $c = le nom du champ demandé
156
-		[$t, $c] = index_tables_en_pile($idb, $nom_champ, $boucles, $joker);
157
-		if ($t) {
158
-			if ($select and !in_array($t, $boucles[$idb]->select)) {
159
-				$boucles[$idb]->select[] = $t;
160
-			}
161
-			// renseigner la boucle source de ce champ pour les traitements
162
-			$boucles[$idb_origine]->index_champ[$nom_champ_origine] = $idb;
163
-			$champ = '$Pile[$SP' . ($i ? "-$i" : '') . '][\'' . $c . '\']';
164
-			if (!$joker) {
165
-				return index_compose($conditionnel, $champ);
166
-			}
167
-
168
-			// tant que l'on trouve des tables avec joker, on continue
169
-			// avec la boucle parente et on conditionne à l'exécution
170
-			// la présence du champ. Si le champ existe à l'exécution
171
-			// dans une boucle, il est pris, sinon on le cherche dans le parent...
172
-			$conditionnel[] = "isset($champ)?$champ";
173
-		}
174
-
175
-		if ($remonte_pile) {
176
-			#	spip_log("On remonte vers $i");
177
-			// Sinon on remonte d'un cran
178
-			$idb = $boucles[$idb]->id_parent;
179
-			$i++;
180
-		} else {
181
-			$idb = null;
182
-		}
183
-	}
184
-
185
-	#	spip_log("Pas vu $nom_champ");
186
-	// esperons qu'il y sera
187
-	// ou qu'on a fourni une valeur par "defaut" plus pertinent
188
-	return index_compose($conditionnel, $defaut);
129
+    if (!is_string($defaut)) {
130
+        $defaut = '($Pile[0][\'' . strtolower($nom_champ) . '\'] ?? null)';
131
+    }
132
+
133
+    $idb_origine = $idb;
134
+    $nom_champ_origine = $nom_champ;
135
+
136
+    $i = 0;
137
+    if (strlen($explicite)) {
138
+        // Recherche d'un champ dans un etage superieur
139
+        while (($idb !== $explicite) && ($idb !== '')) {
140
+            #	spip_log("Cherchexpl: $nom_champ '$explicite' '$idb' '$i'");
141
+            $i++;
142
+            $idb = $boucles[$idb]->id_parent;
143
+        }
144
+    }
145
+
146
+    #	spip_log("Cherche: $nom_champ a partir de '$idb'");
147
+    $nom_champ = strtolower($nom_champ);
148
+    $conditionnel = [];
149
+    // attention: entre la boucle nommee 0, "" et le tableau vide,
150
+    // il y a incoherences qu'il vaut mieux eviter
151
+    while (isset($boucles[$idb])) {
152
+        $joker = true;
153
+        // modifie $joker si tous les champs sont autorisés.
154
+        // $t = le select pour le champ, si on l'a trouvé (ou si joker)
155
+        // $c = le nom du champ demandé
156
+        [$t, $c] = index_tables_en_pile($idb, $nom_champ, $boucles, $joker);
157
+        if ($t) {
158
+            if ($select and !in_array($t, $boucles[$idb]->select)) {
159
+                $boucles[$idb]->select[] = $t;
160
+            }
161
+            // renseigner la boucle source de ce champ pour les traitements
162
+            $boucles[$idb_origine]->index_champ[$nom_champ_origine] = $idb;
163
+            $champ = '$Pile[$SP' . ($i ? "-$i" : '') . '][\'' . $c . '\']';
164
+            if (!$joker) {
165
+                return index_compose($conditionnel, $champ);
166
+            }
167
+
168
+            // tant que l'on trouve des tables avec joker, on continue
169
+            // avec la boucle parente et on conditionne à l'exécution
170
+            // la présence du champ. Si le champ existe à l'exécution
171
+            // dans une boucle, il est pris, sinon on le cherche dans le parent...
172
+            $conditionnel[] = "isset($champ)?$champ";
173
+        }
174
+
175
+        if ($remonte_pile) {
176
+            #	spip_log("On remonte vers $i");
177
+            // Sinon on remonte d'un cran
178
+            $idb = $boucles[$idb]->id_parent;
179
+            $i++;
180
+        } else {
181
+            $idb = null;
182
+        }
183
+    }
184
+
185
+    #	spip_log("Pas vu $nom_champ");
186
+    // esperons qu'il y sera
187
+    // ou qu'on a fourni une valeur par "defaut" plus pertinent
188
+    return index_compose($conditionnel, $defaut);
189 189
 }
190 190
 
191 191
 /**
@@ -199,12 +199,12 @@  discard block
 block discarded – undo
199 199
  * @return string              Code PHP complet de recherche d'un champ
200 200
  */
201 201
 function index_compose($conditionnel, $defaut) {
202
-	while ($c = array_pop($conditionnel)) {
203
-		// si on passe defaut = '', ne pas générer d'erreur de compilation.
204
-		$defaut = "($c:(" . ($defaut ?: "''") . '))';
205
-	}
202
+    while ($c = array_pop($conditionnel)) {
203
+        // si on passe defaut = '', ne pas générer d'erreur de compilation.
204
+        $defaut = "($c:(" . ($defaut ?: "''") . '))';
205
+    }
206 206
 
207
-	return $defaut;
207
+    return $defaut;
208 208
 }
209 209
 
210 210
 /**
@@ -240,97 +240,97 @@  discard block
 block discarded – undo
240 240
  **/
241 241
 function index_tables_en_pile($idb, $nom_champ, &$boucles, &$joker) {
242 242
 
243
-	$r = $boucles[$idb]->type_requete;
244
-	// boucle recursive, c'est foutu...
245
-	if ($r == TYPE_RECURSIF) {
246
-		return [];
247
-	}
248
-	if (!$r) {
249
-		$joker = false; // indiquer a l'appelant
250
-		# continuer pour chercher l'erreur suivante
251
-		return ["'#" . $r . ':' . $nom_champ . "'", ''];
252
-	}
253
-
254
-	$desc = $boucles[$idb]->show;
255
-	// le nom du champ est il une exception de la table ? un alias ?
256
-	$excep = $GLOBALS['exceptions_des_tables'][$r] ?? '';
257
-	if ($excep) {
258
-		$excep = $excep[$nom_champ] ?? '';
259
-	}
260
-
261
-	// il y a un alias connu pour ce champ
262
-	if ($excep) {
263
-		$joker = false; // indiquer a l'appelant
264
-		return index_exception($boucles[$idb], $desc, $nom_champ, $excep);
265
-	}
266
-
267
-	// le champ existe dans la table, on le prend.
268
-	if (isset($desc['field'][$nom_champ])) {
269
-		$t = $boucles[$idb]->id_table ?? '';
270
-		$joker = false; // indiquer a l'appelant
271
-		// note: dans certains cas ('valeur' d’une boucle DATA, sans id_table), retourne ['.valeur', 'valeur'] …
272
-		return ["$t.$nom_champ", $nom_champ];
273
-	}
274
-
275
-	// Tous les champs sont-ils acceptés ?
276
-	// Si oui, on retourne le champ, et on lève le flag joker
277
-	// C'est le cas des itérateurs DATA qui acceptent tout
278
-	// et testent la présence du champ à l'exécution et non à la compilation
279
-	// car ils ne connaissent pas ici leurs contenus.
280
-	if (
281
-		/*$joker AND */
282
-		isset($desc['field']['*'])
283
-	) {
284
-		$joker = true; // indiquer a l'appelant
285
-		return [$nom_champ, $nom_champ];
286
-	}
287
-
288
-	$joker = false; // indiquer a l'appelant
289
-
290
-	// la table de jointure est explicitement indiquée (rubrique.titre)
291
-	if (preg_match('/^(.*)\.(.*)$/', $nom_champ, $r)) {
292
-		[, $_table, $_nom_champ] = $r;
293
-		if ($cle = trouver_jointure_champ($_nom_champ, $boucles[$idb], [$_table])) {
294
-			$_alias = $cle . '_' . $_nom_champ;
295
-			return index_exception(
296
-				$boucles[$idb],
297
-				$desc,
298
-				$_alias,
299
-				[$_table, $_nom_champ]
300
-			);
301
-		}
302
-		return ['', ''];
303
-	}
304
-
305
-	// pas d'alias, pas de champ, pas de joker...
306
-	// tenter via une jointure...
307
-
308
-	// regarder si le champ est deja dans une jointure existante
309
-	// sinon, si il y a des joitures explicites, la construire
310
-	if (!$t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb])) {
311
-		if ($boucles[$idb]->jointures_explicites) {
312
-			// [todo] Ne pas lancer que lorsque il y a des jointures explicites !!!!
313
-			// fonctionnel, il suffit d'utiliser $boucles[$idb]->jointures au lieu de jointures_explicites
314
-			// mais est-ce ce qu'on veut ?
315
-			$jointures = preg_split('/\s+/', $boucles[$idb]->jointures_explicites);
316
-			if ($cle = trouver_jointure_champ($nom_champ, $boucles[$idb], $jointures)) {
317
-				$t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb]);
318
-			}
319
-		}
320
-	}
321
-
322
-	if ($t) {
323
-		// si on a trouvé une jointure possible, on fait comme
324
-		// si c'était une exception pour le champ demandé
325
-		return index_exception(
326
-			$boucles[$idb],
327
-			$desc,
328
-			$nom_champ,
329
-			[$t[1]['id_table'], reset($t[2])]
330
-		);
331
-	}
332
-
333
-	return ['', ''];
243
+    $r = $boucles[$idb]->type_requete;
244
+    // boucle recursive, c'est foutu...
245
+    if ($r == TYPE_RECURSIF) {
246
+        return [];
247
+    }
248
+    if (!$r) {
249
+        $joker = false; // indiquer a l'appelant
250
+        # continuer pour chercher l'erreur suivante
251
+        return ["'#" . $r . ':' . $nom_champ . "'", ''];
252
+    }
253
+
254
+    $desc = $boucles[$idb]->show;
255
+    // le nom du champ est il une exception de la table ? un alias ?
256
+    $excep = $GLOBALS['exceptions_des_tables'][$r] ?? '';
257
+    if ($excep) {
258
+        $excep = $excep[$nom_champ] ?? '';
259
+    }
260
+
261
+    // il y a un alias connu pour ce champ
262
+    if ($excep) {
263
+        $joker = false; // indiquer a l'appelant
264
+        return index_exception($boucles[$idb], $desc, $nom_champ, $excep);
265
+    }
266
+
267
+    // le champ existe dans la table, on le prend.
268
+    if (isset($desc['field'][$nom_champ])) {
269
+        $t = $boucles[$idb]->id_table ?? '';
270
+        $joker = false; // indiquer a l'appelant
271
+        // note: dans certains cas ('valeur' d’une boucle DATA, sans id_table), retourne ['.valeur', 'valeur'] …
272
+        return ["$t.$nom_champ", $nom_champ];
273
+    }
274
+
275
+    // Tous les champs sont-ils acceptés ?
276
+    // Si oui, on retourne le champ, et on lève le flag joker
277
+    // C'est le cas des itérateurs DATA qui acceptent tout
278
+    // et testent la présence du champ à l'exécution et non à la compilation
279
+    // car ils ne connaissent pas ici leurs contenus.
280
+    if (
281
+        /*$joker AND */
282
+        isset($desc['field']['*'])
283
+    ) {
284
+        $joker = true; // indiquer a l'appelant
285
+        return [$nom_champ, $nom_champ];
286
+    }
287
+
288
+    $joker = false; // indiquer a l'appelant
289
+
290
+    // la table de jointure est explicitement indiquée (rubrique.titre)
291
+    if (preg_match('/^(.*)\.(.*)$/', $nom_champ, $r)) {
292
+        [, $_table, $_nom_champ] = $r;
293
+        if ($cle = trouver_jointure_champ($_nom_champ, $boucles[$idb], [$_table])) {
294
+            $_alias = $cle . '_' . $_nom_champ;
295
+            return index_exception(
296
+                $boucles[$idb],
297
+                $desc,
298
+                $_alias,
299
+                [$_table, $_nom_champ]
300
+            );
301
+        }
302
+        return ['', ''];
303
+    }
304
+
305
+    // pas d'alias, pas de champ, pas de joker...
306
+    // tenter via une jointure...
307
+
308
+    // regarder si le champ est deja dans une jointure existante
309
+    // sinon, si il y a des joitures explicites, la construire
310
+    if (!$t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb])) {
311
+        if ($boucles[$idb]->jointures_explicites) {
312
+            // [todo] Ne pas lancer que lorsque il y a des jointures explicites !!!!
313
+            // fonctionnel, il suffit d'utiliser $boucles[$idb]->jointures au lieu de jointures_explicites
314
+            // mais est-ce ce qu'on veut ?
315
+            $jointures = preg_split('/\s+/', $boucles[$idb]->jointures_explicites);
316
+            if ($cle = trouver_jointure_champ($nom_champ, $boucles[$idb], $jointures)) {
317
+                $t = trouver_champ_exterieur($nom_champ, $boucles[$idb]->from, $boucles[$idb]);
318
+            }
319
+        }
320
+    }
321
+
322
+    if ($t) {
323
+        // si on a trouvé une jointure possible, on fait comme
324
+        // si c'était une exception pour le champ demandé
325
+        return index_exception(
326
+            $boucles[$idb],
327
+            $desc,
328
+            $nom_champ,
329
+            [$t[1]['id_table'], reset($t[2])]
330
+        );
331
+    }
332
+
333
+    return ['', ''];
334 334
 }
335 335
 
336 336
 
@@ -358,52 +358,52 @@  discard block
 block discarded – undo
358 358
  *     est une expression pour le SELECT de la boucle du style "mots.titre AS titre_mot"
359 359
  **/
360 360
 function index_exception(&$boucle, $desc, $nom_champ, $excep) {
361
-	static $trouver_table;
362
-	if (!$trouver_table) {
363
-		$trouver_table = charger_fonction('trouver_table', 'base');
364
-	}
365
-
366
-	if (is_array($excep)) {
367
-		// permettre aux plugins de gerer eux meme des jointures derogatoire ingerables
368
-		$t = null;
369
-		if (count($excep) == 3) {
370
-			$index_exception_derogatoire = array_pop($excep);
371
-			$t = $index_exception_derogatoire($boucle, $desc, $nom_champ, $excep);
372
-		}
373
-		if ($t == null) {
374
-			[$e, $x] = $excep;  #PHP4 affecte de gauche a droite
375
-			$excep = $x;    #PHP5 de droite a gauche !
376
-			$j = $trouver_table($e, $boucle->sql_serveur);
377
-			if (!$j) {
378
-				return ['', ''];
379
-			}
380
-			$e = $j['table'];
381
-			if (!$t = array_search($e, $boucle->from)) {
382
-				$k = $j['key']['PRIMARY KEY'];
383
-				if (strpos($k, ',')) {
384
-					$l = (preg_split('/\s*,\s*/', $k));
385
-					$k = $desc['key']['PRIMARY KEY'];
386
-					if (!in_array($k, $l)) {
387
-						spip_log("jointure impossible $e " . join(',', $l));
388
-
389
-						return ['', ''];
390
-					}
391
-				}
392
-				$k = [$boucle->id_table, [$e], $k];
393
-				fabrique_jointures($boucle, [$k]);
394
-				$t = array_search($e, $boucle->from);
395
-			}
396
-		}
397
-	} else {
398
-		$t = $boucle->id_table;
399
-	}
400
-	// demander a SQL de gerer le synonyme
401
-	// ca permet que excep soit dynamique (Cedric, 2/3/06)
402
-	if ($excep != $nom_champ) {
403
-		$excep .= ' AS ' . $nom_champ;
404
-	}
405
-
406
-	return ["$t.$excep", $nom_champ];
361
+    static $trouver_table;
362
+    if (!$trouver_table) {
363
+        $trouver_table = charger_fonction('trouver_table', 'base');
364
+    }
365
+
366
+    if (is_array($excep)) {
367
+        // permettre aux plugins de gerer eux meme des jointures derogatoire ingerables
368
+        $t = null;
369
+        if (count($excep) == 3) {
370
+            $index_exception_derogatoire = array_pop($excep);
371
+            $t = $index_exception_derogatoire($boucle, $desc, $nom_champ, $excep);
372
+        }
373
+        if ($t == null) {
374
+            [$e, $x] = $excep;  #PHP4 affecte de gauche a droite
375
+            $excep = $x;    #PHP5 de droite a gauche !
376
+            $j = $trouver_table($e, $boucle->sql_serveur);
377
+            if (!$j) {
378
+                return ['', ''];
379
+            }
380
+            $e = $j['table'];
381
+            if (!$t = array_search($e, $boucle->from)) {
382
+                $k = $j['key']['PRIMARY KEY'];
383
+                if (strpos($k, ',')) {
384
+                    $l = (preg_split('/\s*,\s*/', $k));
385
+                    $k = $desc['key']['PRIMARY KEY'];
386
+                    if (!in_array($k, $l)) {
387
+                        spip_log("jointure impossible $e " . join(',', $l));
388
+
389
+                        return ['', ''];
390
+                    }
391
+                }
392
+                $k = [$boucle->id_table, [$e], $k];
393
+                fabrique_jointures($boucle, [$k]);
394
+                $t = array_search($e, $boucle->from);
395
+            }
396
+        }
397
+    } else {
398
+        $t = $boucle->id_table;
399
+    }
400
+    // demander a SQL de gerer le synonyme
401
+    // ca permet que excep soit dynamique (Cedric, 2/3/06)
402
+    if ($excep != $nom_champ) {
403
+        $excep .= ' AS ' . $nom_champ;
404
+    }
405
+
406
+    return ["$t.$excep", $nom_champ];
407 407
 }
408 408
 
409 409
 /**
@@ -428,7 +428,7 @@  discard block
 block discarded – undo
428 428
  *     Code PHP pour retrouver le champ
429 429
  */
430 430
 function champ_sql($champ, $p, $defaut = null, $remonte_pile = true) {
431
-	return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $defaut, $remonte_pile);
431
+    return index_pile($p->id_boucle, $champ, $p->boucles, $p->nom_boucle, $defaut, $remonte_pile);
432 432
 }
433 433
 
434 434
 
@@ -448,9 +448,9 @@  discard block
 block discarded – undo
448 448
  *     Code PHP pour d'exécution de la balise et de ses filtres
449 449
  **/
450 450
 function calculer_champ($p) {
451
-	$p = calculer_balise($p->nom_champ, $p);
451
+    $p = calculer_balise($p->nom_champ, $p);
452 452
 
453
-	return applique_filtres($p);
453
+    return applique_filtres($p);
454 454
 }
455 455
 
456 456
 
@@ -487,26 +487,26 @@  discard block
 block discarded – undo
487 487
  **/
488 488
 function calculer_balise(string $nom, Champ $p): Champ {
489 489
 
490
-	// S'agit-t-il d'une balise_XXXX[_dist]() ?
491
-	if ($f = charger_fonction($nom, 'balise', true)) {
492
-		$p->balise_calculee = true;
493
-		$res = $f($p);
494
-		if ($res !== null and is_object($res)) {
495
-			return $res;
496
-		}
497
-	}
498
-
499
-	// Certaines des balises comportant un _ sont generiques
500
-	if ($balise_generique = chercher_balise_generique($nom)) {
501
-		$res = $balise_generique['fonction_generique']($p);
502
-		if ($res !== null and is_object($res)) {
503
-			return $res;
504
-		}
505
-	}
506
-
507
-	$f = charger_fonction('DEFAUT', 'calculer_balise');
508
-
509
-	return $f($nom, $p);
490
+    // S'agit-t-il d'une balise_XXXX[_dist]() ?
491
+    if ($f = charger_fonction($nom, 'balise', true)) {
492
+        $p->balise_calculee = true;
493
+        $res = $f($p);
494
+        if ($res !== null and is_object($res)) {
495
+            return $res;
496
+        }
497
+    }
498
+
499
+    // Certaines des balises comportant un _ sont generiques
500
+    if ($balise_generique = chercher_balise_generique($nom)) {
501
+        $res = $balise_generique['fonction_generique']($p);
502
+        if ($res !== null and is_object($res)) {
503
+            return $res;
504
+        }
505
+    }
506
+
507
+    $f = charger_fonction('DEFAUT', 'calculer_balise');
508
+
509
+    return $f($nom, $p);
510 510
 }
511 511
 
512 512
 
@@ -534,37 +534,37 @@  discard block
 block discarded – undo
534 534
  **/
535 535
 function calculer_balise_DEFAUT_dist($nom, $p) {
536 536
 
537
-	// ca pourrait etre un champ SQL homonyme,
538
-	$p->code = index_pile($p->id_boucle, $nom, $p->boucles, $p->nom_boucle);
539
-
540
-	// compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour
541
-	// il faut recracher {...} quand ce n'est finalement pas des args
542
-	if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) {
543
-		$code = addslashes($p->fonctions[0][1]);
544
-		$p->code .= " . '$code'";
545
-	}
546
-
547
-	// ne pas passer le filtre securite sur les id_xxx
548
-	if (strpos($nom, 'ID_') === 0) {
549
-		$p->interdire_scripts = false;
550
-	}
551
-
552
-	// Compatibilite ascendante avec les couleurs html (#FEFEFE) :
553
-	// SI le champ SQL n'est pas trouve
554
-	// ET si la balise a une forme de couleur
555
-	// ET s'il n'y a ni filtre ni etoile
556
-	// ALORS retourner la couleur.
557
-	// Ca permet si l'on veut vraiment de recuperer [(#ACCEDE*)]
558
-	if (
559
-		preg_match('/^[A-F]{1,6}$/i', $nom)
560
-		and !$p->etoile
561
-		and !$p->fonctions
562
-	) {
563
-		$p->code = "'#$nom'";
564
-		$p->interdire_scripts = false;
565
-	}
566
-
567
-	return $p;
537
+    // ca pourrait etre un champ SQL homonyme,
538
+    $p->code = index_pile($p->id_boucle, $nom, $p->boucles, $p->nom_boucle);
539
+
540
+    // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour
541
+    // il faut recracher {...} quand ce n'est finalement pas des args
542
+    if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) {
543
+        $code = addslashes($p->fonctions[0][1]);
544
+        $p->code .= " . '$code'";
545
+    }
546
+
547
+    // ne pas passer le filtre securite sur les id_xxx
548
+    if (strpos($nom, 'ID_') === 0) {
549
+        $p->interdire_scripts = false;
550
+    }
551
+
552
+    // Compatibilite ascendante avec les couleurs html (#FEFEFE) :
553
+    // SI le champ SQL n'est pas trouve
554
+    // ET si la balise a une forme de couleur
555
+    // ET s'il n'y a ni filtre ni etoile
556
+    // ALORS retourner la couleur.
557
+    // Ca permet si l'on veut vraiment de recuperer [(#ACCEDE*)]
558
+    if (
559
+        preg_match('/^[A-F]{1,6}$/i', $nom)
560
+        and !$p->etoile
561
+        and !$p->fonctions
562
+    ) {
563
+        $p->code = "'#$nom'";
564
+        $p->interdire_scripts = false;
565
+    }
566
+
567
+    return $p;
568 568
 }
569 569
 
570 570
 
@@ -613,53 +613,53 @@  discard block
 block discarded – undo
613 613
  **/
614 614
 function calculer_balise_dynamique($p, $nom, $l, $supp = []) {
615 615
 
616
-	if (!balise_distante_interdite($p)) {
617
-		$p->code = "''";
618
-
619
-		return $p;
620
-	}
621
-	// compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour
622
-	// il faut recracher {...} quand ce n'est finalement pas des args
623
-	if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) {
624
-		$p->fonctions = [];
625
-	}
626
-
627
-	if ($p->param and ($c = $p->param[0])) {
628
-		// liste d'arguments commence toujours par la chaine vide
629
-		array_shift($c);
630
-		// construire la liste d'arguments comme pour un filtre
631
-		$param = compose_filtres_args($p, $c, ',');
632
-	} else {
633
-		$param = '';
634
-	}
635
-	$collecte = collecter_balise_dynamique($l, $p, $nom);
636
-
637
-	$dans_un_modele = false;
638
-	if (!empty($p->descr['sourcefile'])
639
-	  and $f = $p->descr['sourcefile']
640
-	  and basename(dirname($f)) === 'modeles'
641
-	) {
642
-		$dans_un_modele = true;
643
-	}
644
-
645
-	// un modele est toujours inséré en texte dans son contenant
646
-	// donc si on est dans le public avec un cache on va perdre le dynamisme
647
-	// et on risque de mettre en cache les valeurs pre-remplies du formulaire
648
-	// on passe donc par une fonction proxy qui si besoin va collecter les arguments
649
-	// et injecter le PHP qui va appeler la fonction pour generer le formulaire au lieu de directement la fonction
650
-	// (dans l'espace prive on a pas de cache, donc pas de soucis (et un leak serait moins grave))
651
-	$p->code = sprintf(
652
-		$dans_un_modele ? CODE_EXECUTER_BALISE_MODELE : CODE_EXECUTER_BALISE,
653
-		$nom,
654
-		join(',', $collecte),
655
-		($collecte ? $param : substr($param, 1)), # virer la virgule
656
-		memoriser_contexte_compil($p),
657
-		(!$supp ? '' : (', ' . join(',', $supp)))
658
-	);
659
-
660
-	$p->interdire_scripts = false;
661
-
662
-	return $p;
616
+    if (!balise_distante_interdite($p)) {
617
+        $p->code = "''";
618
+
619
+        return $p;
620
+    }
621
+    // compatibilite: depuis qu'on accepte #BALISE{ses_args} sans [(...)] autour
622
+    // il faut recracher {...} quand ce n'est finalement pas des args
623
+    if ($p->fonctions and (!$p->fonctions[0][0]) and $p->fonctions[0][1]) {
624
+        $p->fonctions = [];
625
+    }
626
+
627
+    if ($p->param and ($c = $p->param[0])) {
628
+        // liste d'arguments commence toujours par la chaine vide
629
+        array_shift($c);
630
+        // construire la liste d'arguments comme pour un filtre
631
+        $param = compose_filtres_args($p, $c, ',');
632
+    } else {
633
+        $param = '';
634
+    }
635
+    $collecte = collecter_balise_dynamique($l, $p, $nom);
636
+
637
+    $dans_un_modele = false;
638
+    if (!empty($p->descr['sourcefile'])
639
+      and $f = $p->descr['sourcefile']
640
+      and basename(dirname($f)) === 'modeles'
641
+    ) {
642
+        $dans_un_modele = true;
643
+    }
644
+
645
+    // un modele est toujours inséré en texte dans son contenant
646
+    // donc si on est dans le public avec un cache on va perdre le dynamisme
647
+    // et on risque de mettre en cache les valeurs pre-remplies du formulaire
648
+    // on passe donc par une fonction proxy qui si besoin va collecter les arguments
649
+    // et injecter le PHP qui va appeler la fonction pour generer le formulaire au lieu de directement la fonction
650
+    // (dans l'espace prive on a pas de cache, donc pas de soucis (et un leak serait moins grave))
651
+    $p->code = sprintf(
652
+        $dans_un_modele ? CODE_EXECUTER_BALISE_MODELE : CODE_EXECUTER_BALISE,
653
+        $nom,
654
+        join(',', $collecte),
655
+        ($collecte ? $param : substr($param, 1)), # virer la virgule
656
+        memoriser_contexte_compil($p),
657
+        (!$supp ? '' : (', ' . join(',', $supp)))
658
+    );
659
+
660
+    $p->interdire_scripts = false;
661
+
662
+    return $p;
663 663
 }
664 664
 
665 665
 
@@ -689,17 +689,17 @@  discard block
 block discarded – undo
689 689
  *     Liste des codes PHP d'éxecution des balises collectées
690 690
  **/
691 691
 function collecter_balise_dynamique(array $l, Champ &$p, string $nom): array {
692
-	$args = [];
693
-	foreach ($l as $c) {
694
-		if ($c === null) {
695
-			$args[] = 'null';
696
-		} else {
697
-			$x = calculer_balise($c, $p);
698
-			$args[] = $x->code;
699
-		}
700
-	}
701
-
702
-	return $args;
692
+    $args = [];
693
+    foreach ($l as $c) {
694
+        if ($c === null) {
695
+            $args[] = 'null';
696
+        } else {
697
+            $x = calculer_balise($c, $p);
698
+            $args[] = $x->code;
699
+        }
700
+    }
701
+
702
+    return $args;
703 703
 }
704 704
 
705 705
 
@@ -714,22 +714,22 @@  discard block
 block discarded – undo
714 714
  *     Nom de la connexion
715 715
  **/
716 716
 function trouver_nom_serveur_distant($p) {
717
-	$nom = $p->id_boucle;
718
-	if (
719
-		$nom
720
-		and isset($p->boucles[$nom])
721
-	) {
722
-		$s = $p->boucles[$nom]->sql_serveur;
723
-		if (
724
-			strlen($s)
725
-			and strlen($serveur = strtolower($s))
726
-			and !in_array($serveur, $GLOBALS['exception_des_connect'])
727
-		) {
728
-			return $serveur;
729
-		}
730
-	}
731
-
732
-	return '';
717
+    $nom = $p->id_boucle;
718
+    if (
719
+        $nom
720
+        and isset($p->boucles[$nom])
721
+    ) {
722
+        $s = $p->boucles[$nom]->sql_serveur;
723
+        if (
724
+            strlen($s)
725
+            and strlen($serveur = strtolower($s))
726
+            and !in_array($serveur, $GLOBALS['exception_des_connect'])
727
+        ) {
728
+            return $serveur;
729
+        }
730
+    }
731
+
732
+    return '';
733 733
 }
734 734
 
735 735
 
@@ -753,15 +753,15 @@  discard block
 block discarded – undo
753 753
  *     - false : La balise est interdite car le serveur est distant
754 754
  **/
755 755
 function balise_distante_interdite($p) {
756
-	$nom = $p->id_boucle;
756
+    $nom = $p->id_boucle;
757 757
 
758
-	if ($nom and trouver_nom_serveur_distant($p)) {
759
-		spip_log($nom . ':' . $p->nom_champ . ' ' . _T('zbug_distant_interdit'));
758
+    if ($nom and trouver_nom_serveur_distant($p)) {
759
+        spip_log($nom . ':' . $p->nom_champ . ' ' . _T('zbug_distant_interdit'));
760 760
 
761
-		return false;
762
-	}
761
+        return false;
762
+    }
763 763
 
764
-	return true;
764
+    return true;
765 765
 }
766 766
 
767 767
 
@@ -771,84 +771,84 @@  discard block
 block discarded – undo
771 771
 //
772 772
 function champs_traitements($p) {
773 773
 
774
-	if (isset($GLOBALS['table_des_traitements'][$p->nom_champ])) {
775
-		$ps = $GLOBALS['table_des_traitements'][$p->nom_champ];
776
-	} else {
777
-		// quand on utilise un traitement catch-all *
778
-		// celui-ci ne s'applique pas sur les balises calculees qui peuvent gerer
779
-		// leur propre securite
780
-		if (!$p->balise_calculee) {
781
-			$ps = $GLOBALS['table_des_traitements']['*'];
782
-		} else {
783
-			$ps = false;
784
-		}
785
-	}
786
-
787
-	if (is_array($ps)) {
788
-		// Recuperer le type de boucle (articles, DATA) et la table SQL sur laquelle elle porte
789
-		$idb = index_boucle($p);
790
-		// si le champ a ete trouve dans une boucle parente sa source est renseignee ici
791
-		if (!empty($p->boucles[$idb]->index_champ[$p->nom_champ])) {
792
-			$idb = $p->boucles[$idb]->index_champ[$p->nom_champ];
793
-		}
794
-
795
-		// mais on peut aussi etre hors boucle. Se mefier.
796
-		$type_requete = $p->boucles[$idb]->type_requete ?? false;
797
-		$table_sql = $p->boucles[$idb]->show['table_sql'] ?? false;
798
-
799
-		// bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.)
800
-		if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) {
801
-			$type_alias = $type_requete;
802
-			$type_requete = $GLOBALS['table_des_tables'][$type_requete];
803
-		} else {
804
-			$type_alias = false;
805
-		}
806
-
807
-		// le traitement peut n'etre defini que pour une table en particulier "spip_articles"
808
-		if ($table_sql and isset($ps[$table_sql])) {
809
-			$ps = $ps[$table_sql];
810
-		} // ou pour une boucle en particulier "DATA","articles"
811
-		elseif ($type_requete and isset($ps[$type_requete])) {
812
-			$ps = $ps[$type_requete];
813
-		} // ou pour une boucle utilisant un alias ("hierarchie")
814
-		elseif ($type_alias and isset($ps[$type_alias])) {
815
-			$ps = $ps[$type_alias];
816
-		} // ou pour indifféremment quelle que soit la boucle
817
-		elseif (isset($ps[0])) {
818
-			$ps = $ps[0];
819
-		} else {
820
-			$ps = false;
821
-		}
822
-	}
823
-
824
-	if (!$ps) {
825
-		return $p->code;
826
-	}
827
-
828
-	// Si une boucle DOCUMENTS{doublons} est presente dans le squelette,
829
-	// ou si in INCLURE contient {doublons}
830
-	// on insere une fonction de remplissage du tableau des doublons
831
-	// dans les filtres propre() ou typo()
832
-	// (qui traitent les raccourcis <docXX> referencant les docs)
833
-
834
-	if (
835
-		isset($p->descr['documents'])
836
-		and
837
-		$p->descr['documents']
838
-		and (
839
-			(strpos($ps, 'propre') !== false)
840
-			or
841
-			(strpos($ps, 'typo') !== false)
842
-		)
843
-	) {
844
-		$ps = 'traiter_doublons_documents($doublons, ' . $ps . ')';
845
-	}
846
-
847
-	// La protection des champs par |safehtml est assuree par les extensions
848
-	// dans la declaration des traitements des champs sensibles
849
-
850
-	// Remplacer enfin le placeholder %s par le vrai code de la balise
851
-	return str_replace('%s', $p->code, $ps);
774
+    if (isset($GLOBALS['table_des_traitements'][$p->nom_champ])) {
775
+        $ps = $GLOBALS['table_des_traitements'][$p->nom_champ];
776
+    } else {
777
+        // quand on utilise un traitement catch-all *
778
+        // celui-ci ne s'applique pas sur les balises calculees qui peuvent gerer
779
+        // leur propre securite
780
+        if (!$p->balise_calculee) {
781
+            $ps = $GLOBALS['table_des_traitements']['*'];
782
+        } else {
783
+            $ps = false;
784
+        }
785
+    }
786
+
787
+    if (is_array($ps)) {
788
+        // Recuperer le type de boucle (articles, DATA) et la table SQL sur laquelle elle porte
789
+        $idb = index_boucle($p);
790
+        // si le champ a ete trouve dans une boucle parente sa source est renseignee ici
791
+        if (!empty($p->boucles[$idb]->index_champ[$p->nom_champ])) {
792
+            $idb = $p->boucles[$idb]->index_champ[$p->nom_champ];
793
+        }
794
+
795
+        // mais on peut aussi etre hors boucle. Se mefier.
796
+        $type_requete = $p->boucles[$idb]->type_requete ?? false;
797
+        $table_sql = $p->boucles[$idb]->show['table_sql'] ?? false;
798
+
799
+        // bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.)
800
+        if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) {
801
+            $type_alias = $type_requete;
802
+            $type_requete = $GLOBALS['table_des_tables'][$type_requete];
803
+        } else {
804
+            $type_alias = false;
805
+        }
806
+
807
+        // le traitement peut n'etre defini que pour une table en particulier "spip_articles"
808
+        if ($table_sql and isset($ps[$table_sql])) {
809
+            $ps = $ps[$table_sql];
810
+        } // ou pour une boucle en particulier "DATA","articles"
811
+        elseif ($type_requete and isset($ps[$type_requete])) {
812
+            $ps = $ps[$type_requete];
813
+        } // ou pour une boucle utilisant un alias ("hierarchie")
814
+        elseif ($type_alias and isset($ps[$type_alias])) {
815
+            $ps = $ps[$type_alias];
816
+        } // ou pour indifféremment quelle que soit la boucle
817
+        elseif (isset($ps[0])) {
818
+            $ps = $ps[0];
819
+        } else {
820
+            $ps = false;
821
+        }
822
+    }
823
+
824
+    if (!$ps) {
825
+        return $p->code;
826
+    }
827
+
828
+    // Si une boucle DOCUMENTS{doublons} est presente dans le squelette,
829
+    // ou si in INCLURE contient {doublons}
830
+    // on insere une fonction de remplissage du tableau des doublons
831
+    // dans les filtres propre() ou typo()
832
+    // (qui traitent les raccourcis <docXX> referencant les docs)
833
+
834
+    if (
835
+        isset($p->descr['documents'])
836
+        and
837
+        $p->descr['documents']
838
+        and (
839
+            (strpos($ps, 'propre') !== false)
840
+            or
841
+            (strpos($ps, 'typo') !== false)
842
+        )
843
+    ) {
844
+        $ps = 'traiter_doublons_documents($doublons, ' . $ps . ')';
845
+    }
846
+
847
+    // La protection des champs par |safehtml est assuree par les extensions
848
+    // dans la declaration des traitements des champs sensibles
849
+
850
+    // Remplacer enfin le placeholder %s par le vrai code de la balise
851
+    return str_replace('%s', $p->code, $ps);
852 852
 }
853 853
 
854 854
 
@@ -860,110 +860,110 @@  discard block
 block discarded – undo
860 860
 //
861 861
 function applique_filtres($p) {
862 862
 
863
-	// Traitements standards (cf. supra)
864
-	if ($p->etoile == '') {
865
-		$code = champs_traitements($p);
866
-	} else {
867
-		$code = $p->code;
868
-	}
863
+    // Traitements standards (cf. supra)
864
+    if ($p->etoile == '') {
865
+        $code = champs_traitements($p);
866
+    } else {
867
+        $code = $p->code;
868
+    }
869 869
 
870
-	// Appliquer les filtres perso
871
-	if ($p->param) {
872
-		$code = compose_filtres($p, $code);
873
-	}
870
+    // Appliquer les filtres perso
871
+    if ($p->param) {
872
+        $code = compose_filtres($p, $code);
873
+    }
874 874
 
875
-	// S'il y a un lien avec la session, ajouter un code qui levera
876
-	// un drapeau dans la structure d'invalidation $Cache
877
-	if (isset($p->descr['session'])) {
878
-		$code = "invalideur_session(\$Cache, $code)";
879
-	}
875
+    // S'il y a un lien avec la session, ajouter un code qui levera
876
+    // un drapeau dans la structure d'invalidation $Cache
877
+    if (isset($p->descr['session'])) {
878
+        $code = "invalideur_session(\$Cache, $code)";
879
+    }
880 880
 
881
-	$code = sandbox_composer_interdire_scripts($code, $p);
881
+    $code = sandbox_composer_interdire_scripts($code, $p);
882 882
 
883
-	return $code;
883
+    return $code;
884 884
 }
885 885
 
886 886
 // Cf. function pipeline dans ecrire/inc_utils.php
887 887
 function compose_filtres(&$p, $code) {
888 888
 
889
-	$image_miette = false;
890
-	foreach ($p->param as $filtre) {
891
-		$fonc = array_shift($filtre);
892
-		if (!$fonc) {
893
-			continue;
894
-		} // normalement qu'au premier tour.
895
-		$is_filtre_image = ((substr($fonc, 0, 6) == 'image_') and $fonc != 'image_graver');
896
-		if ($image_miette and !$is_filtre_image) {
897
-			// il faut graver maintenant car apres le filtre en cours
898
-			// on est pas sur d'avoir encore le nom du fichier dans le pipe
899
-			$code = "filtrer('image_graver', $code)";
900
-			$image_miette = false;
901
-		}
902
-
903
-		// recuperer les arguments du filtre,
904
-		// a separer par "," ou ":" dans le cas du filtre "?{a,b}"
905
-		$countfiltre = is_countable($filtre) ? count($filtre) : 0;
906
-		if ($fonc !== '?') {
907
-			$sep = ',';
908
-		} else {
909
-			$sep = ':';
910
-			// |?{a,b} *doit* avoir exactement 2 arguments ; on les force
911
-			if ($countfiltre != 2) {
912
-				$filtre = [$filtre[0] ?? '', $filtre[1] ?? ''];
913
-				$countfiltre = 2;
914
-			}
915
-		}
916
-		$arglist = compose_filtres_args($p, $filtre, $sep);
917
-		$logique = filtre_logique($fonc, $code, substr($arglist, 1));
918
-		if ($logique) {
919
-			$code = $logique;
920
-		} else {
921
-			$code = sandbox_composer_filtre($fonc, $code, $arglist, $p, $countfiltre);
922
-			if ($is_filtre_image) {
923
-				$image_miette = true;
924
-			}
925
-		}
926
-	}
927
-	// ramasser les images intermediaires inutiles et graver l'image finale
928
-	if ($image_miette) {
929
-		$code = "filtrer('image_graver',$code)";
930
-	}
931
-
932
-	return $code;
889
+    $image_miette = false;
890
+    foreach ($p->param as $filtre) {
891
+        $fonc = array_shift($filtre);
892
+        if (!$fonc) {
893
+            continue;
894
+        } // normalement qu'au premier tour.
895
+        $is_filtre_image = ((substr($fonc, 0, 6) == 'image_') and $fonc != 'image_graver');
896
+        if ($image_miette and !$is_filtre_image) {
897
+            // il faut graver maintenant car apres le filtre en cours
898
+            // on est pas sur d'avoir encore le nom du fichier dans le pipe
899
+            $code = "filtrer('image_graver', $code)";
900
+            $image_miette = false;
901
+        }
902
+
903
+        // recuperer les arguments du filtre,
904
+        // a separer par "," ou ":" dans le cas du filtre "?{a,b}"
905
+        $countfiltre = is_countable($filtre) ? count($filtre) : 0;
906
+        if ($fonc !== '?') {
907
+            $sep = ',';
908
+        } else {
909
+            $sep = ':';
910
+            // |?{a,b} *doit* avoir exactement 2 arguments ; on les force
911
+            if ($countfiltre != 2) {
912
+                $filtre = [$filtre[0] ?? '', $filtre[1] ?? ''];
913
+                $countfiltre = 2;
914
+            }
915
+        }
916
+        $arglist = compose_filtres_args($p, $filtre, $sep);
917
+        $logique = filtre_logique($fonc, $code, substr($arglist, 1));
918
+        if ($logique) {
919
+            $code = $logique;
920
+        } else {
921
+            $code = sandbox_composer_filtre($fonc, $code, $arglist, $p, $countfiltre);
922
+            if ($is_filtre_image) {
923
+                $image_miette = true;
924
+            }
925
+        }
926
+    }
927
+    // ramasser les images intermediaires inutiles et graver l'image finale
928
+    if ($image_miette) {
929
+        $code = "filtrer('image_graver',$code)";
930
+    }
931
+
932
+    return $code;
933 933
 }
934 934
 
935 935
 // Filtres et,ou,oui,non,sinon,xou,xor,and,or,not,yes
936 936
 // et comparateurs
937 937
 function filtre_logique($fonc, $code, $arg) {
938 938
 
939
-	switch (true) {
940
-		case in_array($fonc, $GLOBALS['table_criteres_infixes']):
941
-			return "($code $fonc $arg)";
942
-		case ($fonc == 'and') or ($fonc == 'et'):
943
-			return "((($code) AND ($arg)) ?' ' :'')";
944
-		case ($fonc == 'or') or ($fonc == 'ou'):
945
-			return "((($code) OR ($arg)) ?' ' :'')";
946
-		case ($fonc == 'xor') or ($fonc == 'xou'):
947
-			return "((($code) XOR ($arg)) ?' ' :'')";
948
-		case ($fonc == 'sinon'):
949
-			return "(((\$a = $code) OR (is_string(\$a) AND strlen(\$a))) ? \$a : $arg)";
950
-		case ($fonc == 'not') or ($fonc == 'non'):
951
-			return "(($code) ?'' :' ')";
952
-		case ($fonc == 'yes') or ($fonc == 'oui'):
953
-			return "(($code) ?' ' :'')";
954
-	}
955
-
956
-	return '';
939
+    switch (true) {
940
+        case in_array($fonc, $GLOBALS['table_criteres_infixes']):
941
+            return "($code $fonc $arg)";
942
+        case ($fonc == 'and') or ($fonc == 'et'):
943
+            return "((($code) AND ($arg)) ?' ' :'')";
944
+        case ($fonc == 'or') or ($fonc == 'ou'):
945
+            return "((($code) OR ($arg)) ?' ' :'')";
946
+        case ($fonc == 'xor') or ($fonc == 'xou'):
947
+            return "((($code) XOR ($arg)) ?' ' :'')";
948
+        case ($fonc == 'sinon'):
949
+            return "(((\$a = $code) OR (is_string(\$a) AND strlen(\$a))) ? \$a : $arg)";
950
+        case ($fonc == 'not') or ($fonc == 'non'):
951
+            return "(($code) ?'' :' ')";
952
+        case ($fonc == 'yes') or ($fonc == 'oui'):
953
+            return "(($code) ?' ' :'')";
954
+    }
955
+
956
+    return '';
957 957
 }
958 958
 
959 959
 function compose_filtres_args($p, $args, $sep) {
960
-	$arglist = '';
961
-	foreach ($args as $arg) {
962
-		$arglist .= $sep .
963
-			calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle);
964
-	}
960
+    $arglist = '';
961
+    foreach ($args as $arg) {
962
+        $arglist .= $sep .
963
+            calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle);
964
+    }
965 965
 
966
-	return $arglist;
966
+    return $arglist;
967 967
 }
968 968
 
969 969
 
@@ -981,15 +981,15 @@  discard block
 block discarded – undo
981 981
  **/
982 982
 function calculer_argument_precedent($idb, $nom_champ, &$boucles, $defaut = null) {
983 983
 
984
-	// si recursif, forcer l'extraction du champ SQL mais ignorer le code
985
-	if ($boucles[$idb]->externe) {
986
-		index_pile($idb, $nom_champ, $boucles, '', $defaut);
987
-		// retourner $Pile[$SP] et pas $Pile[0] si recursion en 1ere boucle
988
-		// on ignore le defaut fourni dans ce cas
989
-		$defaut = "(\$Pile[\$SP]['$nom_champ'] ?? null)";
990
-	}
984
+    // si recursif, forcer l'extraction du champ SQL mais ignorer le code
985
+    if ($boucles[$idb]->externe) {
986
+        index_pile($idb, $nom_champ, $boucles, '', $defaut);
987
+        // retourner $Pile[$SP] et pas $Pile[0] si recursion en 1ere boucle
988
+        // on ignore le defaut fourni dans ce cas
989
+        $defaut = "(\$Pile[\$SP]['$nom_champ'] ?? null)";
990
+    }
991 991
 
992
-	return index_pile($boucles[$idb]->id_parent, $nom_champ, $boucles, '', $defaut);
992
+    return index_pile($boucles[$idb]->id_parent, $nom_champ, $boucles, '', $defaut);
993 993
 }
994 994
 
995 995
 //
@@ -1003,30 +1003,30 @@  discard block
 block discarded – undo
1003 1003
 //
1004 1004
 
1005 1005
 function rindex_pile($p, $champ, $motif) {
1006
-	$n = 0;
1007
-	$b = $p->id_boucle;
1008
-	$p->code = '';
1009
-	while ($b != '') {
1010
-		foreach ($p->boucles[$b]->criteres as $critere) {
1011
-			if ($critere->op == $motif) {
1012
-				$p->code = '$Pile[$SP' . (($n == 0) ? '' : "-$n") .
1013
-					"]['$champ']";
1014
-				$b = '';
1015
-				break 2;
1016
-			}
1017
-		}
1018
-		$n++;
1019
-		$b = $p->boucles[$b]->id_parent;
1020
-	}
1021
-
1022
-	// si on est hors d'une boucle de {recherche}, cette balise est vide
1023
-	if (!$p->code) {
1024
-		$p->code = "''";
1025
-	}
1026
-
1027
-	$p->interdire_scripts = false;
1028
-
1029
-	return $p;
1006
+    $n = 0;
1007
+    $b = $p->id_boucle;
1008
+    $p->code = '';
1009
+    while ($b != '') {
1010
+        foreach ($p->boucles[$b]->criteres as $critere) {
1011
+            if ($critere->op == $motif) {
1012
+                $p->code = '$Pile[$SP' . (($n == 0) ? '' : "-$n") .
1013
+                    "]['$champ']";
1014
+                $b = '';
1015
+                break 2;
1016
+            }
1017
+        }
1018
+        $n++;
1019
+        $b = $p->boucles[$b]->id_parent;
1020
+    }
1021
+
1022
+    // si on est hors d'une boucle de {recherche}, cette balise est vide
1023
+    if (!$p->code) {
1024
+        $p->code = "''";
1025
+    }
1026
+
1027
+    $p->interdire_scripts = false;
1028
+
1029
+    return $p;
1030 1030
 }
1031 1031
 
1032 1032
 /**
@@ -1036,7 +1036,7 @@  discard block
 block discarded – undo
1036 1036
  * @return string Nom de la balise, avec indication de boucle explicite si présent.
1037 1037
  */
1038 1038
 function zbug_presenter_champ($p, $champ = '') {
1039
-	$balise = $champ ?: $p->nom_champ;
1040
-	$explicite = $p->nom_boucle ? $p->nom_boucle . ':' : '';
1041
-	return "#{$explicite}{$balise}";
1039
+    $balise = $champ ?: $p->nom_champ;
1040
+    $explicite = $p->nom_boucle ? $p->nom_boucle . ':' : '';
1041
+    return "#{$explicite}{$balise}";
1042 1042
 }
Please login to merge, or discard this patch.
ecrire/public/interfaces.php 1 patch
Indentation   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  **/
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 
@@ -48,90 +48,90 @@  discard block
 block discarded – undo
48 48
  */
49 49
 function declarer_interfaces() {
50 50
 
51
-	$GLOBALS['table_des_tables']['articles'] = 'articles';
52
-	$GLOBALS['table_des_tables']['auteurs'] = 'auteurs';
53
-	$GLOBALS['table_des_tables']['rubriques'] = 'rubriques';
54
-	$GLOBALS['table_des_tables']['hierarchie'] = 'rubriques';
55
-
56
-	// definition des statuts de publication
57
-	$GLOBALS['table_statut'] = [];
58
-
59
-	//
60
-	// tableau des tables de jointures
61
-	// Ex: gestion du critere {id_mot} dans la boucle(ARTICLES)
62
-	$GLOBALS['tables_jointures'] = [];
63
-	$GLOBALS['tables_jointures']['spip_jobs'][] = 'jobs_liens';
64
-
65
-	// $GLOBALS['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre'); // pour exemple
66
-	$GLOBALS['exceptions_des_jointures']['profondeur'] = ['spip_rubriques', 'profondeur'];
67
-
68
-
69
-	if (!defined('_TRAITEMENT_TYPO')) {
70
-		define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])');
71
-	}
72
-	if (!defined('_TRAITEMENT_RACCOURCIS')) {
73
-		define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])');
74
-	}
75
-	if (!defined('_TRAITEMENT_TYPO_SANS_NUMERO')) {
76
-		define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s, "TYPO", $connect, $Pile[0]))');
77
-	}
78
-	$GLOBALS['table_des_traitements']['BIO'][] = 'safehtml(' . _TRAITEMENT_RACCOURCIS . ')';
79
-	$GLOBALS['table_des_traitements']['NOM_SITE']['auteurs'] = 'entites_html(%s)';
80
-	$GLOBALS['table_des_traitements']['NOM']['auteurs'] = 'safehtml(' . _TRAITEMENT_TYPO_SANS_NUMERO . ')';
81
-	$GLOBALS['table_des_traitements']['CHAPO'][] = _TRAITEMENT_RACCOURCIS;
82
-	$GLOBALS['table_des_traitements']['DATE'][] = 'normaliser_date(%s)';
83
-	$GLOBALS['table_des_traitements']['DATE_REDAC'][] = 'normaliser_date(%s)';
84
-	$GLOBALS['table_des_traitements']['DATE_MODIF'][] = 'normaliser_date(%s)';
85
-	$GLOBALS['table_des_traitements']['DATE_NOUVEAUTES'][] = 'normaliser_date(%s)';
86
-	$GLOBALS['table_des_traitements']['DESCRIPTIF'][] = _TRAITEMENT_RACCOURCIS;
87
-	$GLOBALS['table_des_traitements']['INTRODUCTION'][] = _TRAITEMENT_RACCOURCIS;
88
-	$GLOBALS['table_des_traitements']['NOM_SITE_SPIP'][] = _TRAITEMENT_TYPO;
89
-	$GLOBALS['table_des_traitements']['NOM'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
90
-	$GLOBALS['table_des_traitements']['AUTEUR'][] = _TRAITEMENT_TYPO;
91
-	$GLOBALS['table_des_traitements']['PS'][] = _TRAITEMENT_RACCOURCIS;
92
-	$GLOBALS['table_des_traitements']['SOURCE'][] = _TRAITEMENT_TYPO;
93
-	$GLOBALS['table_des_traitements']['SOUSTITRE'][] = _TRAITEMENT_TYPO;
94
-	$GLOBALS['table_des_traitements']['SURTITRE'][] = _TRAITEMENT_TYPO;
95
-	$GLOBALS['table_des_traitements']['TAGS'][] = '%s';
96
-	$GLOBALS['table_des_traitements']['TEXTE'][] = _TRAITEMENT_RACCOURCIS;
97
-	$GLOBALS['table_des_traitements']['TITRE'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
98
-	$GLOBALS['table_des_traitements']['TYPE'][] = _TRAITEMENT_TYPO;
99
-	$GLOBALS['table_des_traitements']['DESCRIPTIF_SITE_SPIP'][] = _TRAITEMENT_RACCOURCIS;
100
-	$GLOBALS['table_des_traitements']['SLOGAN_SITE_SPIP'][] = _TRAITEMENT_TYPO;
101
-	$GLOBALS['table_des_traitements']['ENV'][] = 'entites_html(%s,true)';
102
-
103
-	// valeur par defaut pour les balises non listees ci-dessus
104
-	$GLOBALS['table_des_traitements']['*'][] = false; // pas de traitement, mais permet au compilo de trouver la declaration suivante
105
-	// toujours securiser les DATA
106
-	$GLOBALS['table_des_traitements']['*']['DATA'] = 'safehtml(%s)';
107
-	// expliciter pour VALEUR qui est un champ calcule et ne sera pas protege par le catch-all *
108
-	$GLOBALS['table_des_traitements']['VALEUR']['DATA'] = 'safehtml(%s)';
109
-
110
-
111
-	// gerer l'affectation en 2 temps car si le pipe n'est pas encore declare, on ecrase les globales
112
-	$interfaces = pipeline(
113
-		'declarer_tables_interfaces',
114
-		[
115
-			'table_des_tables' => $GLOBALS['table_des_tables'],
116
-			'exceptions_des_tables' => $GLOBALS['exceptions_des_tables'],
117
-			'table_date' => $GLOBALS['table_date'],
118
-			'table_titre' => $GLOBALS['table_titre'],
119
-			'tables_jointures' => $GLOBALS['tables_jointures'],
120
-			'exceptions_des_jointures' => $GLOBALS['exceptions_des_jointures'],
121
-			'table_des_traitements' => $GLOBALS['table_des_traitements'],
122
-			'table_statut' => $GLOBALS['table_statut'],
123
-		]
124
-	);
125
-	if ($interfaces) {
126
-		$GLOBALS['table_des_tables'] = $interfaces['table_des_tables'];
127
-		$GLOBALS['exceptions_des_tables'] = $interfaces['exceptions_des_tables'];
128
-		$GLOBALS['table_date'] = $interfaces['table_date'];
129
-		$GLOBALS['table_titre'] = $interfaces['table_titre'];
130
-		$GLOBALS['tables_jointures'] = $interfaces['tables_jointures'];
131
-		$GLOBALS['exceptions_des_jointures'] = $interfaces['exceptions_des_jointures'];
132
-		$GLOBALS['table_des_traitements'] = $interfaces['table_des_traitements'];
133
-		$GLOBALS['table_statut'] = $interfaces['table_statut'];
134
-	}
51
+    $GLOBALS['table_des_tables']['articles'] = 'articles';
52
+    $GLOBALS['table_des_tables']['auteurs'] = 'auteurs';
53
+    $GLOBALS['table_des_tables']['rubriques'] = 'rubriques';
54
+    $GLOBALS['table_des_tables']['hierarchie'] = 'rubriques';
55
+
56
+    // definition des statuts de publication
57
+    $GLOBALS['table_statut'] = [];
58
+
59
+    //
60
+    // tableau des tables de jointures
61
+    // Ex: gestion du critere {id_mot} dans la boucle(ARTICLES)
62
+    $GLOBALS['tables_jointures'] = [];
63
+    $GLOBALS['tables_jointures']['spip_jobs'][] = 'jobs_liens';
64
+
65
+    // $GLOBALS['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre'); // pour exemple
66
+    $GLOBALS['exceptions_des_jointures']['profondeur'] = ['spip_rubriques', 'profondeur'];
67
+
68
+
69
+    if (!defined('_TRAITEMENT_TYPO')) {
70
+        define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect, $Pile[0])');
71
+    }
72
+    if (!defined('_TRAITEMENT_RACCOURCIS')) {
73
+        define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect, $Pile[0])');
74
+    }
75
+    if (!defined('_TRAITEMENT_TYPO_SANS_NUMERO')) {
76
+        define('_TRAITEMENT_TYPO_SANS_NUMERO', 'supprimer_numero(typo(%s, "TYPO", $connect, $Pile[0]))');
77
+    }
78
+    $GLOBALS['table_des_traitements']['BIO'][] = 'safehtml(' . _TRAITEMENT_RACCOURCIS . ')';
79
+    $GLOBALS['table_des_traitements']['NOM_SITE']['auteurs'] = 'entites_html(%s)';
80
+    $GLOBALS['table_des_traitements']['NOM']['auteurs'] = 'safehtml(' . _TRAITEMENT_TYPO_SANS_NUMERO . ')';
81
+    $GLOBALS['table_des_traitements']['CHAPO'][] = _TRAITEMENT_RACCOURCIS;
82
+    $GLOBALS['table_des_traitements']['DATE'][] = 'normaliser_date(%s)';
83
+    $GLOBALS['table_des_traitements']['DATE_REDAC'][] = 'normaliser_date(%s)';
84
+    $GLOBALS['table_des_traitements']['DATE_MODIF'][] = 'normaliser_date(%s)';
85
+    $GLOBALS['table_des_traitements']['DATE_NOUVEAUTES'][] = 'normaliser_date(%s)';
86
+    $GLOBALS['table_des_traitements']['DESCRIPTIF'][] = _TRAITEMENT_RACCOURCIS;
87
+    $GLOBALS['table_des_traitements']['INTRODUCTION'][] = _TRAITEMENT_RACCOURCIS;
88
+    $GLOBALS['table_des_traitements']['NOM_SITE_SPIP'][] = _TRAITEMENT_TYPO;
89
+    $GLOBALS['table_des_traitements']['NOM'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
90
+    $GLOBALS['table_des_traitements']['AUTEUR'][] = _TRAITEMENT_TYPO;
91
+    $GLOBALS['table_des_traitements']['PS'][] = _TRAITEMENT_RACCOURCIS;
92
+    $GLOBALS['table_des_traitements']['SOURCE'][] = _TRAITEMENT_TYPO;
93
+    $GLOBALS['table_des_traitements']['SOUSTITRE'][] = _TRAITEMENT_TYPO;
94
+    $GLOBALS['table_des_traitements']['SURTITRE'][] = _TRAITEMENT_TYPO;
95
+    $GLOBALS['table_des_traitements']['TAGS'][] = '%s';
96
+    $GLOBALS['table_des_traitements']['TEXTE'][] = _TRAITEMENT_RACCOURCIS;
97
+    $GLOBALS['table_des_traitements']['TITRE'][] = _TRAITEMENT_TYPO_SANS_NUMERO;
98
+    $GLOBALS['table_des_traitements']['TYPE'][] = _TRAITEMENT_TYPO;
99
+    $GLOBALS['table_des_traitements']['DESCRIPTIF_SITE_SPIP'][] = _TRAITEMENT_RACCOURCIS;
100
+    $GLOBALS['table_des_traitements']['SLOGAN_SITE_SPIP'][] = _TRAITEMENT_TYPO;
101
+    $GLOBALS['table_des_traitements']['ENV'][] = 'entites_html(%s,true)';
102
+
103
+    // valeur par defaut pour les balises non listees ci-dessus
104
+    $GLOBALS['table_des_traitements']['*'][] = false; // pas de traitement, mais permet au compilo de trouver la declaration suivante
105
+    // toujours securiser les DATA
106
+    $GLOBALS['table_des_traitements']['*']['DATA'] = 'safehtml(%s)';
107
+    // expliciter pour VALEUR qui est un champ calcule et ne sera pas protege par le catch-all *
108
+    $GLOBALS['table_des_traitements']['VALEUR']['DATA'] = 'safehtml(%s)';
109
+
110
+
111
+    // gerer l'affectation en 2 temps car si le pipe n'est pas encore declare, on ecrase les globales
112
+    $interfaces = pipeline(
113
+        'declarer_tables_interfaces',
114
+        [
115
+            'table_des_tables' => $GLOBALS['table_des_tables'],
116
+            'exceptions_des_tables' => $GLOBALS['exceptions_des_tables'],
117
+            'table_date' => $GLOBALS['table_date'],
118
+            'table_titre' => $GLOBALS['table_titre'],
119
+            'tables_jointures' => $GLOBALS['tables_jointures'],
120
+            'exceptions_des_jointures' => $GLOBALS['exceptions_des_jointures'],
121
+            'table_des_traitements' => $GLOBALS['table_des_traitements'],
122
+            'table_statut' => $GLOBALS['table_statut'],
123
+        ]
124
+    );
125
+    if ($interfaces) {
126
+        $GLOBALS['table_des_tables'] = $interfaces['table_des_tables'];
127
+        $GLOBALS['exceptions_des_tables'] = $interfaces['exceptions_des_tables'];
128
+        $GLOBALS['table_date'] = $interfaces['table_date'];
129
+        $GLOBALS['table_titre'] = $interfaces['table_titre'];
130
+        $GLOBALS['tables_jointures'] = $interfaces['tables_jointures'];
131
+        $GLOBALS['exceptions_des_jointures'] = $interfaces['exceptions_des_jointures'];
132
+        $GLOBALS['table_des_traitements'] = $interfaces['table_des_traitements'];
133
+        $GLOBALS['table_statut'] = $interfaces['table_statut'];
134
+    }
135 135
 }
136 136
 
137 137
 declarer_interfaces();
Please login to merge, or discard this patch.
ecrire/public/composer.php 1 patch
Indentation   +768 added lines, -768 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  **/
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 include_spip('inc/texte');
@@ -41,234 +41,234 @@  discard block
 block discarded – undo
41 41
 
42 42
 function public_composer_dist($squelette, $mime_type, $gram, $source, string $connect = '') {
43 43
 
44
-	$skel = null;
45
-	$boucle = null;
46
-	$nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
47
-
48
-	//  si deja en memoire (INCLURE  a repetition) c'est bon.
49
-	if (function_exists($nom)) {
50
-		return $nom;
51
-	}
52
-
53
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
54
-		$GLOBALS['debug_objets']['courant'] = $nom;
55
-	}
56
-
57
-	$phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
58
-
59
-	// si squelette est deja compile et perenne, le charger
60
-	if (!squelette_obsolete($phpfile, $source)) {
61
-		include_once $phpfile;
62
-		#if (!squelette_obsolete($phpfile, $source)
63
-		#  AND lire_fichier ($phpfile, $skel_code,
64
-		#  array('critique' => 'oui', 'phpcheck' => 'oui'))){
65
-		## eval('?'.'>'.$skel_code);
66
-		#	 spip_log($skel_code, 'comp')
67
-		#}
68
-	}
69
-
70
-	if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
71
-		include_once $lib;
72
-	}
73
-
74
-	// tester si le eval ci-dessus a mis le squelette en memoire
75
-
76
-	if (function_exists($nom)) {
77
-		return $nom;
78
-	}
79
-
80
-	// charger le source, si possible, et compiler
81
-	$skel_code = '';
82
-	if (lire_fichier($source, $skel)) {
83
-		$compiler = charger_fonction('compiler', 'public');
84
-		$skel_code = $compiler($skel, $nom, $gram, $source, $connect);
85
-	}
86
-
87
-	// Ne plus rien faire si le compilateur n'a pas pu operer.
88
-	if (!$skel_code) {
89
-		return false;
90
-	}
91
-
92
-	foreach ($skel_code as $id => $boucle) {
93
-		$f = $boucle->return;
94
-		try {
95
-			eval("return true; $f ;");
96
-		} catch (\ParseError $e) {
97
-			// Code syntaxiquement faux (critere etc mal programme')
98
-			$msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
99
-			erreur_squelette($msg, $boucle);
100
-			// continuer pour trouver d'autres fautes eventuelles
101
-			// mais prevenir que c'est mort
102
-			$nom = '';
103
-		}
104
-
105
-		// contexte de compil inutile a present
106
-		// (mais la derniere valeur de $boucle est utilisee ci-dessous)
107
-		$skel_code[$id] = $f;
108
-	}
109
-
110
-	$code = '';
111
-	if ($nom) {
112
-		// Si le code est bon, concatener et mettre en cache
113
-		if (function_exists($nom)) {
114
-			$code = squelette_traduit($skel, $source, $phpfile, $skel_code);
115
-		} else {
116
-			// code semantiquement faux: bug du compilateur
117
-			// $boucle est en fait ici la fct principale du squelette
118
-			$msg = _T('zbug_erreur_compilation');
119
-			erreur_squelette($msg, $boucle);
120
-			$nom = '';
121
-		}
122
-	}
123
-
124
-	if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
125
-		// Tracer ce qui vient d'etre compile
126
-		$GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
127
-
128
-		// si c'est ce que demande le debusqueur, lui passer la main
129
-		if (
130
-			$GLOBALS['debug_objets']['sourcefile']
131
-			and (_request('var_mode_objet') == $nom)
132
-			and (_request('var_mode_affiche') == 'code')
133
-		) {
134
-			erreur_squelette();
135
-		}
136
-	}
137
-
138
-	return $nom ?: false;
44
+    $skel = null;
45
+    $boucle = null;
46
+    $nom = calculer_nom_fonction_squel($squelette, $mime_type, $connect);
47
+
48
+    //  si deja en memoire (INCLURE  a repetition) c'est bon.
49
+    if (function_exists($nom)) {
50
+        return $nom;
51
+    }
52
+
53
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
54
+        $GLOBALS['debug_objets']['courant'] = $nom;
55
+    }
56
+
57
+    $phpfile = sous_repertoire(_DIR_SKELS, '', false, true) . $nom . '.php';
58
+
59
+    // si squelette est deja compile et perenne, le charger
60
+    if (!squelette_obsolete($phpfile, $source)) {
61
+        include_once $phpfile;
62
+        #if (!squelette_obsolete($phpfile, $source)
63
+        #  AND lire_fichier ($phpfile, $skel_code,
64
+        #  array('critique' => 'oui', 'phpcheck' => 'oui'))){
65
+        ## eval('?'.'>'.$skel_code);
66
+        #	 spip_log($skel_code, 'comp')
67
+        #}
68
+    }
69
+
70
+    if (file_exists($lib = $squelette . '_fonctions' . '.php')) {
71
+        include_once $lib;
72
+    }
73
+
74
+    // tester si le eval ci-dessus a mis le squelette en memoire
75
+
76
+    if (function_exists($nom)) {
77
+        return $nom;
78
+    }
79
+
80
+    // charger le source, si possible, et compiler
81
+    $skel_code = '';
82
+    if (lire_fichier($source, $skel)) {
83
+        $compiler = charger_fonction('compiler', 'public');
84
+        $skel_code = $compiler($skel, $nom, $gram, $source, $connect);
85
+    }
86
+
87
+    // Ne plus rien faire si le compilateur n'a pas pu operer.
88
+    if (!$skel_code) {
89
+        return false;
90
+    }
91
+
92
+    foreach ($skel_code as $id => $boucle) {
93
+        $f = $boucle->return;
94
+        try {
95
+            eval("return true; $f ;");
96
+        } catch (\ParseError $e) {
97
+            // Code syntaxiquement faux (critere etc mal programme')
98
+            $msg = _T('zbug_erreur_compilation') . ' | Line ' . $e->getLine() . ' : ' . $e->getMessage();
99
+            erreur_squelette($msg, $boucle);
100
+            // continuer pour trouver d'autres fautes eventuelles
101
+            // mais prevenir que c'est mort
102
+            $nom = '';
103
+        }
104
+
105
+        // contexte de compil inutile a present
106
+        // (mais la derniere valeur de $boucle est utilisee ci-dessous)
107
+        $skel_code[$id] = $f;
108
+    }
109
+
110
+    $code = '';
111
+    if ($nom) {
112
+        // Si le code est bon, concatener et mettre en cache
113
+        if (function_exists($nom)) {
114
+            $code = squelette_traduit($skel, $source, $phpfile, $skel_code);
115
+        } else {
116
+            // code semantiquement faux: bug du compilateur
117
+            // $boucle est en fait ici la fct principale du squelette
118
+            $msg = _T('zbug_erreur_compilation');
119
+            erreur_squelette($msg, $boucle);
120
+            $nom = '';
121
+        }
122
+    }
123
+
124
+    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
125
+        // Tracer ce qui vient d'etre compile
126
+        $GLOBALS['debug_objets']['code'][$nom . 'tout'] = $code;
127
+
128
+        // si c'est ce que demande le debusqueur, lui passer la main
129
+        if (
130
+            $GLOBALS['debug_objets']['sourcefile']
131
+            and (_request('var_mode_objet') == $nom)
132
+            and (_request('var_mode_affiche') == 'code')
133
+        ) {
134
+            erreur_squelette();
135
+        }
136
+    }
137
+
138
+    return $nom ?: false;
139 139
 }
140 140
 
141 141
 function squelette_traduit($squelette, $sourcefile, $phpfile, $boucles) {
142 142
 
143
-	$code = null;
144
-	// Le dernier index est '' (fonction principale)
145
-	$noms = substr(join(', ', array_keys($boucles)), 0, -2);
146
-	if (CODE_COMMENTE) {
147
-		$code = "
143
+    $code = null;
144
+    // Le dernier index est '' (fonction principale)
145
+    $noms = substr(join(', ', array_keys($boucles)), 0, -2);
146
+    if (CODE_COMMENTE) {
147
+        $code = "
148 148
 /*
149 149
  * Squelette : $sourcefile
150 150
  * Date :      " . gmdate('D, d M Y H:i:s', @filemtime($sourcefile)) . ' GMT
151 151
  * Compile :   ' . gmdate('D, d M Y H:i:s', time()) . ' GMT
152 152
  * ' . (!$boucles ? 'Pas de boucle' : ('Boucles :   ' . $noms)) . '
153 153
  */ ';
154
-	}
154
+    }
155 155
 
156
-	$code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
157
-	if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
158
-		ecrire_fichier($phpfile, $code);
159
-	}
156
+    $code = '<' . "?php\n" . $code . join('', $boucles) . "\n";
157
+    if (!defined('_VAR_NOCACHE') or !_VAR_NOCACHE) {
158
+        ecrire_fichier($phpfile, $code);
159
+    }
160 160
 
161
-	return $code;
161
+    return $code;
162 162
 }
163 163
 
164 164
 // Le squelette compile est-il trop vieux ?
165 165
 function squelette_obsolete($skel, $squelette) {
166
-	static $date_change = null;
167
-	// ne verifier la date de mes_fonctions et mes_options qu'une seule fois
168
-	// par hit
169
-	if (is_null($date_change)) {
170
-		if (@file_exists($fonc = 'mes_fonctions.php')) {
171
-			$date_change = @filemtime($fonc);
172
-		} # compatibilite
173
-		if (defined('_FILE_OPTIONS')) {
174
-			$date_change = max($date_change, @filemtime(_FILE_OPTIONS));
175
-		}
176
-	}
177
-
178
-	return (
179
-		(defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug']))
180
-		or !@file_exists($skel)
181
-		or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
182
-			> ($date = @filemtime($skel)))
183
-		or ($date_change > $date)
184
-	);
166
+    static $date_change = null;
167
+    // ne verifier la date de mes_fonctions et mes_options qu'une seule fois
168
+    // par hit
169
+    if (is_null($date_change)) {
170
+        if (@file_exists($fonc = 'mes_fonctions.php')) {
171
+            $date_change = @filemtime($fonc);
172
+        } # compatibilite
173
+        if (defined('_FILE_OPTIONS')) {
174
+            $date_change = max($date_change, @filemtime(_FILE_OPTIONS));
175
+        }
176
+    }
177
+
178
+    return (
179
+        (defined('_VAR_MODE') and in_array(_VAR_MODE, ['recalcul', 'preview', 'debug']))
180
+        or !@file_exists($skel)
181
+        or ((@file_exists($squelette) ? @filemtime($squelette) : 0)
182
+            > ($date = @filemtime($skel)))
183
+        or ($date_change > $date)
184
+    );
185 185
 }
186 186
 
187 187
 // Activer l'invalideur de session
188 188
 function invalideur_session(&$Cache, $code = null) {
189
-	$Cache['session'] = spip_session();
189
+    $Cache['session'] = spip_session();
190 190
 
191
-	return $code;
191
+    return $code;
192 192
 }
193 193
 
194 194
 
195 195
 function analyse_resultat_skel($nom, $cache, $corps, $source = '') {
196
-	static $filtres = [];
197
-	$headers = [];
198
-	$corps ??= '';
199
-
200
-	// Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
201
-	// note: on essaie d'attrapper aussi certains de ces entetes codes
202
-	// "a la main" dans les squelettes, mais evidemment sans exhaustivite
203
-	if (
204
-		stripos($corps, 'header') !== false
205
-		and preg_match_all(
206
-			'/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
207
-			$corps,
208
-			$regs,
209
-			PREG_SET_ORDER
210
-		)
211
-	) {
212
-		foreach ($regs as $r) {
213
-			$corps = str_replace($r[0], '', $corps);
214
-			# $j = Content-Type, et pas content-TYPE.
215
-			$j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
216
-
217
-			if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
218
-				$headers[$j] .= '|' . $r[3];
219
-			} else {
220
-				$headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
221
-			}
222
-		}
223
-	}
224
-	// S'agit-il d'un resultat constant ou contenant du code php
225
-	$process_ins = (
226
-		strpos($corps, '<' . '?') === false
227
-		or
228
-		(strpos($corps, '<' . '?xml') !== false and
229
-			strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
230
-	)
231
-		? 'html'
232
-		: 'php';
233
-
234
-	$skel = [
235
-		'squelette' => $nom,
236
-		'source' => $source,
237
-		'process_ins' => $process_ins,
238
-		'invalideurs' => $cache,
239
-		'entetes' => $headers,
240
-		'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
241
-	];
242
-
243
-	// traiter #FILTRE{} et filtres
244
-	if (!isset($filtres[$nom])) {
245
-		$filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
246
-	}
247
-	$filtres_headers = [];
248
-	if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
249
-		$filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
250
-		unset($headers['X-Spip-Filtre']);
251
-	}
252
-	if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) {
253
-		include_spip('public/sandbox');
254
-		$corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
255
-
256
-		if ($process_ins == 'html') {
257
-			$skel['process_ins'] = (
258
-				strpos($corps, '<' . '?') === false
259
-				or
260
-				(strpos($corps, '<' . '?xml') !== false and
261
-					strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
262
-			)
263
-				? 'html'
264
-				: 'php';
265
-		}
266
-	}
267
-
268
-	$skel['entetes'] = $headers;
269
-	$skel['texte'] = $corps;
270
-
271
-	return $skel;
196
+    static $filtres = [];
197
+    $headers = [];
198
+    $corps ??= '';
199
+
200
+    // Recupere les < ?php header('Xx: y'); ? > pour $page['headers']
201
+    // note: on essaie d'attrapper aussi certains de ces entetes codes
202
+    // "a la main" dans les squelettes, mais evidemment sans exhaustivite
203
+    if (
204
+        stripos($corps, 'header') !== false
205
+        and preg_match_all(
206
+            '/(<[?]php\s+)@?header\s*\(\s*.([^:\'"]*):?\s*([^)]*)[^)]\s*\)\s*[;]?\s*[?]>/ims',
207
+            $corps,
208
+            $regs,
209
+            PREG_SET_ORDER
210
+        )
211
+    ) {
212
+        foreach ($regs as $r) {
213
+            $corps = str_replace($r[0], '', $corps);
214
+            # $j = Content-Type, et pas content-TYPE.
215
+            $j = join('-', array_map('ucwords', explode('-', strtolower($r[2]))));
216
+
217
+            if ($j == 'X-Spip-Filtre' and isset($headers[$j])) {
218
+                $headers[$j] .= '|' . $r[3];
219
+            } else {
220
+                $headers[$j] = str_replace(['\\\\',"\\'",'\\"'], ['\\',"'",'"'], $r[3]);
221
+            }
222
+        }
223
+    }
224
+    // S'agit-il d'un resultat constant ou contenant du code php
225
+    $process_ins = (
226
+        strpos($corps, '<' . '?') === false
227
+        or
228
+        (strpos($corps, '<' . '?xml') !== false and
229
+            strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
230
+    )
231
+        ? 'html'
232
+        : 'php';
233
+
234
+    $skel = [
235
+        'squelette' => $nom,
236
+        'source' => $source,
237
+        'process_ins' => $process_ins,
238
+        'invalideurs' => $cache,
239
+        'entetes' => $headers,
240
+        'duree' => isset($headers['X-Spip-Cache']) ? intval($headers['X-Spip-Cache']) : 0
241
+    ];
242
+
243
+    // traiter #FILTRE{} et filtres
244
+    if (!isset($filtres[$nom])) {
245
+        $filtres[$nom] = pipeline('declarer_filtres_squelettes', ['args' => $skel, 'data' => []]);
246
+    }
247
+    $filtres_headers = [];
248
+    if (isset($headers['X-Spip-Filtre']) and strlen($headers['X-Spip-Filtre'])) {
249
+        $filtres_headers = array_filter(explode('|', $headers['X-Spip-Filtre']));
250
+        unset($headers['X-Spip-Filtre']);
251
+    }
252
+    if (is_array($filtres[$nom]) || $filtres[$nom] instanceof \Countable ? count($filtres[$nom]) : 0 or count($filtres_headers)) {
253
+        include_spip('public/sandbox');
254
+        $corps = sandbox_filtrer_squelette($skel, $corps, $filtres_headers, $filtres[$nom]);
255
+
256
+        if ($process_ins == 'html') {
257
+            $skel['process_ins'] = (
258
+                strpos($corps, '<' . '?') === false
259
+                or
260
+                (strpos($corps, '<' . '?xml') !== false and
261
+                    strpos(str_replace('<' . '?xml', '', $corps), '<' . '?') === false)
262
+            )
263
+                ? 'html'
264
+                : 'php';
265
+        }
266
+    }
267
+
268
+    $skel['entetes'] = $headers;
269
+    $skel['texte'] = $corps;
270
+
271
+    return $skel;
272 272
 }
273 273
 
274 274
 //
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
 inserer_balise_dynamique(balise_%s_dyn(%s), array(%s));
283 283
 if ($lang_select) lang_select();
284 284
 ?'
285
-	. '>');
285
+    . '>');
286 286
 
287 287
 /**
288 288
  * Synthétise une balise dynamique : crée l'appel à l'inclusion
@@ -302,35 +302,35 @@  discard block
 block discarded – undo
302 302
  *     Code PHP pour inclure le squelette de la balise dynamique
303 303
  **/
304 304
 function synthetiser_balise_dynamique($nom, $args, $file, $context_compil) {
305
-	if (
306
-		strncmp($file, '/', 1) !== 0
307
-		// pas de lien symbolique sous Windows
308
-		and !(stristr(PHP_OS, 'WIN') and str_contains($file, ':'))
309
-	) {
310
-		$file = './" . _DIR_RACINE . "' . $file;
311
-	}
312
-
313
-	$lang = $context_compil[4];
314
-	if (preg_match(',\W,', $lang)) {
315
-		$lang = '';
316
-	}
317
-
318
-	$args = array_map('argumenter_squelette', $args);
319
-	if (!empty($context_compil['appel_php_depuis_modele'])) {
320
-		$args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
321
-	}
322
-	$args = join(', ', $args);
323
-
324
-	$r = sprintf(
325
-		CODE_INCLURE_BALISE,
326
-		$file,
327
-		$lang,
328
-		$nom,
329
-		$args,
330
-		join(', ', array_map('_q', $context_compil))
331
-	);
332
-
333
-	return $r;
305
+    if (
306
+        strncmp($file, '/', 1) !== 0
307
+        // pas de lien symbolique sous Windows
308
+        and !(stristr(PHP_OS, 'WIN') and str_contains($file, ':'))
309
+    ) {
310
+        $file = './" . _DIR_RACINE . "' . $file;
311
+    }
312
+
313
+    $lang = $context_compil[4];
314
+    if (preg_match(',\W,', $lang)) {
315
+        $lang = '';
316
+    }
317
+
318
+    $args = array_map('argumenter_squelette', $args);
319
+    if (!empty($context_compil['appel_php_depuis_modele'])) {
320
+        $args[0] = 'arguments_balise_dyn_depuis_modele(' . $args[0] . ')';
321
+    }
322
+    $args = join(', ', $args);
323
+
324
+    $r = sprintf(
325
+        CODE_INCLURE_BALISE,
326
+        $file,
327
+        $lang,
328
+        $nom,
329
+        $args,
330
+        join(', ', array_map('_q', $context_compil))
331
+    );
332
+
333
+    return $r;
334 334
 }
335 335
 
336 336
 /**
@@ -348,18 +348,18 @@  discard block
 block discarded – undo
348 348
  **/
349 349
 function argumenter_squelette($v) {
350 350
 
351
-	if (is_object($v)) {
352
-		return var_export($v, true);
353
-	} elseif (!is_array($v)) {
354
-		return "'" . texte_script((string) $v) . "'";
355
-	} else {
356
-		$out = [];
357
-		foreach ($v as $k => $val) {
358
-			$out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
359
-		}
360
-
361
-		return 'array(' . join(', ', $out) . ')';
362
-	}
351
+    if (is_object($v)) {
352
+        return var_export($v, true);
353
+    } elseif (!is_array($v)) {
354
+        return "'" . texte_script((string) $v) . "'";
355
+    } else {
356
+        $out = [];
357
+        foreach ($v as $k => $val) {
358
+            $out [] = argumenter_squelette($k) . '=>' . argumenter_squelette($val);
359
+        }
360
+
361
+        return 'array(' . join(', ', $out) . ')';
362
+    }
363 363
 }
364 364
 
365 365
 /**
@@ -378,13 +378,13 @@  discard block
 block discarded – undo
378 378
  * @return string
379 379
  */
380 380
 function executer_balise_dynamique_dans_un_modele(...$args) {
381
-	if (test_espace_prive()) {
382
-		return executer_balise_dynamique(...$args);
383
-	}
384
-	else {
385
-		$str_args = base64_encode(serialize($args));
386
-		return "<?" . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?".">\n";
387
-	}
381
+    if (test_espace_prive()) {
382
+        return executer_balise_dynamique(...$args);
383
+    }
384
+    else {
385
+        $str_args = base64_encode(serialize($args));
386
+        return "<?" . "php \$_zargs=unserialize(base64_decode('$str_args'));echo executer_balise_dynamique(...\$_zargs); ?".">\n";
387
+    }
388 388
 }
389 389
 
390 390
 
@@ -415,87 +415,87 @@  discard block
 block discarded – undo
415 415
  *     Code PHP d'exécutant l'inclusion du squelette (ou texte) de la balise dynamique
416 416
  **/
417 417
 function executer_balise_dynamique($nom, $args, $context_compil) {
418
-	/** @var string Nom de la balise à charger (balise demandée ou balise générique) */
419
-	$nom_balise = $nom;
420
-	/** @var string Nom de la balise générique (si utilisée) */
421
-	$nom_balise_generique = '';
422
-
423
-	$appel_php_depuis_modele = false;
424
-	if (
425
-		is_array($context_compil)
426
-		and !is_numeric($context_compil[3])
427
-		and empty($context_compil[0])
428
-		and empty($context_compil[1])
429
-		and empty($context_compil[2])
430
-		and empty($context_compil[3])
431
-	) {
432
-		$appel_php_depuis_modele = true;
433
-	}
434
-
435
-	if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
436
-		// Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
437
-		if ($balise_generique = chercher_balise_generique($nom)) {
438
-			// injecter en premier arg le nom de la balise
439
-			array_unshift($args, $nom);
440
-			$nom_balise_generique = $balise_generique['nom_generique'];
441
-			$fonction_balise = $balise_generique['fonction_generique'];
442
-			$nom_balise = $nom_balise_generique;
443
-		}
444
-		unset($balise_generique);
445
-	}
446
-
447
-	if (!$fonction_balise) {
448
-		$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
449
-		erreur_squelette($msg, $context_compil);
450
-
451
-		return '';
452
-	}
453
-
454
-	// retrouver le fichier qui a déclaré la fonction
455
-	// même si la fonction dynamique est déclarée dans un fichier de fonctions.
456
-	// Attention sous windows, getFileName() retourne un antislash.
457
-	$reflector = new ReflectionFunction($fonction_balise);
458
-	$file = str_replace('\\', '/', $reflector->getFileName());
459
-	if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
460
-		$file = substr($file, strlen(_ROOT_RACINE));
461
-	}
462
-
463
-	// Y a-t-il une fonction de traitement des arguments ?
464
-	$f = 'balise_' . $nom_balise . '_stat';
465
-
466
-	$r = !function_exists($f) ? $args : $f($args, $context_compil);
467
-
468
-	if (!is_array($r)) {
469
-		return $r;
470
-	}
471
-
472
-	// verifier que la fonction dyn est la,
473
-	// sinon se replier sur la generique si elle existe
474
-	if (!function_exists('balise_' . $nom_balise . '_dyn')) {
475
-		if (
476
-			$balise_generique = chercher_balise_generique($nom)
477
-			and $nom_balise_generique = $balise_generique['nom_generique']
478
-			and $file = include_spip('balise/' . strtolower($nom_balise_generique))
479
-			and function_exists('balise_' . $nom_balise_generique . '_dyn')
480
-		) {
481
-			// et lui injecter en premier arg le nom de la balise
482
-			array_unshift($r, $nom);
483
-			$nom_balise = $nom_balise_generique;
484
-			if (!_DIR_RESTREINT) {
485
-				$file = _DIR_RESTREINT_ABS . $file;
486
-			}
487
-		} else {
488
-			$msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
489
-			erreur_squelette($msg, $context_compil);
490
-
491
-			return '';
492
-		}
493
-	}
494
-
495
-	if ($appel_php_depuis_modele) {
496
-		$context_compil['appel_php_depuis_modele'] = true;
497
-	}
498
-	return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
418
+    /** @var string Nom de la balise à charger (balise demandée ou balise générique) */
419
+    $nom_balise = $nom;
420
+    /** @var string Nom de la balise générique (si utilisée) */
421
+    $nom_balise_generique = '';
422
+
423
+    $appel_php_depuis_modele = false;
424
+    if (
425
+        is_array($context_compil)
426
+        and !is_numeric($context_compil[3])
427
+        and empty($context_compil[0])
428
+        and empty($context_compil[1])
429
+        and empty($context_compil[2])
430
+        and empty($context_compil[3])
431
+    ) {
432
+        $appel_php_depuis_modele = true;
433
+    }
434
+
435
+    if (!$fonction_balise = charger_fonction($nom_balise, 'balise', true)) {
436
+        // Calculer un nom générique (ie. 'formulaire_' dans 'formulaire_editer_article')
437
+        if ($balise_generique = chercher_balise_generique($nom)) {
438
+            // injecter en premier arg le nom de la balise
439
+            array_unshift($args, $nom);
440
+            $nom_balise_generique = $balise_generique['nom_generique'];
441
+            $fonction_balise = $balise_generique['fonction_generique'];
442
+            $nom_balise = $nom_balise_generique;
443
+        }
444
+        unset($balise_generique);
445
+    }
446
+
447
+    if (!$fonction_balise) {
448
+        $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
449
+        erreur_squelette($msg, $context_compil);
450
+
451
+        return '';
452
+    }
453
+
454
+    // retrouver le fichier qui a déclaré la fonction
455
+    // même si la fonction dynamique est déclarée dans un fichier de fonctions.
456
+    // Attention sous windows, getFileName() retourne un antislash.
457
+    $reflector = new ReflectionFunction($fonction_balise);
458
+    $file = str_replace('\\', '/', $reflector->getFileName());
459
+    if (strncmp($file, str_replace('\\', '/', _ROOT_RACINE), strlen(_ROOT_RACINE)) === 0) {
460
+        $file = substr($file, strlen(_ROOT_RACINE));
461
+    }
462
+
463
+    // Y a-t-il une fonction de traitement des arguments ?
464
+    $f = 'balise_' . $nom_balise . '_stat';
465
+
466
+    $r = !function_exists($f) ? $args : $f($args, $context_compil);
467
+
468
+    if (!is_array($r)) {
469
+        return $r;
470
+    }
471
+
472
+    // verifier que la fonction dyn est la,
473
+    // sinon se replier sur la generique si elle existe
474
+    if (!function_exists('balise_' . $nom_balise . '_dyn')) {
475
+        if (
476
+            $balise_generique = chercher_balise_generique($nom)
477
+            and $nom_balise_generique = $balise_generique['nom_generique']
478
+            and $file = include_spip('balise/' . strtolower($nom_balise_generique))
479
+            and function_exists('balise_' . $nom_balise_generique . '_dyn')
480
+        ) {
481
+            // et lui injecter en premier arg le nom de la balise
482
+            array_unshift($r, $nom);
483
+            $nom_balise = $nom_balise_generique;
484
+            if (!_DIR_RESTREINT) {
485
+                $file = _DIR_RESTREINT_ABS . $file;
486
+            }
487
+        } else {
488
+            $msg = ['zbug_balise_inexistante', ['from' => 'CVT', 'balise' => $nom]];
489
+            erreur_squelette($msg, $context_compil);
490
+
491
+            return '';
492
+        }
493
+    }
494
+
495
+    if ($appel_php_depuis_modele) {
496
+        $context_compil['appel_php_depuis_modele'] = true;
497
+    }
498
+    return synthetiser_balise_dynamique($nom_balise, $r, $file, $context_compil);
499 499
 }
500 500
 
501 501
 /**
@@ -510,23 +510,23 @@  discard block
 block discarded – undo
510 510
  * @return array|null
511 511
  */
512 512
 function chercher_balise_generique($nom) {
513
-	if (!str_contains($nom, '_')) {
514
-		return null;
515
-	}
516
-	$nom_generique = $nom;
517
-	while (false !== ($p = strrpos($nom_generique, '_'))) {
518
-		$nom_generique = substr($nom_generique, 0, $p + 1);
519
-		$fonction_generique = charger_fonction($nom_generique, 'balise', true);
520
-		if ($fonction_generique) {
521
-			return [
522
-				'nom' => $nom,
523
-				'nom_generique' => $nom_generique,
524
-				'fonction_generique' => $fonction_generique,
525
-			];
526
-		}
527
-		$nom_generique = substr($nom_generique, 0, -1);
528
-	}
529
-	return null;
513
+    if (!str_contains($nom, '_')) {
514
+        return null;
515
+    }
516
+    $nom_generique = $nom;
517
+    while (false !== ($p = strrpos($nom_generique, '_'))) {
518
+        $nom_generique = substr($nom_generique, 0, $p + 1);
519
+        $fonction_generique = charger_fonction($nom_generique, 'balise', true);
520
+        if ($fonction_generique) {
521
+            return [
522
+                'nom' => $nom,
523
+                'nom_generique' => $nom_generique,
524
+                'fonction_generique' => $fonction_generique,
525
+            ];
526
+        }
527
+        $nom_generique = substr($nom_generique, 0, -1);
528
+    }
529
+    return null;
530 530
 }
531 531
 
532 532
 
@@ -550,50 +550,50 @@  discard block
 block discarded – undo
550 550
  * @return null;
551 551
  **/
552 552
 function lang_select_public($lang, $lang_select, $titre = null) {
553
-	// Cas 1. forcer_lang = true et pas de critere {lang_select}
554
-	if (
555
-		isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
556
-		and $lang_select !== 'oui'
557
-	) {
558
-		$lang = $GLOBALS['spip_lang'];
559
-	} // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
560
-	elseif (!strlen($lang)) {
561
-		$lang = $GLOBALS['spip_lang'];
562
-	} // Cas 3. l'objet est multilingue !
563
-	elseif (
564
-		$lang_select !== 'oui'
565
-		and strlen($titre) > 10
566
-		and str_contains($titre, '<multi>')
567
-		and str_contains(echappe_html($titre), '<multi>')
568
-	) {
569
-		$lang = $GLOBALS['spip_lang'];
570
-	}
571
-
572
-	// faire un lang_select() eventuellement sur la langue inchangee
573
-	lang_select($lang);
574
-
575
-	return;
553
+    // Cas 1. forcer_lang = true et pas de critere {lang_select}
554
+    if (
555
+        isset($GLOBALS['forcer_lang']) and $GLOBALS['forcer_lang']
556
+        and $lang_select !== 'oui'
557
+    ) {
558
+        $lang = $GLOBALS['spip_lang'];
559
+    } // Cas 2. l'objet n'a pas de langue definie (ou definie a '')
560
+    elseif (!strlen($lang)) {
561
+        $lang = $GLOBALS['spip_lang'];
562
+    } // Cas 3. l'objet est multilingue !
563
+    elseif (
564
+        $lang_select !== 'oui'
565
+        and strlen($titre) > 10
566
+        and str_contains($titre, '<multi>')
567
+        and str_contains(echappe_html($titre), '<multi>')
568
+    ) {
569
+        $lang = $GLOBALS['spip_lang'];
570
+    }
571
+
572
+    // faire un lang_select() eventuellement sur la langue inchangee
573
+    lang_select($lang);
574
+
575
+    return;
576 576
 }
577 577
 
578 578
 
579 579
 // Si un tableau &doublons[articles] est passe en parametre,
580 580
 // il faut le nettoyer car il pourrait etre injecte en SQL
581 581
 function nettoyer_env_doublons($envd) {
582
-	foreach ($envd as $table => $liste) {
583
-		$n = '';
584
-		foreach (explode(',', $liste) as $val) {
585
-			if ($a = intval($val) and $val === strval($a)) {
586
-				$n .= ',' . $val;
587
-			}
588
-		}
589
-		if (strlen($n)) {
590
-			$envd[$table] = $n;
591
-		} else {
592
-			unset($envd[$table]);
593
-		}
594
-	}
595
-
596
-	return $envd;
582
+    foreach ($envd as $table => $liste) {
583
+        $n = '';
584
+        foreach (explode(',', $liste) as $val) {
585
+            if ($a = intval($val) and $val === strval($a)) {
586
+                $n .= ',' . $val;
587
+            }
588
+        }
589
+        if (strlen($n)) {
590
+            $envd[$table] = $n;
591
+        } else {
592
+            unset($envd[$table]);
593
+        }
594
+    }
595
+
596
+    return $envd;
597 597
 }
598 598
 
599 599
 /**
@@ -612,21 +612,21 @@  discard block
 block discarded – undo
612 612
  *     Opérateur trouvé (SELF ou SUBSELECT) sinon false.
613 613
  **/
614 614
 function match_self($w) {
615
-	if (is_string($w)) {
616
-		return false;
617
-	}
618
-	if (is_array($w)) {
619
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
620
-			return $w;
621
-		}
622
-		foreach (array_filter($w, 'is_array') as $sw) {
623
-			if ($m = match_self($sw)) {
624
-				return $m;
625
-			}
626
-		}
627
-	}
628
-
629
-	return false;
615
+    if (is_string($w)) {
616
+        return false;
617
+    }
618
+    if (is_array($w)) {
619
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
620
+            return $w;
621
+        }
622
+        foreach (array_filter($w, 'is_array') as $sw) {
623
+            if ($m = match_self($sw)) {
624
+                return $m;
625
+            }
626
+        }
627
+    }
628
+
629
+    return false;
630 630
 }
631 631
 
632 632
 /**
@@ -642,16 +642,16 @@  discard block
 block discarded – undo
642 642
  *     est remplacée par son code.
643 643
  **/
644 644
 function remplace_sous_requete($w, $sousrequete) {
645
-	if (is_array($w)) {
646
-		if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
647
-			return $sousrequete;
648
-		}
649
-		foreach ($w as $k => $sw) {
650
-			$w[$k] = remplace_sous_requete($sw, $sousrequete);
651
-		}
652
-	}
653
-
654
-	return $w;
645
+    if (is_array($w)) {
646
+        if (in_array(reset($w), ['SELF', 'SUBSELECT'])) {
647
+            return $sousrequete;
648
+        }
649
+        foreach ($w as $k => $sw) {
650
+            $w[$k] = remplace_sous_requete($sw, $sousrequete);
651
+        }
652
+    }
653
+
654
+    return $w;
655 655
 }
656 656
 
657 657
 /**
@@ -665,17 +665,17 @@  discard block
 block discarded – undo
665 665
  *     - Conditions avec des sous requêtes
666 666
  **/
667 667
 function trouver_sous_requetes($where) {
668
-	$where_simples = [];
669
-	$where_sous = [];
670
-	foreach ($where as $k => $w) {
671
-		if (match_self($w)) {
672
-			$where_sous[$k] = $w;
673
-		} else {
674
-			$where_simples[$k] = $w;
675
-		}
676
-	}
677
-
678
-	return [$where_simples, $where_sous];
668
+    $where_simples = [];
669
+    $where_sous = [];
670
+    foreach ($where as $k => $w) {
671
+        if (match_self($w)) {
672
+            $where_sous[$k] = $w;
673
+        } else {
674
+            $where_simples[$k] = $w;
675
+        }
676
+    }
677
+
678
+    return [$where_simples, $where_sous];
679 679
 }
680 680
 
681 681
 
@@ -701,292 +701,292 @@  discard block
 block discarded – undo
701 701
  * @return resource
702 702
  */
703 703
 function calculer_select(
704
-	$select = [],
705
-	$from = [],
706
-	$from_type = [],
707
-	$where = [],
708
-	$join = [],
709
-	$groupby = [],
710
-	$orderby = [],
711
-	$limit = '',
712
-	$having = [],
713
-	$table = '',
714
-	$id = '',
715
-	$serveur = '',
716
-	$requeter = true
704
+    $select = [],
705
+    $from = [],
706
+    $from_type = [],
707
+    $where = [],
708
+    $join = [],
709
+    $groupby = [],
710
+    $orderby = [],
711
+    $limit = '',
712
+    $having = [],
713
+    $table = '',
714
+    $id = '',
715
+    $serveur = '',
716
+    $requeter = true
717 717
 ) {
718 718
 
719
-	// retirer les criteres vides:
720
-	// {X ?} avec X absent de l'URL
721
-	// {par #ENV{X}} avec X absent de l'URL
722
-	// IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
723
-	$menage = false;
724
-	foreach ($where as $k => $v) {
725
-		if (is_array($v) and count($v)) {
726
-			if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
727
-				$op = false;
728
-			} elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
729
-				$op = false;
730
-			} else {
731
-				$op = $v[0] ?: $v;
732
-			}
733
-		} else {
734
-			$op = $v;
735
-		}
736
-		if ((!$op) or ($op == 1) or ($op == '0=0')) {
737
-			unset($where[$k]);
738
-			$menage = true;
739
-		}
740
-	}
741
-
742
-	// evacuer les eventuels groupby vide issus d'un calcul dynamique
743
-	$groupby = array_diff($groupby, ['']);
744
-
745
-	// remplacer les sous requetes recursives au calcul
746
-	[$where_simples, $where_sous] = trouver_sous_requetes($where);
747
-	foreach ($where_sous as $k => $w) {
748
-		$menage = true;
749
-		// on recupere la sous requete
750
-		$sous = match_self($w);
751
-		if ($sous[0] == 'SELF') {
752
-			// c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
753
-			array_push($where_simples, $sous[2]);
754
-			$wheresub = [
755
-				$sous[2],
756
-				'0=0'
757
-			]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
758
-			$jsub = $join;
759
-			// trouver les jointures utiles a
760
-			// reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
761
-			// ie L1.objet='article'
762
-			// on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
763
-			$i = 0;
764
-			do {
765
-				$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
766
-					[$sous[1] . ' AS id'],
767
-					$from,
768
-					$from_type,
769
-					$wheresub,
770
-					$jsub,
771
-					[],
772
-					[],
773
-					'',
774
-					$having,
775
-					$table,
776
-					$id,
777
-					$serveur,
778
-					false
779
-				) . ')');
780
-				if (!$i) {
781
-					$i = 1;
782
-					$wherestring = calculer_where_to_string($where[$k]);
783
-					foreach ($join as $cle => $wj) {
784
-						if (
785
-							(is_countable($wj) ? count($wj) : 0) == 4
786
-							and str_contains($wherestring, (string) "{$cle}.")
787
-						) {
788
-							$i = 0;
789
-							$wheresub[] = $wj[3];
790
-							unset($jsub[$cle][3]);
791
-						}
792
-					}
793
-				}
794
-			} while ($i++ < 1);
795
-		}
796
-		if ($sous[0] == 'SUBSELECT') {
797
-			// c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
798
-			array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
799
-			$where[$k] = remplace_sous_requete($w, '(' . calculer_select(
800
-				$sous[1], # select
801
-				$sous[2], #from
802
-				[], #from_type
803
-				$sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
804
-				#where, qui peut etre de la forme string comme dans sql_select
805
-					[], #join
806
-				$sous[4] ?: [], #groupby
807
-				$sous[5] ?: [], #orderby
808
-				$sous[6], #limit
809
-				$sous[7] ?: [], #having
810
-				$table,
811
-				$id,
812
-				$serveur,
813
-				false
814
-			) . ')');
815
-		}
816
-		array_pop($where_simples);
817
-	}
818
-
819
-	foreach ($having as $k => $v) {
820
-		if ((!$v) or ($v == 1) or ($v == '0=0')) {
821
-			unset($having[$k]);
822
-		}
823
-	}
824
-
825
-	// Installer les jointures.
826
-	// Retirer celles seulement utiles aux criteres finalement absents mais
827
-	// parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
828
-	// si elle est seulement utile a Ln+1 elle meme inutile
829
-
830
-	$afrom = [];
831
-	$equiv = [];
832
-	$k = count($join);
833
-	foreach (array_reverse($join, true) as $cledef => $j) {
834
-		$cle = $cledef;
835
-		// le format de join est :
836
-		// array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
837
-		$join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
838
-		if (count($join[$cle]) == 2) {
839
-			$join[$cle][] = $join[$cle][1];
840
-		}
841
-		if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) {
842
-			$join[$cle][] = '';
843
-		}
844
-		[$t, $c, $carr, $and] = $join[$cle];
845
-		// si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
846
-		// pour compat avec ancienne convention
847
-		if (is_numeric($cle)) {
848
-			$cle = "L$k";
849
-		}
850
-		$cle_where_lie = "JOIN-$cle";
851
-		if (
852
-			!$menage
853
-			or isset($afrom[$cle])
854
-			or calculer_jointnul($cle, $select)
855
-			or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
856
-			or calculer_jointnul($cle, $having)
857
-			or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
858
-		) {
859
-			// corriger les references non explicites dans select
860
-			// ou groupby
861
-			foreach ($select as $i => $s) {
862
-				if ($s == $c) {
863
-					$select[$i] = "$cle.$c AS $c";
864
-					break;
865
-				}
866
-			}
867
-			foreach ($groupby as $i => $g) {
868
-				if ($g == $c) {
869
-					$groupby[$i] = "$cle.$c";
870
-					break;
871
-				}
872
-			}
873
-			// on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
874
-			// sans recours a preg_match
875
-			// un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
876
-			$afrom[$t][$cle] = [
877
-				"\n" .
878
-				($from_type[$cle] ?? 'INNER') . ' JOIN',
879
-				$from[$cle],
880
-				"AS $cle",
881
-				'ON (',
882
-				"$cle.$c",
883
-				'=',
884
-				"$t.$carr",
885
-				($and ? 'AND ' . $and : '') .
886
-				')'
887
-			];
888
-			if (isset($afrom[$cle])) {
889
-				$afrom[$t] = $afrom[$t] + $afrom[$cle];
890
-				unset($afrom[$cle]);
891
-			}
892
-			$equiv[] = $carr;
893
-		} else {
894
-			unset($join[$cledef]);
895
-			if (isset($where_simples[$cle_where_lie])) {
896
-				unset($where_simples[$cle_where_lie]);
897
-				unset($where[$cle_where_lie]);
898
-			}
899
-		}
900
-		unset($from[$cle]);
901
-		$k--;
902
-	}
903
-
904
-	if (count($afrom)) {
905
-		// Regarder si la table principale ne sert finalement a rien comme dans
906
-		//<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
907
-		//<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
908
-		//<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
909
-		// ou dans
910
-		//<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
911
-		// qui comporte plusieurs jointures
912
-		// ou dans
913
-		// <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
914
-		// <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
915
-		// penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
916
-		// <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
917
-		// penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
918
-		// <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
919
-
920
-		$t = key($from);
921
-		$c = current($from);
922
-		reset($from);
923
-		$e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
924
-		if (
925
-			!(strpos($t, ' ') or // jointure des le depart cf boucle_doc
926
-				calculer_jointnul($t, $select, $e) or
927
-				calculer_jointnul($t, $join, $e) or
928
-				calculer_jointnul($t, $where, $e) or
929
-				calculer_jointnul($t, $orderby, $e) or
930
-				calculer_jointnul($t, $groupby, $e) or
931
-				calculer_jointnul($t, $having, $e))
932
-			&& count($afrom[$t])
933
-		) {
934
-			$nfrom = reset($afrom[$t]);
935
-			$nt = array_key_first($afrom[$t]);
936
-			unset($from[$t]);
937
-			$from[$nt] = $nfrom[1];
938
-			unset($afrom[$t][$nt]);
939
-			$afrom[$nt] = $afrom[$t];
940
-			unset($afrom[$t]);
941
-			$e = '/\b' . preg_quote($nfrom[6]) . '\b/';
942
-			$t = $nfrom[4];
943
-			$alias = '';
944
-			// verifier que les deux cles sont homonymes, sinon installer un alias dans le select
945
-			$oldcle = explode('.', $nfrom[6]);
946
-			$oldcle = end($oldcle);
947
-			$newcle = explode('.', $nfrom[4]);
948
-			$newcle = end($newcle);
949
-			if ($newcle != $oldcle) {
950
-				// si l'ancienne cle etait deja dans le select avec un AS
951
-				// reprendre simplement ce AS
952
-				$as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
953
-				if (preg_match($as, implode(',', $select), $m)) {
954
-					$alias = '';
955
-				} else {
956
-					$alias = ', ' . $nfrom[4] . " AS $oldcle";
957
-				}
958
-			}
959
-			$select = remplacer_jointnul($t . $alias, $select, $e);
960
-			$join = remplacer_jointnul($t, $join, $e);
961
-			$where = remplacer_jointnul($t, $where, $e);
962
-			$having = remplacer_jointnul($t, $having, $e);
963
-			$groupby = remplacer_jointnul($t, $groupby, $e);
964
-			$orderby = remplacer_jointnul($t, $orderby, $e);
965
-		}
966
-		$from = reinjecte_joint($afrom, $from);
967
-	}
968
-	if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) {
969
-		$wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
970
-		$GLOBALS['debug'] = [];
971
-		if ($wasdebug) {
972
-			$GLOBALS['debug']['debug'] = true;
973
-		}
974
-	}
975
-	$GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
976
-	$r = sql_select(
977
-		$select,
978
-		$from,
979
-		$where,
980
-		$groupby,
981
-		array_filter($orderby),
982
-		$limit,
983
-		$having,
984
-		$serveur,
985
-		$requeter
986
-	);
987
-	unset($GLOBALS['debug']['aucasou']);
988
-
989
-	return $r;
719
+    // retirer les criteres vides:
720
+    // {X ?} avec X absent de l'URL
721
+    // {par #ENV{X}} avec X absent de l'URL
722
+    // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil)
723
+    $menage = false;
724
+    foreach ($where as $k => $v) {
725
+        if (is_array($v) and count($v)) {
726
+            if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) {
727
+                $op = false;
728
+            } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) {
729
+                $op = false;
730
+            } else {
731
+                $op = $v[0] ?: $v;
732
+            }
733
+        } else {
734
+            $op = $v;
735
+        }
736
+        if ((!$op) or ($op == 1) or ($op == '0=0')) {
737
+            unset($where[$k]);
738
+            $menage = true;
739
+        }
740
+    }
741
+
742
+    // evacuer les eventuels groupby vide issus d'un calcul dynamique
743
+    $groupby = array_diff($groupby, ['']);
744
+
745
+    // remplacer les sous requetes recursives au calcul
746
+    [$where_simples, $where_sous] = trouver_sous_requetes($where);
747
+    foreach ($where_sous as $k => $w) {
748
+        $menage = true;
749
+        // on recupere la sous requete
750
+        $sous = match_self($w);
751
+        if ($sous[0] == 'SELF') {
752
+            // c'est une sous requete identique a elle meme sous la forme (SELF,$select,$where)
753
+            array_push($where_simples, $sous[2]);
754
+            $wheresub = [
755
+                $sous[2],
756
+                '0=0'
757
+            ]; // pour accepter une string et forcer a faire le menage car on a surement simplifie select et where
758
+            $jsub = $join;
759
+            // trouver les jointures utiles a
760
+            // reinjecter dans le where de la sous requete les conditions supplementaires des jointures qui y sont mentionnees
761
+            // ie L1.objet='article'
762
+            // on construit le where une fois, puis on ajoute les where complentaires si besoin, et on reconstruit le where en fonction
763
+            $i = 0;
764
+            do {
765
+                $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
766
+                    [$sous[1] . ' AS id'],
767
+                    $from,
768
+                    $from_type,
769
+                    $wheresub,
770
+                    $jsub,
771
+                    [],
772
+                    [],
773
+                    '',
774
+                    $having,
775
+                    $table,
776
+                    $id,
777
+                    $serveur,
778
+                    false
779
+                ) . ')');
780
+                if (!$i) {
781
+                    $i = 1;
782
+                    $wherestring = calculer_where_to_string($where[$k]);
783
+                    foreach ($join as $cle => $wj) {
784
+                        if (
785
+                            (is_countable($wj) ? count($wj) : 0) == 4
786
+                            and str_contains($wherestring, (string) "{$cle}.")
787
+                        ) {
788
+                            $i = 0;
789
+                            $wheresub[] = $wj[3];
790
+                            unset($jsub[$cle][3]);
791
+                        }
792
+                    }
793
+                }
794
+            } while ($i++ < 1);
795
+        }
796
+        if ($sous[0] == 'SUBSELECT') {
797
+            // c'est une sous requete explicite sous la forme identique a sql_select : (SUBSELECT,$select,$from,$where,$groupby,$orderby,$limit,$having)
798
+            array_push($where_simples, $sous[3]); // est-ce utile dans ce cas ?
799
+            $where[$k] = remplace_sous_requete($w, '(' . calculer_select(
800
+                $sous[1], # select
801
+                $sous[2], #from
802
+                [], #from_type
803
+                $sous[3] ? (is_array($sous[3]) ? $sous[3] : [$sous[3]]) : [],
804
+                #where, qui peut etre de la forme string comme dans sql_select
805
+                    [], #join
806
+                $sous[4] ?: [], #groupby
807
+                $sous[5] ?: [], #orderby
808
+                $sous[6], #limit
809
+                $sous[7] ?: [], #having
810
+                $table,
811
+                $id,
812
+                $serveur,
813
+                false
814
+            ) . ')');
815
+        }
816
+        array_pop($where_simples);
817
+    }
818
+
819
+    foreach ($having as $k => $v) {
820
+        if ((!$v) or ($v == 1) or ($v == '0=0')) {
821
+            unset($having[$k]);
822
+        }
823
+    }
824
+
825
+    // Installer les jointures.
826
+    // Retirer celles seulement utiles aux criteres finalement absents mais
827
+    // parcourir de la plus recente a la moins recente pour pouvoir eliminer Ln
828
+    // si elle est seulement utile a Ln+1 elle meme inutile
829
+
830
+    $afrom = [];
831
+    $equiv = [];
832
+    $k = count($join);
833
+    foreach (array_reverse($join, true) as $cledef => $j) {
834
+        $cle = $cledef;
835
+        // le format de join est :
836
+        // array(table depart, cle depart [,cle arrivee[,condition optionnelle and ...]])
837
+        $join[$cle] = array_values($join[$cle]); // recalculer les cles car des unset ont pu perturber
838
+        if (count($join[$cle]) == 2) {
839
+            $join[$cle][] = $join[$cle][1];
840
+        }
841
+        if ((is_array($join[$cle]) || $join[$cle] instanceof \Countable ? count($join[$cle]) : 0) == 3) {
842
+            $join[$cle][] = '';
843
+        }
844
+        [$t, $c, $carr, $and] = $join[$cle];
845
+        // si le nom de la jointure n'a pas ete specifiee, on prend Lx avec x sont rang dans la liste
846
+        // pour compat avec ancienne convention
847
+        if (is_numeric($cle)) {
848
+            $cle = "L$k";
849
+        }
850
+        $cle_where_lie = "JOIN-$cle";
851
+        if (
852
+            !$menage
853
+            or isset($afrom[$cle])
854
+            or calculer_jointnul($cle, $select)
855
+            or calculer_jointnul($cle, array_diff_key($join, [$cle => $join[$cle]]))
856
+            or calculer_jointnul($cle, $having)
857
+            or calculer_jointnul($cle, array_diff_key($where_simples, [$cle_where_lie => '']))
858
+        ) {
859
+            // corriger les references non explicites dans select
860
+            // ou groupby
861
+            foreach ($select as $i => $s) {
862
+                if ($s == $c) {
863
+                    $select[$i] = "$cle.$c AS $c";
864
+                    break;
865
+                }
866
+            }
867
+            foreach ($groupby as $i => $g) {
868
+                if ($g == $c) {
869
+                    $groupby[$i] = "$cle.$c";
870
+                    break;
871
+                }
872
+            }
873
+            // on garde une ecriture decomposee pour permettre une simplification ulterieure si besoin
874
+            // sans recours a preg_match
875
+            // un implode(' ',..) est fait dans reinjecte_joint un peu plus bas
876
+            $afrom[$t][$cle] = [
877
+                "\n" .
878
+                ($from_type[$cle] ?? 'INNER') . ' JOIN',
879
+                $from[$cle],
880
+                "AS $cle",
881
+                'ON (',
882
+                "$cle.$c",
883
+                '=',
884
+                "$t.$carr",
885
+                ($and ? 'AND ' . $and : '') .
886
+                ')'
887
+            ];
888
+            if (isset($afrom[$cle])) {
889
+                $afrom[$t] = $afrom[$t] + $afrom[$cle];
890
+                unset($afrom[$cle]);
891
+            }
892
+            $equiv[] = $carr;
893
+        } else {
894
+            unset($join[$cledef]);
895
+            if (isset($where_simples[$cle_where_lie])) {
896
+                unset($where_simples[$cle_where_lie]);
897
+                unset($where[$cle_where_lie]);
898
+            }
899
+        }
900
+        unset($from[$cle]);
901
+        $k--;
902
+    }
903
+
904
+    if (count($afrom)) {
905
+        // Regarder si la table principale ne sert finalement a rien comme dans
906
+        //<BOUCLE3(MOTS){id_article}{id_mot}> class='on'</BOUCLE3>
907
+        //<BOUCLE2(MOTS){id_article} />#TOTAL_BOUCLE<//B2>
908
+        //<BOUCLE5(RUBRIQUES){id_mot}{tout} />#TOTAL_BOUCLE<//B5>
909
+        // ou dans
910
+        //<BOUCLE8(HIERARCHIE){id_rubrique}{tout}{type='Squelette'}{inverse}{0,1}{lang_select=non} />#TOTAL_BOUCLE<//B8>
911
+        // qui comporte plusieurs jointures
912
+        // ou dans
913
+        // <BOUCLE6(ARTICLES){id_mot=2}{statut==.*} />#TOTAL_BOUCLE<//B6>
914
+        // <BOUCLE7(ARTICLES){id_mot>0}{statut?} />#TOTAL_BOUCLE<//B7>
915
+        // penser a regarder aussi la clause orderby pour ne pas simplifier abusivement
916
+        // <BOUCLE9(ARTICLES){recherche truc}{par titre}>#ID_ARTICLE</BOUCLE9>
917
+        // penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
918
+        // <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
919
+
920
+        $t = key($from);
921
+        $c = current($from);
922
+        reset($from);
923
+        $e = '/\b(' . "$t\\." . join('|' . $t . '\.', $equiv) . ')\b/';
924
+        if (
925
+            !(strpos($t, ' ') or // jointure des le depart cf boucle_doc
926
+                calculer_jointnul($t, $select, $e) or
927
+                calculer_jointnul($t, $join, $e) or
928
+                calculer_jointnul($t, $where, $e) or
929
+                calculer_jointnul($t, $orderby, $e) or
930
+                calculer_jointnul($t, $groupby, $e) or
931
+                calculer_jointnul($t, $having, $e))
932
+            && count($afrom[$t])
933
+        ) {
934
+            $nfrom = reset($afrom[$t]);
935
+            $nt = array_key_first($afrom[$t]);
936
+            unset($from[$t]);
937
+            $from[$nt] = $nfrom[1];
938
+            unset($afrom[$t][$nt]);
939
+            $afrom[$nt] = $afrom[$t];
940
+            unset($afrom[$t]);
941
+            $e = '/\b' . preg_quote($nfrom[6]) . '\b/';
942
+            $t = $nfrom[4];
943
+            $alias = '';
944
+            // verifier que les deux cles sont homonymes, sinon installer un alias dans le select
945
+            $oldcle = explode('.', $nfrom[6]);
946
+            $oldcle = end($oldcle);
947
+            $newcle = explode('.', $nfrom[4]);
948
+            $newcle = end($newcle);
949
+            if ($newcle != $oldcle) {
950
+                // si l'ancienne cle etait deja dans le select avec un AS
951
+                // reprendre simplement ce AS
952
+                $as = '/\b' . preg_quote($nfrom[6]) . '\s+(AS\s+\w+)\b/';
953
+                if (preg_match($as, implode(',', $select), $m)) {
954
+                    $alias = '';
955
+                } else {
956
+                    $alias = ', ' . $nfrom[4] . " AS $oldcle";
957
+                }
958
+            }
959
+            $select = remplacer_jointnul($t . $alias, $select, $e);
960
+            $join = remplacer_jointnul($t, $join, $e);
961
+            $where = remplacer_jointnul($t, $where, $e);
962
+            $having = remplacer_jointnul($t, $having, $e);
963
+            $groupby = remplacer_jointnul($t, $groupby, $e);
964
+            $orderby = remplacer_jointnul($t, $orderby, $e);
965
+        }
966
+        $from = reinjecte_joint($afrom, $from);
967
+    }
968
+    if (empty($GLOBALS['debug']) or !is_array($GLOBALS['debug'])) {
969
+        $wasdebug = empty($GLOBALS['debug']) ? false : $GLOBALS['debug'];
970
+        $GLOBALS['debug'] = [];
971
+        if ($wasdebug) {
972
+            $GLOBALS['debug']['debug'] = true;
973
+        }
974
+    }
975
+    $GLOBALS['debug']['aucasou'] = [$table, $id, $serveur, $requeter];
976
+    $r = sql_select(
977
+        $select,
978
+        $from,
979
+        $where,
980
+        $groupby,
981
+        array_filter($orderby),
982
+        $limit,
983
+        $having,
984
+        $serveur,
985
+        $requeter
986
+    );
987
+    unset($GLOBALS['debug']['aucasou']);
988
+
989
+    return $r;
990 990
 }
991 991
 
992 992
 /**
@@ -997,79 +997,79 @@  discard block
 block discarded – undo
997 997
  * @return string
998 998
  */
999 999
 function calculer_where_to_string($v, $join = 'AND') {
1000
-	if (empty($v)) {
1001
-		return '';
1002
-	}
1003
-
1004
-	if (!is_array($v)) {
1005
-		return $v;
1006
-	} else {
1007
-		$exp = '';
1008
-		if (strtoupper($join) === 'AND') {
1009
-			return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1010
-		} else {
1011
-			return $exp . join($join, $v);
1012
-		}
1013
-	}
1000
+    if (empty($v)) {
1001
+        return '';
1002
+    }
1003
+
1004
+    if (!is_array($v)) {
1005
+        return $v;
1006
+    } else {
1007
+        $exp = '';
1008
+        if (strtoupper($join) === 'AND') {
1009
+            return $exp . join(" $join ", array_map('calculer_where_to_string', $v));
1010
+        } else {
1011
+            return $exp . join($join, $v);
1012
+        }
1013
+    }
1014 1014
 }
1015 1015
 
1016 1016
 
1017 1017
 //condition suffisante (mais non necessaire) pour qu'une table soit utile
1018 1018
 
1019 1019
 function calculer_jointnul($cle, $exp, $equiv = '') {
1020
-	if (!is_array($exp)) {
1021
-		if ($equiv) {
1022
-			$exp = preg_replace($equiv, '', $exp);
1023
-		}
1024
-
1025
-		return preg_match("/\\b$cle\\./", $exp);
1026
-	} else {
1027
-		foreach ($exp as $v) {
1028
-			if (calculer_jointnul($cle, $v, $equiv)) {
1029
-				return true;
1030
-			}
1031
-		}
1032
-
1033
-		return false;
1034
-	}
1020
+    if (!is_array($exp)) {
1021
+        if ($equiv) {
1022
+            $exp = preg_replace($equiv, '', $exp);
1023
+        }
1024
+
1025
+        return preg_match("/\\b$cle\\./", $exp);
1026
+    } else {
1027
+        foreach ($exp as $v) {
1028
+            if (calculer_jointnul($cle, $v, $equiv)) {
1029
+                return true;
1030
+            }
1031
+        }
1032
+
1033
+        return false;
1034
+    }
1035 1035
 }
1036 1036
 
1037 1037
 function reinjecte_joint($afrom, $from) {
1038
-	$from_synth = [];
1039
-	foreach ($from as $k => $v) {
1040
-		$from_synth[$k] = $from[$k];
1041
-		if (isset($afrom[$k])) {
1042
-			foreach ($afrom[$k] as $kk => $vv) {
1043
-				$afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1044
-			}
1045
-			$from_synth["$k@"] = implode(' ', $afrom[$k]);
1046
-			unset($afrom[$k]);
1047
-		}
1048
-	}
1049
-
1050
-	return $from_synth;
1038
+    $from_synth = [];
1039
+    foreach ($from as $k => $v) {
1040
+        $from_synth[$k] = $from[$k];
1041
+        if (isset($afrom[$k])) {
1042
+            foreach ($afrom[$k] as $kk => $vv) {
1043
+                $afrom[$k][$kk] = implode(' ', $afrom[$k][$kk]);
1044
+            }
1045
+            $from_synth["$k@"] = implode(' ', $afrom[$k]);
1046
+            unset($afrom[$k]);
1047
+        }
1048
+    }
1049
+
1050
+    return $from_synth;
1051 1051
 }
1052 1052
 
1053 1053
 function remplacer_jointnul($cle, $exp, $equiv = '') {
1054
-	if (!is_array($exp)) {
1055
-		return preg_replace($equiv, $cle, $exp);
1056
-	} else {
1057
-		foreach ($exp as $k => $v) {
1058
-			$exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1059
-		}
1060
-
1061
-		return $exp;
1062
-	}
1054
+    if (!is_array($exp)) {
1055
+        return preg_replace($equiv, $cle, $exp);
1056
+    } else {
1057
+        foreach ($exp as $k => $v) {
1058
+            $exp[$k] = remplacer_jointnul($cle, $v, $equiv);
1059
+        }
1060
+
1061
+        return $exp;
1062
+    }
1063 1063
 }
1064 1064
 
1065 1065
 // calcul du nom du squelette
1066 1066
 function calculer_nom_fonction_squel($skel, $mime_type = 'html', string $connect = '') {
1067
-	// ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1068
-	if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
1069
-		$skel = substr($skel, strlen(_DIR_RACINE));
1070
-	}
1071
-
1072
-	return $mime_type
1073
-	. (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1074
-	. md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1067
+    // ne pas doublonner les squelette selon qu'ils sont calcules depuis ecrire/ ou depuis la racine
1068
+    if ($l = strlen(_DIR_RACINE) and strncmp($skel, _DIR_RACINE, $l) == 0) {
1069
+        $skel = substr($skel, strlen(_DIR_RACINE));
1070
+    }
1071
+
1072
+    return $mime_type
1073
+    . (!$connect ? '' : preg_replace('/\W/', '_', $connect)) . '_'
1074
+    . md5($GLOBALS['spip_version_code'] . ' * ' . $skel . (isset($GLOBALS['marqueur_skel']) ? '*' . $GLOBALS['marqueur_skel'] : ''));
1075 1075
 }
Please login to merge, or discard this patch.
ecrire/public/styliser_par_z.php 1 patch
Indentation   +319 added lines, -319 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
  * @package SPIP\Core\Public\Styliser
20 20
  **/
21 21
 if (!defined('_ECRIRE_INC_VERSION')) {
22
-	return;
22
+    return;
23 23
 }
24 24
 
25 25
 /**
@@ -29,193 +29,193 @@  discard block
 block discarded – undo
29 29
  * @return array Données modifiées du pipeline
30 30
  */
31 31
 function public_styliser_par_z_dist($flux) {
32
-	static $prefix_path = null;
33
-	static $prefix_length;
34
-	static $z_blocs;
35
-	static $apl_constant;
36
-	static $page;
37
-	static $disponible = [];
38
-	static $echafauder;
39
-	static $prepend = '';
40
-
41
-	if (!isset($prefix_path)) {
42
-		$z_blocs = z_blocs(test_espace_prive());
43
-		if (test_espace_prive()) {
44
-			$prefix_path = 'prive/squelettes/';
45
-			$prefix_length = strlen($prefix_path);
46
-			$apl_constant = '_ECRIRE_AJAX_PARALLEL_LOAD';
47
-			$page = 'exec';
48
-			$echafauder = charger_fonction('echafauder', 'prive', true);
49
-			define('_ZCORE_EXCLURE_PATH', '');
50
-		} else {
51
-			$prefix_path = '';
52
-			$prefix_length = 0;
53
-			$apl_constant = '_Z_AJAX_PARALLEL_LOAD';
54
-			$page = _SPIP_PAGE;
55
-			$echafauder = charger_fonction('echafauder', 'public', true);
56
-			define('_ZCORE_EXCLURE_PATH', '\bprive|\bsquelettes-dist' . (defined('_DIR_PLUGIN_DIST') ? '|\b' . rtrim(
57
-				_DIR_PLUGIN_DIST,
58
-				'/'
59
-			) : ''));
60
-		}
61
-		$prepend = (defined('_Z_PREPEND_PATH') ? _Z_PREPEND_PATH : '');
62
-	}
63
-	$z_contenu = reset($z_blocs); // contenu par defaut
64
-
65
-	$fond = $flux['args']['fond'];
66
-
67
-	if ($prepend or strncmp($fond, $prefix_path, $prefix_length) == 0) {
68
-		$fond = substr($fond, $prefix_length);
69
-		$squelette = $flux['data'];
70
-		$ext = $flux['args']['ext'];
71
-		// Ajax Parallel loading : ne pas calculer le bloc, mais renvoyer un js qui le loadera en ajax
72
-		if (
73
-			defined('_Z_AJAX_PARALLEL_LOAD_OK')
74
-			and $dir = explode('/', $fond)
75
-			and count($dir) == 2 // pas un sous repertoire
76
-			and $dir = reset($dir)
77
-			and in_array($dir, $z_blocs) // verifier deja qu'on est dans un bloc Z
78
-			and defined($apl_constant)
79
-			and in_array($dir, explode(',', constant($apl_constant))) // et dans un demande en APL
80
-			and $pipe = z_trouver_bloc($prefix_path . $prepend, $dir, 'z_apl', $ext) // et qui contient le squelette APL
81
-		) {
82
-			$flux['data'] = $pipe;
83
-
84
-			return $flux;
85
-		}
86
-
87
-		// surcharger aussi les squelettes venant de squelettes-dist/
88
-		if ($squelette and !z_fond_valide($squelette)) {
89
-			$squelette = '';
90
-			$echafauder = '';
91
-		}
92
-		if ($prepend) {
93
-			$squelette = substr(find_in_path($prefix_path . $prepend . "$fond.$ext"), 0, -strlen(".$ext"));
94
-			if ($squelette) {
95
-				$flux['data'] = $squelette;
96
-			}
97
-		}
98
-
99
-		// gerer les squelettes non trouves
100
-		// -> router vers les /dist.html
101
-		// ou scaffolding ou page automatique les contenus
102
-		if (!$squelette) {
103
-			// si on est sur un ?page=XX non trouve
104
-			if (
105
-				(isset($flux['args']['contexte'][$page])
106
-					and $flux['args']['contexte'][$page] == $fond)
107
-				or (isset($flux['args']['contexte']['type-page'])
108
-					and $flux['args']['contexte']['type-page'] == $fond)
109
-				or ($fond == 'sommaire'
110
-					and (!isset($flux['args']['contexte'][$page]) or !$flux['args']['contexte'][$page]))
111
-			) {
112
-				// si on est sur un ?page=XX non trouve
113
-				// se brancher sur contenu/xx si il existe
114
-				// ou si c'est un objet spip, associe a une table, utiliser le fond homonyme
115
-				if (!isset($disponible[$fond])) {
116
-					$disponible[$fond] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $fond, $ext, $echafauder);
117
-				}
118
-
119
-				if ($disponible[$fond]) {
120
-					$flux['data'] = substr(find_in_path($prefix_path . "page.$ext"), 0, -strlen(".$ext"));
121
-				}
122
-			}
123
-
124
-			// echafaudage :
125
-			// si c'est un fond de contenu d'un objet en base
126
-			// generer un fond automatique a la volee pour les webmestres
127
-			elseif (strncmp($fond, "$z_contenu/", strlen($z_contenu) + 1) == 0) {
128
-				$type = substr($fond, strlen($z_contenu) + 1);
129
-				if (($type == 'page') and isset($flux['args']['contexte'][$page])) {
130
-					$type = $flux['args']['contexte'][$page];
131
-				}
132
-				if (!isset($disponible[$type])) {
133
-					$disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, $echafauder);
134
-				}
135
-				if (is_string($disponible[$type])) {
136
-					$flux['data'] = $disponible[$type];
137
-				} elseif (
138
-					$echafauder
139
-					and include_spip('inc/autoriser')
140
-					and isset($GLOBALS['visiteur_session']['statut']) // performance
141
-					and autoriser('echafauder', $type)
142
-					and $is = $disponible[$type]
143
-					and is_array($is)
144
-				) {
145
-					$flux['data'] = $echafauder($type, $is[0], $is[1], $is[2], $ext);
146
-				} else {
147
-					$flux['data'] = ($disponible['404'] = z_contenu_disponible(
148
-						$prefix_path . $prepend,
149
-						$z_contenu,
150
-						'404',
151
-						$ext,
152
-						$echafauder
153
-					));
154
-				}
155
-			}
156
-
157
-			// sinon, si on demande un fond non trouve dans un des autres blocs
158
-			// et si il y a bien un contenu correspondant ou echafaudable
159
-			// se rabbatre sur le dist.html du bloc concerne
160
-			else {
161
-				if (
162
-					$dir = explode('/', $fond)
163
-					and $dir = reset($dir)
164
-					and $dir !== $z_contenu
165
-					and in_array($dir, $z_blocs)
166
-				) {
167
-					$type = substr($fond, strlen("$dir/"));
168
-					if (($type == 'page') and isset($flux['args']['contexte'][$page])) {
169
-						$type = $flux['args']['contexte'][$page];
170
-					}
171
-					if ($type !== 'page' and !isset($disponible[$type])) {
172
-						$disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, $echafauder);
173
-					}
174
-					if ($type == 'page' or $disponible[$type]) {
175
-						$flux['data'] = z_trouver_bloc($prefix_path . $prepend, $dir, 'dist', $ext);
176
-					}
177
-				}
178
-			}
179
-			$squelette = $flux['data'];
180
-		}
181
-		// layout specifiques par type et compositions :
182
-		// body-article.html
183
-		// body-sommaire.html
184
-		// pour des raisons de perfo, les declinaisons doivent etre dans le
185
-		// meme dossier que body.html
186
-		if ($fond == 'body' and substr($squelette, -strlen($fond)) == $fond) {
187
-			if (
188
-				isset($flux['args']['contexte']['type-page'])
189
-				and (
190
-					(isset($flux['args']['contexte']['composition'])
191
-						and file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page'] . '-' . $flux['args']['contexte']['composition']) . ".$ext"))
192
-					or
193
-					file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page']) . ".$ext")
194
-				)
195
-			) {
196
-				$flux['data'] = $f;
197
-			}
198
-		} elseif (
199
-			$fond == 'structure'
200
-			and z_sanitize_var_zajax()
201
-			and $f = find_in_path($prefix_path . $prepend . 'ajax' . ".$ext")
202
-		) {
203
-			$flux['data'] = substr($f, 0, -strlen(".$ext"));
204
-		} // chercher le fond correspondant a la composition
205
-		elseif (
206
-			isset($flux['args']['contexte']['composition'])
207
-			and (basename($fond) == 'page' or ($squelette and substr($squelette, -strlen($fond)) == $fond))
208
-			and $dir = substr($fond, $prefix_length)
209
-			and $dir = explode('/', $dir)
210
-			and $dir = reset($dir)
211
-			and in_array($dir, $z_blocs)
212
-			and $f = find_in_path($prefix_path . $prepend . $fond . '-' . $flux['args']['contexte']['composition'] . ".$ext")
213
-		) {
214
-			$flux['data'] = substr($f, 0, -strlen(".$ext"));
215
-		}
216
-	}
217
-
218
-	return $flux;
32
+    static $prefix_path = null;
33
+    static $prefix_length;
34
+    static $z_blocs;
35
+    static $apl_constant;
36
+    static $page;
37
+    static $disponible = [];
38
+    static $echafauder;
39
+    static $prepend = '';
40
+
41
+    if (!isset($prefix_path)) {
42
+        $z_blocs = z_blocs(test_espace_prive());
43
+        if (test_espace_prive()) {
44
+            $prefix_path = 'prive/squelettes/';
45
+            $prefix_length = strlen($prefix_path);
46
+            $apl_constant = '_ECRIRE_AJAX_PARALLEL_LOAD';
47
+            $page = 'exec';
48
+            $echafauder = charger_fonction('echafauder', 'prive', true);
49
+            define('_ZCORE_EXCLURE_PATH', '');
50
+        } else {
51
+            $prefix_path = '';
52
+            $prefix_length = 0;
53
+            $apl_constant = '_Z_AJAX_PARALLEL_LOAD';
54
+            $page = _SPIP_PAGE;
55
+            $echafauder = charger_fonction('echafauder', 'public', true);
56
+            define('_ZCORE_EXCLURE_PATH', '\bprive|\bsquelettes-dist' . (defined('_DIR_PLUGIN_DIST') ? '|\b' . rtrim(
57
+                _DIR_PLUGIN_DIST,
58
+                '/'
59
+            ) : ''));
60
+        }
61
+        $prepend = (defined('_Z_PREPEND_PATH') ? _Z_PREPEND_PATH : '');
62
+    }
63
+    $z_contenu = reset($z_blocs); // contenu par defaut
64
+
65
+    $fond = $flux['args']['fond'];
66
+
67
+    if ($prepend or strncmp($fond, $prefix_path, $prefix_length) == 0) {
68
+        $fond = substr($fond, $prefix_length);
69
+        $squelette = $flux['data'];
70
+        $ext = $flux['args']['ext'];
71
+        // Ajax Parallel loading : ne pas calculer le bloc, mais renvoyer un js qui le loadera en ajax
72
+        if (
73
+            defined('_Z_AJAX_PARALLEL_LOAD_OK')
74
+            and $dir = explode('/', $fond)
75
+            and count($dir) == 2 // pas un sous repertoire
76
+            and $dir = reset($dir)
77
+            and in_array($dir, $z_blocs) // verifier deja qu'on est dans un bloc Z
78
+            and defined($apl_constant)
79
+            and in_array($dir, explode(',', constant($apl_constant))) // et dans un demande en APL
80
+            and $pipe = z_trouver_bloc($prefix_path . $prepend, $dir, 'z_apl', $ext) // et qui contient le squelette APL
81
+        ) {
82
+            $flux['data'] = $pipe;
83
+
84
+            return $flux;
85
+        }
86
+
87
+        // surcharger aussi les squelettes venant de squelettes-dist/
88
+        if ($squelette and !z_fond_valide($squelette)) {
89
+            $squelette = '';
90
+            $echafauder = '';
91
+        }
92
+        if ($prepend) {
93
+            $squelette = substr(find_in_path($prefix_path . $prepend . "$fond.$ext"), 0, -strlen(".$ext"));
94
+            if ($squelette) {
95
+                $flux['data'] = $squelette;
96
+            }
97
+        }
98
+
99
+        // gerer les squelettes non trouves
100
+        // -> router vers les /dist.html
101
+        // ou scaffolding ou page automatique les contenus
102
+        if (!$squelette) {
103
+            // si on est sur un ?page=XX non trouve
104
+            if (
105
+                (isset($flux['args']['contexte'][$page])
106
+                    and $flux['args']['contexte'][$page] == $fond)
107
+                or (isset($flux['args']['contexte']['type-page'])
108
+                    and $flux['args']['contexte']['type-page'] == $fond)
109
+                or ($fond == 'sommaire'
110
+                    and (!isset($flux['args']['contexte'][$page]) or !$flux['args']['contexte'][$page]))
111
+            ) {
112
+                // si on est sur un ?page=XX non trouve
113
+                // se brancher sur contenu/xx si il existe
114
+                // ou si c'est un objet spip, associe a une table, utiliser le fond homonyme
115
+                if (!isset($disponible[$fond])) {
116
+                    $disponible[$fond] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $fond, $ext, $echafauder);
117
+                }
118
+
119
+                if ($disponible[$fond]) {
120
+                    $flux['data'] = substr(find_in_path($prefix_path . "page.$ext"), 0, -strlen(".$ext"));
121
+                }
122
+            }
123
+
124
+            // echafaudage :
125
+            // si c'est un fond de contenu d'un objet en base
126
+            // generer un fond automatique a la volee pour les webmestres
127
+            elseif (strncmp($fond, "$z_contenu/", strlen($z_contenu) + 1) == 0) {
128
+                $type = substr($fond, strlen($z_contenu) + 1);
129
+                if (($type == 'page') and isset($flux['args']['contexte'][$page])) {
130
+                    $type = $flux['args']['contexte'][$page];
131
+                }
132
+                if (!isset($disponible[$type])) {
133
+                    $disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, $echafauder);
134
+                }
135
+                if (is_string($disponible[$type])) {
136
+                    $flux['data'] = $disponible[$type];
137
+                } elseif (
138
+                    $echafauder
139
+                    and include_spip('inc/autoriser')
140
+                    and isset($GLOBALS['visiteur_session']['statut']) // performance
141
+                    and autoriser('echafauder', $type)
142
+                    and $is = $disponible[$type]
143
+                    and is_array($is)
144
+                ) {
145
+                    $flux['data'] = $echafauder($type, $is[0], $is[1], $is[2], $ext);
146
+                } else {
147
+                    $flux['data'] = ($disponible['404'] = z_contenu_disponible(
148
+                        $prefix_path . $prepend,
149
+                        $z_contenu,
150
+                        '404',
151
+                        $ext,
152
+                        $echafauder
153
+                    ));
154
+                }
155
+            }
156
+
157
+            // sinon, si on demande un fond non trouve dans un des autres blocs
158
+            // et si il y a bien un contenu correspondant ou echafaudable
159
+            // se rabbatre sur le dist.html du bloc concerne
160
+            else {
161
+                if (
162
+                    $dir = explode('/', $fond)
163
+                    and $dir = reset($dir)
164
+                    and $dir !== $z_contenu
165
+                    and in_array($dir, $z_blocs)
166
+                ) {
167
+                    $type = substr($fond, strlen("$dir/"));
168
+                    if (($type == 'page') and isset($flux['args']['contexte'][$page])) {
169
+                        $type = $flux['args']['contexte'][$page];
170
+                    }
171
+                    if ($type !== 'page' and !isset($disponible[$type])) {
172
+                        $disponible[$type] = z_contenu_disponible($prefix_path . $prepend, $z_contenu, $type, $ext, $echafauder);
173
+                    }
174
+                    if ($type == 'page' or $disponible[$type]) {
175
+                        $flux['data'] = z_trouver_bloc($prefix_path . $prepend, $dir, 'dist', $ext);
176
+                    }
177
+                }
178
+            }
179
+            $squelette = $flux['data'];
180
+        }
181
+        // layout specifiques par type et compositions :
182
+        // body-article.html
183
+        // body-sommaire.html
184
+        // pour des raisons de perfo, les declinaisons doivent etre dans le
185
+        // meme dossier que body.html
186
+        if ($fond == 'body' and substr($squelette, -strlen($fond)) == $fond) {
187
+            if (
188
+                isset($flux['args']['contexte']['type-page'])
189
+                and (
190
+                    (isset($flux['args']['contexte']['composition'])
191
+                        and file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page'] . '-' . $flux['args']['contexte']['composition']) . ".$ext"))
192
+                    or
193
+                    file_exists(($f = $squelette . '-' . $flux['args']['contexte']['type-page']) . ".$ext")
194
+                )
195
+            ) {
196
+                $flux['data'] = $f;
197
+            }
198
+        } elseif (
199
+            $fond == 'structure'
200
+            and z_sanitize_var_zajax()
201
+            and $f = find_in_path($prefix_path . $prepend . 'ajax' . ".$ext")
202
+        ) {
203
+            $flux['data'] = substr($f, 0, -strlen(".$ext"));
204
+        } // chercher le fond correspondant a la composition
205
+        elseif (
206
+            isset($flux['args']['contexte']['composition'])
207
+            and (basename($fond) == 'page' or ($squelette and substr($squelette, -strlen($fond)) == $fond))
208
+            and $dir = substr($fond, $prefix_length)
209
+            and $dir = explode('/', $dir)
210
+            and $dir = reset($dir)
211
+            and in_array($dir, $z_blocs)
212
+            and $f = find_in_path($prefix_path . $prepend . $fond . '-' . $flux['args']['contexte']['composition'] . ".$ext")
213
+        ) {
214
+            $flux['data'] = substr($f, 0, -strlen(".$ext"));
215
+        }
216
+    }
217
+
218
+    return $flux;
219 219
 }
220 220
 
221 221
 /**
@@ -225,18 +225,18 @@  discard block
 block discarded – undo
225 225
  * @return array
226 226
  */
227 227
 function z_blocs($espace_prive = false) {
228
-	if ($espace_prive) {
229
-		return ($GLOBALS['z_blocs_ecrire'] ?? [
230
-			'contenu',
231
-			'navigation',
232
-			'extra',
233
-			'head',
234
-			'hierarchie',
235
-			'top'
236
-		]);
237
-	}
238
-
239
-	return ($GLOBALS['z_blocs'] ?? ['contenu']);
228
+    if ($espace_prive) {
229
+        return ($GLOBALS['z_blocs_ecrire'] ?? [
230
+            'contenu',
231
+            'navigation',
232
+            'extra',
233
+            'head',
234
+            'hierarchie',
235
+            'top'
236
+        ]);
237
+    }
238
+
239
+    return ($GLOBALS['z_blocs'] ?? ['contenu']);
240 240
 }
241 241
 
242 242
 /**
@@ -251,11 +251,11 @@  discard block
 block discarded – undo
251 251
  * @return mixed
252 252
  */
253 253
 function z_contenu_disponible($prefix_path, $z_contenu, $type, $ext, $echafauder = true) {
254
-	if ($d = z_trouver_bloc($prefix_path, $z_contenu, $type, $ext)) {
255
-		return $d;
256
-	}
254
+    if ($d = z_trouver_bloc($prefix_path, $z_contenu, $type, $ext)) {
255
+        return $d;
256
+    }
257 257
 
258
-	return $echafauder ? z_echafaudable($type) : false;
258
+    return $echafauder ? z_echafaudable($type) : false;
259 259
 }
260 260
 
261 261
 /**
@@ -269,14 +269,14 @@  discard block
 block discarded – undo
269 269
  *   `true` si on peut l'utiliser, `false` sinon.
270 270
  **/
271 271
 function z_fond_valide($squelette) {
272
-	if (
273
-		!_ZCORE_EXCLURE_PATH
274
-		or !preg_match(',(' . _ZCORE_EXCLURE_PATH . ')/,', $squelette)
275
-	) {
276
-		return true;
277
-	}
278
-
279
-	return false;
272
+    if (
273
+        !_ZCORE_EXCLURE_PATH
274
+        or !preg_match(',(' . _ZCORE_EXCLURE_PATH . ')/,', $squelette)
275
+    ) {
276
+        return true;
277
+    }
278
+
279
+    return false;
280 280
 }
281 281
 
282 282
 /**
@@ -294,14 +294,14 @@  discard block
 block discarded – undo
294 294
  * @return string
295 295
  */
296 296
 function z_trouver_bloc($prefix_path, $bloc, $fond, $ext) {
297
-	if (
298
-		(defined('_ZCORE_BLOC_PREFIX_SKEL') and $f = find_in_path("$prefix_path$bloc/$bloc.$fond.$ext") and z_fond_valide($f))
299
-		or ($f = find_in_path("$prefix_path$bloc/$fond.$ext") and z_fond_valide($f))
300
-	) {
301
-		return substr($f, 0, -strlen(".$ext"));
302
-	}
303
-
304
-	return '';
297
+    if (
298
+        (defined('_ZCORE_BLOC_PREFIX_SKEL') and $f = find_in_path("$prefix_path$bloc/$bloc.$fond.$ext") and z_fond_valide($f))
299
+        or ($f = find_in_path("$prefix_path$bloc/$fond.$ext") and z_fond_valide($f))
300
+    ) {
301
+        return substr($f, 0, -strlen(".$ext"));
302
+    }
303
+
304
+    return '';
305 305
 }
306 306
 
307 307
 /**
@@ -313,52 +313,52 @@  discard block
 block discarded – undo
313 313
  * @return bool
314 314
  */
315 315
 function z_echafaudable($type) {
316
-	static $pages = null;
317
-	static $echafaudable = [];
318
-	if (isset($echafaudable[$type])) {
319
-		return $echafaudable[$type];
320
-	}
321
-	if (preg_match(',[^\w],', $type)) {
322
-		return $echafaudable[$type] = false;
323
-	}
324
-
325
-	if (test_espace_prive()) {
326
-		if (!function_exists('trouver_objet_exec')) {
327
-			include_spip('inc/pipelines_ecrire');
328
-		}
329
-		if ($e = trouver_objet_exec($type)) {
330
-			return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $e];
331
-		} else {
332
-			// peut etre c'est un exec=types qui liste tous les objets "type"
333
-			if (
334
-				($t = objet_type($type, false)) !== $type
335
-				and $e = trouver_objet_exec($t)
336
-			) {
337
-				return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $t];
338
-			}
339
-		}
340
-	} else {
341
-		if (is_null($pages)) {
342
-			$pages = [];
343
-			$liste = lister_tables_objets_sql();
344
-			foreach ($liste as $t => $d) {
345
-				if ($d['page']) {
346
-					$pages[$d['page']] = [$d['table_objet'], $t];
347
-				}
348
-			}
349
-		}
350
-		if (!isset($pages[$type])) {
351
-			return $echafaudable[$type] = false;
352
-		}
353
-		if ((is_countable($pages[$type]) ? count($pages[$type]) : 0) == 2) {
354
-			$trouver_table = charger_fonction('trouver_table', 'base');
355
-			$pages[$type][] = $trouver_table(reset($pages[$type]));
356
-		}
357
-
358
-		return $echafaudable[$type] = $pages[$type];
359
-	}
360
-
361
-	return $echafaudable[$type] = false;
316
+    static $pages = null;
317
+    static $echafaudable = [];
318
+    if (isset($echafaudable[$type])) {
319
+        return $echafaudable[$type];
320
+    }
321
+    if (preg_match(',[^\w],', $type)) {
322
+        return $echafaudable[$type] = false;
323
+    }
324
+
325
+    if (test_espace_prive()) {
326
+        if (!function_exists('trouver_objet_exec')) {
327
+            include_spip('inc/pipelines_ecrire');
328
+        }
329
+        if ($e = trouver_objet_exec($type)) {
330
+            return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $e];
331
+        } else {
332
+            // peut etre c'est un exec=types qui liste tous les objets "type"
333
+            if (
334
+                ($t = objet_type($type, false)) !== $type
335
+                and $e = trouver_objet_exec($t)
336
+            ) {
337
+                return $echafaudable[$type] = [$e['table'], $e['table_objet_sql'], $t];
338
+            }
339
+        }
340
+    } else {
341
+        if (is_null($pages)) {
342
+            $pages = [];
343
+            $liste = lister_tables_objets_sql();
344
+            foreach ($liste as $t => $d) {
345
+                if ($d['page']) {
346
+                    $pages[$d['page']] = [$d['table_objet'], $t];
347
+                }
348
+            }
349
+        }
350
+        if (!isset($pages[$type])) {
351
+            return $echafaudable[$type] = false;
352
+        }
353
+        if ((is_countable($pages[$type]) ? count($pages[$type]) : 0) == 2) {
354
+            $trouver_table = charger_fonction('trouver_table', 'base');
355
+            $pages[$type][] = $trouver_table(reset($pages[$type]));
356
+        }
357
+
358
+        return $echafaudable[$type] = $pages[$type];
359
+    }
360
+
361
+    return $echafaudable[$type] = false;
362 362
 }
363 363
 
364 364
 
@@ -375,46 +375,46 @@  discard block
 block discarded – undo
375 375
  * @return string
376 376
  */
377 377
 function prive_echafauder_dist($exec, $table, $table_sql, $desc_exec, $ext) {
378
-	$scaffold = '';
379
-
380
-	// page objet ou objet_edit
381
-	if (is_array($desc_exec)) {
382
-		$type = $desc_exec['type'];
383
-		$primary = $desc_exec['id_table_objet'];
384
-
385
-		if ($desc_exec['edition'] === false) {
386
-			$fond = 'objet';
387
-		} else {
388
-			$trouver_table = charger_fonction('trouver_table', 'base');
389
-			$desc = $trouver_table($table_sql);
390
-			if (isset($desc['field']['id_rubrique'])) {
391
-				$fond = 'objet_edit';
392
-			} else {
393
-				$fond = 'objet_edit.sans_rubrique';
394
-			}
395
-		}
396
-		$dir = z_blocs(test_espace_prive());
397
-		$dir = reset($dir);
398
-		$scaffold = "<INCLURE{fond=prive/echafaudage/$dir/" . $fond . ',objet=' . $type . ',id_objet=#' . strtoupper($primary) . ',env}>';
399
-	} // page objets
400
-	elseif ($type = $desc_exec and !str_contains($type, '/')) {
401
-		$dir = z_blocs(test_espace_prive());
402
-		$dir = reset($dir);
403
-		$scaffold = "<INCLURE{fond=prive/echafaudage/$dir/objets,objet=" . $type . ',env} />';
404
-	}
405
-	// morceau d'objet : on fournit le fond de sibstitution dans $desc_exec
406
-	// et objet et tire de $table
407
-	elseif ($fond = $desc_exec) {
408
-		$dir = md5(dirname($fond));
409
-		$scaffold = "<INCLURE{fond=$fond,objet=" . objet_type($table) . ',env} />';
410
-	}
411
-
412
-	$base_dir = sous_repertoire(_DIR_CACHE, 'scaffold', false);
413
-	$base_dir = sous_repertoire($base_dir, $dir, false);
414
-	$f = $base_dir . "$exec";
415
-	ecrire_fichier("$f.$ext", $scaffold);
416
-
417
-	return $f;
378
+    $scaffold = '';
379
+
380
+    // page objet ou objet_edit
381
+    if (is_array($desc_exec)) {
382
+        $type = $desc_exec['type'];
383
+        $primary = $desc_exec['id_table_objet'];
384
+
385
+        if ($desc_exec['edition'] === false) {
386
+            $fond = 'objet';
387
+        } else {
388
+            $trouver_table = charger_fonction('trouver_table', 'base');
389
+            $desc = $trouver_table($table_sql);
390
+            if (isset($desc['field']['id_rubrique'])) {
391
+                $fond = 'objet_edit';
392
+            } else {
393
+                $fond = 'objet_edit.sans_rubrique';
394
+            }
395
+        }
396
+        $dir = z_blocs(test_espace_prive());
397
+        $dir = reset($dir);
398
+        $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/" . $fond . ',objet=' . $type . ',id_objet=#' . strtoupper($primary) . ',env}>';
399
+    } // page objets
400
+    elseif ($type = $desc_exec and !str_contains($type, '/')) {
401
+        $dir = z_blocs(test_espace_prive());
402
+        $dir = reset($dir);
403
+        $scaffold = "<INCLURE{fond=prive/echafaudage/$dir/objets,objet=" . $type . ',env} />';
404
+    }
405
+    // morceau d'objet : on fournit le fond de sibstitution dans $desc_exec
406
+    // et objet et tire de $table
407
+    elseif ($fond = $desc_exec) {
408
+        $dir = md5(dirname($fond));
409
+        $scaffold = "<INCLURE{fond=$fond,objet=" . objet_type($table) . ',env} />';
410
+    }
411
+
412
+    $base_dir = sous_repertoire(_DIR_CACHE, 'scaffold', false);
413
+    $base_dir = sous_repertoire($base_dir, $dir, false);
414
+    $f = $base_dir . "$exec";
415
+    ecrire_fichier("$f.$ext", $scaffold);
416
+
417
+    return $f;
418 418
 }
419 419
 
420 420
 /**
@@ -423,17 +423,17 @@  discard block
 block discarded – undo
423 423
  * @return bool|string
424 424
  */
425 425
 function z_sanitize_var_zajax() {
426
-	$z_ajax = _request('var_zajax');
427
-	if (!$z_ajax) {
428
-		return false;
429
-	}
430
-	if (
431
-		!$z_blocs = z_blocs(test_espace_prive())
432
-		or !in_array($z_ajax, $z_blocs)
433
-	) {
434
-		set_request('var_zajax'); // enlever cette demande incongrue
435
-		$z_ajax = false;
436
-	}
437
-
438
-	return $z_ajax;
426
+    $z_ajax = _request('var_zajax');
427
+    if (!$z_ajax) {
428
+        return false;
429
+    }
430
+    if (
431
+        !$z_blocs = z_blocs(test_espace_prive())
432
+        or !in_array($z_ajax, $z_blocs)
433
+    ) {
434
+        set_request('var_zajax'); // enlever cette demande incongrue
435
+        $z_ajax = false;
436
+    }
437
+
438
+    return $z_ajax;
439 439
 }
Please login to merge, or discard this patch.
ecrire/public/sandbox.php 1 patch
Indentation   +99 added lines, -99 removed lines patch added patch discarded remove patch
@@ -23,7 +23,7 @@  discard block
 block discarded – undo
23 23
  **/
24 24
 
25 25
 if (!defined('_ECRIRE_INC_VERSION')) {
26
-	return;
26
+    return;
27 27
 }
28 28
 
29 29
 /**
@@ -41,9 +41,9 @@  discard block
 block discarded – undo
41 41
  *     texte
42 42
  */
43 43
 function sandbox_composer_texte($texte, &$p) {
44
-	$code = "'" . str_replace(['\\', "'"], ['\\\\', "\\'"], $texte) . "'";
44
+    $code = "'" . str_replace(['\\', "'"], ['\\\\', "\\'"], $texte) . "'";
45 45
 
46
-	return $code;
46
+    return $code;
47 47
 }
48 48
 
49 49
 
@@ -59,42 +59,42 @@  discard block
 block discarded – undo
59 59
  * @return string
60 60
  */
61 61
 function sandbox_composer_filtre($fonc, $code, $arglist, &$p, $nb_arg_droite = 1000): string {
62
-	if (isset($GLOBALS['spip_matrice'][$fonc])) {
63
-		$code = "filtrer('$fonc',$code$arglist)";
64
-	}
65
-
66
-	// le filtre est defini sous forme de fonction ou de methode
67
-	// par ex. dans inc_texte, inc_filtres ou mes_fonctions
68
-	elseif ($f = chercher_filtre($fonc)) {
69
-		// cas particulier : le filtre |set doit acceder a la $Pile
70
-		// proto: filtre_set(&$Pile, $val, $args...)
71
-		if (strpbrk($f, ':')) { // Class::method
72
-			$refl = new ReflectionMethod($f);
73
-		} else {
74
-			$refl = new ReflectionFunction($f);
75
-		}
76
-		$refs = $refl->getParameters();
77
-		if (isset($refs[0]) and $refs[0]->name == 'Pile') {
78
-			$code = "$f(\$Pile,$code$arglist)";
79
-			$nb_arg_gauche = 2; // la balise à laquelle s'applique le filtre + $Pile
80
-		} else {
81
-			$code = "$f($code$arglist)";
82
-			$nb_arg_gauche = 1; // la balise à laquelle s'applique le filtre
83
-		}
84
-		$nb_args_f = $nb_arg_gauche + $nb_arg_droite;
85
-		$min_f = $refl->getNumberOfRequiredParameters();
86
-		if (($nb_args_f < $min_f)) {
87
-			$msg_args = ['filtre' => texte_script($fonc), 'nb' => $min_f - $nb_args_f];
88
-			erreur_squelette([ 'zbug_erreur_filtre_nbarg_min', $msg_args], $p);
89
-		}
90
-	}
91
-	// le filtre n'existe pas,
92
-	// on le notifie
93
-	else {
94
-		erreur_squelette(['zbug_erreur_filtre', ['filtre' => texte_script($fonc)]], $p);
95
-	}
96
-
97
-	return $code;
62
+    if (isset($GLOBALS['spip_matrice'][$fonc])) {
63
+        $code = "filtrer('$fonc',$code$arglist)";
64
+    }
65
+
66
+    // le filtre est defini sous forme de fonction ou de methode
67
+    // par ex. dans inc_texte, inc_filtres ou mes_fonctions
68
+    elseif ($f = chercher_filtre($fonc)) {
69
+        // cas particulier : le filtre |set doit acceder a la $Pile
70
+        // proto: filtre_set(&$Pile, $val, $args...)
71
+        if (strpbrk($f, ':')) { // Class::method
72
+            $refl = new ReflectionMethod($f);
73
+        } else {
74
+            $refl = new ReflectionFunction($f);
75
+        }
76
+        $refs = $refl->getParameters();
77
+        if (isset($refs[0]) and $refs[0]->name == 'Pile') {
78
+            $code = "$f(\$Pile,$code$arglist)";
79
+            $nb_arg_gauche = 2; // la balise à laquelle s'applique le filtre + $Pile
80
+        } else {
81
+            $code = "$f($code$arglist)";
82
+            $nb_arg_gauche = 1; // la balise à laquelle s'applique le filtre
83
+        }
84
+        $nb_args_f = $nb_arg_gauche + $nb_arg_droite;
85
+        $min_f = $refl->getNumberOfRequiredParameters();
86
+        if (($nb_args_f < $min_f)) {
87
+            $msg_args = ['filtre' => texte_script($fonc), 'nb' => $min_f - $nb_args_f];
88
+            erreur_squelette([ 'zbug_erreur_filtre_nbarg_min', $msg_args], $p);
89
+        }
90
+    }
91
+    // le filtre n'existe pas,
92
+    // on le notifie
93
+    else {
94
+        erreur_squelette(['zbug_erreur_filtre', ['filtre' => texte_script($fonc)]], $p);
95
+    }
96
+
97
+    return $code;
98 98
 }
99 99
 
100 100
 // Calculer un <INCLURE(xx.php)>
@@ -117,15 +117,15 @@  discard block
 block discarded – undo
117 117
  * @return string
118 118
  */
119 119
 function sandbox_composer_inclure_php($fichier, &$p, $_contexte) {
120
-	$compil = texte_script(memoriser_contexte_compil($p));
121
-	// si inexistant, on essaiera a l'execution
122
-	if ($path = find_in_path($fichier)) {
123
-		$path = "\"$path\"";
124
-	} else {
125
-		$path = "find_in_path(\"$fichier\")";
126
-	}
127
-
128
-	return sprintf(CODE_INCLURE_SCRIPT, $path, $fichier, $compil, $_contexte);
120
+    $compil = texte_script(memoriser_contexte_compil($p));
121
+    // si inexistant, on essaiera a l'execution
122
+    if ($path = find_in_path($fichier)) {
123
+        $path = "\"$path\"";
124
+    } else {
125
+        $path = "find_in_path(\"$fichier\")";
126
+    }
127
+
128
+    return sprintf(CODE_INCLURE_SCRIPT, $path, $fichier, $compil, $_contexte);
129 129
 }
130 130
 
131 131
 /**
@@ -137,20 +137,20 @@  discard block
 block discarded – undo
137 137
  * @return string
138 138
  */
139 139
 function sandbox_composer_interdire_scripts($code, &$p) {
140
-	// Securite
141
-	if (
142
-		$p->interdire_scripts
143
-		and $p->etoile != '**'
144
-	) {
145
-		if (!preg_match("/^sinon[(](.*),'([^']*)'[)]$/", $code, $r)) {
146
-			$code = "interdire_scripts($code)";
147
-		} else {
148
-			$code = interdire_scripts($r[2]);
149
-			$code = "sinon(interdire_scripts($r[1]),'$code')";
150
-		}
151
-	}
152
-
153
-	return $code;
140
+    // Securite
141
+    if (
142
+        $p->interdire_scripts
143
+        and $p->etoile != '**'
144
+    ) {
145
+        if (!preg_match("/^sinon[(](.*),'([^']*)'[)]$/", $code, $r)) {
146
+            $code = "interdire_scripts($code)";
147
+        } else {
148
+            $code = interdire_scripts($r[2]);
149
+            $code = "sinon(interdire_scripts($r[1]),'$code')";
150
+        }
151
+    }
152
+
153
+    return $code;
154 154
 }
155 155
 
156 156
 
@@ -169,30 +169,30 @@  discard block
 block discarded – undo
169 169
  * @return mixed|string
170 170
  */
171 171
 function sandbox_filtrer_squelette($skel, $corps, $filtres) {
172
-	$series_filtres = func_get_args();
173
-	array_shift($series_filtres);// skel
174
-	array_shift($series_filtres);// corps
175
-
176
-	// proteger les <INCLUDE> et tous les morceaux de php licites
177
-	if ($skel['process_ins'] == 'php') {
178
-		$corps = preg_replace_callback(',<[?](\s|php|=).*[?]>,UimsS', 'echapper_php_callback', $corps);
179
-	}
180
-
181
-	// recuperer les couples de remplacement
182
-	$replace = echapper_php_callback();
183
-
184
-	foreach ($series_filtres as $filtres) {
185
-		if (is_countable($filtres) ? count($filtres) : 0) {
186
-			foreach ($filtres as $filtre) {
187
-				if ($filtre and $f = chercher_filtre($filtre)) {
188
-					$corps = $f($corps);
189
-				}
190
-			}
191
-		}
192
-	}
193
-
194
-	// restaurer les echappements
195
-	return str_replace($replace[0], $replace[1], $corps);
172
+    $series_filtres = func_get_args();
173
+    array_shift($series_filtres);// skel
174
+    array_shift($series_filtres);// corps
175
+
176
+    // proteger les <INCLUDE> et tous les morceaux de php licites
177
+    if ($skel['process_ins'] == 'php') {
178
+        $corps = preg_replace_callback(',<[?](\s|php|=).*[?]>,UimsS', 'echapper_php_callback', $corps);
179
+    }
180
+
181
+    // recuperer les couples de remplacement
182
+    $replace = echapper_php_callback();
183
+
184
+    foreach ($series_filtres as $filtres) {
185
+        if (is_countable($filtres) ? count($filtres) : 0) {
186
+            foreach ($filtres as $filtre) {
187
+                if ($filtre and $f = chercher_filtre($filtre)) {
188
+                    $corps = $f($corps);
189
+                }
190
+            }
191
+        }
192
+    }
193
+
194
+    // restaurer les echappements
195
+    return str_replace($replace[0], $replace[1], $corps);
196 196
 }
197 197
 
198 198
 
@@ -211,21 +211,21 @@  discard block
 block discarded – undo
211 211
  *     - array : Liste( liste des codes PHP, liste des substitutions )
212 212
  **/
213 213
 function echapper_php_callback($r = null) {
214
-	static $src = [];
215
-	static $dst = [];
214
+    static $src = [];
215
+    static $dst = [];
216 216
 
217
-	// si on recoit un tableau, on est en mode echappement
218
-	// on enregistre le code a echapper dans dst, et le code echappe dans src
219
-	if (is_array($r)) {
220
-		$dst[] = $r[0];
217
+    // si on recoit un tableau, on est en mode echappement
218
+    // on enregistre le code a echapper dans dst, et le code echappe dans src
219
+    if (is_array($r)) {
220
+        $dst[] = $r[0];
221 221
 
222
-		return $src[] = '___' . md5($r[0]) . '___';
223
-	}
222
+        return $src[] = '___' . md5($r[0]) . '___';
223
+    }
224 224
 
225
-	// si on recoit pas un tableau, on renvoit les couples de substitution
226
-	// et on RAZ les remplacements
227
-	$r = [$src, $dst];
228
-	$src = $dst = [];
225
+    // si on recoit pas un tableau, on renvoit les couples de substitution
226
+    // et on RAZ les remplacements
227
+    $r = [$src, $dst];
228
+    $src = $dst = [];
229 229
 
230
-	return $r;
230
+    return $r;
231 231
 }
Please login to merge, or discard this patch.
ecrire/public/phraser_html.php 1 patch
Indentation   +1032 added lines, -1032 removed lines patch added patch discarded remove patch
@@ -28,7 +28,7 @@  discard block
 block discarded – undo
28 28
  **/
29 29
 
30 30
 if (!defined('_ECRIRE_INC_VERSION')) {
31
-	return;
31
+    return;
32 32
 }
33 33
 
34 34
 /** Début de la partie principale d'une boucle */
@@ -72,82 +72,82 @@  discard block
 block discarded – undo
72 72
 
73 73
 function phraser_inclure($texte, $ligne, $result) {
74 74
 
75
-	while (preg_match(BALISE_INCLURE, $texte, $match)) {
76
-		$match = array_pad($match, 3, null);
77
-		$p = strpos($texte, (string) $match[0]);
78
-		$debut = substr($texte, 0, $p);
79
-		if ($p) {
80
-			$result = phraser_idiomes($debut, $ligne, $result);
81
-		}
82
-		$ligne += substr_count($debut, "\n");
83
-		$champ = new Inclure();
84
-		$champ->ligne = $ligne;
85
-		$ligne += substr_count($match[0], "\n");
86
-		$fichier = $match[2];
87
-		# assurer ici la migration .php3 => .php
88
-		# et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
89
-		if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
90
-			$fichier = $r[1];
91
-		}
92
-		$champ->texte = ($fichier !== 'page.php') ? $fichier : '';
93
-		$texte = substr($texte, $p + strlen($match[0]));
94
-		// on assimile {var=val} a une liste de un argument sans fonction
95
-		$pos_apres = 0;
96
-		phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
97
-		if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
98
-			if (!function_exists('normaliser_inclure')) {
99
-				include_spip('public/normaliser');
100
-			}
101
-			normaliser_inclure($champ);
102
-		}
103
-		$texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
104
-		$texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
105
-		$result[] = $champ;
106
-	}
107
-
108
-	return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
75
+    while (preg_match(BALISE_INCLURE, $texte, $match)) {
76
+        $match = array_pad($match, 3, null);
77
+        $p = strpos($texte, (string) $match[0]);
78
+        $debut = substr($texte, 0, $p);
79
+        if ($p) {
80
+            $result = phraser_idiomes($debut, $ligne, $result);
81
+        }
82
+        $ligne += substr_count($debut, "\n");
83
+        $champ = new Inclure();
84
+        $champ->ligne = $ligne;
85
+        $ligne += substr_count($match[0], "\n");
86
+        $fichier = $match[2];
87
+        # assurer ici la migration .php3 => .php
88
+        # et de l'ancienne syntaxe INCLURE(page.php3) devenue surperflue
89
+        if ($fichier and preg_match(',^(.*[.]php)3$,', $fichier, $r)) {
90
+            $fichier = $r[1];
91
+        }
92
+        $champ->texte = ($fichier !== 'page.php') ? $fichier : '';
93
+        $texte = substr($texte, $p + strlen($match[0]));
94
+        // on assimile {var=val} a une liste de un argument sans fonction
95
+        $pos_apres = 0;
96
+        phraser_args($texte, '/>', '', $result, $champ, $pos_apres);
97
+        if (!$champ->texte or (is_countable($champ->param) ? count($champ->param) : 0) > 1) {
98
+            if (!function_exists('normaliser_inclure')) {
99
+                include_spip('public/normaliser');
100
+            }
101
+            normaliser_inclure($champ);
102
+        }
103
+        $texte = substr($texte, strpos($texte, '>', $pos_apres) + 1);
104
+        $texte = preg_replace(',^</INCLU[DR]E>,', '', $texte);
105
+        $result[] = $champ;
106
+    }
107
+
108
+    return (($texte === '') ? $result : phraser_idiomes($texte, $ligne, $result));
109 109
 }
110 110
 
111 111
 function phraser_polyglotte($texte, $ligne, $result) {
112 112
 
113
-	if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
114
-		foreach ($m as $match) {
115
-			$p = strpos($texte, (string) $match[0]);
116
-			$debut = substr($texte, 0, $p);
117
-			if ($p) {
118
-				$champ = new Texte();
119
-				$champ->texte = $debut;
120
-				$champ->ligne = $ligne;
121
-				$result[] = $champ;
122
-				$ligne += substr_count($champ->texte, "\n");
123
-			}
124
-
125
-			$champ = new Polyglotte();
126
-			$champ->ligne = $ligne;
127
-			$ligne += substr_count($match[0], "\n");
128
-			$lang = '';
129
-			$bloc = $match[1];
130
-			$texte = substr($texte, $p + strlen($match[0]));
131
-			while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
132
-				$trad = $regs[1];
133
-				if ($trad or $lang) {
134
-					$champ->traductions[$lang] = $trad;
135
-				}
136
-				$lang = $regs[2];
137
-				$bloc = $regs[3];
138
-			}
139
-			$champ->traductions[$lang] = $bloc;
140
-			$result[] = $champ;
141
-		}
142
-	}
143
-	if ($texte !== '') {
144
-		$champ = new Texte();
145
-		$champ->texte = $texte;
146
-		$champ->ligne = $ligne;
147
-		$result[] = $champ;
148
-	}
149
-
150
-	return $result;
113
+    if (preg_match_all(BALISE_POLYGLOTTE, $texte, $m, PREG_SET_ORDER)) {
114
+        foreach ($m as $match) {
115
+            $p = strpos($texte, (string) $match[0]);
116
+            $debut = substr($texte, 0, $p);
117
+            if ($p) {
118
+                $champ = new Texte();
119
+                $champ->texte = $debut;
120
+                $champ->ligne = $ligne;
121
+                $result[] = $champ;
122
+                $ligne += substr_count($champ->texte, "\n");
123
+            }
124
+
125
+            $champ = new Polyglotte();
126
+            $champ->ligne = $ligne;
127
+            $ligne += substr_count($match[0], "\n");
128
+            $lang = '';
129
+            $bloc = $match[1];
130
+            $texte = substr($texte, $p + strlen($match[0]));
131
+            while (preg_match('/^[[:space:]]*([^[{]*)[[:space:]]*[[{]([a-z_]+)[]}](.*)$/si', $bloc, $regs)) {
132
+                $trad = $regs[1];
133
+                if ($trad or $lang) {
134
+                    $champ->traductions[$lang] = $trad;
135
+                }
136
+                $lang = $regs[2];
137
+                $bloc = $regs[3];
138
+            }
139
+            $champ->traductions[$lang] = $bloc;
140
+            $result[] = $champ;
141
+        }
142
+    }
143
+    if ($texte !== '') {
144
+        $champ = new Texte();
145
+        $champ->texte = $texte;
146
+        $champ->ligne = $ligne;
147
+        $result[] = $champ;
148
+    }
149
+
150
+    return $result;
151 151
 }
152 152
 
153 153
 
@@ -169,43 +169,43 @@  discard block
 block discarded – undo
169 169
  * @return array
170 170
  **/
171 171
 function phraser_idiomes($texte, $ligne, $result) {
172
-	while (preg_match(BALISE_IDIOMES, $texte, $match)) {
173
-		$match = array_pad($match, 8, null);
174
-		$p = strpos($texte, (string) $match[0]);
175
-		$ko = (!$match[3] && ($match[5][0] !== '='));
176
-		$debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
177
-		if ($debut) {
178
-			$result = phraser_champs($debut, $ligne, $result);
179
-		}
180
-		$texte = substr($texte, $p + strlen($match[0]));
181
-		$ligne += substr_count($debut, "\n");
182
-		if ($ko) {
183
-			continue;
184
-		} // faux idiome
185
-		$champ = new Idiome();
186
-		$champ->ligne = $ligne;
187
-		$ligne += substr_count($match[0], "\n");
188
-		// Stocker les arguments de la balise de traduction
189
-		$args = [];
190
-		$largs = $match[5];
191
-		while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
192
-			$args[$r[1]] = phraser_champs($r[2], 0, []);
193
-			$largs = substr($largs, strlen($r[0]));
194
-		}
195
-		$champ->arg = $args;
196
-		$champ->nom_champ = strtolower($match[3]);
197
-		$champ->module = $match[2];
198
-		// pas d'imbrication pour les filtres sur langue
199
-		$pos_apres = 0;
200
-		phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
201
-		$champ->apres = substr($match[7] ?? '', $pos_apres);
202
-		$result[] = $champ;
203
-	}
204
-	if ($texte !== '') {
205
-		$result = phraser_champs($texte, $ligne, $result);
206
-	}
207
-
208
-	return $result;
172
+    while (preg_match(BALISE_IDIOMES, $texte, $match)) {
173
+        $match = array_pad($match, 8, null);
174
+        $p = strpos($texte, (string) $match[0]);
175
+        $ko = (!$match[3] && ($match[5][0] !== '='));
176
+        $debut = substr($texte, 0, $p + ($ko ? strlen($match[0]) : 0));
177
+        if ($debut) {
178
+            $result = phraser_champs($debut, $ligne, $result);
179
+        }
180
+        $texte = substr($texte, $p + strlen($match[0]));
181
+        $ligne += substr_count($debut, "\n");
182
+        if ($ko) {
183
+            continue;
184
+        } // faux idiome
185
+        $champ = new Idiome();
186
+        $champ->ligne = $ligne;
187
+        $ligne += substr_count($match[0], "\n");
188
+        // Stocker les arguments de la balise de traduction
189
+        $args = [];
190
+        $largs = $match[5];
191
+        while (preg_match(BALISE_IDIOMES_ARGS, $largs, $r)) {
192
+            $args[$r[1]] = phraser_champs($r[2], 0, []);
193
+            $largs = substr($largs, strlen($r[0]));
194
+        }
195
+        $champ->arg = $args;
196
+        $champ->nom_champ = strtolower($match[3]);
197
+        $champ->module = $match[2];
198
+        // pas d'imbrication pour les filtres sur langue
199
+        $pos_apres = 0;
200
+        phraser_args($match[7] ?? '', ':', '', [], $champ, $pos_apres);
201
+        $champ->apres = substr($match[7] ?? '', $pos_apres);
202
+        $result[] = $champ;
203
+    }
204
+    if ($texte !== '') {
205
+        $result = phraser_champs($texte, $ligne, $result);
206
+    }
207
+
208
+    return $result;
209 209
 }
210 210
 
211 211
 /**
@@ -223,47 +223,47 @@  discard block
 block discarded – undo
223 223
  * @return array
224 224
  **/
225 225
 function phraser_champs($texte, $ligne, $result) {
226
-	while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
227
-		$p = strpos($texte, (string) $match[0]);
228
-		// texte après la balise
229
-		$suite = substr($texte, $p + strlen($match[0]));
230
-
231
-		$debut = substr($texte, 0, $p);
232
-		if ($p) {
233
-			$result = phraser_polyglotte($debut, $ligne, $result);
234
-		}
235
-		$ligne += substr_count($debut, "\n");
236
-		$champ = new Champ();
237
-		$champ->ligne = $ligne;
238
-		$ligne += substr_count($match[0], "\n");
239
-		$champ->nom_boucle = $match[2];
240
-		$champ->nom_champ = $match[3];
241
-		$champ->etoile = $match[5];
242
-
243
-		if ($suite and $suite[0] == '{') {
244
-			phraser_arg($suite, '', [], $champ);
245
-			// ce ltrim est une ereur de conception
246
-			// mais on le conserve par souci de compatibilite
247
-			$texte = ltrim($suite);
248
-			// Il faudrait le normaliser dans l'arbre de syntaxe abstraite
249
-			// pour faire sauter ce cas particulier a la decompilation.
250
-			/* Ce qui suit est malheureusement incomplet pour cela:
226
+    while (preg_match('/' . NOM_DE_CHAMP . '/S', $texte, $match)) {
227
+        $p = strpos($texte, (string) $match[0]);
228
+        // texte après la balise
229
+        $suite = substr($texte, $p + strlen($match[0]));
230
+
231
+        $debut = substr($texte, 0, $p);
232
+        if ($p) {
233
+            $result = phraser_polyglotte($debut, $ligne, $result);
234
+        }
235
+        $ligne += substr_count($debut, "\n");
236
+        $champ = new Champ();
237
+        $champ->ligne = $ligne;
238
+        $ligne += substr_count($match[0], "\n");
239
+        $champ->nom_boucle = $match[2];
240
+        $champ->nom_champ = $match[3];
241
+        $champ->etoile = $match[5];
242
+
243
+        if ($suite and $suite[0] == '{') {
244
+            phraser_arg($suite, '', [], $champ);
245
+            // ce ltrim est une ereur de conception
246
+            // mais on le conserve par souci de compatibilite
247
+            $texte = ltrim($suite);
248
+            // Il faudrait le normaliser dans l'arbre de syntaxe abstraite
249
+            // pour faire sauter ce cas particulier a la decompilation.
250
+            /* Ce qui suit est malheureusement incomplet pour cela:
251 251
 			if ($n = (strlen($suite) - strlen($texte))) {
252 252
 				$champ->apres = array(new Texte);
253 253
 				$champ->apres[0]->texte = substr($suite,0,$n);
254 254
 			}
255 255
 			*/
256
-		} else {
257
-			$texte = $suite;
258
-		}
259
-		phraser_vieux($champ);
260
-		$result[] = $champ;
261
-	}
262
-	if ($texte !== '') {
263
-		$result = phraser_polyglotte($texte, $ligne, $result);
264
-	}
265
-
266
-	return $result;
256
+        } else {
257
+            $texte = $suite;
258
+        }
259
+        phraser_vieux($champ);
260
+        $result[] = $champ;
261
+    }
262
+    if ($texte !== '') {
263
+        $result = phraser_polyglotte($texte, $ligne, $result);
264
+    }
265
+
266
+    return $result;
267 267
 }
268 268
 
269 269
 // Gestion des imbrications:
@@ -272,15 +272,15 @@  discard block
 block discarded – undo
272 272
 // on recommence tant qu'il y a des [...] en substituant a l'appel suivant
273 273
 
274 274
 function phraser_champs_etendus($texte, $ligne, $result) {
275
-	if ($texte === '') {
276
-		return $result;
277
-	}
278
-	$sep = '##';
279
-	while (strpos($texte, (string) $sep) !== false) {
280
-		$sep .= '#';
281
-	}
282
-
283
-	return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
275
+    if ($texte === '') {
276
+        return $result;
277
+    }
278
+    $sep = '##';
279
+    while (strpos($texte, (string) $sep) !== false) {
280
+        $sep .= '#';
281
+    }
282
+
283
+    return array_merge($result, phraser_champs_interieurs($texte, $ligne, $sep, []));
284 284
 }
285 285
 
286 286
 /**
@@ -299,275 +299,275 @@  discard block
 block discarded – undo
299 299
  * @return array
300 300
  */
301 301
 function phraser_args(string $texte, $fin, $sep, $result, &$pointeur_champ, &$pos_debut) {
302
-	$length = strlen($texte);
303
-	while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
304
-		$pos_debut++;
305
-	}
306
-	while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
307
-		// phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
308
-		$st = substr($texte, $pos_debut);
309
-		$result = phraser_arg($st, $sep, $result, $pointeur_champ);
310
-		$pos_debut = $length - strlen($st);
311
-		while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
312
-			$pos_debut++;
313
-		}
314
-	}
315
-
316
-	return $result;
302
+    $length = strlen($texte);
303
+    while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
304
+        $pos_debut++;
305
+    }
306
+    while (($pos_debut < $length) && !str_contains($fin, $texte[$pos_debut])) {
307
+        // phraser_arg modifie directement le $texte, on fait donc avec ici en passant par une sous chaine
308
+        $st = substr($texte, $pos_debut);
309
+        $result = phraser_arg($st, $sep, $result, $pointeur_champ);
310
+        $pos_debut = $length - strlen($st);
311
+        while ($pos_debut < $length and trim($texte[$pos_debut]) === '') {
312
+            $pos_debut++;
313
+        }
314
+    }
315
+
316
+    return $result;
317 317
 }
318 318
 
319 319
 function phraser_arg(&$texte, $sep, $result, &$pointeur_champ) {
320
-	preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
321
-	$suite = ltrim($match[2]);
322
-	$fonc = trim($match[1]);
323
-	if ($fonc && $fonc[0] == '|') {
324
-		$fonc = ltrim(substr($fonc, 1));
325
-	}
326
-	$res = [$fonc];
327
-	$err_f = '';
328
-	// cas du filtre sans argument ou du critere /
329
-	if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
330
-		// si pas d'argument, alors il faut une fonction ou un double |
331
-		if (!$match[1]) {
332
-			$err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
333
-			erreur_squelette($err_f, $pointeur_champ);
334
-			$texte = '';
335
-		} else {
336
-			$texte = $suite;
337
-		}
338
-		if ($err_f) {
339
-			$pointeur_champ->param = false;
340
-		} elseif ($fonc !== '') {
341
-			$pointeur_champ->param[] = $res;
342
-		}
343
-		// pour les balises avec faux filtres qui boudent ce dur larbeur
344
-		$pointeur_champ->fonctions[] = [$fonc, ''];
345
-
346
-		return $result;
347
-	}
348
-	$args = ltrim(substr($suite, 1)); // virer le '(' initial
349
-	$collecte = [];
350
-	while ($args && $args[0] != '}') {
351
-		if ($args[0] == '"') {
352
-			preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
353
-		} elseif ($args[0] == "'") {
354
-			preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
355
-		} else {
356
-			preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
357
-			if (!isset($regs[2]) or !strlen($regs[2])) {
358
-				$err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
359
-				erreur_squelette($err_f, $pointeur_champ);
360
-				$champ = new Texte();
361
-				$champ->apres = $champ->avant = $args = '';
362
-				break;
363
-			}
364
-		}
365
-		$arg = $regs[2];
366
-		if (trim($regs[1])) {
367
-			$champ = new Texte();
368
-			$champ->texte = $arg;
369
-			$champ->apres = $champ->avant = $regs[1];
370
-			$result[] = $champ;
371
-			$collecte[] = $champ;
372
-			$args = ltrim($regs[count($regs) - 1]);
373
-		} else {
374
-			if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
375
-				// 0 est un aveu d'impuissance. A completer
376
-				$arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
377
-
378
-				$args = ltrim($regs[count($regs) - 1]);
379
-				$collecte = array_merge($collecte, $arg);
380
-				$result = array_merge($result, $arg);
381
-			} else {
382
-				$n = strpos($args, (string) $r[0]);
383
-				$pred = substr($args, 0, $n);
384
-				$par = ',}';
385
-				if (preg_match('/^(.*)\($/', $pred, $m)) {
386
-					$pred = $m[1];
387
-					$par = ')';
388
-				}
389
-				if ($pred) {
390
-					$champ = new Texte();
391
-					$champ->texte = $pred;
392
-					$champ->apres = $champ->avant = '';
393
-					$result[] = $champ;
394
-					$collecte[] = $champ;
395
-				}
396
-				$rec = substr($args, $n + strlen($r[0]) - 1);
397
-				$champ = new Champ();
398
-				$champ->nom_boucle = $r[2];
399
-				$champ->nom_champ = $r[3];
400
-				$champ->etoile = $r[5];
401
-				$next = $r[6];
402
-				while ($next == '{') {
403
-					phraser_arg($rec, $sep, [], $champ);
404
-					$args = ltrim($rec);
405
-					$next = $args[0] ?? '';
406
-				}
407
-				while ($next == '|') {
408
-					$pos_apres = 0;
409
-					phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
410
-					$args = substr($rec, $pos_apres);
411
-					$next = $args[0] ?? '';
412
-				}
413
-				// Si erreur de syntaxe dans un sous-argument, propager.
414
-				if ($champ->param === false) {
415
-					$err_f = true;
416
-				} else {
417
-					phraser_vieux($champ);
418
-				}
419
-				if ($par == ')') {
420
-					$args = substr($args, 1);
421
-				}
422
-				$collecte[] = $champ;
423
-				$result[] = $champ;
424
-			}
425
-		}
426
-		if (isset($args[0]) and $args[0] == ',') {
427
-			$args = ltrim(substr($args, 1));
428
-			if ($collecte) {
429
-				$res[] = $collecte;
430
-				$collecte = [];
431
-			}
432
-		}
433
-	}
434
-	if ($collecte) {
435
-		$res[] = $collecte;
436
-		$collecte = [];
437
-	}
438
-	$texte = substr($args, 1);
439
-	$source = substr($suite, 0, strlen($suite) - strlen($texte));
440
-	// propager les erreurs, et ignorer les param vides
441
-	if ($pointeur_champ->param !== false) {
442
-		if ($err_f) {
443
-			$pointeur_champ->param = false;
444
-		} elseif ($fonc !== '' || count($res) > 1) {
445
-			$pointeur_champ->param[] = $res;
446
-		}
447
-	}
448
-	// pour les balises avec faux filtres qui boudent ce dur larbeur
449
-	$pointeur_champ->fonctions[] = [$fonc, $source];
450
-
451
-	return $result;
320
+    preg_match(',^(\|?[^}{)|]*)(.*)$,ms', $texte, $match);
321
+    $suite = ltrim($match[2]);
322
+    $fonc = trim($match[1]);
323
+    if ($fonc && $fonc[0] == '|') {
324
+        $fonc = ltrim(substr($fonc, 1));
325
+    }
326
+    $res = [$fonc];
327
+    $err_f = '';
328
+    // cas du filtre sans argument ou du critere /
329
+    if (($suite && ($suite[0] != '{')) || ($fonc && $fonc[0] == '/')) {
330
+        // si pas d'argument, alors il faut une fonction ou un double |
331
+        if (!$match[1]) {
332
+            $err_f = ['zbug_erreur_filtre', ['filtre' => $texte]];
333
+            erreur_squelette($err_f, $pointeur_champ);
334
+            $texte = '';
335
+        } else {
336
+            $texte = $suite;
337
+        }
338
+        if ($err_f) {
339
+            $pointeur_champ->param = false;
340
+        } elseif ($fonc !== '') {
341
+            $pointeur_champ->param[] = $res;
342
+        }
343
+        // pour les balises avec faux filtres qui boudent ce dur larbeur
344
+        $pointeur_champ->fonctions[] = [$fonc, ''];
345
+
346
+        return $result;
347
+    }
348
+    $args = ltrim(substr($suite, 1)); // virer le '(' initial
349
+    $collecte = [];
350
+    while ($args && $args[0] != '}') {
351
+        if ($args[0] == '"') {
352
+            preg_match('/^(")([^"]*)(")(.*)$/ms', $args, $regs);
353
+        } elseif ($args[0] == "'") {
354
+            preg_match("/^(')([^']*)(')(.*)$/ms", $args, $regs);
355
+        } else {
356
+            preg_match('/^([[:space:]]*)([^,([{}]*([(\[{][^])}]*[])}])?[^,}]*)([,}].*)$/ms', $args, $regs);
357
+            if (!isset($regs[2]) or !strlen($regs[2])) {
358
+                $err_f = ['zbug_erreur_filtre', ['filtre' => $args]];
359
+                erreur_squelette($err_f, $pointeur_champ);
360
+                $champ = new Texte();
361
+                $champ->apres = $champ->avant = $args = '';
362
+                break;
363
+            }
364
+        }
365
+        $arg = $regs[2];
366
+        if (trim($regs[1])) {
367
+            $champ = new Texte();
368
+            $champ->texte = $arg;
369
+            $champ->apres = $champ->avant = $regs[1];
370
+            $result[] = $champ;
371
+            $collecte[] = $champ;
372
+            $args = ltrim($regs[count($regs) - 1]);
373
+        } else {
374
+            if (!preg_match('/' . NOM_DE_CHAMP . '([{|])/', $arg, $r)) {
375
+                // 0 est un aveu d'impuissance. A completer
376
+                $arg = phraser_champs_exterieurs($arg, 0, $sep, $result);
377
+
378
+                $args = ltrim($regs[count($regs) - 1]);
379
+                $collecte = array_merge($collecte, $arg);
380
+                $result = array_merge($result, $arg);
381
+            } else {
382
+                $n = strpos($args, (string) $r[0]);
383
+                $pred = substr($args, 0, $n);
384
+                $par = ',}';
385
+                if (preg_match('/^(.*)\($/', $pred, $m)) {
386
+                    $pred = $m[1];
387
+                    $par = ')';
388
+                }
389
+                if ($pred) {
390
+                    $champ = new Texte();
391
+                    $champ->texte = $pred;
392
+                    $champ->apres = $champ->avant = '';
393
+                    $result[] = $champ;
394
+                    $collecte[] = $champ;
395
+                }
396
+                $rec = substr($args, $n + strlen($r[0]) - 1);
397
+                $champ = new Champ();
398
+                $champ->nom_boucle = $r[2];
399
+                $champ->nom_champ = $r[3];
400
+                $champ->etoile = $r[5];
401
+                $next = $r[6];
402
+                while ($next == '{') {
403
+                    phraser_arg($rec, $sep, [], $champ);
404
+                    $args = ltrim($rec);
405
+                    $next = $args[0] ?? '';
406
+                }
407
+                while ($next == '|') {
408
+                    $pos_apres = 0;
409
+                    phraser_args($rec, $par, $sep, [], $champ, $pos_apres);
410
+                    $args = substr($rec, $pos_apres);
411
+                    $next = $args[0] ?? '';
412
+                }
413
+                // Si erreur de syntaxe dans un sous-argument, propager.
414
+                if ($champ->param === false) {
415
+                    $err_f = true;
416
+                } else {
417
+                    phraser_vieux($champ);
418
+                }
419
+                if ($par == ')') {
420
+                    $args = substr($args, 1);
421
+                }
422
+                $collecte[] = $champ;
423
+                $result[] = $champ;
424
+            }
425
+        }
426
+        if (isset($args[0]) and $args[0] == ',') {
427
+            $args = ltrim(substr($args, 1));
428
+            if ($collecte) {
429
+                $res[] = $collecte;
430
+                $collecte = [];
431
+            }
432
+        }
433
+    }
434
+    if ($collecte) {
435
+        $res[] = $collecte;
436
+        $collecte = [];
437
+    }
438
+    $texte = substr($args, 1);
439
+    $source = substr($suite, 0, strlen($suite) - strlen($texte));
440
+    // propager les erreurs, et ignorer les param vides
441
+    if ($pointeur_champ->param !== false) {
442
+        if ($err_f) {
443
+            $pointeur_champ->param = false;
444
+        } elseif ($fonc !== '' || count($res) > 1) {
445
+            $pointeur_champ->param[] = $res;
446
+        }
447
+    }
448
+    // pour les balises avec faux filtres qui boudent ce dur larbeur
449
+    $pointeur_champ->fonctions[] = [$fonc, $source];
450
+
451
+    return $result;
452 452
 }
453 453
 
454 454
 
455 455
 function phraser_champs_exterieurs($texte, $ligne, $sep, $nested) {
456
-	$res = [];
457
-	while (($p = strpos($texte, (string) "%$sep")) !== false) {
458
-		if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
459
-			break;
460
-		}
461
-		$debut = substr($texte, 0, $p);
462
-		$texte = substr($texte, $p + strlen($m[0]));
463
-		if ($p) {
464
-			$res = phraser_inclure($debut, $ligne, $res);
465
-		}
466
-		$ligne += substr_count($debut, "\n");
467
-		$res[] = $nested[$m[1]];
468
-	}
469
-
470
-	return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
456
+    $res = [];
457
+    while (($p = strpos($texte, (string) "%$sep")) !== false) {
458
+        if (!preg_match(',^%' . preg_quote($sep) . '([0-9]+)@,', substr($texte, $p), $m)) {
459
+            break;
460
+        }
461
+        $debut = substr($texte, 0, $p);
462
+        $texte = substr($texte, $p + strlen($m[0]));
463
+        if ($p) {
464
+            $res = phraser_inclure($debut, $ligne, $res);
465
+        }
466
+        $ligne += substr_count($debut, "\n");
467
+        $res[] = $nested[$m[1]];
468
+    }
469
+
470
+    return (($texte === '') ? $res : phraser_inclure($texte, $ligne, $res));
471 471
 }
472 472
 
473 473
 function phraser_champs_interieurs($texte, $ligne, $sep, $result) {
474
-	$i = 0; // en fait count($result)
475
-	$x = '';
476
-
477
-	while (true) {
478
-		$j = $i;
479
-		$n = $ligne;
480
-		while (preg_match(CHAMP_ETENDU, $texte, $match)) {
481
-			$p = strpos($texte, (string) $match[0]);
482
-			$debut = substr($texte, 0, $p);
483
-			if ($p) {
484
-				$result[$i] = $debut;
485
-				$i++;
486
-			}
487
-			$nom = $match[4];
488
-			$champ = new Champ();
489
-			// ca ne marche pas encore en cas de champ imbrique
490
-			$champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
491
-			$champ->nom_boucle = $match[3];
492
-			$champ->nom_champ = $nom;
493
-			$champ->etoile = $match[6];
494
-			// phraser_args indiquera ou commence apres
495
-			$pos_apres = 0;
496
-			$result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
497
-			phraser_vieux($champ);
498
-			$champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
499
-			$debut = substr($match[7], $pos_apres + 1);
500
-			if (!empty($debut)) {
501
-				$n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
502
-			}
503
-			$champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
504
-
505
-			// reinjecter la boucle si c'en est une
506
-			phraser_boucle_placeholder($champ);
507
-
508
-			$result[$i] = $champ;
509
-			$i++;
510
-			$texte = substr($texte, $p + strlen($match[0]));
511
-		}
512
-		if ($texte !== '') {
513
-			$result[$i] = $texte;
514
-			$i++;
515
-		}
516
-		$x = '';
517
-
518
-		while ($j < $i) {
519
-			$z = $result[$j];
520
-			// j'aurais besoin de connaitre le nombre de lignes...
521
-			if (is_object($z)) {
522
-				$x .= "%$sep$j@";
523
-			} else {
524
-				$x .= $z;
525
-			}
526
-			$j++;
527
-		}
528
-		if (preg_match(CHAMP_ETENDU, $x)) {
529
-			$texte = $x;
530
-		} else {
531
-			return phraser_champs_exterieurs($x, $ligne, $sep, $result);
532
-		}
533
-	}
474
+    $i = 0; // en fait count($result)
475
+    $x = '';
476
+
477
+    while (true) {
478
+        $j = $i;
479
+        $n = $ligne;
480
+        while (preg_match(CHAMP_ETENDU, $texte, $match)) {
481
+            $p = strpos($texte, (string) $match[0]);
482
+            $debut = substr($texte, 0, $p);
483
+            if ($p) {
484
+                $result[$i] = $debut;
485
+                $i++;
486
+            }
487
+            $nom = $match[4];
488
+            $champ = new Champ();
489
+            // ca ne marche pas encore en cas de champ imbrique
490
+            $champ->ligne = $x ? 0 : ($n + substr_count($debut, "\n"));
491
+            $champ->nom_boucle = $match[3];
492
+            $champ->nom_champ = $nom;
493
+            $champ->etoile = $match[6];
494
+            // phraser_args indiquera ou commence apres
495
+            $pos_apres = 0;
496
+            $result = phraser_args($match[7], ')', $sep, $result, $champ, $pos_apres);
497
+            phraser_vieux($champ);
498
+            $champ->avant =	phraser_champs_exterieurs($match[1], $n, $sep, $result);
499
+            $debut = substr($match[7], $pos_apres + 1);
500
+            if (!empty($debut)) {
501
+                $n += substr_count(substr($texte, 0, strpos($texte, $debut)), "\n");
502
+            }
503
+            $champ->apres = phraser_champs_exterieurs($debut, $n, $sep, $result);
504
+
505
+            // reinjecter la boucle si c'en est une
506
+            phraser_boucle_placeholder($champ);
507
+
508
+            $result[$i] = $champ;
509
+            $i++;
510
+            $texte = substr($texte, $p + strlen($match[0]));
511
+        }
512
+        if ($texte !== '') {
513
+            $result[$i] = $texte;
514
+            $i++;
515
+        }
516
+        $x = '';
517
+
518
+        while ($j < $i) {
519
+            $z = $result[$j];
520
+            // j'aurais besoin de connaitre le nombre de lignes...
521
+            if (is_object($z)) {
522
+                $x .= "%$sep$j@";
523
+            } else {
524
+                $x .= $z;
525
+            }
526
+            $j++;
527
+        }
528
+        if (preg_match(CHAMP_ETENDU, $x)) {
529
+            $texte = $x;
530
+        } else {
531
+            return phraser_champs_exterieurs($x, $ligne, $sep, $result);
532
+        }
533
+    }
534 534
 }
535 535
 
536 536
 function phraser_vieux(&$champ) {
537
-	$nom = $champ->nom_champ;
538
-	if ($nom == 'EMBED_DOCUMENT') {
539
-		if (!function_exists('phraser_vieux_emb')) {
540
-			include_spip('public/normaliser');
541
-		}
542
-		phraser_vieux_emb($champ);
543
-	} elseif ($nom == 'EXPOSER') {
544
-		if (!function_exists('phraser_vieux_exposer')) {
545
-			include_spip('public/normaliser');
546
-		}
547
-		phraser_vieux_exposer($champ);
548
-	} elseif ($champ->param) {
549
-		if ($nom == 'FORMULAIRE_RECHERCHE') {
550
-			if (!function_exists('phraser_vieux_recherche')) {
551
-				include_spip('public/normaliser');
552
-			}
553
-			phraser_vieux_recherche($champ);
554
-		} elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
555
-			if (!function_exists('phraser_vieux_logos')) {
556
-				include_spip('public/normaliser');
557
-			}
558
-			phraser_vieux_logos($champ);
559
-		} elseif ($nom == 'MODELE') {
560
-			if (!function_exists('phraser_vieux_modele')) {
561
-				include_spip('public/normaliser');
562
-			}
563
-			phraser_vieux_modele($champ);
564
-		} elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
565
-			if (!function_exists('phraser_vieux_inclu')) {
566
-				include_spip('public/normaliser');
567
-			}
568
-			phraser_vieux_inclu($champ);
569
-		}
570
-	}
537
+    $nom = $champ->nom_champ;
538
+    if ($nom == 'EMBED_DOCUMENT') {
539
+        if (!function_exists('phraser_vieux_emb')) {
540
+            include_spip('public/normaliser');
541
+        }
542
+        phraser_vieux_emb($champ);
543
+    } elseif ($nom == 'EXPOSER') {
544
+        if (!function_exists('phraser_vieux_exposer')) {
545
+            include_spip('public/normaliser');
546
+        }
547
+        phraser_vieux_exposer($champ);
548
+    } elseif ($champ->param) {
549
+        if ($nom == 'FORMULAIRE_RECHERCHE') {
550
+            if (!function_exists('phraser_vieux_recherche')) {
551
+                include_spip('public/normaliser');
552
+            }
553
+            phraser_vieux_recherche($champ);
554
+        } elseif (preg_match(',^LOGO_[A-Z]+,', $nom)) {
555
+            if (!function_exists('phraser_vieux_logos')) {
556
+                include_spip('public/normaliser');
557
+            }
558
+            phraser_vieux_logos($champ);
559
+        } elseif ($nom == 'MODELE') {
560
+            if (!function_exists('phraser_vieux_modele')) {
561
+                include_spip('public/normaliser');
562
+            }
563
+            phraser_vieux_modele($champ);
564
+        } elseif ($nom == 'INCLURE' or $nom == 'INCLUDE') {
565
+            if (!function_exists('phraser_vieux_inclu')) {
566
+                include_spip('public/normaliser');
567
+            }
568
+            phraser_vieux_inclu($champ);
569
+        }
570
+    }
571 571
 }
572 572
 
573 573
 
@@ -595,200 +595,200 @@  discard block
 block discarded – undo
595 595
  **/
596 596
 function phraser_criteres($params, &$result) {
597 597
 
598
-	$err_ci = ''; // indiquera s'il y a eu une erreur
599
-	$args = [];
600
-	$type = $result->type_requete;
601
-	$doublons = [];
602
-	foreach ($params as $v) {
603
-		$var = $v[1][0];
604
-		$param = ($var->type != 'texte') ? '' : $var->texte;
605
-		if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
606
-			// plus d'un argument et pas le critere IN:
607
-			// detecter comme on peut si c'est le critere implicite LIMIT debut, fin
608
-			if (
609
-				$var->type != 'texte'
610
-				or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
611
-			) {
612
-				$op = ',';
613
-				$not = false;
614
-				$cond = false;
615
-			} else {
616
-				// Le debut du premier argument est l'operateur
617
-				preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
618
-				$op = $m[2];
619
-				$not = (bool) $m[1];
620
-				$cond = $m[3];
621
-				// virer le premier argument,
622
-				// et mettre son reliquat eventuel
623
-				// Recopier pour ne pas alterer le texte source
624
-				// utile au debusqueur
625
-				if ($m[4]) {
626
-					// une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
627
-					if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
628
-						$c = null;
629
-						eval('$c = ' . $m[4] . ';');
630
-						if (isset($c)) {
631
-							$m[4] = $c;
632
-						}
633
-					}
634
-					$texte = new Texte();
635
-					$texte->texte = $m[4];
636
-					$v[1][0] = $texte;
637
-				} else {
638
-					array_shift($v[1]);
639
-				}
640
-			}
641
-			array_shift($v); // $v[O] est vide
642
-			$crit = new Critere();
643
-			$crit->op = $op;
644
-			$crit->not = $not;
645
-			$crit->cond = $cond;
646
-			$crit->exclus = '';
647
-			$crit->param = $v;
648
-			$args[] = $crit;
649
-		} else {
650
-			if ($var->type != 'texte') {
651
-				// cas 1 seul arg ne commencant pas par du texte brut:
652
-				// erreur ou critere infixe "/"
653
-				if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
654
-					$err_ci = [
655
-						'zbug_critere_inconnu',
656
-						['critere' => $var->nom_champ]
657
-					];
658
-					erreur_squelette($err_ci, $result);
659
-				} else {
660
-					$crit = new Critere();
661
-					$crit->op = '/';
662
-					$crit->not = false;
663
-					$crit->exclus = '';
664
-					$crit->param = [[$v[1][0]], [$v[1][2]]];
665
-					$args[] = $crit;
666
-				}
667
-			} else {
668
-				// traiter qq lexemes particuliers pour faciliter la suite
669
-				// les separateurs
670
-				if ($var->apres) {
671
-					$result->separateur[] = $param;
672
-				} elseif (($param == 'tout') or ($param == 'tous')) {
673
-					$result->modificateur['tout'] = true;
674
-				} elseif ($param == 'plat') {
675
-					$result->modificateur['plat'] = true;
676
-				}
677
-
678
-				// Boucle hierarchie, analyser le critere id_rubrique
679
-				// et les autres critères {id_x} pour forcer {tout} sur
680
-				// ceux-ci pour avoir la rubrique mere...
681
-				// Les autres critères de la boucle hierarchie doivent être
682
-				// traités normalement.
683
-				elseif (
684
-					strcasecmp($type, 'hierarchie') == 0
685
-					and !preg_match(",^id_rubrique\b,", $param)
686
-					and preg_match(',^id_\w+\s*$,', $param)
687
-				) {
688
-					$result->modificateur['tout'] = true;
689
-				} elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
690
-					// rien a faire sur {id_rubrique} tout seul
691
-				} else {
692
-					// pas d'emplacement statique, faut un dynamique
693
-					// mais il y a 2 cas qui ont les 2 !
694
-					if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
695
-						// cette variable sera inseree dans le code
696
-						// et son nom sert d'indicateur des maintenant
697
-						$result->doublons = '$doublons_index';
698
-						if ($param == 'unique') {
699
-							$param = 'doublons';
700
-						}
701
-					} elseif ($param == 'recherche') {
702
-						// meme chose (a cause de #nom_de_boucle:URL_*)
703
-						$result->hash = ' ';
704
-					}
705
-
706
-					if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
707
-						$crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
708
-					} elseif (
709
-						preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
710
-						')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
711
-					) {
712
-						$a2 = trim($m[8]);
713
-						if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
714
-							$a2 = substr($a2, 1, -1);
715
-						}
716
-						$crit = phraser_critere_infixe(
717
-							$m[2],
718
-							$a2,
719
-							$v,
720
-							(($m[2] == 'lang_select') ? $m[2] : $m[7]),
721
-							$m[6],
722
-							$m[5]
723
-						);
724
-						$crit->exclus = $m[1];
725
-					} elseif (
726
-						preg_match('/^([!]?)\s*(' .
727
-						CHAMP_SQL_PLUS_FONC .
728
-						')\s*(\??)(.*)$/is', $param, $m)
729
-					) {
730
-						// contient aussi les comparaisons implicites !
731
-						// Comme ci-dessus:
732
-						// le premier arg contient l'operateur
733
-						array_shift($v);
734
-						if ($m[6]) {
735
-							$v[0][0] = new Texte();
736
-							$v[0][0]->texte = $m[6];
737
-						} else {
738
-							array_shift($v[0]);
739
-							if (!$v[0]) {
740
-								array_shift($v);
741
-							}
742
-						}
743
-						$crit = new Critere();
744
-						$crit->op = $m[2];
745
-						$crit->param = $v;
746
-						$crit->not = (bool) $m[1];
747
-						$crit->cond = $m[5];
748
-					} else {
749
-						$err_ci = [
750
-							'zbug_critere_inconnu',
751
-							['critere' => $param]
752
-						];
753
-						erreur_squelette($err_ci, $result);
754
-					}
755
-
756
-					if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
757
-						$args[] = $crit;
758
-					} else {
759
-						$doublons[] = $crit;
760
-					}
761
-				}
762
-			}
763
-		}
764
-	}
765
-
766
-	// les doublons non nies doivent etre le dernier critere
767
-	// pour que la variable $doublon_index ait la bonne valeur
768
-	// cf critere_doublon
769
-	if ($doublons) {
770
-		$args = [...$args, ...$doublons];
771
-	}
772
-
773
-	// Si erreur, laisser la chaine dans ce champ pour le HTTP 503
774
-	if (!$err_ci) {
775
-		$result->criteres = $args;
776
-	}
598
+    $err_ci = ''; // indiquera s'il y a eu une erreur
599
+    $args = [];
600
+    $type = $result->type_requete;
601
+    $doublons = [];
602
+    foreach ($params as $v) {
603
+        $var = $v[1][0];
604
+        $param = ($var->type != 'texte') ? '' : $var->texte;
605
+        if (((is_countable($v) ? count($v) : 0) > 2) && (!preg_match(',[^A-Za-z]IN[^A-Za-z],i', $param))) {
606
+            // plus d'un argument et pas le critere IN:
607
+            // detecter comme on peut si c'est le critere implicite LIMIT debut, fin
608
+            if (
609
+                $var->type != 'texte'
610
+                or preg_match('/^(n|n-|(n-)?\d+)$/S', $param)
611
+            ) {
612
+                $op = ',';
613
+                $not = false;
614
+                $cond = false;
615
+            } else {
616
+                // Le debut du premier argument est l'operateur
617
+                preg_match('/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\??)[[:space:]]*(.*)$/ms', $param, $m);
618
+                $op = $m[2];
619
+                $not = (bool) $m[1];
620
+                $cond = $m[3];
621
+                // virer le premier argument,
622
+                // et mettre son reliquat eventuel
623
+                // Recopier pour ne pas alterer le texte source
624
+                // utile au debusqueur
625
+                if ($m[4]) {
626
+                    // une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
627
+                    if (preg_match(',^(["\'])(.*)\1$,', $m[4])) {
628
+                        $c = null;
629
+                        eval('$c = ' . $m[4] . ';');
630
+                        if (isset($c)) {
631
+                            $m[4] = $c;
632
+                        }
633
+                    }
634
+                    $texte = new Texte();
635
+                    $texte->texte = $m[4];
636
+                    $v[1][0] = $texte;
637
+                } else {
638
+                    array_shift($v[1]);
639
+                }
640
+            }
641
+            array_shift($v); // $v[O] est vide
642
+            $crit = new Critere();
643
+            $crit->op = $op;
644
+            $crit->not = $not;
645
+            $crit->cond = $cond;
646
+            $crit->exclus = '';
647
+            $crit->param = $v;
648
+            $args[] = $crit;
649
+        } else {
650
+            if ($var->type != 'texte') {
651
+                // cas 1 seul arg ne commencant pas par du texte brut:
652
+                // erreur ou critere infixe "/"
653
+                if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) != '/')) {
654
+                    $err_ci = [
655
+                        'zbug_critere_inconnu',
656
+                        ['critere' => $var->nom_champ]
657
+                    ];
658
+                    erreur_squelette($err_ci, $result);
659
+                } else {
660
+                    $crit = new Critere();
661
+                    $crit->op = '/';
662
+                    $crit->not = false;
663
+                    $crit->exclus = '';
664
+                    $crit->param = [[$v[1][0]], [$v[1][2]]];
665
+                    $args[] = $crit;
666
+                }
667
+            } else {
668
+                // traiter qq lexemes particuliers pour faciliter la suite
669
+                // les separateurs
670
+                if ($var->apres) {
671
+                    $result->separateur[] = $param;
672
+                } elseif (($param == 'tout') or ($param == 'tous')) {
673
+                    $result->modificateur['tout'] = true;
674
+                } elseif ($param == 'plat') {
675
+                    $result->modificateur['plat'] = true;
676
+                }
677
+
678
+                // Boucle hierarchie, analyser le critere id_rubrique
679
+                // et les autres critères {id_x} pour forcer {tout} sur
680
+                // ceux-ci pour avoir la rubrique mere...
681
+                // Les autres critères de la boucle hierarchie doivent être
682
+                // traités normalement.
683
+                elseif (
684
+                    strcasecmp($type, 'hierarchie') == 0
685
+                    and !preg_match(",^id_rubrique\b,", $param)
686
+                    and preg_match(',^id_\w+\s*$,', $param)
687
+                ) {
688
+                    $result->modificateur['tout'] = true;
689
+                } elseif (strcasecmp($type, 'hierarchie') == 0 and $param == 'id_rubrique') {
690
+                    // rien a faire sur {id_rubrique} tout seul
691
+                } else {
692
+                    // pas d'emplacement statique, faut un dynamique
693
+                    // mais il y a 2 cas qui ont les 2 !
694
+                    if (($param == 'unique') || (preg_match(',^!?doublons *,', $param))) {
695
+                        // cette variable sera inseree dans le code
696
+                        // et son nom sert d'indicateur des maintenant
697
+                        $result->doublons = '$doublons_index';
698
+                        if ($param == 'unique') {
699
+                            $param = 'doublons';
700
+                        }
701
+                    } elseif ($param == 'recherche') {
702
+                        // meme chose (a cause de #nom_de_boucle:URL_*)
703
+                        $result->hash = ' ';
704
+                    }
705
+
706
+                    if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
707
+                        $crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
708
+                    } elseif (
709
+                        preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC .
710
+                        ')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)
711
+                    ) {
712
+                        $a2 = trim($m[8]);
713
+                        if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and ($a2[0] == substr($a2, -1))) {
714
+                            $a2 = substr($a2, 1, -1);
715
+                        }
716
+                        $crit = phraser_critere_infixe(
717
+                            $m[2],
718
+                            $a2,
719
+                            $v,
720
+                            (($m[2] == 'lang_select') ? $m[2] : $m[7]),
721
+                            $m[6],
722
+                            $m[5]
723
+                        );
724
+                        $crit->exclus = $m[1];
725
+                    } elseif (
726
+                        preg_match('/^([!]?)\s*(' .
727
+                        CHAMP_SQL_PLUS_FONC .
728
+                        ')\s*(\??)(.*)$/is', $param, $m)
729
+                    ) {
730
+                        // contient aussi les comparaisons implicites !
731
+                        // Comme ci-dessus:
732
+                        // le premier arg contient l'operateur
733
+                        array_shift($v);
734
+                        if ($m[6]) {
735
+                            $v[0][0] = new Texte();
736
+                            $v[0][0]->texte = $m[6];
737
+                        } else {
738
+                            array_shift($v[0]);
739
+                            if (!$v[0]) {
740
+                                array_shift($v);
741
+                            }
742
+                        }
743
+                        $crit = new Critere();
744
+                        $crit->op = $m[2];
745
+                        $crit->param = $v;
746
+                        $crit->not = (bool) $m[1];
747
+                        $crit->cond = $m[5];
748
+                    } else {
749
+                        $err_ci = [
750
+                            'zbug_critere_inconnu',
751
+                            ['critere' => $param]
752
+                        ];
753
+                        erreur_squelette($err_ci, $result);
754
+                    }
755
+
756
+                    if ((!preg_match(',^!?doublons *,', $param)) || $crit->not) {
757
+                        $args[] = $crit;
758
+                    } else {
759
+                        $doublons[] = $crit;
760
+                    }
761
+                }
762
+            }
763
+        }
764
+    }
765
+
766
+    // les doublons non nies doivent etre le dernier critere
767
+    // pour que la variable $doublon_index ait la bonne valeur
768
+    // cf critere_doublon
769
+    if ($doublons) {
770
+        $args = [...$args, ...$doublons];
771
+    }
772
+
773
+    // Si erreur, laisser la chaine dans ce champ pour le HTTP 503
774
+    if (!$err_ci) {
775
+        $result->criteres = $args;
776
+    }
777 777
 }
778 778
 
779 779
 function phraser_critere_infixe($arg1, $arg2, $args, $op, $not, $cond) {
780
-	$args[0] = new Texte();
781
-	$args[0]->texte = $arg1;
782
-	$args[0] = [$args[0]];
783
-	$args[1][0] = new Texte();
784
-	$args[1][0]->texte = $arg2;
785
-	$crit = new Critere();
786
-	$crit->op = $op;
787
-	$crit->not = $not;
788
-	$crit->cond = $cond;
789
-	$crit->param = $args;
790
-
791
-	return $crit;
780
+    $args[0] = new Texte();
781
+    $args[0]->texte = $arg1;
782
+    $args[0] = [$args[0]];
783
+    $args[1][0] = new Texte();
784
+    $args[1][0]->texte = $arg2;
785
+    $crit = new Critere();
786
+    $crit->op = $op;
787
+    $crit->not = $not;
788
+    $crit->cond = $cond;
789
+    $crit->param = $args;
790
+
791
+    return $crit;
792 792
 }
793 793
 
794 794
 /**
@@ -799,12 +799,12 @@  discard block
 block discarded – undo
799 799
  * @return int
800 800
  */
801 801
 function public_compte_ligne($texte, $debut = 0, $fin = null) {
802
-	if (is_null($fin)) {
803
-		return substr_count($texte, "\n", $debut);
804
-	}
805
-	else {
806
-		return substr_count($texte, "\n", $debut, $fin - $debut);
807
-	}
802
+    if (is_null($fin)) {
803
+        return substr_count($texte, "\n", $debut);
804
+    }
805
+    else {
806
+        return substr_count($texte, "\n", $debut, $fin - $debut);
807
+    }
808 808
 }
809 809
 
810 810
 
@@ -820,87 +820,87 @@  discard block
 block discarded – undo
820 820
  * @return array|null
821 821
  */
822 822
 function public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte = 0) {
823
-	$premiere_boucle = null;
824
-	$pos_derniere_boucle_anonyme = $pos_debut_texte;
825
-
826
-	$current_pos = $pos_debut_texte;
827
-	while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
828
-		$current_pos = $pos_boucle + 1;
829
-		$pos_parent = strpos($texte, '(', $pos_boucle);
830
-
831
-		$id_boucle = '';
832
-		if ($pos_parent !== false) {
833
-			$id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
834
-		}
835
-		if (
836
-			$pos_parent === false
837
-			or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
838
-		) {
839
-			$result = new Boucle();
840
-			$result->id_parent = $id_parent;
841
-			$result->descr = $descr;
842
-
843
-			// un id_boucle pour l'affichage de l'erreur
844
-			if (!strlen($id_boucle)) {
845
-				$id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
846
-			}
847
-			$result->id_boucle = $id_boucle;
848
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
849
-			erreur_squelette($err_b, $result);
850
-
851
-			continue;
852
-		}
853
-		else {
854
-			$boucle = [
855
-				'id_boucle' => $id_boucle,
856
-				'id_boucle_err' => $id_boucle,
857
-				'debut_boucle' => $pos_boucle,
858
-				'pos_boucle' => $pos_boucle,
859
-				'pos_parent' => $pos_parent,
860
-				'pos_precond' => false,
861
-				'pos_precond_inside' => false,
862
-				'pos_preaff' => false,
863
-				'pos_preaff_inside' => false,
864
-			];
865
-
866
-			// un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
867
-			if (!strlen($id_boucle)) {
868
-				$boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
869
-			}
870
-
871
-			// trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
872
-			$precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
873
-			$pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
874
-			if (
875
-				$pos_precond !== false
876
-				and $pos_precond < $boucle['debut_boucle']
877
-			) {
878
-				$boucle['debut_boucle'] = $pos_precond;
879
-				$boucle['pos_precond'] = $pos_precond;
880
-				$boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
881
-			}
882
-
883
-			$preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
884
-			$pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
885
-			if (
886
-				$pos_preaff !== false
887
-				and $pos_preaff < $boucle['debut_boucle']
888
-			) {
889
-				$boucle['debut_boucle'] = $pos_preaff;
890
-				$boucle['pos_preaff'] = $pos_preaff;
891
-				$boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
892
-			}
893
-			if (!strlen($id_boucle)) {
894
-				$pos_derniere_boucle_anonyme = $pos_boucle;
895
-			}
896
-
897
-			if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
898
-				$premiere_boucle = $boucle;
899
-			}
900
-		}
901
-	}
902
-
903
-	return $premiere_boucle;
823
+    $premiere_boucle = null;
824
+    $pos_derniere_boucle_anonyme = $pos_debut_texte;
825
+
826
+    $current_pos = $pos_debut_texte;
827
+    while (($pos_boucle = strpos($texte, BALISE_BOUCLE, $current_pos)) !== false) {
828
+        $current_pos = $pos_boucle + 1;
829
+        $pos_parent = strpos($texte, '(', $pos_boucle);
830
+
831
+        $id_boucle = '';
832
+        if ($pos_parent !== false) {
833
+            $id_boucle = trim(substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), $pos_parent - $pos_boucle - strlen(BALISE_BOUCLE)));
834
+        }
835
+        if (
836
+            $pos_parent === false
837
+            or (strlen($id_boucle) and !(is_numeric($id_boucle) or strpos($id_boucle, '_') === 0))
838
+        ) {
839
+            $result = new Boucle();
840
+            $result->id_parent = $id_parent;
841
+            $result->descr = $descr;
842
+
843
+            // un id_boucle pour l'affichage de l'erreur
844
+            if (!strlen($id_boucle)) {
845
+                $id_boucle = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
846
+            }
847
+            $result->id_boucle = $id_boucle;
848
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
849
+            erreur_squelette($err_b, $result);
850
+
851
+            continue;
852
+        }
853
+        else {
854
+            $boucle = [
855
+                'id_boucle' => $id_boucle,
856
+                'id_boucle_err' => $id_boucle,
857
+                'debut_boucle' => $pos_boucle,
858
+                'pos_boucle' => $pos_boucle,
859
+                'pos_parent' => $pos_parent,
860
+                'pos_precond' => false,
861
+                'pos_precond_inside' => false,
862
+                'pos_preaff' => false,
863
+                'pos_preaff_inside' => false,
864
+            ];
865
+
866
+            // un id_boucle pour l'affichage de l'erreur sur les boucle anonymes
867
+            if (!strlen($id_boucle)) {
868
+                $boucle['id_boucle_err'] = substr($texte, $pos_boucle + strlen(BALISE_BOUCLE), 15);
869
+            }
870
+
871
+            // trouver sa position de depart reelle : au <Bxx> ou au <BBxx>
872
+            $precond_boucle = BALISE_PRECOND_BOUCLE . $id_boucle . '>';
873
+            $pos_precond = strpos($texte, $precond_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
874
+            if (
875
+                $pos_precond !== false
876
+                and $pos_precond < $boucle['debut_boucle']
877
+            ) {
878
+                $boucle['debut_boucle'] = $pos_precond;
879
+                $boucle['pos_precond'] = $pos_precond;
880
+                $boucle['pos_precond_inside'] = $pos_precond + strlen($precond_boucle);
881
+            }
882
+
883
+            $preaff_boucle = BALISE_PREAFF_BOUCLE . $id_boucle . '>';
884
+            $pos_preaff = strpos($texte, $preaff_boucle, $id_boucle ? $pos_debut_texte : $pos_derniere_boucle_anonyme);
885
+            if (
886
+                $pos_preaff !== false
887
+                and $pos_preaff < $boucle['debut_boucle']
888
+            ) {
889
+                $boucle['debut_boucle'] = $pos_preaff;
890
+                $boucle['pos_preaff'] = $pos_preaff;
891
+                $boucle['pos_preaff_inside'] = $pos_preaff + strlen($preaff_boucle);
892
+            }
893
+            if (!strlen($id_boucle)) {
894
+                $pos_derniere_boucle_anonyme = $pos_boucle;
895
+            }
896
+
897
+            if (is_null($premiere_boucle) or $premiere_boucle['debut_boucle'] > $boucle['debut_boucle']) {
898
+                $premiere_boucle = $boucle;
899
+            }
900
+        }
901
+    }
902
+
903
+    return $premiere_boucle;
904 904
 }
905 905
 
906 906
 /**
@@ -915,68 +915,68 @@  discard block
 block discarded – undo
915 915
  * @return mixed
916 916
  */
917 917
 function public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_debut_texte, $result) {
918
-	$id_boucle = $boucle['id_boucle'];
919
-	$pos_courante = $pos_debut_texte;
920
-
921
-	$boucle['pos_postcond'] = false;
922
-	$boucle['pos_postcond_inside'] = false;
923
-	$boucle['pos_altern'] = false;
924
-	$boucle['pos_altern_inside'] = false;
925
-	$boucle['pos_postaff'] = false;
926
-	$boucle['pos_postaff_inside'] = false;
927
-
928
-	$pos_anonyme_next = null;
929
-	// si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
930
-	if (!strlen($id_boucle)) {
931
-		$pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
932
-	}
933
-
934
-	//
935
-	// 1. Recuperer la partie conditionnelle apres
936
-	//
937
-	$apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
938
-	$pos_apres = strpos($texte, $apres_boucle, $pos_courante);
939
-	if (
940
-		$pos_apres !== false
941
-		and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
942
-	) {
943
-		$boucle['pos_postcond'] = $pos_apres;
944
-		$pos_apres += strlen($apres_boucle);
945
-		$boucle['pos_postcond_inside'] = $pos_apres;
946
-		$pos_courante = $pos_apres ;
947
-	}
948
-
949
-	//
950
-	// 2. Récuperer la partie alternative apres
951
-	//
952
-	$altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
953
-	$pos_altern = strpos($texte, $altern_boucle, $pos_courante);
954
-	if (
955
-		$pos_altern !== false
956
-		and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
957
-	) {
958
-		$boucle['pos_altern'] = $pos_altern;
959
-		$pos_altern += strlen($altern_boucle);
960
-		$boucle['pos_altern_inside'] = $pos_altern;
961
-		$pos_courante = $pos_altern;
962
-	}
963
-
964
-	//
965
-	// 3. Recuperer la partie footer non alternative
966
-	//
967
-	$postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
968
-	$pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
969
-	if (
970
-		$pos_postaff !== false
971
-		and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
972
-	) {
973
-		$boucle['pos_postaff'] = $pos_postaff;
974
-		$pos_postaff += strlen($postaff_boucle);
975
-		$boucle['pos_postaff_inside'] = $pos_postaff;
976
-		$pos_courante = $pos_postaff ;
977
-	}
978
-
979
-	return $boucle;
918
+    $id_boucle = $boucle['id_boucle'];
919
+    $pos_courante = $pos_debut_texte;
920
+
921
+    $boucle['pos_postcond'] = false;
922
+    $boucle['pos_postcond_inside'] = false;
923
+    $boucle['pos_altern'] = false;
924
+    $boucle['pos_altern_inside'] = false;
925
+    $boucle['pos_postaff'] = false;
926
+    $boucle['pos_postaff_inside'] = false;
927
+
928
+    $pos_anonyme_next = null;
929
+    // si c'est une boucle anonyme, chercher la position de la prochaine boucle anonyme
930
+    if (!strlen($id_boucle)) {
931
+        $pos_anonyme_next = strpos($texte, BALISE_BOUCLE . '(', $pos_courante);
932
+    }
933
+
934
+    //
935
+    // 1. Recuperer la partie conditionnelle apres
936
+    //
937
+    $apres_boucle = BALISE_POSTCOND_BOUCLE . $id_boucle . '>';
938
+    $pos_apres = strpos($texte, $apres_boucle, $pos_courante);
939
+    if (
940
+        $pos_apres !== false
941
+        and (!$pos_anonyme_next or $pos_apres < $pos_anonyme_next)
942
+    ) {
943
+        $boucle['pos_postcond'] = $pos_apres;
944
+        $pos_apres += strlen($apres_boucle);
945
+        $boucle['pos_postcond_inside'] = $pos_apres;
946
+        $pos_courante = $pos_apres ;
947
+    }
948
+
949
+    //
950
+    // 2. Récuperer la partie alternative apres
951
+    //
952
+    $altern_boucle = BALISE_ALT_BOUCLE . $id_boucle . '>';
953
+    $pos_altern = strpos($texte, $altern_boucle, $pos_courante);
954
+    if (
955
+        $pos_altern !== false
956
+        and (!$pos_anonyme_next or $pos_altern < $pos_anonyme_next)
957
+    ) {
958
+        $boucle['pos_altern'] = $pos_altern;
959
+        $pos_altern += strlen($altern_boucle);
960
+        $boucle['pos_altern_inside'] = $pos_altern;
961
+        $pos_courante = $pos_altern;
962
+    }
963
+
964
+    //
965
+    // 3. Recuperer la partie footer non alternative
966
+    //
967
+    $postaff_boucle = BALISE_POSTAFF_BOUCLE . $id_boucle . '>';
968
+    $pos_postaff = strpos($texte, $postaff_boucle, $pos_courante);
969
+    if (
970
+        $pos_postaff !== false
971
+        and (!$pos_anonyme_next or $pos_postaff < $pos_anonyme_next)
972
+    ) {
973
+        $boucle['pos_postaff'] = $pos_postaff;
974
+        $pos_postaff += strlen($postaff_boucle);
975
+        $boucle['pos_postaff_inside'] = $pos_postaff;
976
+        $pos_courante = $pos_postaff ;
977
+    }
978
+
979
+    return $boucle;
980 980
 }
981 981
 
982 982
 
@@ -986,21 +986,21 @@  discard block
 block discarded – undo
986 986
  * @param null|object $boucle
987 987
  */
988 988
 function phraser_boucle_placeholder(&$champ, $boucle_placeholder = null, $boucle = null) {
989
-	static $boucles_connues = [];
990
-	// si c'est un appel pour memoriser une boucle, memorisons la
991
-	if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
992
-		$boucles_connues[$boucle_placeholder][$champ] = &$boucle;
993
-	}
994
-	else {
995
-		if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
996
-			$placeholder = $champ->nom_champ;
997
-			$id = reset($champ->param[0][1]);
998
-			$id = $id->texte;
999
-			if (!empty($boucles_connues[$placeholder][$id])) {
1000
-				$champ = $boucles_connues[$placeholder][$id];
1001
-			}
1002
-		}
1003
-	}
989
+    static $boucles_connues = [];
990
+    // si c'est un appel pour memoriser une boucle, memorisons la
991
+    if (is_string($champ) and !empty($boucle_placeholder) and !empty($boucle)) {
992
+        $boucles_connues[$boucle_placeholder][$champ] = &$boucle;
993
+    }
994
+    else {
995
+        if (!empty($champ->nom_champ) and !empty($boucles_connues[$champ->nom_champ])) {
996
+            $placeholder = $champ->nom_champ;
997
+            $id = reset($champ->param[0][1]);
998
+            $id = $id->texte;
999
+            if (!empty($boucles_connues[$placeholder][$id])) {
1000
+                $champ = $boucles_connues[$placeholder][$id];
1001
+            }
1002
+        }
1003
+    }
1004 1004
 }
1005 1005
 
1006 1006
 
@@ -1013,274 +1013,274 @@  discard block
 block discarded – undo
1013 1013
  * @return string
1014 1014
  */
1015 1015
 function public_generer_boucle_placeholder($id_boucle, &$boucle, $boucle_placeholder, $nb_lignes) {
1016
-	$placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1017
-	//memoriser la boucle a reinjecter
1018
-	$id_boucle = "$id_boucle";
1019
-	phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1020
-	return $placeholder;
1016
+    $placeholder = "[(#{$boucle_placeholder}{" . $id_boucle . '})' . str_pad('', $nb_lignes, "\n") . ']';
1017
+    //memoriser la boucle a reinjecter
1018
+    $id_boucle = "$id_boucle";
1019
+    phraser_boucle_placeholder($id_boucle, $boucle_placeholder, $boucle);
1020
+    return $placeholder;
1021 1021
 }
1022 1022
 
1023 1023
 function public_phraser_html_dist($texte, $id_parent, &$boucles, $descr, $ligne_debut_texte = 1, $boucle_placeholder = null) {
1024 1024
 
1025
-	$all_res = [];
1026
-	// definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1027
-	if (is_null($boucle_placeholder)) {
1028
-		do {
1029
-			$boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1030
-		} while (strpos($texte, $boucle_placeholder) !== false);
1031
-	}
1032
-
1033
-	$ligne_debut_initial = $ligne_debut_texte;
1034
-	$pos_debut_texte = 0;
1035
-	while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1036
-		$err_b = ''; // indiquera s'il y a eu une erreur
1037
-		$result = new Boucle();
1038
-		$result->id_parent = $id_parent;
1039
-		$result->descr = $descr;
1040
-
1041
-		$pos_courante = $boucle['pos_boucle'];
1042
-		$pos_parent = $boucle['pos_parent'];
1043
-		$id_boucle_search = $id_boucle = $boucle['id_boucle'];
1044
-
1045
-		$ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1046
-
1047
-		// boucle anonyme ?
1048
-		if (!strlen($id_boucle)) {
1049
-			$id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1050
-		}
1051
-
1052
-		$pos_debut_boucle = $pos_courante;
1053
-
1054
-		$pos_milieu = $pos_parent;
1055
-
1056
-		// Regarder si on a une partie conditionnelle avant <B_xxx>
1057
-		if ($boucle['pos_precond'] !== false) {
1058
-			$pos_debut_boucle = $boucle['pos_precond'];
1059
-
1060
-			$pos_avant = $boucle['pos_precond_inside'];
1061
-			$result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1062
-			$ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1063
-		}
1064
-
1065
-		// Regarder si on a une partie inconditionnelle avant <BB_xxx>
1066
-		if ($boucle['pos_preaff'] !== false) {
1067
-			$end_preaff = $pos_debut_boucle;
1068
-
1069
-			$pos_preaff = $boucle['pos_preaff_inside'];
1070
-			$result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1071
-			$ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1072
-		}
1073
-
1074
-		$result->id_boucle = $id_boucle;
1075
-
1076
-		if (
1077
-			!preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1078
-			or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1079
-			or $pos_match > $pos_milieu
1080
-		) {
1081
-			$err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1082
-			erreur_squelette($err_b, $result);
1083
-
1084
-			$ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1085
-			$pos_debut_texte = $pos_courante + 1;
1086
-			continue;
1087
-		}
1088
-
1089
-		$result->type_requete = $match[0];
1090
-		$pos_milieu += strlen($match[0]);
1091
-		$pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1092
-
1093
-		$type = $match[1];
1094
-		$jointures = trim($match[2]);
1095
-		$table_optionnelle = ($match[3]);
1096
-		if ($jointures) {
1097
-			// on affecte pas ici les jointures explicites, mais dans la compilation
1098
-			// ou elles seront completees des jointures declarees
1099
-			$result->jointures_explicites = $jointures;
1100
-		}
1101
-
1102
-		if ($table_optionnelle) {
1103
-			$result->table_optionnelle = $type;
1104
-		}
1105
-
1106
-		// 1ere passe sur les criteres, vu comme des arguments sans fct
1107
-		// Resultat mis dans result->param
1108
-		$pos_fin_criteres = $pos_milieu;
1109
-		phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1110
-
1111
-		// En 2e passe result->criteres contiendra un tableau
1112
-		// pour l'instant on met le source (chaine) :
1113
-		// si elle reste ici au final, c'est qu'elle contient une erreur
1114
-		$pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1115
-		$result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1116
-		$pos_milieu = $pos_fin_criteres;
1117
-
1118
-		//
1119
-		// Recuperer la fin :
1120
-		//
1121
-		if ($texte[$pos_milieu] === '/') {
1122
-			// boucle autofermante : pas de partie conditionnelle apres
1123
-			$pos_courante += 2;
1124
-			$result->milieu = '';
1125
-		} else {
1126
-			$pos_milieu += 1;
1127
-
1128
-			$fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1129
-			$pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1130
-			if ($pos_fin === false) {
1131
-				$err_b = [
1132
-					'zbug_erreur_boucle_fermant',
1133
-					['id' => $id_boucle]
1134
-				];
1135
-				erreur_squelette($err_b, $result);
1136
-				$pos_courante += strlen($fin_boucle);
1137
-			}
1138
-			else {
1139
-				// verifier une eventuelle imbrication d'une boucle homonyme
1140
-				// (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1141
-				$search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1142
-				$search_from = $pos_milieu;
1143
-				$nb_open = 1;
1144
-				$nb_close = 1;
1145
-				$maxiter = 0;
1146
-				do {
1147
-					while (
1148
-						$nb_close < $nb_open
1149
-						and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1150
-					) {
1151
-						$nb_close++;
1152
-						$pos_fin = $p;
1153
-					}
1154
-					// si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1155
-					if ($nb_close < $nb_open) {
1156
-						break;
1157
-					}
1158
-					while (
1159
-						$p = strpos($texte, $search_debut_boucle, $search_from)
1160
-						and $p < $pos_fin
1161
-					) {
1162
-						$nb_open++;
1163
-						$search_from = $p + 1;
1164
-					}
1165
-				} while ($nb_close < $nb_open and $maxiter++ < 5);
1166
-
1167
-				$pos_courante = $pos_fin + strlen($fin_boucle);
1168
-			}
1169
-			$result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1170
-		}
1171
-
1172
-		$ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1173
-		$boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1174
-
1175
-		//
1176
-		// 1. Partie conditionnelle apres ?
1177
-		//
1178
-		if ($boucle['pos_postcond']) {
1179
-			$result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1180
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1181
-			$pos_courante = $boucle['pos_postcond_inside'] ;
1182
-		}
1183
-
1184
-
1185
-		//
1186
-		// 2. Partie alternative apres ?
1187
-		//
1188
-		$ligne_altern = $ligne_suite;
1189
-		if ($boucle['pos_altern']) {
1190
-			$result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1191
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1192
-			$pos_courante = $boucle['pos_altern_inside'];
1193
-		}
1194
-
1195
-		//
1196
-		// 3. Partie footer non alternative ?
1197
-		//
1198
-		$ligne_postaff = $ligne_suite;
1199
-		if ($boucle['pos_postaff']) {
1200
-			$result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1201
-			$ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1202
-			$pos_courante = $boucle['pos_postaff_inside'];
1203
-		}
1204
-
1205
-		$result->ligne = $ligne_preaff;
1206
-
1207
-		if ($p = strpos($type, ':')) {
1208
-			$result->sql_serveur = substr($type, 0, $p);
1209
-			$type = substr($type, $p + 1);
1210
-		}
1211
-		$soustype = strtolower($type);
1212
-
1213
-		if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1214
-			$soustype = $type;
1215
-		}
1216
-
1217
-		$result->type_requete = $soustype;
1218
-		// Lancer la 2e passe sur les criteres si la 1ere etait bonne
1219
-		if (!is_array($result->param)) {
1220
-			$err_b = true;
1221
-		} else {
1222
-			phraser_criteres($result->param, $result);
1223
-			if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1224
-				$result->type_requete = TYPE_RECURSIF;
1225
-				$args = $result->param;
1226
-				array_unshift(
1227
-					$args,
1228
-					substr($type, strlen(TYPE_RECURSIF))
1229
-				);
1230
-				$result->param = $args;
1231
-			}
1232
-		}
1233
-
1234
-		$descr['id_mere_contexte'] = $id_boucle;
1235
-		$result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1236
-		// reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1237
-		// ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1238
-		// si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1239
-		if (empty($boucles[$id_boucle])) {
1240
-			$boucles[$id_boucle] = null;
1241
-		}
1242
-		$result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1243
-		$result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1244
-		$result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1245
-		$result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1246
-		$result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1247
-
1248
-		// Prevenir le generateur de code que le squelette est faux
1249
-		if ($err_b) {
1250
-			$result->type_requete = false;
1251
-		}
1252
-
1253
-		// Verifier qu'il n'y a pas double definition
1254
-		// apres analyse des sous-parties (pas avant).
1255
-		if (!empty($boucles[$id_boucle])) {
1256
-			if ($boucles[$id_boucle]->type_requete !== false) {
1257
-				$err_b_d = [
1258
-					'zbug_erreur_boucle_double',
1259
-					['id' => $id_boucle]
1260
-				];
1261
-				erreur_squelette($err_b_d, $result);
1262
-				// Prevenir le generateur de code que le squelette est faux
1263
-				$boucles[$id_boucle]->type_requete = false;
1264
-			}
1265
-		} else {
1266
-			$boucles[$id_boucle] = $result;
1267
-		}
1268
-
1269
-		// remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1270
-		$placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1271
-		$longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1272
-		$texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1273
-		$pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1274
-
1275
-		// phraser la partie avant le debut de la boucle
1276
-		#$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1277
-		#$all_res[] = &$boucles[$id_boucle];
1278
-
1279
-		$ligne_debut_texte = $ligne_suite;
1280
-		$pos_debut_texte = $pos_courante;
1281
-	}
1282
-
1283
-	$all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1284
-
1285
-	return $all_res;
1025
+    $all_res = [];
1026
+    // definir un placholder pour les boucles dont on est sur d'avoir aucune occurence dans le squelette
1027
+    if (is_null($boucle_placeholder)) {
1028
+        do {
1029
+            $boucle_placeholder = 'BOUCLE_PLACEHOLDER_' . strtoupper(md5(uniqid()));
1030
+        } while (strpos($texte, $boucle_placeholder) !== false);
1031
+    }
1032
+
1033
+    $ligne_debut_initial = $ligne_debut_texte;
1034
+    $pos_debut_texte = 0;
1035
+    while ($boucle = public_trouver_premiere_boucle($texte, $id_parent, $descr, $pos_debut_texte)) {
1036
+        $err_b = ''; // indiquera s'il y a eu une erreur
1037
+        $result = new Boucle();
1038
+        $result->id_parent = $id_parent;
1039
+        $result->descr = $descr;
1040
+
1041
+        $pos_courante = $boucle['pos_boucle'];
1042
+        $pos_parent = $boucle['pos_parent'];
1043
+        $id_boucle_search = $id_boucle = $boucle['id_boucle'];
1044
+
1045
+        $ligne_preaff = $ligne_avant = $ligne_milieu = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_parent);
1046
+
1047
+        // boucle anonyme ?
1048
+        if (!strlen($id_boucle)) {
1049
+            $id_boucle = '_anon_L' . $ligne_milieu . '_' . substr(md5('anonyme:' . $id_parent . ':' . json_encode($boucle, JSON_THROW_ON_ERROR)), 0, 8);
1050
+        }
1051
+
1052
+        $pos_debut_boucle = $pos_courante;
1053
+
1054
+        $pos_milieu = $pos_parent;
1055
+
1056
+        // Regarder si on a une partie conditionnelle avant <B_xxx>
1057
+        if ($boucle['pos_precond'] !== false) {
1058
+            $pos_debut_boucle = $boucle['pos_precond'];
1059
+
1060
+            $pos_avant = $boucle['pos_precond_inside'];
1061
+            $result->avant = substr($texte, $pos_avant, $pos_courante - $pos_avant);
1062
+            $ligne_avant = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_avant);
1063
+        }
1064
+
1065
+        // Regarder si on a une partie inconditionnelle avant <BB_xxx>
1066
+        if ($boucle['pos_preaff'] !== false) {
1067
+            $end_preaff = $pos_debut_boucle;
1068
+
1069
+            $pos_preaff = $boucle['pos_preaff_inside'];
1070
+            $result->preaff = substr($texte, $pos_preaff, $end_preaff - $pos_preaff);
1071
+            $ligne_preaff = $ligne_debut_texte +  public_compte_ligne($texte, $pos_debut_texte, $pos_preaff);
1072
+        }
1073
+
1074
+        $result->id_boucle = $id_boucle;
1075
+
1076
+        if (
1077
+            !preg_match(SPEC_BOUCLE, $texte, $match, 0, $pos_milieu)
1078
+            or ($pos_match = strpos($texte, (string) $match[0], $pos_milieu)) === false
1079
+            or $pos_match > $pos_milieu
1080
+        ) {
1081
+            $err_b = ['zbug_erreur_boucle_syntaxe', ['id' => $id_boucle]];
1082
+            erreur_squelette($err_b, $result);
1083
+
1084
+            $ligne_debut_texte += public_compte_ligne($texte, $pos_debut_texte, $pos_courante + 1);
1085
+            $pos_debut_texte = $pos_courante + 1;
1086
+            continue;
1087
+        }
1088
+
1089
+        $result->type_requete = $match[0];
1090
+        $pos_milieu += strlen($match[0]);
1091
+        $pos_courante = $pos_milieu; // on s'en sert pour compter les lignes plus precisemment
1092
+
1093
+        $type = $match[1];
1094
+        $jointures = trim($match[2]);
1095
+        $table_optionnelle = ($match[3]);
1096
+        if ($jointures) {
1097
+            // on affecte pas ici les jointures explicites, mais dans la compilation
1098
+            // ou elles seront completees des jointures declarees
1099
+            $result->jointures_explicites = $jointures;
1100
+        }
1101
+
1102
+        if ($table_optionnelle) {
1103
+            $result->table_optionnelle = $type;
1104
+        }
1105
+
1106
+        // 1ere passe sur les criteres, vu comme des arguments sans fct
1107
+        // Resultat mis dans result->param
1108
+        $pos_fin_criteres = $pos_milieu;
1109
+        phraser_args($texte, '/>', '', $all_res, $result, $pos_fin_criteres);
1110
+
1111
+        // En 2e passe result->criteres contiendra un tableau
1112
+        // pour l'instant on met le source (chaine) :
1113
+        // si elle reste ici au final, c'est qu'elle contient une erreur
1114
+        $pos_courante = $pos_fin_criteres; // on s'en sert pour compter les lignes plus precisemment
1115
+        $result->criteres = substr($texte, $pos_milieu, $pos_fin_criteres - $pos_milieu);
1116
+        $pos_milieu = $pos_fin_criteres;
1117
+
1118
+        //
1119
+        // Recuperer la fin :
1120
+        //
1121
+        if ($texte[$pos_milieu] === '/') {
1122
+            // boucle autofermante : pas de partie conditionnelle apres
1123
+            $pos_courante += 2;
1124
+            $result->milieu = '';
1125
+        } else {
1126
+            $pos_milieu += 1;
1127
+
1128
+            $fin_boucle = BALISE_FIN_BOUCLE . $id_boucle_search . '>';
1129
+            $pos_fin = strpos($texte, $fin_boucle, $pos_milieu);
1130
+            if ($pos_fin === false) {
1131
+                $err_b = [
1132
+                    'zbug_erreur_boucle_fermant',
1133
+                    ['id' => $id_boucle]
1134
+                ];
1135
+                erreur_squelette($err_b, $result);
1136
+                $pos_courante += strlen($fin_boucle);
1137
+            }
1138
+            else {
1139
+                // verifier une eventuelle imbrication d'une boucle homonyme
1140
+                // (interdite, generera une erreur plus loin, mais permet de signaler la bonne erreur)
1141
+                $search_debut_boucle = BALISE_BOUCLE . $id_boucle_search . '(';
1142
+                $search_from = $pos_milieu;
1143
+                $nb_open = 1;
1144
+                $nb_close = 1;
1145
+                $maxiter = 0;
1146
+                do {
1147
+                    while (
1148
+                        $nb_close < $nb_open
1149
+                        and $p = strpos($texte, $fin_boucle, $pos_fin + 1)
1150
+                    ) {
1151
+                        $nb_close++;
1152
+                        $pos_fin = $p;
1153
+                    }
1154
+                    // si on a pas trouve assez de boucles fermantes, sortir de la, on a fait de notre mieux
1155
+                    if ($nb_close < $nb_open) {
1156
+                        break;
1157
+                    }
1158
+                    while (
1159
+                        $p = strpos($texte, $search_debut_boucle, $search_from)
1160
+                        and $p < $pos_fin
1161
+                    ) {
1162
+                        $nb_open++;
1163
+                        $search_from = $p + 1;
1164
+                    }
1165
+                } while ($nb_close < $nb_open and $maxiter++ < 5);
1166
+
1167
+                $pos_courante = $pos_fin + strlen($fin_boucle);
1168
+            }
1169
+            $result->milieu = substr($texte, $pos_milieu, $pos_fin - $pos_milieu);
1170
+        }
1171
+
1172
+        $ligne_suite = $ligne_apres = $ligne_debut_texte + public_compte_ligne($texte, $pos_debut_texte, $pos_courante);
1173
+        $boucle = public_trouver_fin_boucle($texte, $id_parent, $boucle, $pos_courante, $result);
1174
+
1175
+        //
1176
+        // 1. Partie conditionnelle apres ?
1177
+        //
1178
+        if ($boucle['pos_postcond']) {
1179
+            $result->apres = substr($texte, $pos_courante, $boucle['pos_postcond'] - $pos_courante);
1180
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postcond_inside']);
1181
+            $pos_courante = $boucle['pos_postcond_inside'] ;
1182
+        }
1183
+
1184
+
1185
+        //
1186
+        // 2. Partie alternative apres ?
1187
+        //
1188
+        $ligne_altern = $ligne_suite;
1189
+        if ($boucle['pos_altern']) {
1190
+            $result->altern = substr($texte, $pos_courante, $boucle['pos_altern'] - $pos_courante);
1191
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_altern_inside']);
1192
+            $pos_courante = $boucle['pos_altern_inside'];
1193
+        }
1194
+
1195
+        //
1196
+        // 3. Partie footer non alternative ?
1197
+        //
1198
+        $ligne_postaff = $ligne_suite;
1199
+        if ($boucle['pos_postaff']) {
1200
+            $result->postaff = substr($texte, $pos_courante, $boucle['pos_postaff'] - $pos_courante);
1201
+            $ligne_suite += public_compte_ligne($texte, $pos_courante, $boucle['pos_postaff_inside']);
1202
+            $pos_courante = $boucle['pos_postaff_inside'];
1203
+        }
1204
+
1205
+        $result->ligne = $ligne_preaff;
1206
+
1207
+        if ($p = strpos($type, ':')) {
1208
+            $result->sql_serveur = substr($type, 0, $p);
1209
+            $type = substr($type, $p + 1);
1210
+        }
1211
+        $soustype = strtolower($type);
1212
+
1213
+        if (!isset($GLOBALS['table_des_tables'][$soustype])) {
1214
+            $soustype = $type;
1215
+        }
1216
+
1217
+        $result->type_requete = $soustype;
1218
+        // Lancer la 2e passe sur les criteres si la 1ere etait bonne
1219
+        if (!is_array($result->param)) {
1220
+            $err_b = true;
1221
+        } else {
1222
+            phraser_criteres($result->param, $result);
1223
+            if (strncasecmp($soustype, TYPE_RECURSIF, strlen(TYPE_RECURSIF)) == 0) {
1224
+                $result->type_requete = TYPE_RECURSIF;
1225
+                $args = $result->param;
1226
+                array_unshift(
1227
+                    $args,
1228
+                    substr($type, strlen(TYPE_RECURSIF))
1229
+                );
1230
+                $result->param = $args;
1231
+            }
1232
+        }
1233
+
1234
+        $descr['id_mere_contexte'] = $id_boucle;
1235
+        $result->milieu = public_phraser_html_dist($result->milieu, $id_boucle, $boucles, $descr, $ligne_milieu, $boucle_placeholder);
1236
+        // reserver la place dans la pile des boucles pour compiler ensuite dans le bon ordre
1237
+        // ie les boucles qui apparaissent dans les partie conditionnelles doivent etre compilees apres cette boucle
1238
+        // si il y a deja une boucle de ce nom, cela declenchera une erreur ensuite
1239
+        if (empty($boucles[$id_boucle])) {
1240
+            $boucles[$id_boucle] = null;
1241
+        }
1242
+        $result->preaff = public_phraser_html_dist($result->preaff, $id_parent, $boucles, $descr, $ligne_preaff, $boucle_placeholder);
1243
+        $result->avant = public_phraser_html_dist($result->avant, $id_parent, $boucles, $descr, $ligne_avant, $boucle_placeholder);
1244
+        $result->apres = public_phraser_html_dist($result->apres, $id_parent, $boucles, $descr, $ligne_apres, $boucle_placeholder);
1245
+        $result->altern = public_phraser_html_dist($result->altern, $id_parent, $boucles, $descr, $ligne_altern, $boucle_placeholder);
1246
+        $result->postaff = public_phraser_html_dist($result->postaff, $id_parent, $boucles, $descr, $ligne_postaff, $boucle_placeholder);
1247
+
1248
+        // Prevenir le generateur de code que le squelette est faux
1249
+        if ($err_b) {
1250
+            $result->type_requete = false;
1251
+        }
1252
+
1253
+        // Verifier qu'il n'y a pas double definition
1254
+        // apres analyse des sous-parties (pas avant).
1255
+        if (!empty($boucles[$id_boucle])) {
1256
+            if ($boucles[$id_boucle]->type_requete !== false) {
1257
+                $err_b_d = [
1258
+                    'zbug_erreur_boucle_double',
1259
+                    ['id' => $id_boucle]
1260
+                ];
1261
+                erreur_squelette($err_b_d, $result);
1262
+                // Prevenir le generateur de code que le squelette est faux
1263
+                $boucles[$id_boucle]->type_requete = false;
1264
+            }
1265
+        } else {
1266
+            $boucles[$id_boucle] = $result;
1267
+        }
1268
+
1269
+        // remplacer la boucle par un placeholder qui compte le meme nombre de lignes
1270
+        $placeholder = public_generer_boucle_placeholder($id_boucle, $boucles[$id_boucle], $boucle_placeholder, $ligne_suite - $ligne_debut_texte);
1271
+        $longueur_boucle = $pos_courante - $boucle['debut_boucle'];
1272
+        $texte = substr_replace($texte, $placeholder, $boucle['debut_boucle'], $longueur_boucle);
1273
+        $pos_courante = $pos_courante - $longueur_boucle + strlen($placeholder);
1274
+
1275
+        // phraser la partie avant le debut de la boucle
1276
+        #$all_res = phraser_champs_etendus(substr($texte, $pos_debut_texte, $boucle['debut_boucle'] - $pos_debut_texte), $ligne_debut_texte, $all_res);
1277
+        #$all_res[] = &$boucles[$id_boucle];
1278
+
1279
+        $ligne_debut_texte = $ligne_suite;
1280
+        $pos_debut_texte = $pos_courante;
1281
+    }
1282
+
1283
+    $all_res = phraser_champs_etendus($texte, $ligne_debut_initial, $all_res);
1284
+
1285
+    return $all_res;
1286 1286
 }
Please login to merge, or discard this patch.