@@ -20,7 +20,7 @@ discard block |
||
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | 22 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 23 | - return; |
|
| 23 | + return; |
|
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | include_spip('inc/config'); |
@@ -32,31 +32,31 @@ discard block |
||
| 32 | 32 | * @return array|false |
| 33 | 33 | */ |
| 34 | 34 | function cvtconf_formulaire_charger($flux) { |
| 35 | - if ( |
|
| 36 | - $form = $flux['args']['form'] |
|
| 37 | - and strncmp($form, 'configurer_', 11) == 0 // un #FORMULAIRE_CONFIGURER_XXX |
|
| 38 | - ) { |
|
| 39 | - // Pour tous les formulaires CONFIGURER, ayant une fonction charger ou pas, on teste si autorisé |
|
| 40 | - include_spip('inc/autoriser'); |
|
| 41 | - if (!autoriser('configurer', '_' . substr($form, 11))) { |
|
| 42 | - return false; |
|
| 43 | - } |
|
| 35 | + if ( |
|
| 36 | + $form = $flux['args']['form'] |
|
| 37 | + and strncmp($form, 'configurer_', 11) == 0 // un #FORMULAIRE_CONFIGURER_XXX |
|
| 38 | + ) { |
|
| 39 | + // Pour tous les formulaires CONFIGURER, ayant une fonction charger ou pas, on teste si autorisé |
|
| 40 | + include_spip('inc/autoriser'); |
|
| 41 | + if (!autoriser('configurer', '_' . substr($form, 11))) { |
|
| 42 | + return false; |
|
| 43 | + } |
|
| 44 | 44 | |
| 45 | - // S'il n'y a pas de fonction charger(), on génère un contexte automatiquement |
|
| 46 | - if (!charger_fonction('charger', "formulaires/$form/", true)) { |
|
| 47 | - $flux['data'] = cvtconf_formulaires_configurer_recense($form); |
|
| 48 | - $flux['data']['editable'] = true; |
|
| 49 | - if (_request('var_mode') == 'configurer' and autoriser('webmestre')) { |
|
| 50 | - if (!_AJAX) { |
|
| 51 | - var_dump($flux['data']); |
|
| 52 | - } |
|
| 53 | - // reinjecter pour la trace au traitement |
|
| 54 | - $flux['data']['_hidden'] = "<input type='hidden' name='var_mode' value='configurer' />"; |
|
| 55 | - } |
|
| 56 | - } |
|
| 57 | - } |
|
| 45 | + // S'il n'y a pas de fonction charger(), on génère un contexte automatiquement |
|
| 46 | + if (!charger_fonction('charger', "formulaires/$form/", true)) { |
|
| 47 | + $flux['data'] = cvtconf_formulaires_configurer_recense($form); |
|
| 48 | + $flux['data']['editable'] = true; |
|
| 49 | + if (_request('var_mode') == 'configurer' and autoriser('webmestre')) { |
|
| 50 | + if (!_AJAX) { |
|
| 51 | + var_dump($flux['data']); |
|
| 52 | + } |
|
| 53 | + // reinjecter pour la trace au traitement |
|
| 54 | + $flux['data']['_hidden'] = "<input type='hidden' name='var_mode' value='configurer' />"; |
|
| 55 | + } |
|
| 56 | + } |
|
| 57 | + } |
|
| 58 | 58 | |
| 59 | - return $flux; |
|
| 59 | + return $flux; |
|
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | /** |
@@ -66,16 +66,16 @@ discard block |
||
| 66 | 66 | * @return array |
| 67 | 67 | */ |
| 68 | 68 | function cvtconf_formulaire_traiter($flux) { |
| 69 | - if ( |
|
| 70 | - $form = $flux['args']['form'] |
|
| 71 | - and strncmp($form, 'configurer_', 11) == 0 // un #FORMULAIRE_CONFIGURER_XXX |
|
| 72 | - and !charger_fonction('traiter', "formulaires/$form/", true) // sans fonction traiter() |
|
| 73 | - ) { |
|
| 74 | - $trace = cvtconf_formulaires_configurer_enregistre($form, $flux['args']['args']); |
|
| 75 | - $flux['data'] = ['message_ok' => _T('config_info_enregistree') . $trace, 'editable' => true]; |
|
| 76 | - } |
|
| 69 | + if ( |
|
| 70 | + $form = $flux['args']['form'] |
|
| 71 | + and strncmp($form, 'configurer_', 11) == 0 // un #FORMULAIRE_CONFIGURER_XXX |
|
| 72 | + and !charger_fonction('traiter', "formulaires/$form/", true) // sans fonction traiter() |
|
| 73 | + ) { |
|
| 74 | + $trace = cvtconf_formulaires_configurer_enregistre($form, $flux['args']['args']); |
|
| 75 | + $flux['data'] = ['message_ok' => _T('config_info_enregistree') . $trace, 'editable' => true]; |
|
| 76 | + } |
|
| 77 | 77 | |
| 78 | - return $flux; |
|
| 78 | + return $flux; |
|
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | /** |
@@ -91,32 +91,32 @@ discard block |
||
| 91 | 91 | * @return string |
| 92 | 92 | */ |
| 93 | 93 | function cvtconf_formulaires_configurer_enregistre($form, $args) { |
| 94 | - $valeurs = []; |
|
| 95 | - // charger les valeurs |
|
| 96 | - // ce qui permet de prendre en charge une fonction charger() existante |
|
| 97 | - // qui prend alors la main sur l'auto detection |
|
| 98 | - if ($charger_valeurs = charger_fonction('charger', "formulaires/$form/", true)) { |
|
| 99 | - $valeurs = $charger_valeurs(...$args); |
|
| 100 | - } |
|
| 101 | - $valeurs = pipeline( |
|
| 102 | - 'formulaire_charger', |
|
| 103 | - [ |
|
| 104 | - 'args' => ['form' => $form, 'args' => $args, 'je_suis_poste' => false], |
|
| 105 | - 'data' => $valeurs |
|
| 106 | - ] |
|
| 107 | - ); |
|
| 108 | - // ne pas stocker editable ! |
|
| 109 | - unset($valeurs['editable']); |
|
| 94 | + $valeurs = []; |
|
| 95 | + // charger les valeurs |
|
| 96 | + // ce qui permet de prendre en charge une fonction charger() existante |
|
| 97 | + // qui prend alors la main sur l'auto detection |
|
| 98 | + if ($charger_valeurs = charger_fonction('charger', "formulaires/$form/", true)) { |
|
| 99 | + $valeurs = $charger_valeurs(...$args); |
|
| 100 | + } |
|
| 101 | + $valeurs = pipeline( |
|
| 102 | + 'formulaire_charger', |
|
| 103 | + [ |
|
| 104 | + 'args' => ['form' => $form, 'args' => $args, 'je_suis_poste' => false], |
|
| 105 | + 'data' => $valeurs |
|
| 106 | + ] |
|
| 107 | + ); |
|
| 108 | + // ne pas stocker editable ! |
|
| 109 | + unset($valeurs['editable']); |
|
| 110 | 110 | |
| 111 | - // recuperer les valeurs postees |
|
| 112 | - $store = []; |
|
| 113 | - foreach ($valeurs as $k => $v) { |
|
| 114 | - if (substr($k, 0, 1) !== '_') { |
|
| 115 | - $store[$k] = _request($k); |
|
| 116 | - } |
|
| 117 | - } |
|
| 111 | + // recuperer les valeurs postees |
|
| 112 | + $store = []; |
|
| 113 | + foreach ($valeurs as $k => $v) { |
|
| 114 | + if (substr($k, 0, 1) !== '_') { |
|
| 115 | + $store[$k] = _request($k); |
|
| 116 | + } |
|
| 117 | + } |
|
| 118 | 118 | |
| 119 | - return cvtconf_configurer_stocker($form, $valeurs, $store); |
|
| 119 | + return cvtconf_configurer_stocker($form, $valeurs, $store); |
|
| 120 | 120 | } |
| 121 | 121 | |
| 122 | 122 | /** |
@@ -132,31 +132,31 @@ discard block |
||
| 132 | 132 | * @return array |
| 133 | 133 | */ |
| 134 | 134 | function cvtconf_definir_configurer_conteneur($form, $valeurs) { |
| 135 | - // stocker en base |
|
| 136 | - // par defaut, dans un casier serialize dans spip_meta (idem CFG) |
|
| 137 | - $casier = substr($form, 11); |
|
| 138 | - $table = 'meta'; |
|
| 139 | - $prefixe = ''; |
|
| 140 | - $stockage = ''; |
|
| 135 | + // stocker en base |
|
| 136 | + // par defaut, dans un casier serialize dans spip_meta (idem CFG) |
|
| 137 | + $casier = substr($form, 11); |
|
| 138 | + $table = 'meta'; |
|
| 139 | + $prefixe = ''; |
|
| 140 | + $stockage = ''; |
|
| 141 | 141 | |
| 142 | - if (isset($valeurs['_meta_casier'])) { |
|
| 143 | - $casier = $valeurs['_meta_casier']; |
|
| 144 | - } |
|
| 145 | - if (isset($valeurs['_meta_prefixe'])) { |
|
| 146 | - $prefixe = $valeurs['_meta_prefixe']; |
|
| 147 | - } |
|
| 148 | - if (isset($valeurs['_meta_stockage'])) { |
|
| 149 | - $stockage = $valeurs['_meta_stockage'] . '::'; |
|
| 150 | - } |
|
| 142 | + if (isset($valeurs['_meta_casier'])) { |
|
| 143 | + $casier = $valeurs['_meta_casier']; |
|
| 144 | + } |
|
| 145 | + if (isset($valeurs['_meta_prefixe'])) { |
|
| 146 | + $prefixe = $valeurs['_meta_prefixe']; |
|
| 147 | + } |
|
| 148 | + if (isset($valeurs['_meta_stockage'])) { |
|
| 149 | + $stockage = $valeurs['_meta_stockage'] . '::'; |
|
| 150 | + } |
|
| 151 | 151 | |
| 152 | - // si on indique juste une table, il faut vider les autres proprietes |
|
| 153 | - // car par defaut on utilise ni casier ni prefixe dans ce cas |
|
| 154 | - if (isset($valeurs['_meta_table'])) { |
|
| 155 | - $table = $valeurs['_meta_table']; |
|
| 156 | - $casier = ($valeurs['_meta_casier'] ?? ''); |
|
| 157 | - } |
|
| 152 | + // si on indique juste une table, il faut vider les autres proprietes |
|
| 153 | + // car par defaut on utilise ni casier ni prefixe dans ce cas |
|
| 154 | + if (isset($valeurs['_meta_table'])) { |
|
| 155 | + $table = $valeurs['_meta_table']; |
|
| 156 | + $casier = ($valeurs['_meta_casier'] ?? ''); |
|
| 157 | + } |
|
| 158 | 158 | |
| 159 | - return [$table, $casier, $prefixe, $stockage]; |
|
| 159 | + return [$table, $casier, $prefixe, $stockage]; |
|
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | /** |
@@ -167,48 +167,48 @@ discard block |
||
| 167 | 167 | * @return array |
| 168 | 168 | */ |
| 169 | 169 | function cvtconf_formulaires_configurer_recense($form) { |
| 170 | - $valeurs = ['editable' => ' ']; |
|
| 170 | + $valeurs = ['editable' => ' ']; |
|
| 171 | 171 | |
| 172 | - // sinon cas analyse du squelette |
|
| 173 | - if ( |
|
| 174 | - $f = find_in_path($form . '.' . _EXTENSION_SQUELETTES, 'formulaires/') |
|
| 175 | - and lire_fichier($f, $contenu) |
|
| 176 | - ) { |
|
| 177 | - for ($i = 0; $i < 2; $i++) { |
|
| 178 | - // a la seconde iteration, evaluer le fond avec les valeurs deja trouvees |
|
| 179 | - // permet de trouver aussi les name="#GET{truc}" |
|
| 180 | - if ($i == 1) { |
|
| 181 | - $contenu = recuperer_fond("formulaires/$form", $valeurs); |
|
| 182 | - } |
|
| 172 | + // sinon cas analyse du squelette |
|
| 173 | + if ( |
|
| 174 | + $f = find_in_path($form . '.' . _EXTENSION_SQUELETTES, 'formulaires/') |
|
| 175 | + and lire_fichier($f, $contenu) |
|
| 176 | + ) { |
|
| 177 | + for ($i = 0; $i < 2; $i++) { |
|
| 178 | + // a la seconde iteration, evaluer le fond avec les valeurs deja trouvees |
|
| 179 | + // permet de trouver aussi les name="#GET{truc}" |
|
| 180 | + if ($i == 1) { |
|
| 181 | + $contenu = recuperer_fond("formulaires/$form", $valeurs); |
|
| 182 | + } |
|
| 183 | 183 | |
| 184 | - $balises = array_merge( |
|
| 185 | - extraire_balises($contenu, 'input'), |
|
| 186 | - extraire_balises($contenu, 'textarea'), |
|
| 187 | - extraire_balises($contenu, 'select') |
|
| 188 | - ); |
|
| 184 | + $balises = array_merge( |
|
| 185 | + extraire_balises($contenu, 'input'), |
|
| 186 | + extraire_balises($contenu, 'textarea'), |
|
| 187 | + extraire_balises($contenu, 'select') |
|
| 188 | + ); |
|
| 189 | 189 | |
| 190 | - foreach ($balises as $b) { |
|
| 191 | - if ( |
|
| 192 | - $n = extraire_attribut($b, 'name') |
|
| 193 | - and preg_match(',^([\w\-]+)(\[\w*\])?$,', $n, $r) |
|
| 194 | - and !in_array($n, ['formulaire_action', 'formulaire_action_args', 'formulaire_action_sign']) |
|
| 195 | - and extraire_attribut($b, 'type') !== 'submit' |
|
| 196 | - ) { |
|
| 197 | - $valeurs[$r[1]] = ''; |
|
| 198 | - // recuperer les valeurs _meta_xx qui peuvent etre fournies |
|
| 199 | - // en input hidden dans le squelette |
|
| 200 | - if (strncmp($r[1], '_meta_', 6) == 0) { |
|
| 201 | - $valeurs[$r[1]] = extraire_attribut($b, 'value'); |
|
| 202 | - } |
|
| 203 | - } |
|
| 204 | - } |
|
| 205 | - } |
|
| 206 | - } |
|
| 190 | + foreach ($balises as $b) { |
|
| 191 | + if ( |
|
| 192 | + $n = extraire_attribut($b, 'name') |
|
| 193 | + and preg_match(',^([\w\-]+)(\[\w*\])?$,', $n, $r) |
|
| 194 | + and !in_array($n, ['formulaire_action', 'formulaire_action_args', 'formulaire_action_sign']) |
|
| 195 | + and extraire_attribut($b, 'type') !== 'submit' |
|
| 196 | + ) { |
|
| 197 | + $valeurs[$r[1]] = ''; |
|
| 198 | + // recuperer les valeurs _meta_xx qui peuvent etre fournies |
|
| 199 | + // en input hidden dans le squelette |
|
| 200 | + if (strncmp($r[1], '_meta_', 6) == 0) { |
|
| 201 | + $valeurs[$r[1]] = extraire_attribut($b, 'value'); |
|
| 202 | + } |
|
| 203 | + } |
|
| 204 | + } |
|
| 205 | + } |
|
| 206 | + } |
|
| 207 | 207 | |
| 208 | 208 | |
| 209 | - cvtconf_configurer_lire_meta($form, $valeurs); |
|
| 209 | + cvtconf_configurer_lire_meta($form, $valeurs); |
|
| 210 | 210 | |
| 211 | - return $valeurs; |
|
| 211 | + return $valeurs; |
|
| 212 | 212 | } |
| 213 | 213 | |
| 214 | 214 | /** |
@@ -220,26 +220,26 @@ discard block |
||
| 220 | 220 | * @return string |
| 221 | 221 | */ |
| 222 | 222 | function cvtconf_configurer_stocker($form, $valeurs, $store) { |
| 223 | - $trace = ''; |
|
| 224 | - [$table, $casier, $prefixe, $stockage] = cvtconf_definir_configurer_conteneur($form, $valeurs); |
|
| 225 | - // stocker en base |
|
| 226 | - // par defaut, dans un casier serialize dans spip_meta (idem CFG) |
|
| 227 | - if (!isset($GLOBALS[$table])) { |
|
| 228 | - lire_metas($table); |
|
| 229 | - } |
|
| 223 | + $trace = ''; |
|
| 224 | + [$table, $casier, $prefixe, $stockage] = cvtconf_definir_configurer_conteneur($form, $valeurs); |
|
| 225 | + // stocker en base |
|
| 226 | + // par defaut, dans un casier serialize dans spip_meta (idem CFG) |
|
| 227 | + if (!isset($GLOBALS[$table])) { |
|
| 228 | + lire_metas($table); |
|
| 229 | + } |
|
| 230 | 230 | |
| 231 | - $prefixe = ($prefixe ? $prefixe . '_' : ''); |
|
| 232 | - $table = ($table) ? "/$table/" : ''; |
|
| 233 | - $casier = ($casier) ? rtrim($casier, '/') . '/' : ''; // slash final, sinon rien |
|
| 231 | + $prefixe = ($prefixe ? $prefixe . '_' : ''); |
|
| 232 | + $table = ($table) ? "/$table/" : ''; |
|
| 233 | + $casier = ($casier) ? rtrim($casier, '/') . '/' : ''; // slash final, sinon rien |
|
| 234 | 234 | |
| 235 | - foreach ($store as $k => $v) { |
|
| 236 | - ecrire_config("$stockage$table$prefixe$casier$k", $v); |
|
| 237 | - if (_request('var_mode') == 'configurer' and autoriser('webmestre')) { |
|
| 238 | - $trace .= "<br />table $table : " . $prefixe . $k . " = $v;"; |
|
| 239 | - } |
|
| 240 | - } |
|
| 235 | + foreach ($store as $k => $v) { |
|
| 236 | + ecrire_config("$stockage$table$prefixe$casier$k", $v); |
|
| 237 | + if (_request('var_mode') == 'configurer' and autoriser('webmestre')) { |
|
| 238 | + $trace .= "<br />table $table : " . $prefixe . $k . " = $v;"; |
|
| 239 | + } |
|
| 240 | + } |
|
| 241 | 241 | |
| 242 | - return $trace; |
|
| 242 | + return $trace; |
|
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | /** |
@@ -249,21 +249,21 @@ discard block |
||
| 249 | 249 | * @param array $valeurs |
| 250 | 250 | */ |
| 251 | 251 | function cvtconf_configurer_lire_meta($form, &$valeurs) { |
| 252 | - [$table, $casier, $prefixe, $stockage] = cvtconf_definir_configurer_conteneur($form, $valeurs); |
|
| 252 | + [$table, $casier, $prefixe, $stockage] = cvtconf_definir_configurer_conteneur($form, $valeurs); |
|
| 253 | 253 | |
| 254 | - $table = ($table) ? "/$table/" : ''; |
|
| 255 | - $prefixe = ($prefixe ? $prefixe . '_' : ''); |
|
| 256 | - if ($casier) { |
|
| 257 | - $meta = lire_config("$stockage$table$prefixe$casier"); |
|
| 258 | - $prefixe = ''; |
|
| 259 | - } else { |
|
| 260 | - $table = rtrim($table, '/'); |
|
| 261 | - $meta = lire_config("$stockage$table"); |
|
| 262 | - } |
|
| 254 | + $table = ($table) ? "/$table/" : ''; |
|
| 255 | + $prefixe = ($prefixe ? $prefixe . '_' : ''); |
|
| 256 | + if ($casier) { |
|
| 257 | + $meta = lire_config("$stockage$table$prefixe$casier"); |
|
| 258 | + $prefixe = ''; |
|
| 259 | + } else { |
|
| 260 | + $table = rtrim($table, '/'); |
|
| 261 | + $meta = lire_config("$stockage$table"); |
|
| 262 | + } |
|
| 263 | 263 | |
| 264 | - foreach ($valeurs as $k => $v) { |
|
| 265 | - if (substr($k, 0, 1) !== '_') { |
|
| 266 | - $valeurs[$k] = ($meta[$prefixe . $k] ?? null); |
|
| 267 | - } |
|
| 268 | - } |
|
| 264 | + foreach ($valeurs as $k => $v) { |
|
| 265 | + if (substr($k, 0, 1) !== '_') { |
|
| 266 | + $valeurs[$k] = ($meta[$prefixe . $k] ?? null); |
|
| 267 | + } |
|
| 268 | + } |
|
| 269 | 269 | } |
@@ -17,7 +17,7 @@ discard block |
||
| 17 | 17 | **/ |
| 18 | 18 | |
| 19 | 19 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 20 | - return; |
|
| 20 | + return; |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | include_spip('inc/charsets'); |
@@ -32,13 +32,13 @@ discard block |
||
| 32 | 32 | * @return string |
| 33 | 33 | */ |
| 34 | 34 | function exporter_csv_champ($champ) { |
| 35 | - #$champ = str_replace("\r", "\n", $champ); |
|
| 36 | - #$champ = preg_replace(",[\n]+,ms", "\n", $champ); |
|
| 37 | - #$champ = str_replace("\n", ", ", $champ); |
|
| 38 | - $champ = preg_replace(',[\s]+,ms', ' ', $champ); |
|
| 39 | - $champ = str_replace('"', '""', $champ); |
|
| 35 | + #$champ = str_replace("\r", "\n", $champ); |
|
| 36 | + #$champ = preg_replace(",[\n]+,ms", "\n", $champ); |
|
| 37 | + #$champ = str_replace("\n", ", ", $champ); |
|
| 38 | + $champ = preg_replace(',[\s]+,ms', ' ', $champ); |
|
| 39 | + $champ = str_replace('"', '""', $champ); |
|
| 40 | 40 | |
| 41 | - return '"' . $champ . '"'; |
|
| 41 | + return '"' . $champ . '"'; |
|
| 42 | 42 | } |
| 43 | 43 | |
| 44 | 44 | /** |
@@ -55,15 +55,15 @@ discard block |
||
| 55 | 55 | * @return string |
| 56 | 56 | */ |
| 57 | 57 | function exporter_csv_ligne_numerotee($nb, $ligne, $delim = ',', $importer_charset = null, ?callable $callback = null) { |
| 58 | - if ($callback) { |
|
| 59 | - $ligne = $callback($nb, $ligne, $delim, $importer_charset); |
|
| 60 | - } |
|
| 61 | - $output = join($delim, array_map('exporter_csv_champ', $ligne)) . "\r\n"; |
|
| 62 | - if ($importer_charset) { |
|
| 63 | - $output = str_replace('’', '\'', $output); |
|
| 64 | - $output = unicode2charset(html2unicode(charset2unicode($output)), $importer_charset); |
|
| 65 | - } |
|
| 66 | - return $output; |
|
| 58 | + if ($callback) { |
|
| 59 | + $ligne = $callback($nb, $ligne, $delim, $importer_charset); |
|
| 60 | + } |
|
| 61 | + $output = join($delim, array_map('exporter_csv_champ', $ligne)) . "\r\n"; |
|
| 62 | + if ($importer_charset) { |
|
| 63 | + $output = str_replace('’', '\'', $output); |
|
| 64 | + $output = unicode2charset(html2unicode(charset2unicode($output)), $importer_charset); |
|
| 65 | + } |
|
| 66 | + return $output; |
|
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | /** |
@@ -75,7 +75,7 @@ discard block |
||
| 75 | 75 | * @return string |
| 76 | 76 | */ |
| 77 | 77 | function exporter_csv_ligne($ligne, $delim = ',', $importer_charset = null) { |
| 78 | - return exporter_csv_ligne_numerotee(null, $ligne, $delim, $importer_charset); |
|
| 78 | + return exporter_csv_ligne_numerotee(null, $ligne, $delim, $importer_charset); |
|
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | /** |
@@ -101,101 +101,101 @@ discard block |
||
| 101 | 101 | */ |
| 102 | 102 | function inc_exporter_csv_dist($titre, $resource, $options = []) { |
| 103 | 103 | |
| 104 | - // support ancienne syntaxe |
|
| 105 | - // inc_exporter_csv_dist($titre, $resource, $delim = ', ', $entetes = null, $envoyer = true) |
|
| 106 | - if (is_string($options)) { |
|
| 107 | - $args = func_get_args(); |
|
| 108 | - $options = []; |
|
| 109 | - foreach ([2 => 'delim', 3 => 'entetes', 4 => 'envoyer'] as $k => $option) { |
|
| 110 | - if (!empty($args[$k])) { |
|
| 111 | - $options[$option] = $args[$k]; |
|
| 112 | - } |
|
| 113 | - } |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - $default_options = [ |
|
| 117 | - 'delim' => ', ', |
|
| 118 | - 'entetes' => null, |
|
| 119 | - 'envoyer' => true, |
|
| 120 | - 'charset' => null, |
|
| 121 | - 'callback' => null, |
|
| 122 | - ]; |
|
| 123 | - $options = array_merge($default_options, $options); |
|
| 124 | - |
|
| 125 | - $filename = preg_replace(',[^-_\w]+,', '_', translitteration(textebrut(typo($titre)))); |
|
| 126 | - |
|
| 127 | - if ($options['delim'] == 'TAB') { |
|
| 128 | - $options['delim'] = "\t"; |
|
| 129 | - } |
|
| 130 | - if (!in_array($options['delim'], [',', ';', "\t"])) { |
|
| 131 | - $options['delim'] = ','; |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - $charset = $GLOBALS['meta']['charset']; |
|
| 135 | - $importer_charset = null; |
|
| 136 | - if ($options['delim'] == ',') { |
|
| 137 | - $extension = 'csv'; |
|
| 138 | - } else { |
|
| 139 | - $extension = 'xls'; |
|
| 140 | - # Excel n'accepte pas l'utf-8 ni les entites html... on transcode tout ce qu'on peut |
|
| 141 | - $charset = 'iso-8859-1'; |
|
| 142 | - } |
|
| 143 | - // mais si une option charset est explicite, elle a la priorite |
|
| 144 | - if (!empty($options['charset'])) { |
|
| 145 | - $charset = $options['charset']; |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - $importer_charset = (($charset === $GLOBALS['meta']['charset']) ? null : $charset); |
|
| 149 | - |
|
| 150 | - $filename = "$filename.$extension"; |
|
| 151 | - |
|
| 152 | - $output = ''; |
|
| 153 | - $nb = 0; |
|
| 154 | - if (!empty($options['entetes']) and is_array($options['entetes'])) { |
|
| 155 | - $output = exporter_csv_ligne_numerotee($nb, $options['entetes'], $options['delim'], $importer_charset, $options['callback']); |
|
| 156 | - } |
|
| 157 | - // les donnees commencent toujours a la ligne 1, qu'il y ait ou non des entetes |
|
| 158 | - $nb++; |
|
| 159 | - |
|
| 160 | - if ($options['envoyer']) { |
|
| 161 | - $disposition = ($options['envoyer'] === 'attachment' ? 'attachment' : 'inline'); |
|
| 162 | - header("Content-Type: text/comma-separated-values; charset=$charset"); |
|
| 163 | - header("Content-Disposition: $disposition; filename=$filename"); |
|
| 164 | - |
|
| 165 | - // Vider tous les tampons |
|
| 166 | - $level = @ob_get_level(); |
|
| 167 | - while ($level--) { |
|
| 168 | - @ob_end_flush(); |
|
| 169 | - } |
|
| 170 | - } |
|
| 171 | - |
|
| 172 | - // si envoyer=='attachment' on passe par un fichier temporaire |
|
| 173 | - // sinon on ecrit directement sur stdout |
|
| 174 | - if ($options['envoyer'] and $options['envoyer'] !== 'attachment') { |
|
| 175 | - $fichier = 'php://output'; |
|
| 176 | - } |
|
| 177 | - else { |
|
| 178 | - $fichier = sous_repertoire(_DIR_CACHE, 'export') . $filename; |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - $fp = fopen($fichier, 'w'); |
|
| 182 | - $length = fwrite($fp, $output); |
|
| 183 | - |
|
| 184 | - while ($row = is_array($resource) ? array_shift($resource) : sql_fetch($resource)) { |
|
| 185 | - $output = exporter_csv_ligne_numerotee($nb, $row, $options['delim'], $importer_charset, $options['callback']); |
|
| 186 | - $length += fwrite($fp, $output); |
|
| 187 | - $nb++; |
|
| 188 | - } |
|
| 189 | - fclose($fp); |
|
| 190 | - |
|
| 191 | - if ($options['envoyer']) { |
|
| 192 | - if ($options['envoyer'] === 'attachment') { |
|
| 193 | - header("Content-Length: $length"); |
|
| 194 | - readfile($fichier); |
|
| 195 | - } |
|
| 196 | - // si on a envoye inline, c'est deja tout bon |
|
| 197 | - exit; |
|
| 198 | - } |
|
| 199 | - |
|
| 200 | - return $fichier; |
|
| 104 | + // support ancienne syntaxe |
|
| 105 | + // inc_exporter_csv_dist($titre, $resource, $delim = ', ', $entetes = null, $envoyer = true) |
|
| 106 | + if (is_string($options)) { |
|
| 107 | + $args = func_get_args(); |
|
| 108 | + $options = []; |
|
| 109 | + foreach ([2 => 'delim', 3 => 'entetes', 4 => 'envoyer'] as $k => $option) { |
|
| 110 | + if (!empty($args[$k])) { |
|
| 111 | + $options[$option] = $args[$k]; |
|
| 112 | + } |
|
| 113 | + } |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + $default_options = [ |
|
| 117 | + 'delim' => ', ', |
|
| 118 | + 'entetes' => null, |
|
| 119 | + 'envoyer' => true, |
|
| 120 | + 'charset' => null, |
|
| 121 | + 'callback' => null, |
|
| 122 | + ]; |
|
| 123 | + $options = array_merge($default_options, $options); |
|
| 124 | + |
|
| 125 | + $filename = preg_replace(',[^-_\w]+,', '_', translitteration(textebrut(typo($titre)))); |
|
| 126 | + |
|
| 127 | + if ($options['delim'] == 'TAB') { |
|
| 128 | + $options['delim'] = "\t"; |
|
| 129 | + } |
|
| 130 | + if (!in_array($options['delim'], [',', ';', "\t"])) { |
|
| 131 | + $options['delim'] = ','; |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + $charset = $GLOBALS['meta']['charset']; |
|
| 135 | + $importer_charset = null; |
|
| 136 | + if ($options['delim'] == ',') { |
|
| 137 | + $extension = 'csv'; |
|
| 138 | + } else { |
|
| 139 | + $extension = 'xls'; |
|
| 140 | + # Excel n'accepte pas l'utf-8 ni les entites html... on transcode tout ce qu'on peut |
|
| 141 | + $charset = 'iso-8859-1'; |
|
| 142 | + } |
|
| 143 | + // mais si une option charset est explicite, elle a la priorite |
|
| 144 | + if (!empty($options['charset'])) { |
|
| 145 | + $charset = $options['charset']; |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + $importer_charset = (($charset === $GLOBALS['meta']['charset']) ? null : $charset); |
|
| 149 | + |
|
| 150 | + $filename = "$filename.$extension"; |
|
| 151 | + |
|
| 152 | + $output = ''; |
|
| 153 | + $nb = 0; |
|
| 154 | + if (!empty($options['entetes']) and is_array($options['entetes'])) { |
|
| 155 | + $output = exporter_csv_ligne_numerotee($nb, $options['entetes'], $options['delim'], $importer_charset, $options['callback']); |
|
| 156 | + } |
|
| 157 | + // les donnees commencent toujours a la ligne 1, qu'il y ait ou non des entetes |
|
| 158 | + $nb++; |
|
| 159 | + |
|
| 160 | + if ($options['envoyer']) { |
|
| 161 | + $disposition = ($options['envoyer'] === 'attachment' ? 'attachment' : 'inline'); |
|
| 162 | + header("Content-Type: text/comma-separated-values; charset=$charset"); |
|
| 163 | + header("Content-Disposition: $disposition; filename=$filename"); |
|
| 164 | + |
|
| 165 | + // Vider tous les tampons |
|
| 166 | + $level = @ob_get_level(); |
|
| 167 | + while ($level--) { |
|
| 168 | + @ob_end_flush(); |
|
| 169 | + } |
|
| 170 | + } |
|
| 171 | + |
|
| 172 | + // si envoyer=='attachment' on passe par un fichier temporaire |
|
| 173 | + // sinon on ecrit directement sur stdout |
|
| 174 | + if ($options['envoyer'] and $options['envoyer'] !== 'attachment') { |
|
| 175 | + $fichier = 'php://output'; |
|
| 176 | + } |
|
| 177 | + else { |
|
| 178 | + $fichier = sous_repertoire(_DIR_CACHE, 'export') . $filename; |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + $fp = fopen($fichier, 'w'); |
|
| 182 | + $length = fwrite($fp, $output); |
|
| 183 | + |
|
| 184 | + while ($row = is_array($resource) ? array_shift($resource) : sql_fetch($resource)) { |
|
| 185 | + $output = exporter_csv_ligne_numerotee($nb, $row, $options['delim'], $importer_charset, $options['callback']); |
|
| 186 | + $length += fwrite($fp, $output); |
|
| 187 | + $nb++; |
|
| 188 | + } |
|
| 189 | + fclose($fp); |
|
| 190 | + |
|
| 191 | + if ($options['envoyer']) { |
|
| 192 | + if ($options['envoyer'] === 'attachment') { |
|
| 193 | + header("Content-Length: $length"); |
|
| 194 | + readfile($fichier); |
|
| 195 | + } |
|
| 196 | + // si on a envoye inline, c'est deja tout bon |
|
| 197 | + exit; |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + return $fichier; |
|
| 201 | 201 | } |
@@ -17,17 +17,17 @@ discard block |
||
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 20 | - return; |
|
| 20 | + return; |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | if (!defined('_UPGRADE_TIME_OUT')) { |
| 24 | - /** |
|
| 25 | - * Durée en secondes pour relancer les scripts de mises à jour, x secondes |
|
| 26 | - * avant que la durée d'exécution du script provoque un timeout |
|
| 27 | - * |
|
| 28 | - * @var int |
|
| 29 | - **/ |
|
| 30 | - define('_UPGRADE_TIME_OUT', 20); |
|
| 24 | + /** |
|
| 25 | + * Durée en secondes pour relancer les scripts de mises à jour, x secondes |
|
| 26 | + * avant que la durée d'exécution du script provoque un timeout |
|
| 27 | + * |
|
| 28 | + * @var int |
|
| 29 | + **/ |
|
| 30 | + define('_UPGRADE_TIME_OUT', 20); |
|
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | /** |
@@ -50,40 +50,40 @@ discard block |
||
| 50 | 50 | * @return void |
| 51 | 51 | */ |
| 52 | 52 | function base_upgrade_dist($titre = '', $reprise = '') { |
| 53 | - if (!$titre) { |
|
| 54 | - return; |
|
| 55 | - } // anti-testeur automatique |
|
| 56 | - if ($GLOBALS['spip_version_base'] != $GLOBALS['meta']['version_installee']) { |
|
| 57 | - if (!is_numeric(_request('reinstall'))) { |
|
| 58 | - include_spip('base/create'); |
|
| 59 | - spip_log('recree les tables eventuellement disparues', 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 60 | - creer_base(); |
|
| 61 | - } |
|
| 62 | - |
|
| 63 | - // quand on rentre par ici, c'est toujours une mise a jour de SPIP |
|
| 64 | - // lancement de l'upgrade SPIP |
|
| 65 | - $res = maj_base(); |
|
| 66 | - |
|
| 67 | - if ($res) { |
|
| 68 | - // on arrete tout ici ! |
|
| 69 | - exit; |
|
| 70 | - } |
|
| 71 | - } |
|
| 72 | - spip_log('Fin de mise a jour SQL. Debut m-a-j acces et config', 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 73 | - |
|
| 74 | - // supprimer quelques fichiers temporaires qui peuvent se retrouver invalides |
|
| 75 | - @spip_unlink(_CACHE_RUBRIQUES); |
|
| 76 | - @spip_unlink(_CACHE_PIPELINES); |
|
| 77 | - @spip_unlink(_CACHE_PLUGINS_PATH); |
|
| 78 | - @spip_unlink(_CACHE_PLUGINS_OPT); |
|
| 79 | - @spip_unlink(_CACHE_PLUGINS_FCT); |
|
| 80 | - @spip_unlink(_CACHE_CHEMIN); |
|
| 81 | - @spip_unlink(_DIR_TMP . 'plugin_xml_cache.gz'); |
|
| 82 | - |
|
| 83 | - include_spip('inc/auth'); |
|
| 84 | - auth_synchroniser_distant(); |
|
| 85 | - $config = charger_fonction('config', 'inc'); |
|
| 86 | - $config(); |
|
| 53 | + if (!$titre) { |
|
| 54 | + return; |
|
| 55 | + } // anti-testeur automatique |
|
| 56 | + if ($GLOBALS['spip_version_base'] != $GLOBALS['meta']['version_installee']) { |
|
| 57 | + if (!is_numeric(_request('reinstall'))) { |
|
| 58 | + include_spip('base/create'); |
|
| 59 | + spip_log('recree les tables eventuellement disparues', 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 60 | + creer_base(); |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + // quand on rentre par ici, c'est toujours une mise a jour de SPIP |
|
| 64 | + // lancement de l'upgrade SPIP |
|
| 65 | + $res = maj_base(); |
|
| 66 | + |
|
| 67 | + if ($res) { |
|
| 68 | + // on arrete tout ici ! |
|
| 69 | + exit; |
|
| 70 | + } |
|
| 71 | + } |
|
| 72 | + spip_log('Fin de mise a jour SQL. Debut m-a-j acces et config', 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 73 | + |
|
| 74 | + // supprimer quelques fichiers temporaires qui peuvent se retrouver invalides |
|
| 75 | + @spip_unlink(_CACHE_RUBRIQUES); |
|
| 76 | + @spip_unlink(_CACHE_PIPELINES); |
|
| 77 | + @spip_unlink(_CACHE_PLUGINS_PATH); |
|
| 78 | + @spip_unlink(_CACHE_PLUGINS_OPT); |
|
| 79 | + @spip_unlink(_CACHE_PLUGINS_FCT); |
|
| 80 | + @spip_unlink(_CACHE_CHEMIN); |
|
| 81 | + @spip_unlink(_DIR_TMP . 'plugin_xml_cache.gz'); |
|
| 82 | + |
|
| 83 | + include_spip('inc/auth'); |
|
| 84 | + auth_synchroniser_distant(); |
|
| 85 | + $config = charger_fonction('config', 'inc'); |
|
| 86 | + $config(); |
|
| 87 | 87 | } |
| 88 | 88 | |
| 89 | 89 | /** |
@@ -114,51 +114,51 @@ discard block |
||
| 114 | 114 | */ |
| 115 | 115 | function maj_base($version_cible = 0, $redirect = '', $debut_page = true) { |
| 116 | 116 | |
| 117 | - $version_installee = $GLOBALS['meta']['version_installee'] ?? null; |
|
| 118 | - |
|
| 119 | - spip_log( |
|
| 120 | - "Version anterieure: $version_installee. Courante: " . $GLOBALS['spip_version_base'], |
|
| 121 | - 'maj.' . _LOG_INFO_IMPORTANTE |
|
| 122 | - ); |
|
| 123 | - if (!$version_installee or ($GLOBALS['spip_version_base'] < $version_installee)) { |
|
| 124 | - sql_replace( |
|
| 125 | - 'spip_meta', |
|
| 126 | - [ |
|
| 127 | - 'nom' => 'version_installee', |
|
| 128 | - 'valeur' => $GLOBALS['spip_version_base'], |
|
| 129 | - 'impt' => 'non' |
|
| 130 | - ] |
|
| 131 | - ); |
|
| 132 | - return false; |
|
| 133 | - } |
|
| 134 | - if (!upgrade_test()) { |
|
| 135 | - return true; |
|
| 136 | - } |
|
| 137 | - |
|
| 138 | - $cible = ($version_cible ?: $GLOBALS['spip_version_base']); |
|
| 139 | - |
|
| 140 | - if ($version_installee < 2021_01_01_00) { |
|
| 141 | - include_spip('maj/legacy/v21'); |
|
| 142 | - include_spip('maj/legacy/v30'); |
|
| 143 | - include_spip('maj/legacy/v31'); |
|
| 144 | - include_spip('maj/legacy/v32'); |
|
| 145 | - include_spip('maj/legacy/v40'); |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - include_spip('maj/2021'); |
|
| 149 | - |
|
| 150 | - ksort($GLOBALS['maj']); |
|
| 151 | - $res = maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee', 'meta', $redirect, $debut_page); |
|
| 152 | - if ($res) { |
|
| 153 | - if (!is_array($res)) { |
|
| 154 | - spip_log("Pb d'acces SQL a la mise a jour", 'maj.' . _LOG_ERREUR); |
|
| 155 | - } else { |
|
| 156 | - echo _T('avis_operation_echec') . ' ' . join(' ', $res); |
|
| 157 | - echo install_fin_html(); |
|
| 158 | - } |
|
| 159 | - } |
|
| 160 | - |
|
| 161 | - return $res; |
|
| 117 | + $version_installee = $GLOBALS['meta']['version_installee'] ?? null; |
|
| 118 | + |
|
| 119 | + spip_log( |
|
| 120 | + "Version anterieure: $version_installee. Courante: " . $GLOBALS['spip_version_base'], |
|
| 121 | + 'maj.' . _LOG_INFO_IMPORTANTE |
|
| 122 | + ); |
|
| 123 | + if (!$version_installee or ($GLOBALS['spip_version_base'] < $version_installee)) { |
|
| 124 | + sql_replace( |
|
| 125 | + 'spip_meta', |
|
| 126 | + [ |
|
| 127 | + 'nom' => 'version_installee', |
|
| 128 | + 'valeur' => $GLOBALS['spip_version_base'], |
|
| 129 | + 'impt' => 'non' |
|
| 130 | + ] |
|
| 131 | + ); |
|
| 132 | + return false; |
|
| 133 | + } |
|
| 134 | + if (!upgrade_test()) { |
|
| 135 | + return true; |
|
| 136 | + } |
|
| 137 | + |
|
| 138 | + $cible = ($version_cible ?: $GLOBALS['spip_version_base']); |
|
| 139 | + |
|
| 140 | + if ($version_installee < 2021_01_01_00) { |
|
| 141 | + include_spip('maj/legacy/v21'); |
|
| 142 | + include_spip('maj/legacy/v30'); |
|
| 143 | + include_spip('maj/legacy/v31'); |
|
| 144 | + include_spip('maj/legacy/v32'); |
|
| 145 | + include_spip('maj/legacy/v40'); |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + include_spip('maj/2021'); |
|
| 149 | + |
|
| 150 | + ksort($GLOBALS['maj']); |
|
| 151 | + $res = maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee', 'meta', $redirect, $debut_page); |
|
| 152 | + if ($res) { |
|
| 153 | + if (!is_array($res)) { |
|
| 154 | + spip_log("Pb d'acces SQL a la mise a jour", 'maj.' . _LOG_ERREUR); |
|
| 155 | + } else { |
|
| 156 | + echo _T('avis_operation_echec') . ' ' . join(' ', $res); |
|
| 157 | + echo install_fin_html(); |
|
| 158 | + } |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + return $res; |
|
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | /** |
@@ -200,53 +200,53 @@ discard block |
||
| 200 | 200 | */ |
| 201 | 201 | function maj_plugin($nom_meta_base_version, $version_cible, $maj, $table_meta = 'meta') { |
| 202 | 202 | |
| 203 | - if ($table_meta !== 'meta') { |
|
| 204 | - installer_table_meta($table_meta); |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - $current_version = null; |
|
| 208 | - |
|
| 209 | - if ( |
|
| 210 | - (!isset($GLOBALS[$table_meta][$nom_meta_base_version])) |
|
| 211 | - || (!spip_version_compare($current_version = $GLOBALS[$table_meta][$nom_meta_base_version], $version_cible, '=')) |
|
| 212 | - ) { |
|
| 213 | - // $maj['create'] contient les directives propres a la premiere creation de base |
|
| 214 | - // c'est une operation derogatoire qui fait aboutir directement dans la version_cible |
|
| 215 | - if (isset($maj['create'])) { |
|
| 216 | - if (!isset($GLOBALS[$table_meta][$nom_meta_base_version])) { |
|
| 217 | - // installation : on ne fait que l'operation create |
|
| 218 | - $maj = ['init' => $maj['create']]; |
|
| 219 | - // et on lui ajoute un appel a inc/config |
|
| 220 | - // pour creer les metas par defaut |
|
| 221 | - $config = charger_fonction('config', 'inc'); |
|
| 222 | - $maj[$version_cible] = [[$config]]; |
|
| 223 | - } |
|
| 224 | - // dans tous les cas enlever cet index du tableau |
|
| 225 | - unset($maj['create']); |
|
| 226 | - } |
|
| 227 | - // si init, deja dans le bon ordre |
|
| 228 | - if (!isset($maj['init'])) { |
|
| 229 | - include_spip('inc/plugin'); // pour spip_version_compare |
|
| 230 | - uksort($maj, 'spip_version_compare'); |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - // la redirection se fait par defaut sur la page d'administration des plugins |
|
| 234 | - // sauf lorsque nous sommes sur l'installation de SPIP |
|
| 235 | - // ou define _REDIRECT_MAJ_PLUGIN |
|
| 236 | - $redirect = (defined('_REDIRECT_MAJ_PLUGIN') ? _REDIRECT_MAJ_PLUGIN : generer_url_ecrire('admin_plugin')); |
|
| 237 | - if (defined('_ECRIRE_INSTALL')) { |
|
| 238 | - $redirect = parametre_url(generer_url_ecrire('install'), 'etape', _request('etape')); |
|
| 239 | - } |
|
| 240 | - |
|
| 241 | - $res = maj_while($current_version, $version_cible, $maj, $nom_meta_base_version, $table_meta, $redirect); |
|
| 242 | - if ($res) { |
|
| 243 | - if (!is_array($res)) { |
|
| 244 | - spip_log("Pb d'acces SQL a la mise a jour", 'maj.' . _LOG_ERREUR); |
|
| 245 | - } else { |
|
| 246 | - echo '<p>' . _T('avis_operation_echec') . ' ' . join(' ', $res) . '</p>'; |
|
| 247 | - } |
|
| 248 | - } |
|
| 249 | - } |
|
| 203 | + if ($table_meta !== 'meta') { |
|
| 204 | + installer_table_meta($table_meta); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + $current_version = null; |
|
| 208 | + |
|
| 209 | + if ( |
|
| 210 | + (!isset($GLOBALS[$table_meta][$nom_meta_base_version])) |
|
| 211 | + || (!spip_version_compare($current_version = $GLOBALS[$table_meta][$nom_meta_base_version], $version_cible, '=')) |
|
| 212 | + ) { |
|
| 213 | + // $maj['create'] contient les directives propres a la premiere creation de base |
|
| 214 | + // c'est une operation derogatoire qui fait aboutir directement dans la version_cible |
|
| 215 | + if (isset($maj['create'])) { |
|
| 216 | + if (!isset($GLOBALS[$table_meta][$nom_meta_base_version])) { |
|
| 217 | + // installation : on ne fait que l'operation create |
|
| 218 | + $maj = ['init' => $maj['create']]; |
|
| 219 | + // et on lui ajoute un appel a inc/config |
|
| 220 | + // pour creer les metas par defaut |
|
| 221 | + $config = charger_fonction('config', 'inc'); |
|
| 222 | + $maj[$version_cible] = [[$config]]; |
|
| 223 | + } |
|
| 224 | + // dans tous les cas enlever cet index du tableau |
|
| 225 | + unset($maj['create']); |
|
| 226 | + } |
|
| 227 | + // si init, deja dans le bon ordre |
|
| 228 | + if (!isset($maj['init'])) { |
|
| 229 | + include_spip('inc/plugin'); // pour spip_version_compare |
|
| 230 | + uksort($maj, 'spip_version_compare'); |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + // la redirection se fait par defaut sur la page d'administration des plugins |
|
| 234 | + // sauf lorsque nous sommes sur l'installation de SPIP |
|
| 235 | + // ou define _REDIRECT_MAJ_PLUGIN |
|
| 236 | + $redirect = (defined('_REDIRECT_MAJ_PLUGIN') ? _REDIRECT_MAJ_PLUGIN : generer_url_ecrire('admin_plugin')); |
|
| 237 | + if (defined('_ECRIRE_INSTALL')) { |
|
| 238 | + $redirect = parametre_url(generer_url_ecrire('install'), 'etape', _request('etape')); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + $res = maj_while($current_version, $version_cible, $maj, $nom_meta_base_version, $table_meta, $redirect); |
|
| 242 | + if ($res) { |
|
| 243 | + if (!is_array($res)) { |
|
| 244 | + spip_log("Pb d'acces SQL a la mise a jour", 'maj.' . _LOG_ERREUR); |
|
| 245 | + } else { |
|
| 246 | + echo '<p>' . _T('avis_operation_echec') . ' ' . join(' ', $res) . '</p>'; |
|
| 247 | + } |
|
| 248 | + } |
|
| 249 | + } |
|
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | /** |
@@ -263,17 +263,17 @@ discard block |
||
| 263 | 263 | * @return void |
| 264 | 264 | */ |
| 265 | 265 | function relance_maj($meta, $table, $redirect = '') { |
| 266 | - include_spip('inc/headers'); |
|
| 267 | - if (!$redirect) { |
|
| 268 | - // recuperer la valeur installee en cours |
|
| 269 | - // on la tronque numeriquement, elle ne sert pas reellement |
|
| 270 | - // sauf pour verifier que ce n'est pas oui ou non |
|
| 271 | - // sinon is_numeric va echouer sur un numero de version 1.2.3 |
|
| 272 | - $installee = intval($GLOBALS[$table][$meta]); |
|
| 273 | - $redirect = generer_url_ecrire('upgrade', "reinstall=$installee&meta=$meta&table=$table", true); |
|
| 274 | - } |
|
| 275 | - echo redirige_formulaire($redirect); |
|
| 276 | - exit(); |
|
| 266 | + include_spip('inc/headers'); |
|
| 267 | + if (!$redirect) { |
|
| 268 | + // recuperer la valeur installee en cours |
|
| 269 | + // on la tronque numeriquement, elle ne sert pas reellement |
|
| 270 | + // sauf pour verifier que ce n'est pas oui ou non |
|
| 271 | + // sinon is_numeric va echouer sur un numero de version 1.2.3 |
|
| 272 | + $installee = intval($GLOBALS[$table][$meta]); |
|
| 273 | + $redirect = generer_url_ecrire('upgrade', "reinstall=$installee&meta=$meta&table=$table", true); |
|
| 274 | + } |
|
| 275 | + echo redirige_formulaire($redirect); |
|
| 276 | + exit(); |
|
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 | /** |
@@ -286,28 +286,28 @@ discard block |
||
| 286 | 286 | * @return void |
| 287 | 287 | */ |
| 288 | 288 | function maj_debut_page($installee, $meta, $table) { |
| 289 | - static $done = false; |
|
| 290 | - if ($done) { |
|
| 291 | - return; |
|
| 292 | - } |
|
| 293 | - include_spip('inc/minipres'); |
|
| 294 | - if (function_exists('ini_set')) { |
|
| 295 | - @ini_set('zlib.output_compression', '0'); // pour permettre l'affichage au fur et a mesure |
|
| 296 | - } |
|
| 297 | - $timeout = _UPGRADE_TIME_OUT * 2; |
|
| 298 | - $titre = _T('titre_page_upgrade'); |
|
| 299 | - $balise_img = charger_filtre('balise_img'); |
|
| 300 | - $titre .= $balise_img(chemin_image('loader.svg'), '', 'loader'); |
|
| 301 | - echo(install_debut_html($titre)); |
|
| 302 | - // script de rechargement auto sur timeout |
|
| 303 | - $redirect = generer_url_ecrire('upgrade', "reinstall=$installee&meta=$meta&table=$table", true); |
|
| 304 | - echo http_script("window.setTimeout('location.href=\"" . $redirect . "\";'," . ($timeout * 1000) . ')'); |
|
| 305 | - echo "<div style='text-align: left'>\n"; |
|
| 306 | - if (ob_get_level()) { |
|
| 307 | - ob_flush(); |
|
| 308 | - } |
|
| 309 | - flush(); |
|
| 310 | - $done = true; |
|
| 289 | + static $done = false; |
|
| 290 | + if ($done) { |
|
| 291 | + return; |
|
| 292 | + } |
|
| 293 | + include_spip('inc/minipres'); |
|
| 294 | + if (function_exists('ini_set')) { |
|
| 295 | + @ini_set('zlib.output_compression', '0'); // pour permettre l'affichage au fur et a mesure |
|
| 296 | + } |
|
| 297 | + $timeout = _UPGRADE_TIME_OUT * 2; |
|
| 298 | + $titre = _T('titre_page_upgrade'); |
|
| 299 | + $balise_img = charger_filtre('balise_img'); |
|
| 300 | + $titre .= $balise_img(chemin_image('loader.svg'), '', 'loader'); |
|
| 301 | + echo(install_debut_html($titre)); |
|
| 302 | + // script de rechargement auto sur timeout |
|
| 303 | + $redirect = generer_url_ecrire('upgrade', "reinstall=$installee&meta=$meta&table=$table", true); |
|
| 304 | + echo http_script("window.setTimeout('location.href=\"" . $redirect . "\";'," . ($timeout * 1000) . ')'); |
|
| 305 | + echo "<div style='text-align: left'>\n"; |
|
| 306 | + if (ob_get_level()) { |
|
| 307 | + ob_flush(); |
|
| 308 | + } |
|
| 309 | + flush(); |
|
| 310 | + $done = true; |
|
| 311 | 311 | } |
| 312 | 312 | |
| 313 | 313 | |
@@ -351,64 +351,64 @@ discard block |
||
| 351 | 351 | * - tableau vide sinon. |
| 352 | 352 | */ |
| 353 | 353 | function maj_while($installee, $cible, $maj, $meta = '', $table = 'meta', $redirect = '', $debut_page = false) { |
| 354 | - # inclusions pour que les procedures d'upgrade disposent des fonctions de base |
|
| 355 | - include_spip('base/create'); |
|
| 356 | - include_spip('base/abstract_sql'); |
|
| 357 | - $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 358 | - include_spip('inc/plugin'); // pour spip_version_compare |
|
| 359 | - $n = 0; |
|
| 360 | - $time = time(); |
|
| 361 | - |
|
| 362 | - if (!defined('_TIME_OUT')) { |
|
| 363 | - /** |
|
| 364 | - * Définir le timeout qui peut-être utilisé dans les fonctions |
|
| 365 | - * de mises à jour qui durent trop longtemps |
|
| 366 | - * |
|
| 367 | - * À utiliser tel que : `if (time() >= _TIME_OUT)` |
|
| 368 | - * |
|
| 369 | - * @var int |
|
| 370 | - */ |
|
| 371 | - define('_TIME_OUT', $time + _UPGRADE_TIME_OUT); |
|
| 372 | - } |
|
| 373 | - |
|
| 374 | - foreach ($maj as $v => $operations) { |
|
| 375 | - // si une maj pour cette version |
|
| 376 | - if ( |
|
| 377 | - $v == 'init' or |
|
| 378 | - (spip_version_compare($v, $installee, '>') |
|
| 379 | - and spip_version_compare($v, $cible, '<=')) |
|
| 380 | - ) { |
|
| 381 | - if ($debut_page) { |
|
| 382 | - maj_debut_page($v, $meta, $table); |
|
| 383 | - } |
|
| 384 | - echo "MAJ $v"; |
|
| 385 | - $etape = serie_alter($v, $operations, $meta, $table, $redirect); |
|
| 386 | - $trouver_table(''); // vider le cache des descriptions de table |
|
| 387 | - # echec sur une etape en cours ? |
|
| 388 | - # on sort |
|
| 389 | - if ($etape) { |
|
| 390 | - return [$v, $etape]; |
|
| 391 | - } |
|
| 392 | - $n = time() - $time; |
|
| 393 | - spip_log("$table $meta: $v en $n secondes", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 394 | - if ($meta) { |
|
| 395 | - ecrire_meta($meta, $installee = $v, 'oui', $table); |
|
| 396 | - } |
|
| 397 | - echo (_IS_CLI ? "\n" : '<br />'); |
|
| 398 | - } |
|
| 399 | - if (time() >= _TIME_OUT) { |
|
| 400 | - relance_maj($meta, $table, $redirect); |
|
| 401 | - } |
|
| 402 | - } |
|
| 403 | - $trouver_table(''); // vider le cache des descriptions de table |
|
| 404 | - // indispensable pour les chgt de versions qui n'ecrivent pas en base |
|
| 405 | - // tant pis pour la redondance eventuelle avec ci-dessus |
|
| 406 | - if ($meta) { |
|
| 407 | - ecrire_meta($meta, $cible, 'oui', $table); |
|
| 408 | - } |
|
| 409 | - spip_log("MAJ terminee. $meta: $installee", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 410 | - |
|
| 411 | - return []; |
|
| 354 | + # inclusions pour que les procedures d'upgrade disposent des fonctions de base |
|
| 355 | + include_spip('base/create'); |
|
| 356 | + include_spip('base/abstract_sql'); |
|
| 357 | + $trouver_table = charger_fonction('trouver_table', 'base'); |
|
| 358 | + include_spip('inc/plugin'); // pour spip_version_compare |
|
| 359 | + $n = 0; |
|
| 360 | + $time = time(); |
|
| 361 | + |
|
| 362 | + if (!defined('_TIME_OUT')) { |
|
| 363 | + /** |
|
| 364 | + * Définir le timeout qui peut-être utilisé dans les fonctions |
|
| 365 | + * de mises à jour qui durent trop longtemps |
|
| 366 | + * |
|
| 367 | + * À utiliser tel que : `if (time() >= _TIME_OUT)` |
|
| 368 | + * |
|
| 369 | + * @var int |
|
| 370 | + */ |
|
| 371 | + define('_TIME_OUT', $time + _UPGRADE_TIME_OUT); |
|
| 372 | + } |
|
| 373 | + |
|
| 374 | + foreach ($maj as $v => $operations) { |
|
| 375 | + // si une maj pour cette version |
|
| 376 | + if ( |
|
| 377 | + $v == 'init' or |
|
| 378 | + (spip_version_compare($v, $installee, '>') |
|
| 379 | + and spip_version_compare($v, $cible, '<=')) |
|
| 380 | + ) { |
|
| 381 | + if ($debut_page) { |
|
| 382 | + maj_debut_page($v, $meta, $table); |
|
| 383 | + } |
|
| 384 | + echo "MAJ $v"; |
|
| 385 | + $etape = serie_alter($v, $operations, $meta, $table, $redirect); |
|
| 386 | + $trouver_table(''); // vider le cache des descriptions de table |
|
| 387 | + # echec sur une etape en cours ? |
|
| 388 | + # on sort |
|
| 389 | + if ($etape) { |
|
| 390 | + return [$v, $etape]; |
|
| 391 | + } |
|
| 392 | + $n = time() - $time; |
|
| 393 | + spip_log("$table $meta: $v en $n secondes", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 394 | + if ($meta) { |
|
| 395 | + ecrire_meta($meta, $installee = $v, 'oui', $table); |
|
| 396 | + } |
|
| 397 | + echo (_IS_CLI ? "\n" : '<br />'); |
|
| 398 | + } |
|
| 399 | + if (time() >= _TIME_OUT) { |
|
| 400 | + relance_maj($meta, $table, $redirect); |
|
| 401 | + } |
|
| 402 | + } |
|
| 403 | + $trouver_table(''); // vider le cache des descriptions de table |
|
| 404 | + // indispensable pour les chgt de versions qui n'ecrivent pas en base |
|
| 405 | + // tant pis pour la redondance eventuelle avec ci-dessus |
|
| 406 | + if ($meta) { |
|
| 407 | + ecrire_meta($meta, $cible, 'oui', $table); |
|
| 408 | + } |
|
| 409 | + spip_log("MAJ terminee. $meta: $installee", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 410 | + |
|
| 411 | + return []; |
|
| 412 | 412 | } |
| 413 | 413 | |
| 414 | 414 | /** |
@@ -431,53 +431,53 @@ discard block |
||
| 431 | 431 | * @return int |
| 432 | 432 | */ |
| 433 | 433 | function serie_alter($serie, $q = [], $meta = '', $table = 'meta', $redirect = '') { |
| 434 | - $meta2 = $meta . '_maj_' . $serie; |
|
| 435 | - $etape = 0; |
|
| 436 | - if (isset($GLOBALS[$table][$meta2])) { |
|
| 437 | - $etape = intval($GLOBALS[$table][$meta2]); |
|
| 438 | - } |
|
| 439 | - foreach ($q as $i => $r) { |
|
| 440 | - if ($i >= $etape) { |
|
| 441 | - $msg = "maj $table $meta2 etape $i"; |
|
| 442 | - if ( |
|
| 443 | - is_array($r) |
|
| 444 | - and function_exists($f = array_shift($r)) |
|
| 445 | - ) { |
|
| 446 | - // note: $r (arguments de la fonction $f) peut avoir des données tabulaires |
|
| 447 | - spip_log("$msg: $f " . @join(',', $r), 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 448 | - // pour les fonctions atomiques sql_xx |
|
| 449 | - // on enregistre le meta avant de lancer la fonction, |
|
| 450 | - // de maniere a eviter de boucler sur timeout |
|
| 451 | - // mais pour les fonctions complexes, |
|
| 452 | - // il faut les rejouer jusqu'a achevement. |
|
| 453 | - // C'est a elle d'assurer qu'elles progressent a chaque rappel |
|
| 454 | - if (strncmp($f, 'sql_', 4) == 0) { |
|
| 455 | - ecrire_meta($meta2, $i + 1, 'non', $table); |
|
| 456 | - } |
|
| 457 | - echo (_IS_CLI ? '.' : " <span title='$i'>.</span>"); |
|
| 458 | - $f(...$r); |
|
| 459 | - // si temps imparti depasse, on relance sans ecrire en meta |
|
| 460 | - // car on est peut etre sorti sur timeout si c'est une fonction longue |
|
| 461 | - if (time() >= _TIME_OUT) { |
|
| 462 | - relance_maj($meta, $table, $redirect); |
|
| 463 | - } |
|
| 464 | - ecrire_meta($meta2, $i + 1, 'non', $table); |
|
| 465 | - spip_log("$meta2: ok", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 466 | - } else { |
|
| 467 | - if (!is_array($r)) { |
|
| 468 | - spip_log("maj $i format incorrect", 'maj.' . _LOG_ERREUR); |
|
| 469 | - } else { |
|
| 470 | - spip_log("maj $i fonction $f non definie", 'maj.' . _LOG_ERREUR); |
|
| 471 | - } |
|
| 472 | - // en cas d'erreur serieuse, on s'arrete |
|
| 473 | - // mais on permet de passer par dessus en rechargeant la page. |
|
| 474 | - return $i + 1; |
|
| 475 | - } |
|
| 476 | - } |
|
| 477 | - } |
|
| 478 | - effacer_meta($meta2, $table); |
|
| 479 | - |
|
| 480 | - return 0; |
|
| 434 | + $meta2 = $meta . '_maj_' . $serie; |
|
| 435 | + $etape = 0; |
|
| 436 | + if (isset($GLOBALS[$table][$meta2])) { |
|
| 437 | + $etape = intval($GLOBALS[$table][$meta2]); |
|
| 438 | + } |
|
| 439 | + foreach ($q as $i => $r) { |
|
| 440 | + if ($i >= $etape) { |
|
| 441 | + $msg = "maj $table $meta2 etape $i"; |
|
| 442 | + if ( |
|
| 443 | + is_array($r) |
|
| 444 | + and function_exists($f = array_shift($r)) |
|
| 445 | + ) { |
|
| 446 | + // note: $r (arguments de la fonction $f) peut avoir des données tabulaires |
|
| 447 | + spip_log("$msg: $f " . @join(',', $r), 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 448 | + // pour les fonctions atomiques sql_xx |
|
| 449 | + // on enregistre le meta avant de lancer la fonction, |
|
| 450 | + // de maniere a eviter de boucler sur timeout |
|
| 451 | + // mais pour les fonctions complexes, |
|
| 452 | + // il faut les rejouer jusqu'a achevement. |
|
| 453 | + // C'est a elle d'assurer qu'elles progressent a chaque rappel |
|
| 454 | + if (strncmp($f, 'sql_', 4) == 0) { |
|
| 455 | + ecrire_meta($meta2, $i + 1, 'non', $table); |
|
| 456 | + } |
|
| 457 | + echo (_IS_CLI ? '.' : " <span title='$i'>.</span>"); |
|
| 458 | + $f(...$r); |
|
| 459 | + // si temps imparti depasse, on relance sans ecrire en meta |
|
| 460 | + // car on est peut etre sorti sur timeout si c'est une fonction longue |
|
| 461 | + if (time() >= _TIME_OUT) { |
|
| 462 | + relance_maj($meta, $table, $redirect); |
|
| 463 | + } |
|
| 464 | + ecrire_meta($meta2, $i + 1, 'non', $table); |
|
| 465 | + spip_log("$meta2: ok", 'maj.' . _LOG_INFO_IMPORTANTE); |
|
| 466 | + } else { |
|
| 467 | + if (!is_array($r)) { |
|
| 468 | + spip_log("maj $i format incorrect", 'maj.' . _LOG_ERREUR); |
|
| 469 | + } else { |
|
| 470 | + spip_log("maj $i fonction $f non definie", 'maj.' . _LOG_ERREUR); |
|
| 471 | + } |
|
| 472 | + // en cas d'erreur serieuse, on s'arrete |
|
| 473 | + // mais on permet de passer par dessus en rechargeant la page. |
|
| 474 | + return $i + 1; |
|
| 475 | + } |
|
| 476 | + } |
|
| 477 | + } |
|
| 478 | + effacer_meta($meta2, $table); |
|
| 479 | + |
|
| 480 | + return 0; |
|
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | /** |
@@ -486,16 +486,16 @@ discard block |
||
| 486 | 486 | * @return bool True si possible. |
| 487 | 487 | **/ |
| 488 | 488 | function upgrade_test() { |
| 489 | - sql_drop_table('spip_test', true); |
|
| 490 | - sql_create('spip_test', ['a' => 'int']); |
|
| 491 | - sql_alter('TABLE spip_test ADD b INT'); |
|
| 492 | - sql_insertq('spip_test', ['b' => 1], ['field' => ['b' => 'int']]); |
|
| 493 | - $result = sql_select('b', 'spip_test'); |
|
| 494 | - // ne pas garder le resultat de la requete sinon sqlite3 |
|
| 495 | - // ne peut pas supprimer la table spip_test lors du sql_alter qui suit |
|
| 496 | - // car cette table serait alors 'verouillee' |
|
| 497 | - $result = $result ? true : false; |
|
| 498 | - sql_alter('TABLE spip_test DROP b'); |
|
| 499 | - |
|
| 500 | - return $result; |
|
| 489 | + sql_drop_table('spip_test', true); |
|
| 490 | + sql_create('spip_test', ['a' => 'int']); |
|
| 491 | + sql_alter('TABLE spip_test ADD b INT'); |
|
| 492 | + sql_insertq('spip_test', ['b' => 1], ['field' => ['b' => 'int']]); |
|
| 493 | + $result = sql_select('b', 'spip_test'); |
|
| 494 | + // ne pas garder le resultat de la requete sinon sqlite3 |
|
| 495 | + // ne peut pas supprimer la table spip_test lors du sql_alter qui suit |
|
| 496 | + // car cette table serait alors 'verouillee' |
|
| 497 | + $result = $result ? true : false; |
|
| 498 | + sql_alter('TABLE spip_test DROP b'); |
|
| 499 | + |
|
| 500 | + return $result; |
|
| 501 | 501 | } |
@@ -11,7 +11,7 @@ discard block |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | include_spip('inc/charsets'); |
@@ -24,222 +24,222 @@ discard block |
||
| 24 | 24 | * @return string |
| 25 | 25 | */ |
| 26 | 26 | function xml_entites_html($texte) { |
| 27 | - if ( |
|
| 28 | - !is_string($texte) or !$texte |
|
| 29 | - or strpbrk($texte, "&\"'<>") == false |
|
| 30 | - ) { |
|
| 31 | - return $texte; |
|
| 32 | - } |
|
| 33 | - |
|
| 34 | - if (!function_exists('spip_htmlspecialchars')) { |
|
| 35 | - include_spip('inc/filtres_mini'); |
|
| 36 | - } |
|
| 37 | - $texte = spip_htmlspecialchars($texte, ENT_QUOTES); |
|
| 38 | - |
|
| 39 | - return $texte; |
|
| 27 | + if ( |
|
| 28 | + !is_string($texte) or !$texte |
|
| 29 | + or strpbrk($texte, "&\"'<>") == false |
|
| 30 | + ) { |
|
| 31 | + return $texte; |
|
| 32 | + } |
|
| 33 | + |
|
| 34 | + if (!function_exists('spip_htmlspecialchars')) { |
|
| 35 | + include_spip('inc/filtres_mini'); |
|
| 36 | + } |
|
| 37 | + $texte = spip_htmlspecialchars($texte, ENT_QUOTES); |
|
| 38 | + |
|
| 39 | + return $texte; |
|
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | function xml_debutElement($phraseur, $name, $attrs) { |
| 43 | - $depth = $phraseur->depth; |
|
| 44 | - |
|
| 45 | - $t = $phraseur->ouvrant[$depth] ?? ' '; |
|
| 46 | - // espace initial signifie: deja integree au resultat |
|
| 47 | - if ($t[0] != ' ') { |
|
| 48 | - $phraseur->res .= '<' . $t . '>'; |
|
| 49 | - $phraseur->ouvrant[$depth] = ' ' . $t; |
|
| 50 | - } |
|
| 51 | - $t = $phraseur->contenu[$depth]; |
|
| 52 | - // n'indenter que s'il y a un separateur avant |
|
| 53 | - $phraseur->res .= preg_replace("/[\n\t ]+$/", "\n$depth", $t); |
|
| 54 | - $phraseur->contenu[$depth] = ''; |
|
| 55 | - $att = ''; |
|
| 56 | - $sep = ' '; |
|
| 57 | - foreach ($attrs as $k => $v) { |
|
| 58 | - $delim = strpos($v, "'") === false ? "'" : '"'; |
|
| 59 | - $val = xml_entites_html($v); |
|
| 60 | - $att .= $sep . $k . '=' . $delim |
|
| 61 | - . ($delim !== '"' ? str_replace('"', '"', $val) : $val) |
|
| 62 | - . $delim; |
|
| 63 | - $sep = "\n $depth"; |
|
| 64 | - } |
|
| 65 | - $phraseur->depth .= ' '; |
|
| 66 | - $phraseur->contenu[$phraseur->depth] = ''; |
|
| 67 | - $phraseur->ouvrant[$phraseur->depth] = $name . $att; |
|
| 68 | - $phraseur->reperes[$phraseur->depth] = xml_get_current_line_number($phraseur->sax); |
|
| 43 | + $depth = $phraseur->depth; |
|
| 44 | + |
|
| 45 | + $t = $phraseur->ouvrant[$depth] ?? ' '; |
|
| 46 | + // espace initial signifie: deja integree au resultat |
|
| 47 | + if ($t[0] != ' ') { |
|
| 48 | + $phraseur->res .= '<' . $t . '>'; |
|
| 49 | + $phraseur->ouvrant[$depth] = ' ' . $t; |
|
| 50 | + } |
|
| 51 | + $t = $phraseur->contenu[$depth]; |
|
| 52 | + // n'indenter que s'il y a un separateur avant |
|
| 53 | + $phraseur->res .= preg_replace("/[\n\t ]+$/", "\n$depth", $t); |
|
| 54 | + $phraseur->contenu[$depth] = ''; |
|
| 55 | + $att = ''; |
|
| 56 | + $sep = ' '; |
|
| 57 | + foreach ($attrs as $k => $v) { |
|
| 58 | + $delim = strpos($v, "'") === false ? "'" : '"'; |
|
| 59 | + $val = xml_entites_html($v); |
|
| 60 | + $att .= $sep . $k . '=' . $delim |
|
| 61 | + . ($delim !== '"' ? str_replace('"', '"', $val) : $val) |
|
| 62 | + . $delim; |
|
| 63 | + $sep = "\n $depth"; |
|
| 64 | + } |
|
| 65 | + $phraseur->depth .= ' '; |
|
| 66 | + $phraseur->contenu[$phraseur->depth] = ''; |
|
| 67 | + $phraseur->ouvrant[$phraseur->depth] = $name . $att; |
|
| 68 | + $phraseur->reperes[$phraseur->depth] = xml_get_current_line_number($phraseur->sax); |
|
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | function xml_finElement($phraseur, $name, $fusion_bal = false) { |
| 72 | - $ouv = $phraseur->ouvrant[$phraseur->depth]; |
|
| 73 | - |
|
| 74 | - if ($ouv[0] != ' ') { |
|
| 75 | - $phraseur->ouvrant[$phraseur->depth] = ' ' . $ouv; |
|
| 76 | - } else { |
|
| 77 | - $ouv = ''; |
|
| 78 | - } |
|
| 79 | - $t = $phraseur->contenu[$phraseur->depth]; |
|
| 80 | - $phraseur->depth = substr($phraseur->depth, 2); |
|
| 81 | - $t = preg_replace("/[\n\t ]+$/", "\n" . $phraseur->depth, $t); |
|
| 82 | - |
|
| 83 | - // fusion <balise></balise> en <balise />. |
|
| 84 | - // ATTENTION, certains clients http croient que fusion ==> pas d'atttributs |
|
| 85 | - // en particulier pour les balises Script et A. |
|
| 86 | - // en presence d'attributs ne le faire que si la DTD est dispo et d'accord |
|
| 87 | - // (param fusion_bal) |
|
| 88 | - |
|
| 89 | - if ($t || (($ouv != $name) and !$fusion_bal)) { |
|
| 90 | - $phraseur->res .= ($ouv ? ('<' . $ouv . '>') : '') . $t . '</' . $name . '>'; |
|
| 91 | - } else { |
|
| 92 | - $phraseur->res .= ($ouv ? ('<' . $ouv . ' />') : ('</' . $name . '>')); |
|
| 93 | - } |
|
| 72 | + $ouv = $phraseur->ouvrant[$phraseur->depth]; |
|
| 73 | + |
|
| 74 | + if ($ouv[0] != ' ') { |
|
| 75 | + $phraseur->ouvrant[$phraseur->depth] = ' ' . $ouv; |
|
| 76 | + } else { |
|
| 77 | + $ouv = ''; |
|
| 78 | + } |
|
| 79 | + $t = $phraseur->contenu[$phraseur->depth]; |
|
| 80 | + $phraseur->depth = substr($phraseur->depth, 2); |
|
| 81 | + $t = preg_replace("/[\n\t ]+$/", "\n" . $phraseur->depth, $t); |
|
| 82 | + |
|
| 83 | + // fusion <balise></balise> en <balise />. |
|
| 84 | + // ATTENTION, certains clients http croient que fusion ==> pas d'atttributs |
|
| 85 | + // en particulier pour les balises Script et A. |
|
| 86 | + // en presence d'attributs ne le faire que si la DTD est dispo et d'accord |
|
| 87 | + // (param fusion_bal) |
|
| 88 | + |
|
| 89 | + if ($t || (($ouv != $name) and !$fusion_bal)) { |
|
| 90 | + $phraseur->res .= ($ouv ? ('<' . $ouv . '>') : '') . $t . '</' . $name . '>'; |
|
| 91 | + } else { |
|
| 92 | + $phraseur->res .= ($ouv ? ('<' . $ouv . ' />') : ('</' . $name . '>')); |
|
| 93 | + } |
|
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | function xml_textElement($phraseur, $data) { |
| 97 | - $depth = $phraseur->depth; |
|
| 98 | - $phraseur->contenu[$depth] .= preg_match('/^script/', $phraseur->ouvrant[$depth]) |
|
| 99 | - ? $data |
|
| 100 | - : xml_entites_html($data); |
|
| 97 | + $depth = $phraseur->depth; |
|
| 98 | + $phraseur->contenu[$depth] .= preg_match('/^script/', $phraseur->ouvrant[$depth]) |
|
| 99 | + ? $data |
|
| 100 | + : xml_entites_html($data); |
|
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | function xml_piElement($phraseur, $target, $data) { |
| 104 | - $depth = $phraseur->depth; |
|
| 105 | - |
|
| 106 | - if (strtolower($target) != 'php') { |
|
| 107 | - $phraseur->contenu[$depth] .= $data; |
|
| 108 | - } else { |
|
| 109 | - ob_start(); |
|
| 110 | - eval($data); |
|
| 111 | - $data = ob_get_contents(); |
|
| 112 | - ob_end_clean(); |
|
| 113 | - $phraseur->contenu[$depth] .= $data; |
|
| 114 | - } |
|
| 104 | + $depth = $phraseur->depth; |
|
| 105 | + |
|
| 106 | + if (strtolower($target) != 'php') { |
|
| 107 | + $phraseur->contenu[$depth] .= $data; |
|
| 108 | + } else { |
|
| 109 | + ob_start(); |
|
| 110 | + eval($data); |
|
| 111 | + $data = ob_get_contents(); |
|
| 112 | + ob_end_clean(); |
|
| 113 | + $phraseur->contenu[$depth] .= $data; |
|
| 114 | + } |
|
| 115 | 115 | } |
| 116 | 116 | |
| 117 | 117 | |
| 118 | 118 | function xml_defaultElement($phraseur, $data) { |
| 119 | - $depth = $phraseur->depth; |
|
| 119 | + $depth = $phraseur->depth; |
|
| 120 | 120 | |
| 121 | - if (!isset($phraseur->contenu[$depth])) { |
|
| 122 | - $phraseur->contenu[$depth] = ''; |
|
| 123 | - } |
|
| 124 | - $phraseur->contenu[$depth] .= $data; |
|
| 121 | + if (!isset($phraseur->contenu[$depth])) { |
|
| 122 | + $phraseur->contenu[$depth] = ''; |
|
| 123 | + } |
|
| 124 | + $phraseur->contenu[$depth] .= $data; |
|
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | function xml_parsestring($phraseur, $data) { |
| 128 | - $phraseur->contenu[$phraseur->depth] = ''; |
|
| 129 | - |
|
| 130 | - if (!xml_parse($phraseur->sax, $data, true)) { |
|
| 131 | - coordonnees_erreur( |
|
| 132 | - $phraseur, |
|
| 133 | - xml_error_string(xml_get_error_code($phraseur->sax)) |
|
| 134 | - . "<br />\n" . |
|
| 135 | - (!$phraseur->depth ? '' : |
|
| 136 | - ('(' . |
|
| 137 | - _T('erreur_balise_non_fermee') . |
|
| 138 | - ' <tt>' . |
|
| 139 | - $phraseur->ouvrant[$phraseur->depth] . |
|
| 140 | - '</tt> ' . |
|
| 141 | - _T('ligne') . |
|
| 142 | - ' ' . |
|
| 143 | - $phraseur->reperes[$phraseur->depth] . |
|
| 144 | - ") <br />\n")) |
|
| 145 | - ); |
|
| 146 | - } |
|
| 128 | + $phraseur->contenu[$phraseur->depth] = ''; |
|
| 129 | + |
|
| 130 | + if (!xml_parse($phraseur->sax, $data, true)) { |
|
| 131 | + coordonnees_erreur( |
|
| 132 | + $phraseur, |
|
| 133 | + xml_error_string(xml_get_error_code($phraseur->sax)) |
|
| 134 | + . "<br />\n" . |
|
| 135 | + (!$phraseur->depth ? '' : |
|
| 136 | + ('(' . |
|
| 137 | + _T('erreur_balise_non_fermee') . |
|
| 138 | + ' <tt>' . |
|
| 139 | + $phraseur->ouvrant[$phraseur->depth] . |
|
| 140 | + '</tt> ' . |
|
| 141 | + _T('ligne') . |
|
| 142 | + ' ' . |
|
| 143 | + $phraseur->reperes[$phraseur->depth] . |
|
| 144 | + ") <br />\n")) |
|
| 145 | + ); |
|
| 146 | + } |
|
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | function coordonnees_erreur($phraseur, $msg) { |
| 150 | - $entete_length = substr_count($phraseur->entete, "\n"); |
|
| 151 | - $phraseur->err[] = [ |
|
| 152 | - $msg, |
|
| 153 | - xml_get_current_line_number($phraseur->sax) + $entete_length, |
|
| 154 | - xml_get_current_column_number($phraseur->sax) |
|
| 155 | - ]; |
|
| 150 | + $entete_length = substr_count($phraseur->entete, "\n"); |
|
| 151 | + $phraseur->err[] = [ |
|
| 152 | + $msg, |
|
| 153 | + xml_get_current_line_number($phraseur->sax) + $entete_length, |
|
| 154 | + xml_get_current_column_number($phraseur->sax) |
|
| 155 | + ]; |
|
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | function xml_sax_dist($page, $apply = false, $phraseur = null, $doctype = '', $charset = null) { |
| 159 | - if (is_null($charset)) { |
|
| 160 | - $charset = $GLOBALS['meta']['charset']; |
|
| 161 | - } |
|
| 162 | - if ($apply) { |
|
| 163 | - ob_start(); |
|
| 164 | - if (is_array($apply)) { |
|
| 165 | - $r = $page(...$apply); |
|
| 166 | - } else { |
|
| 167 | - $r = $page(); |
|
| 168 | - } |
|
| 169 | - $page = ob_get_contents(); |
|
| 170 | - ob_end_clean(); |
|
| 171 | - // fonction sans aucun "echo", ca doit etre le resultat |
|
| 172 | - if (!$page) { |
|
| 173 | - $page = $r; |
|
| 174 | - } |
|
| 175 | - } |
|
| 176 | - |
|
| 177 | - if (!$page) { |
|
| 178 | - return ''; |
|
| 179 | - } |
|
| 180 | - // charger la DTD et transcoder les entites, |
|
| 181 | - // et escamoter le doctype que sax mange en php5 mais pas en php4 |
|
| 182 | - if (!$doctype) { |
|
| 183 | - if (!$r = analyser_doctype($page)) { |
|
| 184 | - $page = _MESSAGE_DOCTYPE . _DOCTYPE_ECRIRE |
|
| 185 | - . preg_replace(_REGEXP_DOCTYPE, '', $page); |
|
| 186 | - $r = analyser_doctype($page); |
|
| 187 | - } |
|
| 188 | - [$entete, $avail, $grammaire, $rotlvl] = array_pad($r, 4, null); |
|
| 189 | - $page = substr($page, strlen($entete)); |
|
| 190 | - } else { |
|
| 191 | - $avail = 'SYSTEM'; |
|
| 192 | - $grammaire = $doctype; |
|
| 193 | - $rotlvl = basename($grammaire); |
|
| 194 | - } |
|
| 195 | - |
|
| 196 | - include_spip('xml/analyser_dtd'); |
|
| 197 | - $dtc = charger_dtd($grammaire, $avail, $rotlvl); |
|
| 198 | - $page = sax_bug($page, $dtc, $charset); |
|
| 199 | - |
|
| 200 | - // compatibilite Tidy espace public |
|
| 201 | - if (!$phraseur) { |
|
| 202 | - $indenter_xml = charger_fonction('indenter', 'xml'); |
|
| 203 | - |
|
| 204 | - return $indenter_xml($page, $apply); |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - $xml_parser = xml_parser_create($charset); |
|
| 208 | - |
|
| 209 | - xml_set_element_handler( |
|
| 210 | - $xml_parser, |
|
| 211 | - [$phraseur, 'debutElement'], |
|
| 212 | - [$phraseur, 'finElement'] |
|
| 213 | - ); |
|
| 214 | - |
|
| 215 | - xml_set_character_data_handler( |
|
| 216 | - $xml_parser, |
|
| 217 | - [$phraseur, 'textElement'] |
|
| 218 | - ); |
|
| 219 | - |
|
| 220 | - xml_set_processing_instruction_handler( |
|
| 221 | - $xml_parser, |
|
| 222 | - [$phraseur, 'piElement'] |
|
| 223 | - ); |
|
| 224 | - |
|
| 225 | - xml_set_default_handler( |
|
| 226 | - $xml_parser, |
|
| 227 | - [$phraseur, 'defaultElement'] |
|
| 228 | - ); |
|
| 229 | - |
|
| 230 | - xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false); |
|
| 231 | - |
|
| 232 | - $phraseur->sax = $xml_parser; |
|
| 233 | - if (isset($entete)) { |
|
| 234 | - $phraseur->entete = $entete; |
|
| 235 | - } |
|
| 236 | - $phraseur->page = $page; |
|
| 237 | - $phraseur->dtc = $dtc; |
|
| 238 | - $phraseur->phraserTout($xml_parser, $page); |
|
| 239 | - xml_parser_free($xml_parser); |
|
| 240 | - $phraseur->sax = ''; |
|
| 241 | - |
|
| 242 | - return $phraseur; |
|
| 159 | + if (is_null($charset)) { |
|
| 160 | + $charset = $GLOBALS['meta']['charset']; |
|
| 161 | + } |
|
| 162 | + if ($apply) { |
|
| 163 | + ob_start(); |
|
| 164 | + if (is_array($apply)) { |
|
| 165 | + $r = $page(...$apply); |
|
| 166 | + } else { |
|
| 167 | + $r = $page(); |
|
| 168 | + } |
|
| 169 | + $page = ob_get_contents(); |
|
| 170 | + ob_end_clean(); |
|
| 171 | + // fonction sans aucun "echo", ca doit etre le resultat |
|
| 172 | + if (!$page) { |
|
| 173 | + $page = $r; |
|
| 174 | + } |
|
| 175 | + } |
|
| 176 | + |
|
| 177 | + if (!$page) { |
|
| 178 | + return ''; |
|
| 179 | + } |
|
| 180 | + // charger la DTD et transcoder les entites, |
|
| 181 | + // et escamoter le doctype que sax mange en php5 mais pas en php4 |
|
| 182 | + if (!$doctype) { |
|
| 183 | + if (!$r = analyser_doctype($page)) { |
|
| 184 | + $page = _MESSAGE_DOCTYPE . _DOCTYPE_ECRIRE |
|
| 185 | + . preg_replace(_REGEXP_DOCTYPE, '', $page); |
|
| 186 | + $r = analyser_doctype($page); |
|
| 187 | + } |
|
| 188 | + [$entete, $avail, $grammaire, $rotlvl] = array_pad($r, 4, null); |
|
| 189 | + $page = substr($page, strlen($entete)); |
|
| 190 | + } else { |
|
| 191 | + $avail = 'SYSTEM'; |
|
| 192 | + $grammaire = $doctype; |
|
| 193 | + $rotlvl = basename($grammaire); |
|
| 194 | + } |
|
| 195 | + |
|
| 196 | + include_spip('xml/analyser_dtd'); |
|
| 197 | + $dtc = charger_dtd($grammaire, $avail, $rotlvl); |
|
| 198 | + $page = sax_bug($page, $dtc, $charset); |
|
| 199 | + |
|
| 200 | + // compatibilite Tidy espace public |
|
| 201 | + if (!$phraseur) { |
|
| 202 | + $indenter_xml = charger_fonction('indenter', 'xml'); |
|
| 203 | + |
|
| 204 | + return $indenter_xml($page, $apply); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + $xml_parser = xml_parser_create($charset); |
|
| 208 | + |
|
| 209 | + xml_set_element_handler( |
|
| 210 | + $xml_parser, |
|
| 211 | + [$phraseur, 'debutElement'], |
|
| 212 | + [$phraseur, 'finElement'] |
|
| 213 | + ); |
|
| 214 | + |
|
| 215 | + xml_set_character_data_handler( |
|
| 216 | + $xml_parser, |
|
| 217 | + [$phraseur, 'textElement'] |
|
| 218 | + ); |
|
| 219 | + |
|
| 220 | + xml_set_processing_instruction_handler( |
|
| 221 | + $xml_parser, |
|
| 222 | + [$phraseur, 'piElement'] |
|
| 223 | + ); |
|
| 224 | + |
|
| 225 | + xml_set_default_handler( |
|
| 226 | + $xml_parser, |
|
| 227 | + [$phraseur, 'defaultElement'] |
|
| 228 | + ); |
|
| 229 | + |
|
| 230 | + xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false); |
|
| 231 | + |
|
| 232 | + $phraseur->sax = $xml_parser; |
|
| 233 | + if (isset($entete)) { |
|
| 234 | + $phraseur->entete = $entete; |
|
| 235 | + } |
|
| 236 | + $phraseur->page = $page; |
|
| 237 | + $phraseur->dtc = $dtc; |
|
| 238 | + $phraseur->phraserTout($xml_parser, $page); |
|
| 239 | + xml_parser_free($xml_parser); |
|
| 240 | + $phraseur->sax = ''; |
|
| 241 | + |
|
| 242 | + return $phraseur; |
|
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | // SAX ne dit pas si une Entite est dans un attribut ou non. |
@@ -250,24 +250,24 @@ discard block |
||
| 250 | 250 | // sinon on se rabat sur ce qu'en connait SPIP en standard. |
| 251 | 251 | |
| 252 | 252 | function sax_bug($data, $dtc, $charset = null) { |
| 253 | - if (is_null($charset)) { |
|
| 254 | - $charset = $GLOBALS['meta']['charset']; |
|
| 255 | - } |
|
| 256 | - |
|
| 257 | - if ($dtc) { |
|
| 258 | - $trans = []; |
|
| 259 | - |
|
| 260 | - foreach ($dtc->entites as $k => $v) { |
|
| 261 | - if (!strpos(' amp lt gt quot ', (string) $k)) { |
|
| 262 | - $trans["&$k;"] = $v; |
|
| 263 | - } |
|
| 264 | - } |
|
| 265 | - $data = strtr($data, $trans); |
|
| 266 | - } else { |
|
| 267 | - $data = html2unicode($data, true); |
|
| 268 | - } |
|
| 269 | - |
|
| 270 | - return unicode2charset($data, $charset); |
|
| 253 | + if (is_null($charset)) { |
|
| 254 | + $charset = $GLOBALS['meta']['charset']; |
|
| 255 | + } |
|
| 256 | + |
|
| 257 | + if ($dtc) { |
|
| 258 | + $trans = []; |
|
| 259 | + |
|
| 260 | + foreach ($dtc->entites as $k => $v) { |
|
| 261 | + if (!strpos(' amp lt gt quot ', (string) $k)) { |
|
| 262 | + $trans["&$k;"] = $v; |
|
| 263 | + } |
|
| 264 | + } |
|
| 265 | + $data = strtr($data, $trans); |
|
| 266 | + } else { |
|
| 267 | + $data = html2unicode($data, true); |
|
| 268 | + } |
|
| 269 | + |
|
| 270 | + return unicode2charset($data, $charset); |
|
| 271 | 271 | } |
| 272 | 272 | |
| 273 | 273 | // Retirer < ? xml... ? > et autre PI, ainsi que les commentaires en debut |
@@ -277,52 +277,52 @@ discard block |
||
| 277 | 277 | // les autres formats RSS n'ont pas de DTD, |
| 278 | 278 | // mais un XML Schema que SPIP ne fait pas encore lire. |
| 279 | 279 | function analyser_doctype($data) { |
| 280 | - if (!preg_match(_REGEXP_DOCTYPE, $data, $page)) { |
|
| 281 | - if (preg_match(_REGEXP_XML, $data, $page)) { |
|
| 282 | - [, $entete, $topelement] = $page; |
|
| 283 | - if ($topelement == 'rss') { |
|
| 284 | - return [ |
|
| 285 | - $entete, |
|
| 286 | - 'PUBLIC', |
|
| 287 | - _DOCTYPE_RSS, |
|
| 288 | - 'rss-0.91.dtd' |
|
| 289 | - ]; |
|
| 290 | - } else { |
|
| 291 | - $dtd = $topelement . '.dtd'; |
|
| 292 | - $f = find_in_path($dtd); |
|
| 293 | - if (file_exists($f)) { |
|
| 294 | - return [$entete, 'SYSTEM', $f, $dtd]; |
|
| 295 | - } |
|
| 296 | - } |
|
| 297 | - } |
|
| 298 | - spip_log('Dtd pas vu pour ' . substr($data, 0, 100)); |
|
| 299 | - |
|
| 300 | - return []; |
|
| 301 | - } |
|
| 302 | - [$entete, , $topelement, $avail, $suite] = $page; |
|
| 303 | - |
|
| 304 | - if (!preg_match('/^"([^"]*)"\s*(.*)$/', $suite, $r)) { |
|
| 305 | - if (!preg_match("/^'([^']*)'\s*(.*)$/", $suite, $r)) { |
|
| 306 | - return []; |
|
| 307 | - } |
|
| 308 | - } |
|
| 309 | - [, $rotlvl, $suite] = $r; |
|
| 310 | - |
|
| 311 | - if (!$suite) { |
|
| 312 | - if ($avail != 'SYSTEM') { |
|
| 313 | - return []; |
|
| 314 | - } |
|
| 315 | - $grammaire = $rotlvl; |
|
| 316 | - $rotlvl = ''; |
|
| 317 | - } else { |
|
| 318 | - if (!preg_match('/^"([^"]*)"\s*$/', $suite, $r)) { |
|
| 319 | - if (!preg_match("/^'([^']*)'\s*$/", $suite, $r)) { |
|
| 320 | - return []; |
|
| 321 | - } |
|
| 322 | - } |
|
| 323 | - |
|
| 324 | - $grammaire = $r[1]; |
|
| 325 | - } |
|
| 326 | - |
|
| 327 | - return [$entete, $avail, $grammaire, $rotlvl]; |
|
| 280 | + if (!preg_match(_REGEXP_DOCTYPE, $data, $page)) { |
|
| 281 | + if (preg_match(_REGEXP_XML, $data, $page)) { |
|
| 282 | + [, $entete, $topelement] = $page; |
|
| 283 | + if ($topelement == 'rss') { |
|
| 284 | + return [ |
|
| 285 | + $entete, |
|
| 286 | + 'PUBLIC', |
|
| 287 | + _DOCTYPE_RSS, |
|
| 288 | + 'rss-0.91.dtd' |
|
| 289 | + ]; |
|
| 290 | + } else { |
|
| 291 | + $dtd = $topelement . '.dtd'; |
|
| 292 | + $f = find_in_path($dtd); |
|
| 293 | + if (file_exists($f)) { |
|
| 294 | + return [$entete, 'SYSTEM', $f, $dtd]; |
|
| 295 | + } |
|
| 296 | + } |
|
| 297 | + } |
|
| 298 | + spip_log('Dtd pas vu pour ' . substr($data, 0, 100)); |
|
| 299 | + |
|
| 300 | + return []; |
|
| 301 | + } |
|
| 302 | + [$entete, , $topelement, $avail, $suite] = $page; |
|
| 303 | + |
|
| 304 | + if (!preg_match('/^"([^"]*)"\s*(.*)$/', $suite, $r)) { |
|
| 305 | + if (!preg_match("/^'([^']*)'\s*(.*)$/", $suite, $r)) { |
|
| 306 | + return []; |
|
| 307 | + } |
|
| 308 | + } |
|
| 309 | + [, $rotlvl, $suite] = $r; |
|
| 310 | + |
|
| 311 | + if (!$suite) { |
|
| 312 | + if ($avail != 'SYSTEM') { |
|
| 313 | + return []; |
|
| 314 | + } |
|
| 315 | + $grammaire = $rotlvl; |
|
| 316 | + $rotlvl = ''; |
|
| 317 | + } else { |
|
| 318 | + if (!preg_match('/^"([^"]*)"\s*$/', $suite, $r)) { |
|
| 319 | + if (!preg_match("/^'([^']*)'\s*$/", $suite, $r)) { |
|
| 320 | + return []; |
|
| 321 | + } |
|
| 322 | + } |
|
| 323 | + |
|
| 324 | + $grammaire = $r[1]; |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + return [$entete, $avail, $grammaire, $rotlvl]; |
|
| 328 | 328 | } |
@@ -17,91 +17,91 @@ |
||
| 17 | 17 | **/ |
| 18 | 18 | |
| 19 | 19 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 20 | - return; |
|
| 20 | + return; |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | |
| 24 | 24 | function action_api_transmettre_dist($arg = null) { |
| 25 | 25 | |
| 26 | - // Obtenir l'argument 'id_auteur/cle/format/fond' |
|
| 27 | - if (is_null($arg)) { |
|
| 28 | - $arg = _request('arg'); |
|
| 29 | - } |
|
| 30 | - |
|
| 31 | - $args = explode('/', $arg); |
|
| 32 | - |
|
| 33 | - if (count($args) !== 4) { |
|
| 34 | - action_api_transmettre_fail($arg); |
|
| 35 | - } |
|
| 36 | - |
|
| 37 | - [$id_auteur, $cle, $format, $fond] = $args; |
|
| 38 | - $id_auteur = intval($id_auteur); |
|
| 39 | - |
|
| 40 | - if (preg_match(',[^\w\\.-],', $format)) { |
|
| 41 | - action_api_transmettre_fail("format $format ??"); |
|
| 42 | - } |
|
| 43 | - if (preg_match(',[^\w\\.-],', $fond)) { |
|
| 44 | - action_api_transmettre_fail("fond $fond ??"); |
|
| 45 | - } |
|
| 46 | - |
|
| 47 | - // verifier la cle |
|
| 48 | - //[(#ENV{id,0}|securiser_acces{#ENV{cle}, voirstats, #ENV{op}, #ENV{args}}|?{1,0})] |
|
| 49 | - //[(#ENV{id,0}|securiser_acces{#ENV{cle}, voirstats, #ENV{op}, #ENV{args}}|?{1,0})] |
|
| 50 | - |
|
| 51 | - $qs = $_SERVER['QUERY_STRING']; |
|
| 52 | - // retirer action et arg de la qs |
|
| 53 | - $contexte = []; |
|
| 54 | - parse_str($qs, $contexte); |
|
| 55 | - foreach ($contexte as $k => $v) { |
|
| 56 | - if (in_array($k, ['action', 'arg', 'var_mode'])) { |
|
| 57 | - unset($contexte[$k]); |
|
| 58 | - } |
|
| 59 | - } |
|
| 60 | - $qs = http_build_query($contexte); |
|
| 61 | - if (!securiser_acces_low_sec(intval($id_auteur), $cle, "transmettre/$format", $fond, $qs)) { |
|
| 62 | - // si le autoriser low_sec n'est pas bon, on peut valider l'appel si l'auteur est identifie |
|
| 63 | - include_spip('inc/autoriser'); |
|
| 64 | - $autoriser_type = preg_replace(',\W+,', '', "_{$format}{$fond}"); |
|
| 65 | - if ( |
|
| 66 | - !$id_auteur |
|
| 67 | - or empty($GLOBALS['visiteur_session']['id_auteur']) |
|
| 68 | - or $GLOBALS['visiteur_session']['id_auteur'] != $id_auteur |
|
| 69 | - or !autoriser('transmettre', $autoriser_type, $id_auteur) |
|
| 70 | - ) { |
|
| 71 | - action_api_transmettre_fail("auth QS $qs ??"); |
|
| 72 | - } |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - $contexte['id_auteur'] = $id_auteur; |
|
| 76 | - |
|
| 77 | - $fond = "transmettre/$format/$fond"; |
|
| 78 | - |
|
| 79 | - if (!trouver_fond($fond)) { |
|
| 80 | - $fond = "prive/$fond"; |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - if (!trouver_fond($fond)) { |
|
| 84 | - action_api_transmettre_fail("fond $fond ??"); |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - $res = recuperer_fond($fond, $contexte, ['raw' => true]); |
|
| 88 | - if (!empty($res['entetes'])) { |
|
| 89 | - foreach ($res['entetes'] as $h => $v) { |
|
| 90 | - header("$h: $v"); |
|
| 91 | - } |
|
| 92 | - } |
|
| 93 | - |
|
| 94 | - $res = ltrim($res['texte']); |
|
| 95 | - if (empty($res)) { |
|
| 96 | - spip_log("$arg $qs resultat vide", 'transmettre' . _LOG_INFO_IMPORTANTE); |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - echo $res; |
|
| 100 | - exit(); |
|
| 26 | + // Obtenir l'argument 'id_auteur/cle/format/fond' |
|
| 27 | + if (is_null($arg)) { |
|
| 28 | + $arg = _request('arg'); |
|
| 29 | + } |
|
| 30 | + |
|
| 31 | + $args = explode('/', $arg); |
|
| 32 | + |
|
| 33 | + if (count($args) !== 4) { |
|
| 34 | + action_api_transmettre_fail($arg); |
|
| 35 | + } |
|
| 36 | + |
|
| 37 | + [$id_auteur, $cle, $format, $fond] = $args; |
|
| 38 | + $id_auteur = intval($id_auteur); |
|
| 39 | + |
|
| 40 | + if (preg_match(',[^\w\\.-],', $format)) { |
|
| 41 | + action_api_transmettre_fail("format $format ??"); |
|
| 42 | + } |
|
| 43 | + if (preg_match(',[^\w\\.-],', $fond)) { |
|
| 44 | + action_api_transmettre_fail("fond $fond ??"); |
|
| 45 | + } |
|
| 46 | + |
|
| 47 | + // verifier la cle |
|
| 48 | + //[(#ENV{id,0}|securiser_acces{#ENV{cle}, voirstats, #ENV{op}, #ENV{args}}|?{1,0})] |
|
| 49 | + //[(#ENV{id,0}|securiser_acces{#ENV{cle}, voirstats, #ENV{op}, #ENV{args}}|?{1,0})] |
|
| 50 | + |
|
| 51 | + $qs = $_SERVER['QUERY_STRING']; |
|
| 52 | + // retirer action et arg de la qs |
|
| 53 | + $contexte = []; |
|
| 54 | + parse_str($qs, $contexte); |
|
| 55 | + foreach ($contexte as $k => $v) { |
|
| 56 | + if (in_array($k, ['action', 'arg', 'var_mode'])) { |
|
| 57 | + unset($contexte[$k]); |
|
| 58 | + } |
|
| 59 | + } |
|
| 60 | + $qs = http_build_query($contexte); |
|
| 61 | + if (!securiser_acces_low_sec(intval($id_auteur), $cle, "transmettre/$format", $fond, $qs)) { |
|
| 62 | + // si le autoriser low_sec n'est pas bon, on peut valider l'appel si l'auteur est identifie |
|
| 63 | + include_spip('inc/autoriser'); |
|
| 64 | + $autoriser_type = preg_replace(',\W+,', '', "_{$format}{$fond}"); |
|
| 65 | + if ( |
|
| 66 | + !$id_auteur |
|
| 67 | + or empty($GLOBALS['visiteur_session']['id_auteur']) |
|
| 68 | + or $GLOBALS['visiteur_session']['id_auteur'] != $id_auteur |
|
| 69 | + or !autoriser('transmettre', $autoriser_type, $id_auteur) |
|
| 70 | + ) { |
|
| 71 | + action_api_transmettre_fail("auth QS $qs ??"); |
|
| 72 | + } |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + $contexte['id_auteur'] = $id_auteur; |
|
| 76 | + |
|
| 77 | + $fond = "transmettre/$format/$fond"; |
|
| 78 | + |
|
| 79 | + if (!trouver_fond($fond)) { |
|
| 80 | + $fond = "prive/$fond"; |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + if (!trouver_fond($fond)) { |
|
| 84 | + action_api_transmettre_fail("fond $fond ??"); |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + $res = recuperer_fond($fond, $contexte, ['raw' => true]); |
|
| 88 | + if (!empty($res['entetes'])) { |
|
| 89 | + foreach ($res['entetes'] as $h => $v) { |
|
| 90 | + header("$h: $v"); |
|
| 91 | + } |
|
| 92 | + } |
|
| 93 | + |
|
| 94 | + $res = ltrim($res['texte']); |
|
| 95 | + if (empty($res)) { |
|
| 96 | + spip_log("$arg $qs resultat vide", 'transmettre' . _LOG_INFO_IMPORTANTE); |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + echo $res; |
|
| 100 | + exit(); |
|
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | function action_api_transmettre_fail($arg) { |
| 104 | - include_spip('inc/minipres'); |
|
| 105 | - echo minipres(_T('info_acces_interdit'), $arg); |
|
| 106 | - exit; |
|
| 104 | + include_spip('inc/minipres'); |
|
| 105 | + echo minipres(_T('info_acces_interdit'), $arg); |
|
| 106 | + exit; |
|
| 107 | 107 | } |
@@ -11,7 +11,7 @@ discard block |
||
| 11 | 11 | \***************************************************************************/ |
| 12 | 12 | |
| 13 | 13 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 14 | - return; |
|
| 14 | + return; |
|
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | /** |
@@ -21,667 +21,667 @@ discard block |
||
| 21 | 21 | * |
| 22 | 22 | */ |
| 23 | 23 | class IterFactory { |
| 24 | - public static function create($iterateur, $command, $info = null) { |
|
| 25 | - |
|
| 26 | - $iter = null; |
|
| 27 | - // cas des SI {si expression} analises tres tot |
|
| 28 | - // pour eviter le chargement de tout iterateur |
|
| 29 | - if (isset($command['si'])) { |
|
| 30 | - foreach ($command['si'] as $si) { |
|
| 31 | - if (!$si) { |
|
| 32 | - // $command pour boucle SQL peut generer des erreurs de compilation |
|
| 33 | - // s'il est transmis alors qu'on est dans un iterateur vide |
|
| 34 | - return new IterDecorator(new EmptyIterator(), [], $info); |
|
| 35 | - } |
|
| 36 | - } |
|
| 37 | - } |
|
| 38 | - |
|
| 39 | - // chercher un iterateur PHP existant (par exemple dans SPL) |
|
| 40 | - // (il faudrait passer l'argument ->sql_serveur |
|
| 41 | - // pour etre certain qu'on est sur un "php:") |
|
| 42 | - if (class_exists($iterateur)) { |
|
| 43 | - $a = $command['args'] ?? []; |
|
| 44 | - |
|
| 45 | - // permettre de passer un Iterateur directement {args #ITERATEUR} : |
|
| 46 | - // si on recoit deja un iterateur en argument, on l'utilise |
|
| 47 | - if ((is_countable($a) ? count($a) : 0) == 1 and is_object($a[0]) and is_subclass_of($a[0], \Iterator::class)) { |
|
| 48 | - $iter = $a[0]; |
|
| 49 | - |
|
| 50 | - // sinon, on cree un iterateur du type donne |
|
| 51 | - } else { |
|
| 52 | - // arguments de creation de l'iterateur... |
|
| 53 | - // (pas glop) |
|
| 54 | - try { |
|
| 55 | - switch (is_countable($a) ? count($a) : 0) { |
|
| 56 | - case 0: |
|
| 57 | - $iter = new $iterateur(); |
|
| 58 | - break; |
|
| 59 | - case 1: |
|
| 60 | - $iter = new $iterateur($a[0]); |
|
| 61 | - break; |
|
| 62 | - case 2: |
|
| 63 | - $iter = new $iterateur($a[0], $a[1]); |
|
| 64 | - break; |
|
| 65 | - case 3: |
|
| 66 | - $iter = new $iterateur($a[0], $a[1], $a[2]); |
|
| 67 | - break; |
|
| 68 | - case 4: |
|
| 69 | - $iter = new $iterateur($a[0], $a[1], $a[2], $a[3]); |
|
| 70 | - break; |
|
| 71 | - } |
|
| 72 | - } catch (Exception $e) { |
|
| 73 | - spip_log("Erreur de chargement de l'iterateur $iterateur"); |
|
| 74 | - spip_log($e->getMessage()); |
|
| 75 | - $iter = new EmptyIterator(); |
|
| 76 | - } |
|
| 77 | - } |
|
| 78 | - } else { |
|
| 79 | - // chercher la classe d'iterateur |
|
| 80 | - // IterateurXXX |
|
| 81 | - // definie dans le fichier iterateurs/xxx.php |
|
| 82 | - $class = 'Iterateur' . $iterateur; |
|
| 83 | - if (!class_exists($class)) { |
|
| 84 | - if ( |
|
| 85 | - !include_spip('iterateur/' . strtolower($iterateur)) |
|
| 86 | - or !class_exists($class) |
|
| 87 | - ) { |
|
| 88 | - die("Iterateur $iterateur non trouvé"); |
|
| 89 | - // si l'iterateur n'existe pas, on se rabat sur le generique |
|
| 90 | - # $iter = new EmptyIterator(); |
|
| 91 | - } |
|
| 92 | - } |
|
| 93 | - $iter = new $class($command, $info); |
|
| 94 | - } |
|
| 95 | - |
|
| 96 | - return new IterDecorator($iter, $command, $info); |
|
| 97 | - } |
|
| 24 | + public static function create($iterateur, $command, $info = null) { |
|
| 25 | + |
|
| 26 | + $iter = null; |
|
| 27 | + // cas des SI {si expression} analises tres tot |
|
| 28 | + // pour eviter le chargement de tout iterateur |
|
| 29 | + if (isset($command['si'])) { |
|
| 30 | + foreach ($command['si'] as $si) { |
|
| 31 | + if (!$si) { |
|
| 32 | + // $command pour boucle SQL peut generer des erreurs de compilation |
|
| 33 | + // s'il est transmis alors qu'on est dans un iterateur vide |
|
| 34 | + return new IterDecorator(new EmptyIterator(), [], $info); |
|
| 35 | + } |
|
| 36 | + } |
|
| 37 | + } |
|
| 38 | + |
|
| 39 | + // chercher un iterateur PHP existant (par exemple dans SPL) |
|
| 40 | + // (il faudrait passer l'argument ->sql_serveur |
|
| 41 | + // pour etre certain qu'on est sur un "php:") |
|
| 42 | + if (class_exists($iterateur)) { |
|
| 43 | + $a = $command['args'] ?? []; |
|
| 44 | + |
|
| 45 | + // permettre de passer un Iterateur directement {args #ITERATEUR} : |
|
| 46 | + // si on recoit deja un iterateur en argument, on l'utilise |
|
| 47 | + if ((is_countable($a) ? count($a) : 0) == 1 and is_object($a[0]) and is_subclass_of($a[0], \Iterator::class)) { |
|
| 48 | + $iter = $a[0]; |
|
| 49 | + |
|
| 50 | + // sinon, on cree un iterateur du type donne |
|
| 51 | + } else { |
|
| 52 | + // arguments de creation de l'iterateur... |
|
| 53 | + // (pas glop) |
|
| 54 | + try { |
|
| 55 | + switch (is_countable($a) ? count($a) : 0) { |
|
| 56 | + case 0: |
|
| 57 | + $iter = new $iterateur(); |
|
| 58 | + break; |
|
| 59 | + case 1: |
|
| 60 | + $iter = new $iterateur($a[0]); |
|
| 61 | + break; |
|
| 62 | + case 2: |
|
| 63 | + $iter = new $iterateur($a[0], $a[1]); |
|
| 64 | + break; |
|
| 65 | + case 3: |
|
| 66 | + $iter = new $iterateur($a[0], $a[1], $a[2]); |
|
| 67 | + break; |
|
| 68 | + case 4: |
|
| 69 | + $iter = new $iterateur($a[0], $a[1], $a[2], $a[3]); |
|
| 70 | + break; |
|
| 71 | + } |
|
| 72 | + } catch (Exception $e) { |
|
| 73 | + spip_log("Erreur de chargement de l'iterateur $iterateur"); |
|
| 74 | + spip_log($e->getMessage()); |
|
| 75 | + $iter = new EmptyIterator(); |
|
| 76 | + } |
|
| 77 | + } |
|
| 78 | + } else { |
|
| 79 | + // chercher la classe d'iterateur |
|
| 80 | + // IterateurXXX |
|
| 81 | + // definie dans le fichier iterateurs/xxx.php |
|
| 82 | + $class = 'Iterateur' . $iterateur; |
|
| 83 | + if (!class_exists($class)) { |
|
| 84 | + if ( |
|
| 85 | + !include_spip('iterateur/' . strtolower($iterateur)) |
|
| 86 | + or !class_exists($class) |
|
| 87 | + ) { |
|
| 88 | + die("Iterateur $iterateur non trouvé"); |
|
| 89 | + // si l'iterateur n'existe pas, on se rabat sur le generique |
|
| 90 | + # $iter = new EmptyIterator(); |
|
| 91 | + } |
|
| 92 | + } |
|
| 93 | + $iter = new $class($command, $info); |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + return new IterDecorator($iter, $command, $info); |
|
| 97 | + } |
|
| 98 | 98 | } |
| 99 | 99 | |
| 100 | 100 | |
| 101 | 101 | class IterDecorator extends FilterIterator { |
| 102 | - private $iter; |
|
| 103 | - |
|
| 104 | - /** |
|
| 105 | - * Conditions de filtrage |
|
| 106 | - * ie criteres de selection |
|
| 107 | - * |
|
| 108 | - * @var array |
|
| 109 | - */ |
|
| 110 | - protected $filtre = []; |
|
| 111 | - |
|
| 112 | - /** |
|
| 113 | - * Fonction de filtrage compilee a partir des criteres de filtre |
|
| 114 | - * |
|
| 115 | - * @var string |
|
| 116 | - */ |
|
| 117 | - protected $func_filtre = null; |
|
| 118 | - |
|
| 119 | - /** |
|
| 120 | - * Critere {offset, limit} |
|
| 121 | - * |
|
| 122 | - * @var int |
|
| 123 | - * @var int |
|
| 124 | - */ |
|
| 125 | - protected $offset = null; |
|
| 126 | - protected $limit = null; |
|
| 127 | - |
|
| 128 | - /** |
|
| 129 | - * nombre d'elements recuperes depuis la position 0, |
|
| 130 | - * en tenant compte des filtres |
|
| 131 | - * |
|
| 132 | - * @var int |
|
| 133 | - */ |
|
| 134 | - protected $fetched = 0; |
|
| 135 | - |
|
| 136 | - /** |
|
| 137 | - * Y a t'il une erreur ? |
|
| 138 | - * |
|
| 139 | - * @var bool |
|
| 140 | - **/ |
|
| 141 | - protected $err = false; |
|
| 142 | - |
|
| 143 | - /** |
|
| 144 | - * Drapeau a activer en cas d'echec |
|
| 145 | - * (select SQL errone, non chargement des DATA, etc) |
|
| 146 | - */ |
|
| 147 | - public function err() { |
|
| 148 | - if (method_exists($this->iter, 'err')) { |
|
| 149 | - return $this->iter->err(); |
|
| 150 | - } |
|
| 151 | - if (property_exists($this->iter, 'err')) { |
|
| 152 | - return $this->iter->err; |
|
| 153 | - } |
|
| 154 | - |
|
| 155 | - return false; |
|
| 156 | - } |
|
| 157 | - |
|
| 158 | - public function __construct(Iterator $iter, $command, $info) { |
|
| 159 | - parent::__construct($iter); |
|
| 160 | - parent::rewind(); // remettre a la premiere position (bug? connu de FilterIterator) |
|
| 161 | - |
|
| 162 | - // recuperer l'iterateur transmis |
|
| 163 | - $this->iter = $this->getInnerIterator(); |
|
| 164 | - $this->command = $command; |
|
| 165 | - $this->info = $info; |
|
| 166 | - $this->pos = 0; |
|
| 167 | - $this->fetched = 0; |
|
| 168 | - |
|
| 169 | - // chercher la liste des champs a retourner par |
|
| 170 | - // fetch si l'objet ne les calcule pas tout seul |
|
| 171 | - if (!method_exists($this->iter, 'fetch')) { |
|
| 172 | - $this->calculer_select(); |
|
| 173 | - $this->calculer_filtres(); |
|
| 174 | - } |
|
| 175 | - |
|
| 176 | - // emptyIterator critere {si} faux n'a pas d'erreur ! |
|
| 177 | - if (isset($this->iter->err)) { |
|
| 178 | - $this->err = $this->iter->err; |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite) |
|
| 182 | - //$this->total = $this->count(); |
|
| 183 | - } |
|
| 184 | - |
|
| 185 | - |
|
| 186 | - // calcule les elements a retournes par fetch() |
|
| 187 | - // enleve les elements inutiles du select() |
|
| 188 | - // |
|
| 189 | - private function calculer_select() { |
|
| 190 | - if ($select = &$this->command['select']) { |
|
| 191 | - foreach ($select as $s) { |
|
| 192 | - // /!\ $s = '.nom' |
|
| 193 | - if ($s[0] == '.') { |
|
| 194 | - $s = substr($s, 1); |
|
| 195 | - } |
|
| 196 | - $this->select[] = $s; |
|
| 197 | - } |
|
| 198 | - } |
|
| 199 | - } |
|
| 200 | - |
|
| 201 | - // recuperer la valeur d'une balise #X |
|
| 202 | - // en fonction des methodes |
|
| 203 | - // et proprietes disponibles |
|
| 204 | - public function get_select($nom) { |
|
| 205 | - if ( |
|
| 206 | - is_object($this->iter) |
|
| 207 | - and method_exists($this->iter, $nom) |
|
| 208 | - ) { |
|
| 209 | - try { |
|
| 210 | - return $this->iter->$nom(); |
|
| 211 | - } catch (Exception $e) { |
|
| 212 | - // #GETCHILDREN sur un fichier de DirectoryIterator ... |
|
| 213 | - spip_log("Methode $nom en echec sur " . get_class($this->iter)); |
|
| 214 | - spip_log("Cela peut être normal : retour d'une ligne de resultat ne pouvant pas calculer cette methode"); |
|
| 215 | - |
|
| 216 | - return ''; |
|
| 217 | - } |
|
| 218 | - } |
|
| 219 | - /* |
|
| 102 | + private $iter; |
|
| 103 | + |
|
| 104 | + /** |
|
| 105 | + * Conditions de filtrage |
|
| 106 | + * ie criteres de selection |
|
| 107 | + * |
|
| 108 | + * @var array |
|
| 109 | + */ |
|
| 110 | + protected $filtre = []; |
|
| 111 | + |
|
| 112 | + /** |
|
| 113 | + * Fonction de filtrage compilee a partir des criteres de filtre |
|
| 114 | + * |
|
| 115 | + * @var string |
|
| 116 | + */ |
|
| 117 | + protected $func_filtre = null; |
|
| 118 | + |
|
| 119 | + /** |
|
| 120 | + * Critere {offset, limit} |
|
| 121 | + * |
|
| 122 | + * @var int |
|
| 123 | + * @var int |
|
| 124 | + */ |
|
| 125 | + protected $offset = null; |
|
| 126 | + protected $limit = null; |
|
| 127 | + |
|
| 128 | + /** |
|
| 129 | + * nombre d'elements recuperes depuis la position 0, |
|
| 130 | + * en tenant compte des filtres |
|
| 131 | + * |
|
| 132 | + * @var int |
|
| 133 | + */ |
|
| 134 | + protected $fetched = 0; |
|
| 135 | + |
|
| 136 | + /** |
|
| 137 | + * Y a t'il une erreur ? |
|
| 138 | + * |
|
| 139 | + * @var bool |
|
| 140 | + **/ |
|
| 141 | + protected $err = false; |
|
| 142 | + |
|
| 143 | + /** |
|
| 144 | + * Drapeau a activer en cas d'echec |
|
| 145 | + * (select SQL errone, non chargement des DATA, etc) |
|
| 146 | + */ |
|
| 147 | + public function err() { |
|
| 148 | + if (method_exists($this->iter, 'err')) { |
|
| 149 | + return $this->iter->err(); |
|
| 150 | + } |
|
| 151 | + if (property_exists($this->iter, 'err')) { |
|
| 152 | + return $this->iter->err; |
|
| 153 | + } |
|
| 154 | + |
|
| 155 | + return false; |
|
| 156 | + } |
|
| 157 | + |
|
| 158 | + public function __construct(Iterator $iter, $command, $info) { |
|
| 159 | + parent::__construct($iter); |
|
| 160 | + parent::rewind(); // remettre a la premiere position (bug? connu de FilterIterator) |
|
| 161 | + |
|
| 162 | + // recuperer l'iterateur transmis |
|
| 163 | + $this->iter = $this->getInnerIterator(); |
|
| 164 | + $this->command = $command; |
|
| 165 | + $this->info = $info; |
|
| 166 | + $this->pos = 0; |
|
| 167 | + $this->fetched = 0; |
|
| 168 | + |
|
| 169 | + // chercher la liste des champs a retourner par |
|
| 170 | + // fetch si l'objet ne les calcule pas tout seul |
|
| 171 | + if (!method_exists($this->iter, 'fetch')) { |
|
| 172 | + $this->calculer_select(); |
|
| 173 | + $this->calculer_filtres(); |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + // emptyIterator critere {si} faux n'a pas d'erreur ! |
|
| 177 | + if (isset($this->iter->err)) { |
|
| 178 | + $this->err = $this->iter->err; |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + // pas d'init a priori, le calcul ne sera fait qu'en cas de besoin (provoque une double requete souvent inutile en sqlite) |
|
| 182 | + //$this->total = $this->count(); |
|
| 183 | + } |
|
| 184 | + |
|
| 185 | + |
|
| 186 | + // calcule les elements a retournes par fetch() |
|
| 187 | + // enleve les elements inutiles du select() |
|
| 188 | + // |
|
| 189 | + private function calculer_select() { |
|
| 190 | + if ($select = &$this->command['select']) { |
|
| 191 | + foreach ($select as $s) { |
|
| 192 | + // /!\ $s = '.nom' |
|
| 193 | + if ($s[0] == '.') { |
|
| 194 | + $s = substr($s, 1); |
|
| 195 | + } |
|
| 196 | + $this->select[] = $s; |
|
| 197 | + } |
|
| 198 | + } |
|
| 199 | + } |
|
| 200 | + |
|
| 201 | + // recuperer la valeur d'une balise #X |
|
| 202 | + // en fonction des methodes |
|
| 203 | + // et proprietes disponibles |
|
| 204 | + public function get_select($nom) { |
|
| 205 | + if ( |
|
| 206 | + is_object($this->iter) |
|
| 207 | + and method_exists($this->iter, $nom) |
|
| 208 | + ) { |
|
| 209 | + try { |
|
| 210 | + return $this->iter->$nom(); |
|
| 211 | + } catch (Exception $e) { |
|
| 212 | + // #GETCHILDREN sur un fichier de DirectoryIterator ... |
|
| 213 | + spip_log("Methode $nom en echec sur " . get_class($this->iter)); |
|
| 214 | + spip_log("Cela peut être normal : retour d'une ligne de resultat ne pouvant pas calculer cette methode"); |
|
| 215 | + |
|
| 216 | + return ''; |
|
| 217 | + } |
|
| 218 | + } |
|
| 219 | + /* |
|
| 220 | 220 | if (property_exists($this->iter, $nom)) { |
| 221 | 221 | return $this->iter->$nom; |
| 222 | 222 | }*/ |
| 223 | - // cle et valeur par defaut |
|
| 224 | - // ICI PLANTAGE SI ON NE CONTROLE PAS $nom |
|
| 225 | - if ( |
|
| 226 | - in_array($nom, ['cle', 'valeur']) |
|
| 227 | - and method_exists($this, $nom) |
|
| 228 | - ) { |
|
| 229 | - return $this->$nom(); |
|
| 230 | - } |
|
| 231 | - |
|
| 232 | - // Par defaut chercher en xpath dans la valeur() |
|
| 233 | - return table_valeur($this->valeur(), $nom, null); |
|
| 234 | - } |
|
| 235 | - |
|
| 236 | - |
|
| 237 | - private function calculer_filtres() { |
|
| 238 | - |
|
| 239 | - // Issu de calculer_select() de public/composer L.519 |
|
| 240 | - // TODO: externaliser... |
|
| 241 | - // |
|
| 242 | - // retirer les criteres vides: |
|
| 243 | - // {X ?} avec X absent de l'URL |
|
| 244 | - // {par #ENV{X}} avec X absent de l'URL |
|
| 245 | - // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil) |
|
| 246 | - if ($where = &$this->command['where']) { |
|
| 247 | - foreach ($where as $k => $v) { |
|
| 248 | - $this->filtre[] = $this->traduire_condition_sql_en_filtre($v); |
|
| 249 | - } |
|
| 250 | - } |
|
| 251 | - |
|
| 252 | - // critere {2,7} |
|
| 253 | - if (isset($this->command['limit']) and $this->command['limit']) { |
|
| 254 | - $limit = explode(',', $this->command['limit']); |
|
| 255 | - $this->offset = $limit[0]; |
|
| 256 | - $this->limit = $limit[1]; |
|
| 257 | - } |
|
| 258 | - |
|
| 259 | - // Creer la fonction de filtrage sur $this |
|
| 260 | - if ($this->filtre) { |
|
| 261 | - if ($filtres = $this->assembler_filtres($this->filtre)) { |
|
| 262 | - $filtres = 'return ' . $filtres . ';'; |
|
| 263 | - $this->func_filtre = fn() => eval($filtres); |
|
| 264 | - } |
|
| 265 | - else { |
|
| 266 | - $this->func_filtre = null; |
|
| 267 | - } |
|
| 268 | - } |
|
| 269 | - } |
|
| 270 | - |
|
| 271 | - /** |
|
| 272 | - * Assembler le tableau de filtres traduits depuis les conditions SQL |
|
| 273 | - * les filtres vides ou null sont ignores |
|
| 274 | - * @param $filtres |
|
| 275 | - * @param string $operateur |
|
| 276 | - * @return string|null |
|
| 277 | - */ |
|
| 278 | - protected function assembler_filtres($filtres, $operateur = 'AND') { |
|
| 279 | - |
|
| 280 | - $filtres_string = []; |
|
| 281 | - foreach ($filtres as $k => $v) { |
|
| 282 | - // si c'est un tableau de OR/AND + 2 sous-filtres, on recurse pour transformer en chaine |
|
| 283 | - if (is_array($v) and in_array(reset($v), ['OR', 'AND'])) { |
|
| 284 | - $op = array_shift($v); |
|
| 285 | - $v = $this->assembler_filtres($v, $op); |
|
| 286 | - } |
|
| 287 | - if (is_null($v) or !is_string($v) or empty($v)) { |
|
| 288 | - continue; |
|
| 289 | - } |
|
| 290 | - $filtres_string[] = $v; |
|
| 291 | - } |
|
| 292 | - |
|
| 293 | - if (!count($filtres_string)) { |
|
| 294 | - return null; |
|
| 295 | - } |
|
| 296 | - |
|
| 297 | - return '(' . implode(") $operateur (", $filtres_string) . ')'; |
|
| 298 | - } |
|
| 299 | - |
|
| 300 | - /** |
|
| 301 | - * Traduire un element du tableau where SQL en un filtre |
|
| 302 | - * @param $v |
|
| 303 | - * @return string|array|null |
|
| 304 | - */ |
|
| 305 | - protected function traduire_condition_sql_en_filtre($v) { |
|
| 306 | - if (is_array($v)) { |
|
| 307 | - if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) { |
|
| 308 | - return 'true'; |
|
| 309 | - } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) { |
|
| 310 | - return 'true'; |
|
| 311 | - } else { |
|
| 312 | - $op = $v[0] ?: $v; |
|
| 313 | - } |
|
| 314 | - } else { |
|
| 315 | - $op = $v; |
|
| 316 | - } |
|
| 317 | - if ((!$op) or ($op == 1) or ($op == '0=0')) { |
|
| 318 | - return 'true'; |
|
| 319 | - } |
|
| 320 | - if ($op === '0=1') { |
|
| 321 | - return 'false'; |
|
| 322 | - } |
|
| 323 | - // traiter {cle IN a,b} ou {valeur !IN a,b} |
|
| 324 | - if (preg_match(',^\(([\w/]+)(\s+NOT)?\s+IN\s+(\(.*\))\)$,', $op, $regs)) { |
|
| 325 | - return $this->composer_filtre($regs[1], 'IN', $regs[3], $regs[2]); |
|
| 326 | - } |
|
| 327 | - |
|
| 328 | - // 3 possibilites : count($v) = |
|
| 329 | - // * 1 : {x y} ; on recoit $v[0] = y |
|
| 330 | - // * 2 : {x !op y} ; on recoit $v[0] = 'NOT', $v[1] = array() // array du type {x op y} |
|
| 331 | - // * 3 : {x op y} ; on recoit $v[0] = 'op', $v[1] = x, $v[2] = y |
|
| 332 | - |
|
| 333 | - // 1 : forcement traite par un critere, on passe |
|
| 334 | - if (!$v or !is_array($v) or count($v) == 1) { |
|
| 335 | - return null; // sera ignore |
|
| 336 | - } |
|
| 337 | - if (count($v) == 2 and is_array($v[1])) { |
|
| 338 | - return $this->composer_filtre($v[1][1], $v[1][0], $v[1][2], 'NOT'); |
|
| 339 | - } |
|
| 340 | - if (count($v) == 3) { |
|
| 341 | - // traiter le OR/AND suivi de 2 valeurs |
|
| 342 | - if (in_array($op, ['OR', 'AND'])) { |
|
| 343 | - array_shift($v); |
|
| 344 | - foreach (array_keys($v) as $k) { |
|
| 345 | - $v[$k] = $this->traduire_condition_sql_en_filtre($v[$k]); |
|
| 346 | - if ($v[$k] === null) { |
|
| 347 | - unset($v[$k]); |
|
| 348 | - } |
|
| 349 | - elseif ($v[$k] === 'true') { |
|
| 350 | - if ($op === 'OR') { |
|
| 351 | - return 'true'; |
|
| 352 | - } |
|
| 353 | - if ($op === 'AND') { |
|
| 354 | - unset($v[$k]); |
|
| 355 | - } |
|
| 356 | - } |
|
| 357 | - elseif ($v[$k] === 'false') { |
|
| 358 | - if ($op === 'OR') { |
|
| 359 | - unset($v[$k]); |
|
| 360 | - } |
|
| 361 | - if ($op === 'AND') { |
|
| 362 | - return 'false'; |
|
| 363 | - } |
|
| 364 | - } |
|
| 365 | - } |
|
| 366 | - if (!count($v)) { |
|
| 367 | - return null; |
|
| 368 | - } |
|
| 369 | - if (count($v) === 1) { |
|
| 370 | - return reset($v); |
|
| 371 | - } |
|
| 372 | - array_unshift($v, $op); |
|
| 373 | - return $v; |
|
| 374 | - } |
|
| 375 | - return $this->composer_filtre($v[1], $v[0], $v[2]); |
|
| 376 | - } |
|
| 377 | - |
|
| 378 | - return null; // sera ignore |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - /** |
|
| 382 | - * Calculer un filtre sur un champ du tableau |
|
| 383 | - * @param $cle |
|
| 384 | - * @param $op |
|
| 385 | - * @param $valeur |
|
| 386 | - * @param false $not |
|
| 387 | - * @return string|null |
|
| 388 | - */ |
|
| 389 | - protected function composer_filtre($cle, $op, $valeur, $not = false) { |
|
| 390 | - if (method_exists($this->iter, 'exception_des_criteres')) { |
|
| 391 | - if (in_array($cle, $this->iter->exception_des_criteres())) { |
|
| 392 | - return null; |
|
| 393 | - } |
|
| 394 | - } |
|
| 395 | - // TODO: analyser le filtre pour refuser ce qu'on ne sait pas traiter ? |
|
| 396 | - # mais c'est normalement deja opere par calculer_critere_infixe() |
|
| 397 | - # qui regarde la description 'desc' (en casse reelle d'ailleurs : {isDir=1} |
|
| 398 | - # ne sera pas vu si l'on a defini desc['field']['isdir'] pour que #ISDIR soit present. |
|
| 399 | - # il faudrait peut etre definir les 2 champs isDir et isdir... a reflechir... |
|
| 400 | - |
|
| 401 | - # if (!in_array($cle, array('cle', 'valeur'))) |
|
| 402 | - # return; |
|
| 403 | - |
|
| 404 | - $a = '$this->get_select(\'' . $cle . '\')'; |
|
| 405 | - |
|
| 406 | - $filtre = ''; |
|
| 407 | - |
|
| 408 | - if ($op == 'REGEXP') { |
|
| 409 | - $filtre = 'filtrer("match", ' . $a . ', ' . str_replace('\"', '"', $valeur) . ')'; |
|
| 410 | - $op = ''; |
|
| 411 | - } else { |
|
| 412 | - if ($op == 'LIKE') { |
|
| 413 | - $valeur = str_replace(['\"', '_', '%'], ['"', '.', '.*'], preg_quote($valeur)); |
|
| 414 | - $filtre = 'filtrer("match", ' . $a . ', ' . $valeur . ')'; |
|
| 415 | - $op = ''; |
|
| 416 | - } else { |
|
| 417 | - if ($op == '=') { |
|
| 418 | - $op = '=='; |
|
| 419 | - } else { |
|
| 420 | - if ($op == 'IN') { |
|
| 421 | - $filtre = 'in_array(' . $a . ', array' . $valeur . ')'; |
|
| 422 | - $op = ''; |
|
| 423 | - } else { |
|
| 424 | - if (!in_array($op, ['<', '<=', '>', '>='])) { |
|
| 425 | - spip_log('operateur non reconnu ' . $op); // [todo] mettre une erreur de squelette |
|
| 426 | - $op = ''; |
|
| 427 | - } |
|
| 428 | - } |
|
| 429 | - } |
|
| 430 | - } |
|
| 431 | - } |
|
| 432 | - |
|
| 433 | - if ($op) { |
|
| 434 | - $filtre = $a . $op . str_replace('\"', '"', $valeur); |
|
| 435 | - } |
|
| 436 | - |
|
| 437 | - if ($not) { |
|
| 438 | - $filtre = "!($filtre)"; |
|
| 439 | - } |
|
| 440 | - |
|
| 441 | - return $filtre; |
|
| 442 | - } |
|
| 443 | - |
|
| 444 | - |
|
| 445 | - public function next(): void { |
|
| 446 | - $this->pos++; |
|
| 447 | - parent::next(); |
|
| 448 | - } |
|
| 449 | - |
|
| 450 | - /** |
|
| 451 | - * revient au depart |
|
| 452 | - * |
|
| 453 | - * @return void |
|
| 454 | - */ |
|
| 455 | - public function rewind(): void { |
|
| 456 | - $this->pos = 0; |
|
| 457 | - $this->fetched = 0; |
|
| 458 | - parent::rewind(); |
|
| 459 | - } |
|
| 460 | - |
|
| 461 | - |
|
| 462 | - # Extension SPIP des iterateurs PHP |
|
| 463 | - /** |
|
| 464 | - * type de l'iterateur |
|
| 465 | - * |
|
| 466 | - * @var string |
|
| 467 | - */ |
|
| 468 | - protected $type; |
|
| 469 | - |
|
| 470 | - /** |
|
| 471 | - * parametres de l'iterateur |
|
| 472 | - * |
|
| 473 | - * @var array |
|
| 474 | - */ |
|
| 475 | - protected $command; |
|
| 476 | - |
|
| 477 | - /** |
|
| 478 | - * infos de compilateur |
|
| 479 | - * |
|
| 480 | - * @var array |
|
| 481 | - */ |
|
| 482 | - protected $info; |
|
| 483 | - |
|
| 484 | - /** |
|
| 485 | - * position courante de l'iterateur |
|
| 486 | - * |
|
| 487 | - * @var int |
|
| 488 | - */ |
|
| 489 | - protected $pos = null; |
|
| 490 | - |
|
| 491 | - /** |
|
| 492 | - * nombre total resultats dans l'iterateur |
|
| 493 | - * |
|
| 494 | - * @var int |
|
| 495 | - */ |
|
| 496 | - protected $total = null; |
|
| 497 | - |
|
| 498 | - /** |
|
| 499 | - * nombre maximal de recherche pour $total |
|
| 500 | - * si l'iterateur n'implemente pas de fonction specifique |
|
| 501 | - */ |
|
| 502 | - protected $max = 100000; |
|
| 503 | - |
|
| 504 | - |
|
| 505 | - /** |
|
| 506 | - * Liste des champs a inserer dans les $row |
|
| 507 | - * retournes par ->fetch() |
|
| 508 | - */ |
|
| 509 | - protected $select = []; |
|
| 510 | - |
|
| 511 | - |
|
| 512 | - /** |
|
| 513 | - * aller a la position absolue n, |
|
| 514 | - * comptee depuis le debut |
|
| 515 | - * |
|
| 516 | - * @param int $n |
|
| 517 | - * absolute pos |
|
| 518 | - * @param string $continue |
|
| 519 | - * param for sql_ api |
|
| 520 | - * @return bool |
|
| 521 | - * success or fail if not implemented |
|
| 522 | - */ |
|
| 523 | - public function seek($n = 0, $continue = null) { |
|
| 524 | - if ($this->func_filtre or !method_exists($this->iter, 'seek') or !$this->iter->seek($n)) { |
|
| 525 | - $this->seek_loop($n); |
|
| 526 | - } |
|
| 527 | - $this->pos = $n; |
|
| 528 | - $this->fetched = $n; |
|
| 529 | - |
|
| 530 | - return true; |
|
| 531 | - } |
|
| 532 | - |
|
| 533 | - /* |
|
| 223 | + // cle et valeur par defaut |
|
| 224 | + // ICI PLANTAGE SI ON NE CONTROLE PAS $nom |
|
| 225 | + if ( |
|
| 226 | + in_array($nom, ['cle', 'valeur']) |
|
| 227 | + and method_exists($this, $nom) |
|
| 228 | + ) { |
|
| 229 | + return $this->$nom(); |
|
| 230 | + } |
|
| 231 | + |
|
| 232 | + // Par defaut chercher en xpath dans la valeur() |
|
| 233 | + return table_valeur($this->valeur(), $nom, null); |
|
| 234 | + } |
|
| 235 | + |
|
| 236 | + |
|
| 237 | + private function calculer_filtres() { |
|
| 238 | + |
|
| 239 | + // Issu de calculer_select() de public/composer L.519 |
|
| 240 | + // TODO: externaliser... |
|
| 241 | + // |
|
| 242 | + // retirer les criteres vides: |
|
| 243 | + // {X ?} avec X absent de l'URL |
|
| 244 | + // {par #ENV{X}} avec X absent de l'URL |
|
| 245 | + // IN sur collection vide (ce dernier devrait pouvoir etre fait a la compil) |
|
| 246 | + if ($where = &$this->command['where']) { |
|
| 247 | + foreach ($where as $k => $v) { |
|
| 248 | + $this->filtre[] = $this->traduire_condition_sql_en_filtre($v); |
|
| 249 | + } |
|
| 250 | + } |
|
| 251 | + |
|
| 252 | + // critere {2,7} |
|
| 253 | + if (isset($this->command['limit']) and $this->command['limit']) { |
|
| 254 | + $limit = explode(',', $this->command['limit']); |
|
| 255 | + $this->offset = $limit[0]; |
|
| 256 | + $this->limit = $limit[1]; |
|
| 257 | + } |
|
| 258 | + |
|
| 259 | + // Creer la fonction de filtrage sur $this |
|
| 260 | + if ($this->filtre) { |
|
| 261 | + if ($filtres = $this->assembler_filtres($this->filtre)) { |
|
| 262 | + $filtres = 'return ' . $filtres . ';'; |
|
| 263 | + $this->func_filtre = fn() => eval($filtres); |
|
| 264 | + } |
|
| 265 | + else { |
|
| 266 | + $this->func_filtre = null; |
|
| 267 | + } |
|
| 268 | + } |
|
| 269 | + } |
|
| 270 | + |
|
| 271 | + /** |
|
| 272 | + * Assembler le tableau de filtres traduits depuis les conditions SQL |
|
| 273 | + * les filtres vides ou null sont ignores |
|
| 274 | + * @param $filtres |
|
| 275 | + * @param string $operateur |
|
| 276 | + * @return string|null |
|
| 277 | + */ |
|
| 278 | + protected function assembler_filtres($filtres, $operateur = 'AND') { |
|
| 279 | + |
|
| 280 | + $filtres_string = []; |
|
| 281 | + foreach ($filtres as $k => $v) { |
|
| 282 | + // si c'est un tableau de OR/AND + 2 sous-filtres, on recurse pour transformer en chaine |
|
| 283 | + if (is_array($v) and in_array(reset($v), ['OR', 'AND'])) { |
|
| 284 | + $op = array_shift($v); |
|
| 285 | + $v = $this->assembler_filtres($v, $op); |
|
| 286 | + } |
|
| 287 | + if (is_null($v) or !is_string($v) or empty($v)) { |
|
| 288 | + continue; |
|
| 289 | + } |
|
| 290 | + $filtres_string[] = $v; |
|
| 291 | + } |
|
| 292 | + |
|
| 293 | + if (!count($filtres_string)) { |
|
| 294 | + return null; |
|
| 295 | + } |
|
| 296 | + |
|
| 297 | + return '(' . implode(") $operateur (", $filtres_string) . ')'; |
|
| 298 | + } |
|
| 299 | + |
|
| 300 | + /** |
|
| 301 | + * Traduire un element du tableau where SQL en un filtre |
|
| 302 | + * @param $v |
|
| 303 | + * @return string|array|null |
|
| 304 | + */ |
|
| 305 | + protected function traduire_condition_sql_en_filtre($v) { |
|
| 306 | + if (is_array($v)) { |
|
| 307 | + if ((count($v) >= 2) && ($v[0] == 'REGEXP') && ($v[2] == "'.*'")) { |
|
| 308 | + return 'true'; |
|
| 309 | + } elseif ((count($v) >= 2) && ($v[0] == 'LIKE') && ($v[2] == "'%'")) { |
|
| 310 | + return 'true'; |
|
| 311 | + } else { |
|
| 312 | + $op = $v[0] ?: $v; |
|
| 313 | + } |
|
| 314 | + } else { |
|
| 315 | + $op = $v; |
|
| 316 | + } |
|
| 317 | + if ((!$op) or ($op == 1) or ($op == '0=0')) { |
|
| 318 | + return 'true'; |
|
| 319 | + } |
|
| 320 | + if ($op === '0=1') { |
|
| 321 | + return 'false'; |
|
| 322 | + } |
|
| 323 | + // traiter {cle IN a,b} ou {valeur !IN a,b} |
|
| 324 | + if (preg_match(',^\(([\w/]+)(\s+NOT)?\s+IN\s+(\(.*\))\)$,', $op, $regs)) { |
|
| 325 | + return $this->composer_filtre($regs[1], 'IN', $regs[3], $regs[2]); |
|
| 326 | + } |
|
| 327 | + |
|
| 328 | + // 3 possibilites : count($v) = |
|
| 329 | + // * 1 : {x y} ; on recoit $v[0] = y |
|
| 330 | + // * 2 : {x !op y} ; on recoit $v[0] = 'NOT', $v[1] = array() // array du type {x op y} |
|
| 331 | + // * 3 : {x op y} ; on recoit $v[0] = 'op', $v[1] = x, $v[2] = y |
|
| 332 | + |
|
| 333 | + // 1 : forcement traite par un critere, on passe |
|
| 334 | + if (!$v or !is_array($v) or count($v) == 1) { |
|
| 335 | + return null; // sera ignore |
|
| 336 | + } |
|
| 337 | + if (count($v) == 2 and is_array($v[1])) { |
|
| 338 | + return $this->composer_filtre($v[1][1], $v[1][0], $v[1][2], 'NOT'); |
|
| 339 | + } |
|
| 340 | + if (count($v) == 3) { |
|
| 341 | + // traiter le OR/AND suivi de 2 valeurs |
|
| 342 | + if (in_array($op, ['OR', 'AND'])) { |
|
| 343 | + array_shift($v); |
|
| 344 | + foreach (array_keys($v) as $k) { |
|
| 345 | + $v[$k] = $this->traduire_condition_sql_en_filtre($v[$k]); |
|
| 346 | + if ($v[$k] === null) { |
|
| 347 | + unset($v[$k]); |
|
| 348 | + } |
|
| 349 | + elseif ($v[$k] === 'true') { |
|
| 350 | + if ($op === 'OR') { |
|
| 351 | + return 'true'; |
|
| 352 | + } |
|
| 353 | + if ($op === 'AND') { |
|
| 354 | + unset($v[$k]); |
|
| 355 | + } |
|
| 356 | + } |
|
| 357 | + elseif ($v[$k] === 'false') { |
|
| 358 | + if ($op === 'OR') { |
|
| 359 | + unset($v[$k]); |
|
| 360 | + } |
|
| 361 | + if ($op === 'AND') { |
|
| 362 | + return 'false'; |
|
| 363 | + } |
|
| 364 | + } |
|
| 365 | + } |
|
| 366 | + if (!count($v)) { |
|
| 367 | + return null; |
|
| 368 | + } |
|
| 369 | + if (count($v) === 1) { |
|
| 370 | + return reset($v); |
|
| 371 | + } |
|
| 372 | + array_unshift($v, $op); |
|
| 373 | + return $v; |
|
| 374 | + } |
|
| 375 | + return $this->composer_filtre($v[1], $v[0], $v[2]); |
|
| 376 | + } |
|
| 377 | + |
|
| 378 | + return null; // sera ignore |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + /** |
|
| 382 | + * Calculer un filtre sur un champ du tableau |
|
| 383 | + * @param $cle |
|
| 384 | + * @param $op |
|
| 385 | + * @param $valeur |
|
| 386 | + * @param false $not |
|
| 387 | + * @return string|null |
|
| 388 | + */ |
|
| 389 | + protected function composer_filtre($cle, $op, $valeur, $not = false) { |
|
| 390 | + if (method_exists($this->iter, 'exception_des_criteres')) { |
|
| 391 | + if (in_array($cle, $this->iter->exception_des_criteres())) { |
|
| 392 | + return null; |
|
| 393 | + } |
|
| 394 | + } |
|
| 395 | + // TODO: analyser le filtre pour refuser ce qu'on ne sait pas traiter ? |
|
| 396 | + # mais c'est normalement deja opere par calculer_critere_infixe() |
|
| 397 | + # qui regarde la description 'desc' (en casse reelle d'ailleurs : {isDir=1} |
|
| 398 | + # ne sera pas vu si l'on a defini desc['field']['isdir'] pour que #ISDIR soit present. |
|
| 399 | + # il faudrait peut etre definir les 2 champs isDir et isdir... a reflechir... |
|
| 400 | + |
|
| 401 | + # if (!in_array($cle, array('cle', 'valeur'))) |
|
| 402 | + # return; |
|
| 403 | + |
|
| 404 | + $a = '$this->get_select(\'' . $cle . '\')'; |
|
| 405 | + |
|
| 406 | + $filtre = ''; |
|
| 407 | + |
|
| 408 | + if ($op == 'REGEXP') { |
|
| 409 | + $filtre = 'filtrer("match", ' . $a . ', ' . str_replace('\"', '"', $valeur) . ')'; |
|
| 410 | + $op = ''; |
|
| 411 | + } else { |
|
| 412 | + if ($op == 'LIKE') { |
|
| 413 | + $valeur = str_replace(['\"', '_', '%'], ['"', '.', '.*'], preg_quote($valeur)); |
|
| 414 | + $filtre = 'filtrer("match", ' . $a . ', ' . $valeur . ')'; |
|
| 415 | + $op = ''; |
|
| 416 | + } else { |
|
| 417 | + if ($op == '=') { |
|
| 418 | + $op = '=='; |
|
| 419 | + } else { |
|
| 420 | + if ($op == 'IN') { |
|
| 421 | + $filtre = 'in_array(' . $a . ', array' . $valeur . ')'; |
|
| 422 | + $op = ''; |
|
| 423 | + } else { |
|
| 424 | + if (!in_array($op, ['<', '<=', '>', '>='])) { |
|
| 425 | + spip_log('operateur non reconnu ' . $op); // [todo] mettre une erreur de squelette |
|
| 426 | + $op = ''; |
|
| 427 | + } |
|
| 428 | + } |
|
| 429 | + } |
|
| 430 | + } |
|
| 431 | + } |
|
| 432 | + |
|
| 433 | + if ($op) { |
|
| 434 | + $filtre = $a . $op . str_replace('\"', '"', $valeur); |
|
| 435 | + } |
|
| 436 | + |
|
| 437 | + if ($not) { |
|
| 438 | + $filtre = "!($filtre)"; |
|
| 439 | + } |
|
| 440 | + |
|
| 441 | + return $filtre; |
|
| 442 | + } |
|
| 443 | + |
|
| 444 | + |
|
| 445 | + public function next(): void { |
|
| 446 | + $this->pos++; |
|
| 447 | + parent::next(); |
|
| 448 | + } |
|
| 449 | + |
|
| 450 | + /** |
|
| 451 | + * revient au depart |
|
| 452 | + * |
|
| 453 | + * @return void |
|
| 454 | + */ |
|
| 455 | + public function rewind(): void { |
|
| 456 | + $this->pos = 0; |
|
| 457 | + $this->fetched = 0; |
|
| 458 | + parent::rewind(); |
|
| 459 | + } |
|
| 460 | + |
|
| 461 | + |
|
| 462 | + # Extension SPIP des iterateurs PHP |
|
| 463 | + /** |
|
| 464 | + * type de l'iterateur |
|
| 465 | + * |
|
| 466 | + * @var string |
|
| 467 | + */ |
|
| 468 | + protected $type; |
|
| 469 | + |
|
| 470 | + /** |
|
| 471 | + * parametres de l'iterateur |
|
| 472 | + * |
|
| 473 | + * @var array |
|
| 474 | + */ |
|
| 475 | + protected $command; |
|
| 476 | + |
|
| 477 | + /** |
|
| 478 | + * infos de compilateur |
|
| 479 | + * |
|
| 480 | + * @var array |
|
| 481 | + */ |
|
| 482 | + protected $info; |
|
| 483 | + |
|
| 484 | + /** |
|
| 485 | + * position courante de l'iterateur |
|
| 486 | + * |
|
| 487 | + * @var int |
|
| 488 | + */ |
|
| 489 | + protected $pos = null; |
|
| 490 | + |
|
| 491 | + /** |
|
| 492 | + * nombre total resultats dans l'iterateur |
|
| 493 | + * |
|
| 494 | + * @var int |
|
| 495 | + */ |
|
| 496 | + protected $total = null; |
|
| 497 | + |
|
| 498 | + /** |
|
| 499 | + * nombre maximal de recherche pour $total |
|
| 500 | + * si l'iterateur n'implemente pas de fonction specifique |
|
| 501 | + */ |
|
| 502 | + protected $max = 100000; |
|
| 503 | + |
|
| 504 | + |
|
| 505 | + /** |
|
| 506 | + * Liste des champs a inserer dans les $row |
|
| 507 | + * retournes par ->fetch() |
|
| 508 | + */ |
|
| 509 | + protected $select = []; |
|
| 510 | + |
|
| 511 | + |
|
| 512 | + /** |
|
| 513 | + * aller a la position absolue n, |
|
| 514 | + * comptee depuis le debut |
|
| 515 | + * |
|
| 516 | + * @param int $n |
|
| 517 | + * absolute pos |
|
| 518 | + * @param string $continue |
|
| 519 | + * param for sql_ api |
|
| 520 | + * @return bool |
|
| 521 | + * success or fail if not implemented |
|
| 522 | + */ |
|
| 523 | + public function seek($n = 0, $continue = null) { |
|
| 524 | + if ($this->func_filtre or !method_exists($this->iter, 'seek') or !$this->iter->seek($n)) { |
|
| 525 | + $this->seek_loop($n); |
|
| 526 | + } |
|
| 527 | + $this->pos = $n; |
|
| 528 | + $this->fetched = $n; |
|
| 529 | + |
|
| 530 | + return true; |
|
| 531 | + } |
|
| 532 | + |
|
| 533 | + /* |
|
| 534 | 534 | * aller a la position $n en parcourant |
| 535 | 535 | * un par un tous les elements |
| 536 | 536 | */ |
| 537 | - private function seek_loop($n) { |
|
| 538 | - if ($this->pos > $n) { |
|
| 539 | - $this->rewind(); |
|
| 540 | - } |
|
| 541 | - |
|
| 542 | - while ($this->pos < $n and $this->valid()) { |
|
| 543 | - $this->next(); |
|
| 544 | - } |
|
| 545 | - |
|
| 546 | - return true; |
|
| 547 | - } |
|
| 548 | - |
|
| 549 | - /** |
|
| 550 | - * Avancer de $saut pas |
|
| 551 | - * |
|
| 552 | - * @param $saut |
|
| 553 | - * @param $max |
|
| 554 | - * @return int |
|
| 555 | - */ |
|
| 556 | - public function skip($saut, $max = null) { |
|
| 557 | - // pas de saut en arriere autorise pour cette fonction |
|
| 558 | - if (($saut = intval($saut)) <= 0) { |
|
| 559 | - return $this->pos; |
|
| 560 | - } |
|
| 561 | - $seek = $this->pos + $saut; |
|
| 562 | - // si le saut fait depasser le maxi, on libere la resource |
|
| 563 | - // et on sort |
|
| 564 | - if (is_null($max)) { |
|
| 565 | - $max = $this->count(); |
|
| 566 | - } |
|
| 567 | - |
|
| 568 | - if ($seek >= $max or $seek >= $this->count()) { |
|
| 569 | - // sortie plus rapide que de faire next() jusqu'a la fin ! |
|
| 570 | - $this->free(); |
|
| 571 | - |
|
| 572 | - return $max; |
|
| 573 | - } |
|
| 574 | - |
|
| 575 | - $this->seek($seek); |
|
| 576 | - |
|
| 577 | - return $this->pos; |
|
| 578 | - } |
|
| 579 | - |
|
| 580 | - /** |
|
| 581 | - * Renvoyer un tableau des donnees correspondantes |
|
| 582 | - * a la position courante de l'iterateur |
|
| 583 | - * en controlant si on respecte le filtre |
|
| 584 | - * Appliquer aussi le critere {offset,limit} |
|
| 585 | - * |
|
| 586 | - * @return array|bool |
|
| 587 | - */ |
|
| 588 | - public function fetch() { |
|
| 589 | - if (method_exists($this->iter, 'fetch')) { |
|
| 590 | - return $this->iter->fetch(); |
|
| 591 | - } else { |
|
| 592 | - while ( |
|
| 593 | - $this->valid() |
|
| 594 | - and ( |
|
| 595 | - !$this->accept() |
|
| 596 | - or (isset($this->offset) and $this->fetched++ < $this->offset) |
|
| 597 | - ) |
|
| 598 | - ) { |
|
| 599 | - $this->next(); |
|
| 600 | - } |
|
| 601 | - |
|
| 602 | - if (!$this->valid()) { |
|
| 603 | - return false; |
|
| 604 | - } |
|
| 605 | - |
|
| 606 | - if ( |
|
| 607 | - isset($this->limit) |
|
| 608 | - and $this->fetched > $this->offset + $this->limit |
|
| 609 | - ) { |
|
| 610 | - return false; |
|
| 611 | - } |
|
| 612 | - |
|
| 613 | - $r = []; |
|
| 614 | - foreach ($this->select as $nom) { |
|
| 615 | - $r[$nom] = $this->get_select($nom); |
|
| 616 | - } |
|
| 617 | - $this->next(); |
|
| 618 | - |
|
| 619 | - return $r; |
|
| 620 | - } |
|
| 621 | - } |
|
| 622 | - |
|
| 623 | - // retourner la cle pour #CLE |
|
| 624 | - public function cle() { |
|
| 625 | - return $this->key(); |
|
| 626 | - } |
|
| 627 | - |
|
| 628 | - // retourner la valeur pour #VALEUR |
|
| 629 | - public function valeur() { |
|
| 630 | - return $this->current(); |
|
| 631 | - } |
|
| 632 | - |
|
| 633 | - /** |
|
| 634 | - * Accepte-t-on l'entree courante lue ? |
|
| 635 | - * On execute les filtres pour le savoir. |
|
| 636 | - **/ |
|
| 637 | - public function accept(): bool { |
|
| 638 | - if ($f = $this->func_filtre) { |
|
| 639 | - return $f(); |
|
| 640 | - } |
|
| 641 | - |
|
| 642 | - return true; |
|
| 643 | - } |
|
| 644 | - |
|
| 645 | - /** |
|
| 646 | - * liberer la ressource |
|
| 647 | - * |
|
| 648 | - * @return bool |
|
| 649 | - */ |
|
| 650 | - public function free() { |
|
| 651 | - if (method_exists($this->iter, 'free')) { |
|
| 652 | - $this->iter->free(); |
|
| 653 | - } |
|
| 654 | - $this->pos = $this->total = 0; |
|
| 655 | - |
|
| 656 | - return true; |
|
| 657 | - } |
|
| 658 | - |
|
| 659 | - /** |
|
| 660 | - * Compter le nombre total de resultats |
|
| 661 | - * pour #TOTAL_BOUCLE |
|
| 662 | - * |
|
| 663 | - * @return int |
|
| 664 | - */ |
|
| 665 | - public function count() { |
|
| 666 | - if (is_null($this->total)) { |
|
| 667 | - if ( |
|
| 668 | - method_exists($this->iter, 'count') |
|
| 669 | - and !$this->func_filtre |
|
| 670 | - ) { |
|
| 671 | - return $this->total = $this->iter->count(); |
|
| 672 | - } else { |
|
| 673 | - // compter les lignes et rembobiner |
|
| 674 | - $total = 0; |
|
| 675 | - $pos = $this->pos; // sauver la position |
|
| 676 | - $this->rewind(); |
|
| 677 | - while ($this->fetch() and $total < $this->max) { |
|
| 678 | - $total++; |
|
| 679 | - } |
|
| 680 | - $this->seek($pos); |
|
| 681 | - $this->total = $total; |
|
| 682 | - } |
|
| 683 | - } |
|
| 684 | - |
|
| 685 | - return $this->total; |
|
| 686 | - } |
|
| 537 | + private function seek_loop($n) { |
|
| 538 | + if ($this->pos > $n) { |
|
| 539 | + $this->rewind(); |
|
| 540 | + } |
|
| 541 | + |
|
| 542 | + while ($this->pos < $n and $this->valid()) { |
|
| 543 | + $this->next(); |
|
| 544 | + } |
|
| 545 | + |
|
| 546 | + return true; |
|
| 547 | + } |
|
| 548 | + |
|
| 549 | + /** |
|
| 550 | + * Avancer de $saut pas |
|
| 551 | + * |
|
| 552 | + * @param $saut |
|
| 553 | + * @param $max |
|
| 554 | + * @return int |
|
| 555 | + */ |
|
| 556 | + public function skip($saut, $max = null) { |
|
| 557 | + // pas de saut en arriere autorise pour cette fonction |
|
| 558 | + if (($saut = intval($saut)) <= 0) { |
|
| 559 | + return $this->pos; |
|
| 560 | + } |
|
| 561 | + $seek = $this->pos + $saut; |
|
| 562 | + // si le saut fait depasser le maxi, on libere la resource |
|
| 563 | + // et on sort |
|
| 564 | + if (is_null($max)) { |
|
| 565 | + $max = $this->count(); |
|
| 566 | + } |
|
| 567 | + |
|
| 568 | + if ($seek >= $max or $seek >= $this->count()) { |
|
| 569 | + // sortie plus rapide que de faire next() jusqu'a la fin ! |
|
| 570 | + $this->free(); |
|
| 571 | + |
|
| 572 | + return $max; |
|
| 573 | + } |
|
| 574 | + |
|
| 575 | + $this->seek($seek); |
|
| 576 | + |
|
| 577 | + return $this->pos; |
|
| 578 | + } |
|
| 579 | + |
|
| 580 | + /** |
|
| 581 | + * Renvoyer un tableau des donnees correspondantes |
|
| 582 | + * a la position courante de l'iterateur |
|
| 583 | + * en controlant si on respecte le filtre |
|
| 584 | + * Appliquer aussi le critere {offset,limit} |
|
| 585 | + * |
|
| 586 | + * @return array|bool |
|
| 587 | + */ |
|
| 588 | + public function fetch() { |
|
| 589 | + if (method_exists($this->iter, 'fetch')) { |
|
| 590 | + return $this->iter->fetch(); |
|
| 591 | + } else { |
|
| 592 | + while ( |
|
| 593 | + $this->valid() |
|
| 594 | + and ( |
|
| 595 | + !$this->accept() |
|
| 596 | + or (isset($this->offset) and $this->fetched++ < $this->offset) |
|
| 597 | + ) |
|
| 598 | + ) { |
|
| 599 | + $this->next(); |
|
| 600 | + } |
|
| 601 | + |
|
| 602 | + if (!$this->valid()) { |
|
| 603 | + return false; |
|
| 604 | + } |
|
| 605 | + |
|
| 606 | + if ( |
|
| 607 | + isset($this->limit) |
|
| 608 | + and $this->fetched > $this->offset + $this->limit |
|
| 609 | + ) { |
|
| 610 | + return false; |
|
| 611 | + } |
|
| 612 | + |
|
| 613 | + $r = []; |
|
| 614 | + foreach ($this->select as $nom) { |
|
| 615 | + $r[$nom] = $this->get_select($nom); |
|
| 616 | + } |
|
| 617 | + $this->next(); |
|
| 618 | + |
|
| 619 | + return $r; |
|
| 620 | + } |
|
| 621 | + } |
|
| 622 | + |
|
| 623 | + // retourner la cle pour #CLE |
|
| 624 | + public function cle() { |
|
| 625 | + return $this->key(); |
|
| 626 | + } |
|
| 627 | + |
|
| 628 | + // retourner la valeur pour #VALEUR |
|
| 629 | + public function valeur() { |
|
| 630 | + return $this->current(); |
|
| 631 | + } |
|
| 632 | + |
|
| 633 | + /** |
|
| 634 | + * Accepte-t-on l'entree courante lue ? |
|
| 635 | + * On execute les filtres pour le savoir. |
|
| 636 | + **/ |
|
| 637 | + public function accept(): bool { |
|
| 638 | + if ($f = $this->func_filtre) { |
|
| 639 | + return $f(); |
|
| 640 | + } |
|
| 641 | + |
|
| 642 | + return true; |
|
| 643 | + } |
|
| 644 | + |
|
| 645 | + /** |
|
| 646 | + * liberer la ressource |
|
| 647 | + * |
|
| 648 | + * @return bool |
|
| 649 | + */ |
|
| 650 | + public function free() { |
|
| 651 | + if (method_exists($this->iter, 'free')) { |
|
| 652 | + $this->iter->free(); |
|
| 653 | + } |
|
| 654 | + $this->pos = $this->total = 0; |
|
| 655 | + |
|
| 656 | + return true; |
|
| 657 | + } |
|
| 658 | + |
|
| 659 | + /** |
|
| 660 | + * Compter le nombre total de resultats |
|
| 661 | + * pour #TOTAL_BOUCLE |
|
| 662 | + * |
|
| 663 | + * @return int |
|
| 664 | + */ |
|
| 665 | + public function count() { |
|
| 666 | + if (is_null($this->total)) { |
|
| 667 | + if ( |
|
| 668 | + method_exists($this->iter, 'count') |
|
| 669 | + and !$this->func_filtre |
|
| 670 | + ) { |
|
| 671 | + return $this->total = $this->iter->count(); |
|
| 672 | + } else { |
|
| 673 | + // compter les lignes et rembobiner |
|
| 674 | + $total = 0; |
|
| 675 | + $pos = $this->pos; // sauver la position |
|
| 676 | + $this->rewind(); |
|
| 677 | + while ($this->fetch() and $total < $this->max) { |
|
| 678 | + $total++; |
|
| 679 | + } |
|
| 680 | + $this->seek($pos); |
|
| 681 | + $this->total = $total; |
|
| 682 | + } |
|
| 683 | + } |
|
| 684 | + |
|
| 685 | + return $this->total; |
|
| 686 | + } |
|
| 687 | 687 | } |
@@ -16,7 +16,7 @@ discard block |
||
| 16 | 16 | * @package SPIP\Core\Minipres |
| 17 | 17 | **/ |
| 18 | 18 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 19 | - return; |
|
| 19 | + return; |
|
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | include_spip('inc/headers'); |
@@ -46,61 +46,61 @@ discard block |
||
| 46 | 46 | */ |
| 47 | 47 | function install_debut_html($titre = 'AUTO', $onLoad = '', $all_inline = false) { |
| 48 | 48 | |
| 49 | - utiliser_langue_visiteur(); |
|
| 50 | - |
|
| 51 | - http_no_cache(); |
|
| 52 | - |
|
| 53 | - if ($titre == 'AUTO') { |
|
| 54 | - $titre = _T('info_installation_systeme_publication'); |
|
| 55 | - } |
|
| 56 | - |
|
| 57 | - # le charset est en utf-8, pour recuperer le nom comme il faut |
|
| 58 | - # lors de l'installation |
|
| 59 | - if (!headers_sent()) { |
|
| 60 | - header('Content-Type: text/html; charset=utf-8'); |
|
| 61 | - } |
|
| 62 | - |
|
| 63 | - $css = ''; |
|
| 64 | - $files = ['reset.css', 'clear.css', 'minipres.css']; |
|
| 65 | - if ($all_inline) { |
|
| 66 | - // inliner les CSS (optimisation de la page minipres qui passe en un seul hit a la demande) |
|
| 67 | - foreach ($files as $name) { |
|
| 68 | - $file = direction_css(find_in_theme($name)); |
|
| 69 | - if (function_exists('minifier')) { |
|
| 70 | - $file = minifier($file); |
|
| 71 | - } else { |
|
| 72 | - $file = url_absolue_css($file); // precaution |
|
| 73 | - } |
|
| 74 | - lire_fichier($file, $c); |
|
| 75 | - $css .= $c; |
|
| 76 | - } |
|
| 77 | - $css = "<style type='text/css'>" . $css . '</style>'; |
|
| 78 | - } else { |
|
| 79 | - foreach ($files as $name) { |
|
| 80 | - $file = direction_css(find_in_theme($name)); |
|
| 81 | - $css .= "<link rel='stylesheet' href='$file' type='text/css' />\n"; |
|
| 82 | - } |
|
| 83 | - } |
|
| 84 | - |
|
| 85 | - // au cas ou minipres() est appele avant spip_initialisation_suite() |
|
| 86 | - if (!defined('_DOCTYPE_ECRIRE')) { |
|
| 87 | - define('_DOCTYPE_ECRIRE', ''); |
|
| 88 | - } |
|
| 89 | - |
|
| 90 | - return _DOCTYPE_ECRIRE . |
|
| 91 | - html_lang_attributes() . |
|
| 92 | - "<head>\n" . |
|
| 93 | - '<title>' . |
|
| 94 | - textebrut($titre) . |
|
| 95 | - "</title>\n" . |
|
| 96 | - "<meta name='viewport' content='width=device-width' />\n" . |
|
| 97 | - $css . |
|
| 98 | - '</head> |
|
| 49 | + utiliser_langue_visiteur(); |
|
| 50 | + |
|
| 51 | + http_no_cache(); |
|
| 52 | + |
|
| 53 | + if ($titre == 'AUTO') { |
|
| 54 | + $titre = _T('info_installation_systeme_publication'); |
|
| 55 | + } |
|
| 56 | + |
|
| 57 | + # le charset est en utf-8, pour recuperer le nom comme il faut |
|
| 58 | + # lors de l'installation |
|
| 59 | + if (!headers_sent()) { |
|
| 60 | + header('Content-Type: text/html; charset=utf-8'); |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + $css = ''; |
|
| 64 | + $files = ['reset.css', 'clear.css', 'minipres.css']; |
|
| 65 | + if ($all_inline) { |
|
| 66 | + // inliner les CSS (optimisation de la page minipres qui passe en un seul hit a la demande) |
|
| 67 | + foreach ($files as $name) { |
|
| 68 | + $file = direction_css(find_in_theme($name)); |
|
| 69 | + if (function_exists('minifier')) { |
|
| 70 | + $file = minifier($file); |
|
| 71 | + } else { |
|
| 72 | + $file = url_absolue_css($file); // precaution |
|
| 73 | + } |
|
| 74 | + lire_fichier($file, $c); |
|
| 75 | + $css .= $c; |
|
| 76 | + } |
|
| 77 | + $css = "<style type='text/css'>" . $css . '</style>'; |
|
| 78 | + } else { |
|
| 79 | + foreach ($files as $name) { |
|
| 80 | + $file = direction_css(find_in_theme($name)); |
|
| 81 | + $css .= "<link rel='stylesheet' href='$file' type='text/css' />\n"; |
|
| 82 | + } |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + // au cas ou minipres() est appele avant spip_initialisation_suite() |
|
| 86 | + if (!defined('_DOCTYPE_ECRIRE')) { |
|
| 87 | + define('_DOCTYPE_ECRIRE', ''); |
|
| 88 | + } |
|
| 89 | + |
|
| 90 | + return _DOCTYPE_ECRIRE . |
|
| 91 | + html_lang_attributes() . |
|
| 92 | + "<head>\n" . |
|
| 93 | + '<title>' . |
|
| 94 | + textebrut($titre) . |
|
| 95 | + "</title>\n" . |
|
| 96 | + "<meta name='viewport' content='width=device-width' />\n" . |
|
| 97 | + $css . |
|
| 98 | + '</head> |
|
| 99 | 99 | <body' . $onLoad . " class='minipres'> |
| 100 | 100 | <div id='minipres'> |
| 101 | 101 | <h1>" . |
| 102 | - $titre . |
|
| 103 | - "</h1> |
|
| 102 | + $titre . |
|
| 103 | + "</h1> |
|
| 104 | 104 | <div>\n"; |
| 105 | 105 | } |
| 106 | 106 | |
@@ -110,7 +110,7 @@ discard block |
||
| 110 | 110 | * @return string Code HTML |
| 111 | 111 | */ |
| 112 | 112 | function install_fin_html() { |
| 113 | - return "\n\t</div>\n\t</div>\n</body>\n</html>"; |
|
| 113 | + return "\n\t</div>\n\t</div>\n</body>\n</html>"; |
|
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | |
@@ -148,88 +148,88 @@ discard block |
||
| 148 | 148 | */ |
| 149 | 149 | function minipres($titre = '', $corps = '', $options = []) { |
| 150 | 150 | |
| 151 | - // compat signature old |
|
| 152 | - // minipres($titre='', $corps="", $onload='', $all_inline = false) |
|
| 153 | - $args = func_get_args(); |
|
| 154 | - if (isset($args[2]) and is_string($args[2])) { |
|
| 155 | - $options = ['onload' => $args[2]]; |
|
| 156 | - } |
|
| 157 | - if (isset($args[3])) { |
|
| 158 | - $options['all_inline'] = $args[3]; |
|
| 159 | - } |
|
| 160 | - |
|
| 161 | - $options = array_merge([ |
|
| 162 | - 'onload' => '', |
|
| 163 | - 'all_inline' => false, |
|
| 164 | - ], $options); |
|
| 165 | - |
|
| 166 | - if (!defined('_AJAX')) { |
|
| 167 | - define('_AJAX', false); |
|
| 168 | - } // par securite |
|
| 169 | - if (!$titre) { |
|
| 170 | - if (!isset($options['status'])) { |
|
| 171 | - $options['status'] = 403; |
|
| 172 | - } |
|
| 173 | - if ( |
|
| 174 | - !$titre = _request('action') |
|
| 175 | - and !$titre = _request('exec') |
|
| 176 | - and !$titre = _request('page') |
|
| 177 | - ) { |
|
| 178 | - $titre = '?'; |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - $titre = spip_htmlspecialchars($titre); |
|
| 182 | - |
|
| 183 | - $titre = ($titre == 'install') |
|
| 184 | - ? _T('avis_espace_interdit') |
|
| 185 | - : $titre . ' : ' . _T('info_acces_interdit'); |
|
| 186 | - |
|
| 187 | - $statut = $GLOBALS['visiteur_session']['statut'] ?? ''; |
|
| 188 | - $nom = $GLOBALS['visiteur_session']['nom'] ?? ''; |
|
| 189 | - |
|
| 190 | - if ($statut != '0minirezo') { |
|
| 191 | - $titre = _T('info_acces_interdit'); |
|
| 192 | - } |
|
| 193 | - |
|
| 194 | - if ($statut and test_espace_prive()) { |
|
| 195 | - $corps = bouton_action(_T('public:accueil_site'), generer_url_ecrire('accueil')); |
|
| 196 | - } |
|
| 197 | - elseif (!empty($_COOKIE['spip_admin'])) { |
|
| 198 | - $corps = bouton_action(_T('public:lien_connecter'), generer_url_public('login')); |
|
| 199 | - } |
|
| 200 | - else { |
|
| 201 | - $corps = bouton_action(_T('public:accueil_site'), $GLOBALS['meta']['adresse_site']); |
|
| 202 | - } |
|
| 203 | - $corps = "<div class='boutons'>$corps</div>"; |
|
| 204 | - spip_log($nom . " $titre " . $_SERVER['REQUEST_URI']); |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - if (!_AJAX) { |
|
| 208 | - if (isset($options['status'])) { |
|
| 209 | - http_response_code($options['status']); |
|
| 210 | - } |
|
| 211 | - |
|
| 212 | - $html = install_debut_html($titre, $options['onload'], $options['all_inline']) |
|
| 213 | - . $corps |
|
| 214 | - . install_fin_html(); |
|
| 215 | - |
|
| 216 | - if ( |
|
| 217 | - $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 218 | - and empty($options['all_inline']) |
|
| 219 | - ) { |
|
| 220 | - define('_SET_HTML_BASE', true); |
|
| 221 | - include_spip('public/assembler'); |
|
| 222 | - $GLOBALS['html'] = true; |
|
| 223 | - page_base_href($html); |
|
| 224 | - } |
|
| 225 | - return $html; |
|
| 226 | - } else { |
|
| 227 | - include_spip('inc/headers'); |
|
| 228 | - include_spip('inc/actions'); |
|
| 229 | - $url = self('&', true); |
|
| 230 | - foreach ($_POST as $v => $c) { |
|
| 231 | - $url = parametre_url($url, $v, $c, '&'); |
|
| 232 | - } |
|
| 233 | - ajax_retour('<div>' . $titre . redirige_formulaire($url) . '</div>', false); |
|
| 234 | - } |
|
| 151 | + // compat signature old |
|
| 152 | + // minipres($titre='', $corps="", $onload='', $all_inline = false) |
|
| 153 | + $args = func_get_args(); |
|
| 154 | + if (isset($args[2]) and is_string($args[2])) { |
|
| 155 | + $options = ['onload' => $args[2]]; |
|
| 156 | + } |
|
| 157 | + if (isset($args[3])) { |
|
| 158 | + $options['all_inline'] = $args[3]; |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + $options = array_merge([ |
|
| 162 | + 'onload' => '', |
|
| 163 | + 'all_inline' => false, |
|
| 164 | + ], $options); |
|
| 165 | + |
|
| 166 | + if (!defined('_AJAX')) { |
|
| 167 | + define('_AJAX', false); |
|
| 168 | + } // par securite |
|
| 169 | + if (!$titre) { |
|
| 170 | + if (!isset($options['status'])) { |
|
| 171 | + $options['status'] = 403; |
|
| 172 | + } |
|
| 173 | + if ( |
|
| 174 | + !$titre = _request('action') |
|
| 175 | + and !$titre = _request('exec') |
|
| 176 | + and !$titre = _request('page') |
|
| 177 | + ) { |
|
| 178 | + $titre = '?'; |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + $titre = spip_htmlspecialchars($titre); |
|
| 182 | + |
|
| 183 | + $titre = ($titre == 'install') |
|
| 184 | + ? _T('avis_espace_interdit') |
|
| 185 | + : $titre . ' : ' . _T('info_acces_interdit'); |
|
| 186 | + |
|
| 187 | + $statut = $GLOBALS['visiteur_session']['statut'] ?? ''; |
|
| 188 | + $nom = $GLOBALS['visiteur_session']['nom'] ?? ''; |
|
| 189 | + |
|
| 190 | + if ($statut != '0minirezo') { |
|
| 191 | + $titre = _T('info_acces_interdit'); |
|
| 192 | + } |
|
| 193 | + |
|
| 194 | + if ($statut and test_espace_prive()) { |
|
| 195 | + $corps = bouton_action(_T('public:accueil_site'), generer_url_ecrire('accueil')); |
|
| 196 | + } |
|
| 197 | + elseif (!empty($_COOKIE['spip_admin'])) { |
|
| 198 | + $corps = bouton_action(_T('public:lien_connecter'), generer_url_public('login')); |
|
| 199 | + } |
|
| 200 | + else { |
|
| 201 | + $corps = bouton_action(_T('public:accueil_site'), $GLOBALS['meta']['adresse_site']); |
|
| 202 | + } |
|
| 203 | + $corps = "<div class='boutons'>$corps</div>"; |
|
| 204 | + spip_log($nom . " $titre " . $_SERVER['REQUEST_URI']); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + if (!_AJAX) { |
|
| 208 | + if (isset($options['status'])) { |
|
| 209 | + http_response_code($options['status']); |
|
| 210 | + } |
|
| 211 | + |
|
| 212 | + $html = install_debut_html($titre, $options['onload'], $options['all_inline']) |
|
| 213 | + . $corps |
|
| 214 | + . install_fin_html(); |
|
| 215 | + |
|
| 216 | + if ( |
|
| 217 | + $GLOBALS['profondeur_url'] >= (_DIR_RESTREINT ? 1 : 2) |
|
| 218 | + and empty($options['all_inline']) |
|
| 219 | + ) { |
|
| 220 | + define('_SET_HTML_BASE', true); |
|
| 221 | + include_spip('public/assembler'); |
|
| 222 | + $GLOBALS['html'] = true; |
|
| 223 | + page_base_href($html); |
|
| 224 | + } |
|
| 225 | + return $html; |
|
| 226 | + } else { |
|
| 227 | + include_spip('inc/headers'); |
|
| 228 | + include_spip('inc/actions'); |
|
| 229 | + $url = self('&', true); |
|
| 230 | + foreach ($_POST as $v => $c) { |
|
| 231 | + $url = parametre_url($url, $v, $c, '&'); |
|
| 232 | + } |
|
| 233 | + ajax_retour('<div>' . $titre . redirige_formulaire($url) . '</div>', false); |
|
| 234 | + } |
|
| 235 | 235 | } |
@@ -17,7 +17,7 @@ discard block |
||
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 20 | - return; |
|
| 20 | + return; |
|
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | /** |
@@ -30,12 +30,12 @@ discard block |
||
| 30 | 30 | * @return string |
| 31 | 31 | */ |
| 32 | 32 | function set_spip_doc(?string $fichier): string { |
| 33 | - if ($fichier and strpos($fichier, (string) _DIR_IMG) === 0) { |
|
| 34 | - return substr($fichier, strlen(_DIR_IMG)); |
|
| 35 | - } else { |
|
| 36 | - // ex: fichier distant |
|
| 37 | - return $fichier ?? ''; |
|
| 38 | - } |
|
| 33 | + if ($fichier and strpos($fichier, (string) _DIR_IMG) === 0) { |
|
| 34 | + return substr($fichier, strlen(_DIR_IMG)); |
|
| 35 | + } else { |
|
| 36 | + // ex: fichier distant |
|
| 37 | + return $fichier ?? ''; |
|
| 38 | + } |
|
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | /** |
@@ -47,26 +47,26 @@ discard block |
||
| 47 | 47 | * @return bool|string |
| 48 | 48 | */ |
| 49 | 49 | function get_spip_doc(?string $fichier) { |
| 50 | - if ($fichier === null) { |
|
| 51 | - return false; |
|
| 52 | - } |
|
| 53 | - |
|
| 54 | - // fichier distant |
|
| 55 | - if (tester_url_absolue($fichier)) { |
|
| 56 | - return $fichier; |
|
| 57 | - } |
|
| 58 | - |
|
| 59 | - // gestion d'erreurs, fichier='' |
|
| 60 | - if (!strlen($fichier)) { |
|
| 61 | - return false; |
|
| 62 | - } |
|
| 63 | - |
|
| 64 | - if (strncmp($fichier, _DIR_IMG, strlen(_DIR_IMG)) !== 0) { |
|
| 65 | - $fichier = _DIR_IMG . $fichier; |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - // fichier normal |
|
| 69 | - return $fichier; |
|
| 50 | + if ($fichier === null) { |
|
| 51 | + return false; |
|
| 52 | + } |
|
| 53 | + |
|
| 54 | + // fichier distant |
|
| 55 | + if (tester_url_absolue($fichier)) { |
|
| 56 | + return $fichier; |
|
| 57 | + } |
|
| 58 | + |
|
| 59 | + // gestion d'erreurs, fichier='' |
|
| 60 | + if (!strlen($fichier)) { |
|
| 61 | + return false; |
|
| 62 | + } |
|
| 63 | + |
|
| 64 | + if (strncmp($fichier, _DIR_IMG, strlen(_DIR_IMG)) !== 0) { |
|
| 65 | + $fichier = _DIR_IMG . $fichier; |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + // fichier normal |
|
| 69 | + return $fichier; |
|
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | /** |
@@ -80,26 +80,26 @@ discard block |
||
| 80 | 80 | * @return string |
| 81 | 81 | */ |
| 82 | 82 | function creer_repertoire_documents($ext) { |
| 83 | - $rep = sous_repertoire(_DIR_IMG, $ext); |
|
| 84 | - |
|
| 85 | - if (!$ext or !$rep) { |
|
| 86 | - spip_log("creer_repertoire_documents '$rep' interdit"); |
|
| 87 | - exit; |
|
| 88 | - } |
|
| 89 | - |
|
| 90 | - // Cette variable de configuration peut etre posee par un plugin |
|
| 91 | - // par exemple acces_restreint |
|
| 92 | - // sauf pour logo/ utilise pour stocker les logoon et logooff |
|
| 93 | - if ( |
|
| 94 | - isset($GLOBALS['meta']['creer_htaccess']) |
|
| 95 | - and $GLOBALS['meta']['creer_htaccess'] == 'oui' |
|
| 96 | - and $ext !== 'logo' |
|
| 97 | - ) { |
|
| 98 | - include_spip('inc/acces'); |
|
| 99 | - verifier_htaccess($rep); |
|
| 100 | - } |
|
| 101 | - |
|
| 102 | - return $rep; |
|
| 83 | + $rep = sous_repertoire(_DIR_IMG, $ext); |
|
| 84 | + |
|
| 85 | + if (!$ext or !$rep) { |
|
| 86 | + spip_log("creer_repertoire_documents '$rep' interdit"); |
|
| 87 | + exit; |
|
| 88 | + } |
|
| 89 | + |
|
| 90 | + // Cette variable de configuration peut etre posee par un plugin |
|
| 91 | + // par exemple acces_restreint |
|
| 92 | + // sauf pour logo/ utilise pour stocker les logoon et logooff |
|
| 93 | + if ( |
|
| 94 | + isset($GLOBALS['meta']['creer_htaccess']) |
|
| 95 | + and $GLOBALS['meta']['creer_htaccess'] == 'oui' |
|
| 96 | + and $ext !== 'logo' |
|
| 97 | + ) { |
|
| 98 | + include_spip('inc/acces'); |
|
| 99 | + verifier_htaccess($rep); |
|
| 100 | + } |
|
| 101 | + |
|
| 102 | + return $rep; |
|
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | /** |
@@ -108,22 +108,22 @@ discard block |
||
| 108 | 108 | * @param string $nom |
| 109 | 109 | */ |
| 110 | 110 | function effacer_repertoire_temporaire($nom) { |
| 111 | - if ($d = opendir($nom)) { |
|
| 112 | - while (($f = readdir($d)) !== false) { |
|
| 113 | - if (is_file("$nom/$f")) { |
|
| 114 | - spip_unlink("$nom/$f"); |
|
| 115 | - } else { |
|
| 116 | - if ( |
|
| 117 | - $f <> '.' and $f <> '..' |
|
| 118 | - and is_dir("$nom/$f") |
|
| 119 | - ) { |
|
| 120 | - effacer_repertoire_temporaire("$nom/$f"); |
|
| 121 | - } |
|
| 122 | - } |
|
| 123 | - } |
|
| 124 | - } |
|
| 125 | - closedir($d); |
|
| 126 | - @rmdir($nom); |
|
| 111 | + if ($d = opendir($nom)) { |
|
| 112 | + while (($f = readdir($d)) !== false) { |
|
| 113 | + if (is_file("$nom/$f")) { |
|
| 114 | + spip_unlink("$nom/$f"); |
|
| 115 | + } else { |
|
| 116 | + if ( |
|
| 117 | + $f <> '.' and $f <> '..' |
|
| 118 | + and is_dir("$nom/$f") |
|
| 119 | + ) { |
|
| 120 | + effacer_repertoire_temporaire("$nom/$f"); |
|
| 121 | + } |
|
| 122 | + } |
|
| 123 | + } |
|
| 124 | + } |
|
| 125 | + closedir($d); |
|
| 126 | + @rmdir($nom); |
|
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | // |
@@ -140,45 +140,45 @@ discard block |
||
| 140 | 140 | */ |
| 141 | 141 | function copier_document($ext, $orig, $source, $subdir = null) { |
| 142 | 142 | |
| 143 | - $orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc |
|
| 144 | - $dir = creer_repertoire_documents($subdir ?: $ext); |
|
| 145 | - |
|
| 146 | - $dest = preg_replace('/<[^>]*>/', '', basename($orig)); |
|
| 147 | - $dest = preg_replace('/\.([^.]+)$/', '', $dest); |
|
| 148 | - $dest = translitteration($dest); |
|
| 149 | - $dest = preg_replace('/[^.=\w-]+/', '_', $dest); |
|
| 150 | - |
|
| 151 | - // ne pas accepter de noms de la forme -r90.jpg qui sont reserves |
|
| 152 | - // pour les images transformees par rotation (action/documenter) |
|
| 153 | - $dest = preg_replace(',-r(90|180|270)$,', '', $dest); |
|
| 154 | - |
|
| 155 | - while (preg_match(',\.(\w+)$,', $dest, $m)) { |
|
| 156 | - if ( |
|
| 157 | - !function_exists('verifier_upload_autorise') |
|
| 158 | - or !$r = verifier_upload_autorise($dest) |
|
| 159 | - or $r['autozip'] |
|
| 160 | - ) { |
|
| 161 | - $dest = substr($dest, 0, -strlen($m[0])) . '_' . $m[1]; |
|
| 162 | - break; |
|
| 163 | - } |
|
| 164 | - else { |
|
| 165 | - $dest = substr($dest, 0, -strlen($m[0])); |
|
| 166 | - $ext = $m[1] . '.' . $ext; |
|
| 167 | - } |
|
| 168 | - } |
|
| 169 | - |
|
| 170 | - // Si le document "source" est deja au bon endroit, ne rien faire |
|
| 171 | - if ($source == ($dir . $dest . '.' . $ext)) { |
|
| 172 | - return $source; |
|
| 173 | - } |
|
| 174 | - |
|
| 175 | - // sinon tourner jusqu'a trouver un numero correct |
|
| 176 | - $n = 0; |
|
| 177 | - while (@file_exists($newFile = $dir . $dest . ($n++ ? ('-' . $n) : '') . '.' . $ext)) { |
|
| 178 | - ; |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - return deplacer_fichier_upload($source, $newFile); |
|
| 143 | + $orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc |
|
| 144 | + $dir = creer_repertoire_documents($subdir ?: $ext); |
|
| 145 | + |
|
| 146 | + $dest = preg_replace('/<[^>]*>/', '', basename($orig)); |
|
| 147 | + $dest = preg_replace('/\.([^.]+)$/', '', $dest); |
|
| 148 | + $dest = translitteration($dest); |
|
| 149 | + $dest = preg_replace('/[^.=\w-]+/', '_', $dest); |
|
| 150 | + |
|
| 151 | + // ne pas accepter de noms de la forme -r90.jpg qui sont reserves |
|
| 152 | + // pour les images transformees par rotation (action/documenter) |
|
| 153 | + $dest = preg_replace(',-r(90|180|270)$,', '', $dest); |
|
| 154 | + |
|
| 155 | + while (preg_match(',\.(\w+)$,', $dest, $m)) { |
|
| 156 | + if ( |
|
| 157 | + !function_exists('verifier_upload_autorise') |
|
| 158 | + or !$r = verifier_upload_autorise($dest) |
|
| 159 | + or $r['autozip'] |
|
| 160 | + ) { |
|
| 161 | + $dest = substr($dest, 0, -strlen($m[0])) . '_' . $m[1]; |
|
| 162 | + break; |
|
| 163 | + } |
|
| 164 | + else { |
|
| 165 | + $dest = substr($dest, 0, -strlen($m[0])); |
|
| 166 | + $ext = $m[1] . '.' . $ext; |
|
| 167 | + } |
|
| 168 | + } |
|
| 169 | + |
|
| 170 | + // Si le document "source" est deja au bon endroit, ne rien faire |
|
| 171 | + if ($source == ($dir . $dest . '.' . $ext)) { |
|
| 172 | + return $source; |
|
| 173 | + } |
|
| 174 | + |
|
| 175 | + // sinon tourner jusqu'a trouver un numero correct |
|
| 176 | + $n = 0; |
|
| 177 | + while (@file_exists($newFile = $dir . $dest . ($n++ ? ('-' . $n) : '') . '.' . $ext)) { |
|
| 178 | + ; |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + return deplacer_fichier_upload($source, $newFile); |
|
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | /** |
@@ -193,28 +193,28 @@ discard block |
||
| 193 | 193 | * @return bool|string |
| 194 | 194 | */ |
| 195 | 195 | function determine_upload($type = '') { |
| 196 | - if (!function_exists('autoriser')) { |
|
| 197 | - include_spip('inc/autoriser'); |
|
| 198 | - } |
|
| 199 | - |
|
| 200 | - if ( |
|
| 201 | - !autoriser('chargerftp') |
|
| 202 | - or $type == 'logos' |
|
| 203 | - ) { # on ne le permet pas pour les logos |
|
| 204 | - return false; |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - $repertoire = _DIR_TRANSFERT; |
|
| 208 | - if (!@is_dir($repertoire)) { |
|
| 209 | - $repertoire = str_replace(_DIR_TMP, '', $repertoire); |
|
| 210 | - $repertoire = sous_repertoire(_DIR_TMP, $repertoire); |
|
| 211 | - } |
|
| 212 | - |
|
| 213 | - if (!$GLOBALS['visiteur_session']['restreint']) { |
|
| 214 | - return $repertoire; |
|
| 215 | - } else { |
|
| 216 | - return sous_repertoire($repertoire, $GLOBALS['visiteur_session']['login']); |
|
| 217 | - } |
|
| 196 | + if (!function_exists('autoriser')) { |
|
| 197 | + include_spip('inc/autoriser'); |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + if ( |
|
| 201 | + !autoriser('chargerftp') |
|
| 202 | + or $type == 'logos' |
|
| 203 | + ) { # on ne le permet pas pour les logos |
|
| 204 | + return false; |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + $repertoire = _DIR_TRANSFERT; |
|
| 208 | + if (!@is_dir($repertoire)) { |
|
| 209 | + $repertoire = str_replace(_DIR_TMP, '', $repertoire); |
|
| 210 | + $repertoire = sous_repertoire(_DIR_TMP, $repertoire); |
|
| 211 | + } |
|
| 212 | + |
|
| 213 | + if (!$GLOBALS['visiteur_session']['restreint']) { |
|
| 214 | + return $repertoire; |
|
| 215 | + } else { |
|
| 216 | + return sous_repertoire($repertoire, $GLOBALS['visiteur_session']['login']); |
|
| 217 | + } |
|
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | /** |
@@ -233,35 +233,35 @@ discard block |
||
| 233 | 233 | * @return bool|mixed|string |
| 234 | 234 | */ |
| 235 | 235 | function deplacer_fichier_upload($source, $dest, $move = false) { |
| 236 | - // Securite |
|
| 237 | - if (substr($dest, 0, strlen(_DIR_RACINE)) == _DIR_RACINE) { |
|
| 238 | - $dest = _DIR_RACINE . preg_replace(',\.\.+,', '.', substr($dest, strlen(_DIR_RACINE))); |
|
| 239 | - } else { |
|
| 240 | - $dest = preg_replace(',\.\.+,', '.', $dest); |
|
| 241 | - } |
|
| 242 | - |
|
| 243 | - if ($move) { |
|
| 244 | - $ok = @rename($source, $dest); |
|
| 245 | - } else { |
|
| 246 | - $ok = @copy($source, $dest); |
|
| 247 | - } |
|
| 248 | - if (!$ok) { |
|
| 249 | - $ok = @move_uploaded_file($source, $dest); |
|
| 250 | - } |
|
| 251 | - if ($ok) { |
|
| 252 | - @chmod($dest, _SPIP_CHMOD & ~0111); |
|
| 253 | - } else { |
|
| 254 | - $f = @fopen($dest, 'w'); |
|
| 255 | - if ($f) { |
|
| 256 | - fclose($f); |
|
| 257 | - } else { |
|
| 258 | - include_spip('inc/flock'); |
|
| 259 | - raler_fichier($dest); |
|
| 260 | - } |
|
| 261 | - spip_unlink($dest); |
|
| 262 | - } |
|
| 263 | - |
|
| 264 | - return $ok ? $dest : false; |
|
| 236 | + // Securite |
|
| 237 | + if (substr($dest, 0, strlen(_DIR_RACINE)) == _DIR_RACINE) { |
|
| 238 | + $dest = _DIR_RACINE . preg_replace(',\.\.+,', '.', substr($dest, strlen(_DIR_RACINE))); |
|
| 239 | + } else { |
|
| 240 | + $dest = preg_replace(',\.\.+,', '.', $dest); |
|
| 241 | + } |
|
| 242 | + |
|
| 243 | + if ($move) { |
|
| 244 | + $ok = @rename($source, $dest); |
|
| 245 | + } else { |
|
| 246 | + $ok = @copy($source, $dest); |
|
| 247 | + } |
|
| 248 | + if (!$ok) { |
|
| 249 | + $ok = @move_uploaded_file($source, $dest); |
|
| 250 | + } |
|
| 251 | + if ($ok) { |
|
| 252 | + @chmod($dest, _SPIP_CHMOD & ~0111); |
|
| 253 | + } else { |
|
| 254 | + $f = @fopen($dest, 'w'); |
|
| 255 | + if ($f) { |
|
| 256 | + fclose($f); |
|
| 257 | + } else { |
|
| 258 | + include_spip('inc/flock'); |
|
| 259 | + raler_fichier($dest); |
|
| 260 | + } |
|
| 261 | + spip_unlink($dest); |
|
| 262 | + } |
|
| 263 | + |
|
| 264 | + return $ok ? $dest : false; |
|
| 265 | 265 | } |
| 266 | 266 | |
| 267 | 267 | |
@@ -285,60 +285,60 @@ discard block |
||
| 285 | 285 | */ |
| 286 | 286 | function check_upload_error($error, $msg = '', $return = false) { |
| 287 | 287 | |
| 288 | - if (!$error) { |
|
| 289 | - return false; |
|
| 290 | - } |
|
| 291 | - |
|
| 292 | - spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php"); |
|
| 293 | - |
|
| 294 | - switch ($error) { |
|
| 295 | - case 4: /* UPLOAD_ERR_NO_FILE */ |
|
| 296 | - return true; |
|
| 297 | - |
|
| 298 | - # on peut affiner les differents messages d'erreur |
|
| 299 | - case 1: /* UPLOAD_ERR_INI_SIZE */ |
|
| 300 | - $msg = _T( |
|
| 301 | - 'upload_limit', |
|
| 302 | - ['max' => ini_get('upload_max_filesize')] |
|
| 303 | - ); |
|
| 304 | - break; |
|
| 305 | - case 2: /* UPLOAD_ERR_FORM_SIZE */ |
|
| 306 | - $msg = _T( |
|
| 307 | - 'upload_limit', |
|
| 308 | - ['max' => ini_get('upload_max_filesize')] |
|
| 309 | - ); |
|
| 310 | - break; |
|
| 311 | - case 3: /* UPLOAD_ERR_PARTIAL */ |
|
| 312 | - $msg = _T( |
|
| 313 | - 'upload_limit', |
|
| 314 | - ['max' => ini_get('upload_max_filesize')] |
|
| 315 | - ); |
|
| 316 | - break; |
|
| 317 | - |
|
| 318 | - default: /* autre */ |
|
| 319 | - if (!$msg) { |
|
| 320 | - $msg = _T('pass_erreur') . ' ' . $error |
|
| 321 | - . '<br />' . propre('[->http://php.net/manual/fr/features.file-upload.errors.php]'); |
|
| 322 | - } |
|
| 323 | - break; |
|
| 324 | - } |
|
| 325 | - |
|
| 326 | - spip_log("erreur upload $error"); |
|
| 327 | - if ($return) { |
|
| 328 | - return $msg; |
|
| 329 | - } |
|
| 330 | - |
|
| 331 | - if (_request('iframe') == 'iframe') { |
|
| 332 | - echo "<div class='upload_answer upload_error'>$msg</div>"; |
|
| 333 | - exit; |
|
| 334 | - } |
|
| 335 | - |
|
| 336 | - include_spip('inc/minipres'); |
|
| 337 | - echo minipres( |
|
| 338 | - $msg, |
|
| 339 | - "<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><a href='" . rawurldecode($GLOBALS['redirect']) . "'><button type='button'>" . _T('ecrire:bouton_suivant') . '</button></a></div>' |
|
| 340 | - ); |
|
| 341 | - exit; |
|
| 288 | + if (!$error) { |
|
| 289 | + return false; |
|
| 290 | + } |
|
| 291 | + |
|
| 292 | + spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php"); |
|
| 293 | + |
|
| 294 | + switch ($error) { |
|
| 295 | + case 4: /* UPLOAD_ERR_NO_FILE */ |
|
| 296 | + return true; |
|
| 297 | + |
|
| 298 | + # on peut affiner les differents messages d'erreur |
|
| 299 | + case 1: /* UPLOAD_ERR_INI_SIZE */ |
|
| 300 | + $msg = _T( |
|
| 301 | + 'upload_limit', |
|
| 302 | + ['max' => ini_get('upload_max_filesize')] |
|
| 303 | + ); |
|
| 304 | + break; |
|
| 305 | + case 2: /* UPLOAD_ERR_FORM_SIZE */ |
|
| 306 | + $msg = _T( |
|
| 307 | + 'upload_limit', |
|
| 308 | + ['max' => ini_get('upload_max_filesize')] |
|
| 309 | + ); |
|
| 310 | + break; |
|
| 311 | + case 3: /* UPLOAD_ERR_PARTIAL */ |
|
| 312 | + $msg = _T( |
|
| 313 | + 'upload_limit', |
|
| 314 | + ['max' => ini_get('upload_max_filesize')] |
|
| 315 | + ); |
|
| 316 | + break; |
|
| 317 | + |
|
| 318 | + default: /* autre */ |
|
| 319 | + if (!$msg) { |
|
| 320 | + $msg = _T('pass_erreur') . ' ' . $error |
|
| 321 | + . '<br />' . propre('[->http://php.net/manual/fr/features.file-upload.errors.php]'); |
|
| 322 | + } |
|
| 323 | + break; |
|
| 324 | + } |
|
| 325 | + |
|
| 326 | + spip_log("erreur upload $error"); |
|
| 327 | + if ($return) { |
|
| 328 | + return $msg; |
|
| 329 | + } |
|
| 330 | + |
|
| 331 | + if (_request('iframe') == 'iframe') { |
|
| 332 | + echo "<div class='upload_answer upload_error'>$msg</div>"; |
|
| 333 | + exit; |
|
| 334 | + } |
|
| 335 | + |
|
| 336 | + include_spip('inc/minipres'); |
|
| 337 | + echo minipres( |
|
| 338 | + $msg, |
|
| 339 | + "<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><a href='" . rawurldecode($GLOBALS['redirect']) . "'><button type='button'>" . _T('ecrire:bouton_suivant') . '</button></a></div>' |
|
| 340 | + ); |
|
| 341 | + exit; |
|
| 342 | 342 | } |
| 343 | 343 | |
| 344 | 344 | /** |
@@ -355,24 +355,24 @@ discard block |
||
| 355 | 355 | * @return string |
| 356 | 356 | */ |
| 357 | 357 | function corriger_extension($ext) { |
| 358 | - $ext = preg_replace(',[^a-z0-9],i', '', $ext); |
|
| 359 | - switch ($ext) { |
|
| 360 | - case 'htm': |
|
| 361 | - $ext = 'html'; |
|
| 362 | - break; |
|
| 363 | - case 'jpeg': |
|
| 364 | - $ext = 'jpg'; |
|
| 365 | - break; |
|
| 366 | - case 'tiff': |
|
| 367 | - $ext = 'tif'; |
|
| 368 | - break; |
|
| 369 | - case 'aif': |
|
| 370 | - $ext = 'aiff'; |
|
| 371 | - break; |
|
| 372 | - case 'mpeg': |
|
| 373 | - $ext = 'mpg'; |
|
| 374 | - break; |
|
| 375 | - } |
|
| 376 | - |
|
| 377 | - return $ext; |
|
| 358 | + $ext = preg_replace(',[^a-z0-9],i', '', $ext); |
|
| 359 | + switch ($ext) { |
|
| 360 | + case 'htm': |
|
| 361 | + $ext = 'html'; |
|
| 362 | + break; |
|
| 363 | + case 'jpeg': |
|
| 364 | + $ext = 'jpg'; |
|
| 365 | + break; |
|
| 366 | + case 'tiff': |
|
| 367 | + $ext = 'tif'; |
|
| 368 | + break; |
|
| 369 | + case 'aif': |
|
| 370 | + $ext = 'aiff'; |
|
| 371 | + break; |
|
| 372 | + case 'mpeg': |
|
| 373 | + $ext = 'mpg'; |
|
| 374 | + break; |
|
| 375 | + } |
|
| 376 | + |
|
| 377 | + return $ext; |
|
| 378 | 378 | } |
@@ -4,248 +4,248 @@ discard block |
||
| 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 | - 'access_interface_graphique' => 'Back to the full graphic interface', |
|
| 14 | - 'access_mode_texte' => 'Show the simplified text interface', |
|
| 15 | - 'admin_debug' => 'debug', |
|
| 16 | - 'admin_modifier_article' => 'Modify this article', |
|
| 17 | - 'admin_modifier_auteur' => 'Modify this author', |
|
| 18 | - 'admin_modifier_breve' => 'Modify this news item', |
|
| 19 | - 'admin_modifier_mot' => 'Modify this keyword', |
|
| 20 | - 'admin_modifier_rubrique' => 'Modify this section', |
|
| 21 | - 'admin_recalculer' => 'Re-process this page', |
|
| 22 | - 'afficher_calendrier' => 'Show the calendar', |
|
| 23 | - 'afficher_trad' => 'show translations', |
|
| 24 | - 'alerte_maj_impossible' => '<b>Warning!</b> Failed to update the SQL database to version @version@. This may be due to a permissions problem on the database. Please contact your ISP.', |
|
| 25 | - 'alerte_modif_info_concourante' => 'WARNING: This information has been modified elsewhere. The current value is :', |
|
| 26 | - 'analyse_xml' => 'XML parsing', |
|
| 27 | - 'annuler' => 'Cancel', |
|
| 28 | - 'antispam_champ_vide' => 'Please leave this field empty:', |
|
| 29 | - 'articles_recents' => 'Most recent articles', |
|
| 30 | - 'attention_champ_mini_nb_caractères' => 'Warning! At least @nb@ characters', |
|
| 31 | - 'avis_1_erreur_saisie' => 'Your entry contains an error, please check your information.', |
|
| 32 | - 'avis_archive_incorrect' => 'archive is not a valid SPIP file', |
|
| 33 | - 'avis_archive_invalide' => 'archive file is not valid', |
|
| 34 | - 'avis_attention' => 'CAUTION!', |
|
| 35 | - 'avis_champ_incorrect_type_objet' => 'Invalid field name @name@ for object of type @type@', |
|
| 36 | - 'avis_colonne_inexistante' => 'Column @col@ does not exist', |
|
| 37 | - 'avis_erreur' => 'Error: see below', |
|
| 38 | - 'avis_erreur_connexion' => 'Connection error', |
|
| 39 | - 'avis_erreur_cookie' => 'cookie problem', |
|
| 40 | - 'avis_erreur_fonction_contexte' => 'Programming error. This function cannot be called in this context.', |
|
| 41 | - 'avis_erreur_mysql' => 'SQL error', |
|
| 42 | - 'avis_erreur_sauvegarde' => 'Error in backup (@type@ @id_objet@)!', |
|
| 43 | - 'avis_erreur_visiteur' => 'Problem entering the private area', |
|
| 44 | - 'avis_nb_erreurs_saisie' => 'Your entry contains @nb@ errors, please check your information.', |
|
| 12 | + // A |
|
| 13 | + 'access_interface_graphique' => 'Back to the full graphic interface', |
|
| 14 | + 'access_mode_texte' => 'Show the simplified text interface', |
|
| 15 | + 'admin_debug' => 'debug', |
|
| 16 | + 'admin_modifier_article' => 'Modify this article', |
|
| 17 | + 'admin_modifier_auteur' => 'Modify this author', |
|
| 18 | + 'admin_modifier_breve' => 'Modify this news item', |
|
| 19 | + 'admin_modifier_mot' => 'Modify this keyword', |
|
| 20 | + 'admin_modifier_rubrique' => 'Modify this section', |
|
| 21 | + 'admin_recalculer' => 'Re-process this page', |
|
| 22 | + 'afficher_calendrier' => 'Show the calendar', |
|
| 23 | + 'afficher_trad' => 'show translations', |
|
| 24 | + 'alerte_maj_impossible' => '<b>Warning!</b> Failed to update the SQL database to version @version@. This may be due to a permissions problem on the database. Please contact your ISP.', |
|
| 25 | + 'alerte_modif_info_concourante' => 'WARNING: This information has been modified elsewhere. The current value is :', |
|
| 26 | + 'analyse_xml' => 'XML parsing', |
|
| 27 | + 'annuler' => 'Cancel', |
|
| 28 | + 'antispam_champ_vide' => 'Please leave this field empty:', |
|
| 29 | + 'articles_recents' => 'Most recent articles', |
|
| 30 | + 'attention_champ_mini_nb_caractères' => 'Warning! At least @nb@ characters', |
|
| 31 | + 'avis_1_erreur_saisie' => 'Your entry contains an error, please check your information.', |
|
| 32 | + 'avis_archive_incorrect' => 'archive is not a valid SPIP file', |
|
| 33 | + 'avis_archive_invalide' => 'archive file is not valid', |
|
| 34 | + 'avis_attention' => 'CAUTION!', |
|
| 35 | + 'avis_champ_incorrect_type_objet' => 'Invalid field name @name@ for object of type @type@', |
|
| 36 | + 'avis_colonne_inexistante' => 'Column @col@ does not exist', |
|
| 37 | + 'avis_erreur' => 'Error: see below', |
|
| 38 | + 'avis_erreur_connexion' => 'Connection error', |
|
| 39 | + 'avis_erreur_cookie' => 'cookie problem', |
|
| 40 | + 'avis_erreur_fonction_contexte' => 'Programming error. This function cannot be called in this context.', |
|
| 41 | + 'avis_erreur_mysql' => 'SQL error', |
|
| 42 | + 'avis_erreur_sauvegarde' => 'Error in backup (@type@ @id_objet@)!', |
|
| 43 | + 'avis_erreur_visiteur' => 'Problem entering the private area', |
|
| 44 | + 'avis_nb_erreurs_saisie' => 'Your entry contains @nb@ errors, please check your information.', |
|
| 45 | 45 | |
| 46 | - // B |
|
| 47 | - 'barre_a_accent_grave' => 'Insert a capital A with grave accent', |
|
| 48 | - 'barre_aide' => 'Use the typographic short cuts to refine your layout', |
|
| 49 | - 'barre_e_accent_aigu' => 'Insert a capital E with acute accent', |
|
| 50 | - 'barre_eo' => 'Insert an oe-ligature', |
|
| 51 | - 'barre_eo_maj' => 'Insert a capital EO-ligature', |
|
| 52 | - 'barre_euro' => 'Insert a € symbol', |
|
| 53 | - 'barre_gras' => 'Put in {{bold type}}', |
|
| 54 | - 'barre_guillemets' => 'Place between "double quotes"', |
|
| 55 | - 'barre_guillemets_simples' => 'Place between ‘single quotes’', |
|
| 56 | - 'barre_intertitre' => 'Turn into a {{{subheading}}}', |
|
| 57 | - 'barre_italic' => 'Put in {italics}', |
|
| 58 | - 'barre_lien' => 'Turn into a [hyperlink->http://...]', |
|
| 59 | - 'barre_lien_input' => 'Please enter the link address. You may use either an external URL (http://www.mysite.com) or reference another article on this site by simplying entering its number.', |
|
| 60 | - 'barre_note' => 'Turn into a [[Footnote]]', |
|
| 61 | - 'barre_paragraphe' => 'Create a paragraph', |
|
| 62 | - 'barre_quote' => '<quote>Quote a message</quote>', |
|
| 63 | - 'bouton_changer' => 'Change', |
|
| 64 | - 'bouton_chercher' => 'Search', |
|
| 65 | - 'bouton_choisir' => 'Select', |
|
| 66 | - 'bouton_deplacer' => 'Move', |
|
| 67 | - 'bouton_download' => 'Download', |
|
| 68 | - 'bouton_enregistrer' => 'Save', |
|
| 69 | - 'bouton_radio_desactiver_messagerie_interne' => 'Disable internal messaging', |
|
| 70 | - 'bouton_radio_envoi_annonces' => 'Send editorial announcements', |
|
| 71 | - 'bouton_radio_non_envoi_annonces' => 'Do not send any announcements', |
|
| 72 | - 'bouton_radio_non_envoi_liste_nouveautes' => 'Do not send latest news list', |
|
| 73 | - 'bouton_recharger_page' => 'reload this page', |
|
| 74 | - 'bouton_telecharger' => 'Upload', |
|
| 75 | - 'bouton_upload' => 'Upload', |
|
| 76 | - 'bouton_valider' => 'Submit', |
|
| 46 | + // B |
|
| 47 | + 'barre_a_accent_grave' => 'Insert a capital A with grave accent', |
|
| 48 | + 'barre_aide' => 'Use the typographic short cuts to refine your layout', |
|
| 49 | + 'barre_e_accent_aigu' => 'Insert a capital E with acute accent', |
|
| 50 | + 'barre_eo' => 'Insert an oe-ligature', |
|
| 51 | + 'barre_eo_maj' => 'Insert a capital EO-ligature', |
|
| 52 | + 'barre_euro' => 'Insert a € symbol', |
|
| 53 | + 'barre_gras' => 'Put in {{bold type}}', |
|
| 54 | + 'barre_guillemets' => 'Place between "double quotes"', |
|
| 55 | + 'barre_guillemets_simples' => 'Place between ‘single quotes’', |
|
| 56 | + 'barre_intertitre' => 'Turn into a {{{subheading}}}', |
|
| 57 | + 'barre_italic' => 'Put in {italics}', |
|
| 58 | + 'barre_lien' => 'Turn into a [hyperlink->http://...]', |
|
| 59 | + 'barre_lien_input' => 'Please enter the link address. You may use either an external URL (http://www.mysite.com) or reference another article on this site by simplying entering its number.', |
|
| 60 | + 'barre_note' => 'Turn into a [[Footnote]]', |
|
| 61 | + 'barre_paragraphe' => 'Create a paragraph', |
|
| 62 | + 'barre_quote' => '<quote>Quote a message</quote>', |
|
| 63 | + 'bouton_changer' => 'Change', |
|
| 64 | + 'bouton_chercher' => 'Search', |
|
| 65 | + 'bouton_choisir' => 'Select', |
|
| 66 | + 'bouton_deplacer' => 'Move', |
|
| 67 | + 'bouton_download' => 'Download', |
|
| 68 | + 'bouton_enregistrer' => 'Save', |
|
| 69 | + 'bouton_radio_desactiver_messagerie_interne' => 'Disable internal messaging', |
|
| 70 | + 'bouton_radio_envoi_annonces' => 'Send editorial announcements', |
|
| 71 | + 'bouton_radio_non_envoi_annonces' => 'Do not send any announcements', |
|
| 72 | + 'bouton_radio_non_envoi_liste_nouveautes' => 'Do not send latest news list', |
|
| 73 | + 'bouton_recharger_page' => 'reload this page', |
|
| 74 | + 'bouton_telecharger' => 'Upload', |
|
| 75 | + 'bouton_upload' => 'Upload', |
|
| 76 | + 'bouton_valider' => 'Submit', |
|
| 77 | 77 | |
| 78 | - // C |
|
| 79 | - 'cal_apresmidi' => 'afternoon (p.m.)', |
|
| 80 | - 'cal_jour_entier' => 'entire day', |
|
| 81 | - 'cal_matin' => 'morning (a.m.)', |
|
| 82 | - 'cal_par_jour' => 'daily calendar', |
|
| 83 | - 'cal_par_mois' => 'monthly calendar', |
|
| 84 | - 'cal_par_semaine' => 'weekly calendar', |
|
| 85 | - 'choix_couleur_interface' => 'colour', |
|
| 86 | - 'choix_interface' => 'choice of interface', |
|
| 87 | - 'colonne' => 'Column', |
|
| 88 | - 'confirm_changer_statut' => 'Warning: You are about to change this article’s status. Do you wish to continue?', |
|
| 89 | - 'correcte' => 'correct', |
|
| 78 | + // C |
|
| 79 | + 'cal_apresmidi' => 'afternoon (p.m.)', |
|
| 80 | + 'cal_jour_entier' => 'entire day', |
|
| 81 | + 'cal_matin' => 'morning (a.m.)', |
|
| 82 | + 'cal_par_jour' => 'daily calendar', |
|
| 83 | + 'cal_par_mois' => 'monthly calendar', |
|
| 84 | + 'cal_par_semaine' => 'weekly calendar', |
|
| 85 | + 'choix_couleur_interface' => 'colour', |
|
| 86 | + 'choix_interface' => 'choice of interface', |
|
| 87 | + 'colonne' => 'Column', |
|
| 88 | + 'confirm_changer_statut' => 'Warning: You are about to change this article’s status. Do you wish to continue?', |
|
| 89 | + 'correcte' => 'correct', |
|
| 90 | 90 | |
| 91 | - // D |
|
| 92 | - 'date_aujourdhui' => 'today', |
|
| 93 | - 'date_avant_jc' => 'B.C.', |
|
| 94 | - 'date_dans' => 'in @delai@', |
|
| 95 | - 'date_de_mois_1' => '@j@ @nommois@', |
|
| 96 | - 'date_de_mois_10' => '@j@ @nommois@', |
|
| 97 | - 'date_de_mois_11' => '@j@ @nommois@', |
|
| 98 | - 'date_de_mois_12' => '@j@ @nommois@', |
|
| 99 | - 'date_de_mois_2' => '@j@ @nommois@', |
|
| 100 | - 'date_de_mois_3' => '@j@ @nommois@', |
|
| 101 | - 'date_de_mois_4' => '@j@ @nommois@', |
|
| 102 | - 'date_de_mois_5' => '@j@ @nommois@', |
|
| 103 | - 'date_de_mois_6' => '@j@ @nommois@', |
|
| 104 | - 'date_de_mois_7' => '@j@ @nommois@', |
|
| 105 | - 'date_de_mois_8' => '@j@ @nommois@', |
|
| 106 | - 'date_de_mois_9' => '@j@ @nommois@', |
|
| 107 | - 'date_demain' => 'tomorrow', |
|
| 108 | - 'date_fmt_heures_minutes' => '@h@:@m@', |
|
| 109 | - 'date_fmt_heures_minutes_court' => '@h@:@m@', |
|
| 110 | - 'date_fmt_jour' => '@nomjour@ @jour@', |
|
| 111 | - 'date_fmt_jour_heure' => '@jour@ at @heure@', |
|
| 112 | - 'date_fmt_jour_heure_debut_fin' => '@jour@ from @heure_debut@ to @heure_fin@', |
|
| 113 | - 'date_fmt_jour_heure_debut_fin_abbr' => '@dtstart@@jour@ from @heure_debut@@dtabbr@ to @dtend@@heure_fin@@dtabbr@', |
|
| 114 | - 'date_fmt_jour_mois' => '@jourmois@', |
|
| 115 | - 'date_fmt_jour_mois_annee' => '@jourmois@ @annee@', |
|
| 116 | - 'date_fmt_mois_annee' => '@nommois@ @annee@', |
|
| 117 | - 'date_fmt_nomjour' => '@nomjour@ @date@', |
|
| 118 | - 'date_fmt_nomjour_date' => 'on @nomjour@ @date@', |
|
| 119 | - 'date_fmt_periode' => 'From @date_debut@ to @date_fin@', |
|
| 120 | - 'date_fmt_periode_abbr' => 'From @dtart@@date_debut@@dtabbr@ to @dtend@@date_fin@@dtabbr@', |
|
| 121 | - 'date_fmt_periode_from' => 'From', |
|
| 122 | - 'date_fmt_periode_to' => 'to', |
|
| 123 | - 'date_fmt_saison_annee' => '@saison@ @annee@', |
|
| 124 | - 'date_heures' => 'hours', |
|
| 125 | - 'date_hier' => 'yesterday', |
|
| 126 | - 'date_il_y_a' => '@delai@ ago', |
|
| 127 | - 'date_jnum1' => '1', |
|
| 128 | - 'date_jnum10' => '10', |
|
| 129 | - 'date_jnum11' => '11', |
|
| 130 | - 'date_jnum12' => '12', |
|
| 131 | - 'date_jnum13' => '13', |
|
| 132 | - 'date_jnum14' => '14', |
|
| 133 | - 'date_jnum15' => '15', |
|
| 134 | - 'date_jnum16' => '16', |
|
| 135 | - 'date_jnum17' => '17', |
|
| 136 | - 'date_jnum18' => '18', |
|
| 137 | - 'date_jnum19' => '19', |
|
| 138 | - 'date_jnum2' => '2', |
|
| 139 | - 'date_jnum20' => '20', |
|
| 140 | - 'date_jnum21' => '21', |
|
| 141 | - 'date_jnum22' => '22', |
|
| 142 | - 'date_jnum23' => '23', |
|
| 143 | - 'date_jnum24' => '24', |
|
| 144 | - 'date_jnum25' => '25', |
|
| 145 | - 'date_jnum26' => '26', |
|
| 146 | - 'date_jnum27' => '27', |
|
| 147 | - 'date_jnum28' => '28', |
|
| 148 | - 'date_jnum29' => '29', |
|
| 149 | - 'date_jnum3' => '3', |
|
| 150 | - 'date_jnum30' => '30', |
|
| 151 | - 'date_jnum31' => '31', |
|
| 152 | - 'date_jnum4' => '4', |
|
| 153 | - 'date_jnum5' => '5', |
|
| 154 | - 'date_jnum6' => '6', |
|
| 155 | - 'date_jnum7' => '7', |
|
| 156 | - 'date_jnum8' => '8', |
|
| 157 | - 'date_jnum9' => '9', |
|
| 158 | - 'date_jour_1' => 'Sunday', |
|
| 159 | - 'date_jour_1_abbr' => 'Sun.', |
|
| 160 | - 'date_jour_1_initiale' => 'S.', |
|
| 161 | - 'date_jour_2' => 'Monday', |
|
| 162 | - 'date_jour_2_abbr' => 'Mon.', |
|
| 163 | - 'date_jour_2_initiale' => 'M.', |
|
| 164 | - 'date_jour_3' => 'Tuesday', |
|
| 165 | - 'date_jour_3_abbr' => 'Tue.', |
|
| 166 | - 'date_jour_3_initiale' => 'T.', |
|
| 167 | - 'date_jour_4' => 'Wednesday', |
|
| 168 | - 'date_jour_4_abbr' => 'Wed.', |
|
| 169 | - 'date_jour_4_initiale' => 'W.', |
|
| 170 | - 'date_jour_5' => 'Thursday', |
|
| 171 | - 'date_jour_5_abbr' => 'Thu.', |
|
| 172 | - 'date_jour_5_initiale' => 'T.', |
|
| 173 | - 'date_jour_6' => 'Friday', |
|
| 174 | - 'date_jour_6_abbr' => 'Fri.', |
|
| 175 | - 'date_jour_6_initiale' => 'F.', |
|
| 176 | - 'date_jour_7' => 'Saturday', |
|
| 177 | - 'date_jour_7_abbr' => 'Sat.', |
|
| 178 | - 'date_jour_7_initiale' => 'S.', |
|
| 179 | - 'date_jours' => 'days', |
|
| 180 | - 'date_minutes' => 'minutes', |
|
| 181 | - 'date_mois' => 'months', |
|
| 182 | - 'date_mois_1' => 'January', |
|
| 183 | - 'date_mois_10' => 'October', |
|
| 184 | - 'date_mois_10_abbr' => 'Oct', |
|
| 185 | - 'date_mois_11' => 'November', |
|
| 186 | - 'date_mois_11_abbr' => 'Nov', |
|
| 187 | - 'date_mois_12' => 'December', |
|
| 188 | - 'date_mois_12_abbr' => 'Dec', |
|
| 189 | - 'date_mois_1_abbr' => 'Jan', |
|
| 190 | - 'date_mois_2' => 'February', |
|
| 191 | - 'date_mois_2_abbr' => 'Feb', |
|
| 192 | - 'date_mois_3' => 'March', |
|
| 193 | - 'date_mois_3_abbr' => 'Mar', |
|
| 194 | - 'date_mois_4' => 'April', |
|
| 195 | - 'date_mois_4_abbr' => 'Apr', |
|
| 196 | - 'date_mois_5' => 'May', |
|
| 197 | - 'date_mois_5_abbr' => 'May', |
|
| 198 | - 'date_mois_6' => 'June', |
|
| 199 | - 'date_mois_6_abbr' => 'Jun', |
|
| 200 | - 'date_mois_7' => 'July', |
|
| 201 | - 'date_mois_7_abbr' => 'Jul', |
|
| 202 | - 'date_mois_8' => 'August', |
|
| 203 | - 'date_mois_8_abbr' => 'Aug', |
|
| 204 | - 'date_mois_9' => 'September', |
|
| 205 | - 'date_mois_9_abbr' => 'Sep', |
|
| 206 | - 'date_saison_1' => 'winter', |
|
| 207 | - 'date_saison_2' => 'spring', |
|
| 208 | - 'date_saison_3' => 'summer', |
|
| 209 | - 'date_saison_4' => 'autumn', |
|
| 210 | - 'date_secondes' => 'seconds', |
|
| 211 | - 'date_semaines' => 'weeks', |
|
| 212 | - 'date_un_mois' => 'month', |
|
| 213 | - 'date_une_heure' => 'hour', |
|
| 214 | - 'date_une_minute' => 'minute', |
|
| 215 | - 'date_une_seconde' => 'second', |
|
| 216 | - 'date_une_semaine' => 'week', |
|
| 217 | - 'dirs_commencer' => ' in order to start installation for real', |
|
| 218 | - 'dirs_preliminaire' => 'Preliminary: <b>Setting up access permissions</b>', |
|
| 219 | - 'dirs_probleme_droits' => 'Problem with access permissions', |
|
| 220 | - 'dirs_repertoires_absents' => '<p><b>The following directories were not found: </b></p><ul>@bad_dirs@.</ul> |
|
| 91 | + // D |
|
| 92 | + 'date_aujourdhui' => 'today', |
|
| 93 | + 'date_avant_jc' => 'B.C.', |
|
| 94 | + 'date_dans' => 'in @delai@', |
|
| 95 | + 'date_de_mois_1' => '@j@ @nommois@', |
|
| 96 | + 'date_de_mois_10' => '@j@ @nommois@', |
|
| 97 | + 'date_de_mois_11' => '@j@ @nommois@', |
|
| 98 | + 'date_de_mois_12' => '@j@ @nommois@', |
|
| 99 | + 'date_de_mois_2' => '@j@ @nommois@', |
|
| 100 | + 'date_de_mois_3' => '@j@ @nommois@', |
|
| 101 | + 'date_de_mois_4' => '@j@ @nommois@', |
|
| 102 | + 'date_de_mois_5' => '@j@ @nommois@', |
|
| 103 | + 'date_de_mois_6' => '@j@ @nommois@', |
|
| 104 | + 'date_de_mois_7' => '@j@ @nommois@', |
|
| 105 | + 'date_de_mois_8' => '@j@ @nommois@', |
|
| 106 | + 'date_de_mois_9' => '@j@ @nommois@', |
|
| 107 | + 'date_demain' => 'tomorrow', |
|
| 108 | + 'date_fmt_heures_minutes' => '@h@:@m@', |
|
| 109 | + 'date_fmt_heures_minutes_court' => '@h@:@m@', |
|
| 110 | + 'date_fmt_jour' => '@nomjour@ @jour@', |
|
| 111 | + 'date_fmt_jour_heure' => '@jour@ at @heure@', |
|
| 112 | + 'date_fmt_jour_heure_debut_fin' => '@jour@ from @heure_debut@ to @heure_fin@', |
|
| 113 | + 'date_fmt_jour_heure_debut_fin_abbr' => '@dtstart@@jour@ from @heure_debut@@dtabbr@ to @dtend@@heure_fin@@dtabbr@', |
|
| 114 | + 'date_fmt_jour_mois' => '@jourmois@', |
|
| 115 | + 'date_fmt_jour_mois_annee' => '@jourmois@ @annee@', |
|
| 116 | + 'date_fmt_mois_annee' => '@nommois@ @annee@', |
|
| 117 | + 'date_fmt_nomjour' => '@nomjour@ @date@', |
|
| 118 | + 'date_fmt_nomjour_date' => 'on @nomjour@ @date@', |
|
| 119 | + 'date_fmt_periode' => 'From @date_debut@ to @date_fin@', |
|
| 120 | + 'date_fmt_periode_abbr' => 'From @dtart@@date_debut@@dtabbr@ to @dtend@@date_fin@@dtabbr@', |
|
| 121 | + 'date_fmt_periode_from' => 'From', |
|
| 122 | + 'date_fmt_periode_to' => 'to', |
|
| 123 | + 'date_fmt_saison_annee' => '@saison@ @annee@', |
|
| 124 | + 'date_heures' => 'hours', |
|
| 125 | + 'date_hier' => 'yesterday', |
|
| 126 | + 'date_il_y_a' => '@delai@ ago', |
|
| 127 | + 'date_jnum1' => '1', |
|
| 128 | + 'date_jnum10' => '10', |
|
| 129 | + 'date_jnum11' => '11', |
|
| 130 | + 'date_jnum12' => '12', |
|
| 131 | + 'date_jnum13' => '13', |
|
| 132 | + 'date_jnum14' => '14', |
|
| 133 | + 'date_jnum15' => '15', |
|
| 134 | + 'date_jnum16' => '16', |
|
| 135 | + 'date_jnum17' => '17', |
|
| 136 | + 'date_jnum18' => '18', |
|
| 137 | + 'date_jnum19' => '19', |
|
| 138 | + 'date_jnum2' => '2', |
|
| 139 | + 'date_jnum20' => '20', |
|
| 140 | + 'date_jnum21' => '21', |
|
| 141 | + 'date_jnum22' => '22', |
|
| 142 | + 'date_jnum23' => '23', |
|
| 143 | + 'date_jnum24' => '24', |
|
| 144 | + 'date_jnum25' => '25', |
|
| 145 | + 'date_jnum26' => '26', |
|
| 146 | + 'date_jnum27' => '27', |
|
| 147 | + 'date_jnum28' => '28', |
|
| 148 | + 'date_jnum29' => '29', |
|
| 149 | + 'date_jnum3' => '3', |
|
| 150 | + 'date_jnum30' => '30', |
|
| 151 | + 'date_jnum31' => '31', |
|
| 152 | + 'date_jnum4' => '4', |
|
| 153 | + 'date_jnum5' => '5', |
|
| 154 | + 'date_jnum6' => '6', |
|
| 155 | + 'date_jnum7' => '7', |
|
| 156 | + 'date_jnum8' => '8', |
|
| 157 | + 'date_jnum9' => '9', |
|
| 158 | + 'date_jour_1' => 'Sunday', |
|
| 159 | + 'date_jour_1_abbr' => 'Sun.', |
|
| 160 | + 'date_jour_1_initiale' => 'S.', |
|
| 161 | + 'date_jour_2' => 'Monday', |
|
| 162 | + 'date_jour_2_abbr' => 'Mon.', |
|
| 163 | + 'date_jour_2_initiale' => 'M.', |
|
| 164 | + 'date_jour_3' => 'Tuesday', |
|
| 165 | + 'date_jour_3_abbr' => 'Tue.', |
|
| 166 | + 'date_jour_3_initiale' => 'T.', |
|
| 167 | + 'date_jour_4' => 'Wednesday', |
|
| 168 | + 'date_jour_4_abbr' => 'Wed.', |
|
| 169 | + 'date_jour_4_initiale' => 'W.', |
|
| 170 | + 'date_jour_5' => 'Thursday', |
|
| 171 | + 'date_jour_5_abbr' => 'Thu.', |
|
| 172 | + 'date_jour_5_initiale' => 'T.', |
|
| 173 | + 'date_jour_6' => 'Friday', |
|
| 174 | + 'date_jour_6_abbr' => 'Fri.', |
|
| 175 | + 'date_jour_6_initiale' => 'F.', |
|
| 176 | + 'date_jour_7' => 'Saturday', |
|
| 177 | + 'date_jour_7_abbr' => 'Sat.', |
|
| 178 | + 'date_jour_7_initiale' => 'S.', |
|
| 179 | + 'date_jours' => 'days', |
|
| 180 | + 'date_minutes' => 'minutes', |
|
| 181 | + 'date_mois' => 'months', |
|
| 182 | + 'date_mois_1' => 'January', |
|
| 183 | + 'date_mois_10' => 'October', |
|
| 184 | + 'date_mois_10_abbr' => 'Oct', |
|
| 185 | + 'date_mois_11' => 'November', |
|
| 186 | + 'date_mois_11_abbr' => 'Nov', |
|
| 187 | + 'date_mois_12' => 'December', |
|
| 188 | + 'date_mois_12_abbr' => 'Dec', |
|
| 189 | + 'date_mois_1_abbr' => 'Jan', |
|
| 190 | + 'date_mois_2' => 'February', |
|
| 191 | + 'date_mois_2_abbr' => 'Feb', |
|
| 192 | + 'date_mois_3' => 'March', |
|
| 193 | + 'date_mois_3_abbr' => 'Mar', |
|
| 194 | + 'date_mois_4' => 'April', |
|
| 195 | + 'date_mois_4_abbr' => 'Apr', |
|
| 196 | + 'date_mois_5' => 'May', |
|
| 197 | + 'date_mois_5_abbr' => 'May', |
|
| 198 | + 'date_mois_6' => 'June', |
|
| 199 | + 'date_mois_6_abbr' => 'Jun', |
|
| 200 | + 'date_mois_7' => 'July', |
|
| 201 | + 'date_mois_7_abbr' => 'Jul', |
|
| 202 | + 'date_mois_8' => 'August', |
|
| 203 | + 'date_mois_8_abbr' => 'Aug', |
|
| 204 | + 'date_mois_9' => 'September', |
|
| 205 | + 'date_mois_9_abbr' => 'Sep', |
|
| 206 | + 'date_saison_1' => 'winter', |
|
| 207 | + 'date_saison_2' => 'spring', |
|
| 208 | + 'date_saison_3' => 'summer', |
|
| 209 | + 'date_saison_4' => 'autumn', |
|
| 210 | + 'date_secondes' => 'seconds', |
|
| 211 | + 'date_semaines' => 'weeks', |
|
| 212 | + 'date_un_mois' => 'month', |
|
| 213 | + 'date_une_heure' => 'hour', |
|
| 214 | + 'date_une_minute' => 'minute', |
|
| 215 | + 'date_une_seconde' => 'second', |
|
| 216 | + 'date_une_semaine' => 'week', |
|
| 217 | + 'dirs_commencer' => ' in order to start installation for real', |
|
| 218 | + 'dirs_preliminaire' => 'Preliminary: <b>Setting up access permissions</b>', |
|
| 219 | + 'dirs_probleme_droits' => 'Problem with access permissions', |
|
| 220 | + 'dirs_repertoires_absents' => '<p><b>The following directories were not found: </b></p><ul>@bad_dirs@.</ul> |
|
| 221 | 221 | <p>It is possible that this is due to inappropriate lower or upper case letters in directory names. |
| 222 | 222 | Please check that the case of the letters in the names of these directories match what is displayed |
| 223 | 223 | above. If they don’t, correct the directory names using your FTP client.</p> |
| 224 | 224 | <p>Once this is done, you can', |
| 225 | - 'dirs_repertoires_suivants' => '<p><b>The following directories do not have write permission: </b></p><ul>@bad_dirs@</ul> |
|
| 225 | + 'dirs_repertoires_suivants' => '<p><b>The following directories do not have write permission: </b></p><ul>@bad_dirs@</ul> |
|
| 226 | 226 | <p>To change this, use your FTP client to set access permissions for each |
| 227 | 227 | of these directories. The procedure is detailed in the installation guide.</p> |
| 228 | 228 | <p>Once you have done this, you can ', |
| 229 | - 'double_occurrence' => 'Two instances of @balise@', |
|
| 229 | + 'double_occurrence' => 'Two instances of @balise@', |
|
| 230 | 230 | |
| 231 | - // E |
|
| 232 | - 'en_cours' => 'processing', |
|
| 233 | - 'envoi_via_le_site' => 'Sent via the site', |
|
| 234 | - 'erreur' => 'Error', |
|
| 235 | - 'erreur_balise_non_fermee' => 'last tag not closed:', |
|
| 236 | - 'erreur_technique_ajaxform' => 'Ooops. An unexpected error prevented to submit the form. You can try again.', |
|
| 237 | - 'erreur_technique_enregistrement_champs' => 'A technical error prevented the right registration of the field @champs@.', |
|
| 238 | - 'erreur_technique_enregistrement_impossible' => 'A technical error prevented the registration.', |
|
| 239 | - 'erreur_texte' => 'error(s)', |
|
| 240 | - 'etape' => 'Step', |
|
| 231 | + // E |
|
| 232 | + 'en_cours' => 'processing', |
|
| 233 | + 'envoi_via_le_site' => 'Sent via the site', |
|
| 234 | + 'erreur' => 'Error', |
|
| 235 | + 'erreur_balise_non_fermee' => 'last tag not closed:', |
|
| 236 | + 'erreur_technique_ajaxform' => 'Ooops. An unexpected error prevented to submit the form. You can try again.', |
|
| 237 | + 'erreur_technique_enregistrement_champs' => 'A technical error prevented the right registration of the field @champs@.', |
|
| 238 | + 'erreur_technique_enregistrement_impossible' => 'A technical error prevented the registration.', |
|
| 239 | + 'erreur_texte' => 'error(s)', |
|
| 240 | + 'etape' => 'Step', |
|
| 241 | 241 | |
| 242 | - // F |
|
| 243 | - 'fichier_introuvable' => 'File not found: @fichier@', |
|
| 244 | - 'fonction_introuvable' => 'Function @fonction@() not found.', |
|
| 245 | - 'form_auteur_confirmation' => 'Please confirm your email address', |
|
| 246 | - 'form_auteur_email_modifie' => 'Your email address has been changed.', |
|
| 247 | - 'form_auteur_envoi_mail_confirmation' => 'A confirmation email has been sent to @email@. You must visit the URL mentioned in the message to validate your email address.', |
|
| 248 | - 'form_auteur_mail_confirmation' => 'Hello, |
|
| 242 | + // F |
|
| 243 | + 'fichier_introuvable' => 'File not found: @fichier@', |
|
| 244 | + 'fonction_introuvable' => 'Function @fonction@() not found.', |
|
| 245 | + 'form_auteur_confirmation' => 'Please confirm your email address', |
|
| 246 | + 'form_auteur_email_modifie' => 'Your email address has been changed.', |
|
| 247 | + 'form_auteur_envoi_mail_confirmation' => 'A confirmation email has been sent to @email@. You must visit the URL mentioned in the message to validate your email address.', |
|
| 248 | + 'form_auteur_mail_confirmation' => 'Hello, |
|
| 249 | 249 | |
| 250 | 250 | You have asked to change your email address. |
| 251 | 251 | To confirm your new address, you need to connect to |
@@ -253,347 +253,347 @@ discard block |
||
| 253 | 253 | |
| 254 | 254 | @url@ |
| 255 | 255 | ', |
| 256 | - 'form_deja_inscrit' => 'You are already registered.', |
|
| 257 | - 'form_email_non_valide' => 'Your email address is not valid.', |
|
| 258 | - 'form_forum_access_refuse' => 'You no longer have access to this site.', |
|
| 259 | - 'form_forum_bonjour' => 'Hello @nom@,', |
|
| 260 | - 'form_forum_confirmer_email' => 'To confirm your email address, follow this link: @url_confirm@', |
|
| 261 | - 'form_forum_email_deja_enregistre' => 'This email address is already registered. Enter your usual password.', |
|
| 262 | - 'form_forum_identifiant_mail' => 'Your new identifier has just been emailed to you.', |
|
| 263 | - 'form_forum_identifiants' => 'Personal identifiers', |
|
| 264 | - 'form_forum_indiquer_nom_email' => 'Enter your name and email address here. You will receive your personal identifier shortly by email.', |
|
| 265 | - 'form_forum_login' => 'login:', |
|
| 266 | - 'form_forum_message_auto' => '(this is an automated message)', |
|
| 267 | - 'form_forum_pass' => 'password:', |
|
| 268 | - 'form_forum_probleme_mail' => 'Mail problem: the identifier could not be sent.', |
|
| 269 | - 'form_forum_voici1' => 'Here are your identifiers. You may now participate on the site |
|
| 256 | + 'form_deja_inscrit' => 'You are already registered.', |
|
| 257 | + 'form_email_non_valide' => 'Your email address is not valid.', |
|
| 258 | + 'form_forum_access_refuse' => 'You no longer have access to this site.', |
|
| 259 | + 'form_forum_bonjour' => 'Hello @nom@,', |
|
| 260 | + 'form_forum_confirmer_email' => 'To confirm your email address, follow this link: @url_confirm@', |
|
| 261 | + 'form_forum_email_deja_enregistre' => 'This email address is already registered. Enter your usual password.', |
|
| 262 | + 'form_forum_identifiant_mail' => 'Your new identifier has just been emailed to you.', |
|
| 263 | + 'form_forum_identifiants' => 'Personal identifiers', |
|
| 264 | + 'form_forum_indiquer_nom_email' => 'Enter your name and email address here. You will receive your personal identifier shortly by email.', |
|
| 265 | + 'form_forum_login' => 'login:', |
|
| 266 | + 'form_forum_message_auto' => '(this is an automated message)', |
|
| 267 | + 'form_forum_pass' => 'password:', |
|
| 268 | + 'form_forum_probleme_mail' => 'Mail problem: the identifier could not be sent.', |
|
| 269 | + 'form_forum_voici1' => 'Here are your identifiers. You may now participate on the site |
|
| 270 | 270 | "@nom_site_spip@" (@adresse_site@):', |
| 271 | - 'form_forum_voici2' => 'Here are your identifiers for submitting articles to |
|
| 271 | + 'form_forum_voici2' => 'Here are your identifiers for submitting articles to |
|
| 272 | 272 | the site "@nom_site_spip@" (@adresse_login@):', |
| 273 | - 'form_indiquer_email' => 'Please enter your email address.', |
|
| 274 | - 'form_indiquer_nom' => 'Please enter your name.', |
|
| 275 | - 'form_indiquer_nom_site' => 'Please enter the name of your site.', |
|
| 276 | - 'form_pet_deja_enregistre' => 'This site is already registered', |
|
| 277 | - 'form_pet_signature_pasprise' => 'Your signature has been ignored.', |
|
| 278 | - 'form_prop_confirmer_envoi' => 'Confirm send', |
|
| 279 | - 'form_prop_description' => 'Description/comment', |
|
| 280 | - 'form_prop_enregistre' => 'Your suggestion has been recorded. It will appear online after being validated by the administrators of this site.', |
|
| 281 | - 'form_prop_envoyer' => 'Send a message', |
|
| 282 | - 'form_prop_indiquer_email' => 'Please enter a valid email address', |
|
| 283 | - 'form_prop_indiquer_nom_site' => 'Please enter the site’s name.', |
|
| 284 | - 'form_prop_indiquer_sujet' => 'Please enter a subject', |
|
| 285 | - 'form_prop_message_envoye' => 'Message sent', |
|
| 286 | - 'form_prop_non_enregistre' => 'Your suggestion has not been recorded.', |
|
| 287 | - 'form_prop_sujet' => 'Subject', |
|
| 288 | - 'form_prop_url_site' => 'Site URL', |
|
| 289 | - 'format_date_attendu' => 'Enter a date in jj/mm/aaaa format.', |
|
| 290 | - 'format_date_incorrecte' => 'The date or its format is incorrect.', |
|
| 291 | - 'format_heure_attendu' => 'Enter a time in hh:mm format.', |
|
| 292 | - 'format_heure_incorrecte' => 'The hour or its format is incorrect.', |
|
| 293 | - 'forum_non_inscrit' => 'Either you are not registered, or the address or password are wrong.', |
|
| 294 | - 'forum_par_auteur' => 'by @auteur@', |
|
| 295 | - 'forum_titre_erreur' => 'Error...', |
|
| 273 | + 'form_indiquer_email' => 'Please enter your email address.', |
|
| 274 | + 'form_indiquer_nom' => 'Please enter your name.', |
|
| 275 | + 'form_indiquer_nom_site' => 'Please enter the name of your site.', |
|
| 276 | + 'form_pet_deja_enregistre' => 'This site is already registered', |
|
| 277 | + 'form_pet_signature_pasprise' => 'Your signature has been ignored.', |
|
| 278 | + 'form_prop_confirmer_envoi' => 'Confirm send', |
|
| 279 | + 'form_prop_description' => 'Description/comment', |
|
| 280 | + 'form_prop_enregistre' => 'Your suggestion has been recorded. It will appear online after being validated by the administrators of this site.', |
|
| 281 | + 'form_prop_envoyer' => 'Send a message', |
|
| 282 | + 'form_prop_indiquer_email' => 'Please enter a valid email address', |
|
| 283 | + 'form_prop_indiquer_nom_site' => 'Please enter the site’s name.', |
|
| 284 | + 'form_prop_indiquer_sujet' => 'Please enter a subject', |
|
| 285 | + 'form_prop_message_envoye' => 'Message sent', |
|
| 286 | + 'form_prop_non_enregistre' => 'Your suggestion has not been recorded.', |
|
| 287 | + 'form_prop_sujet' => 'Subject', |
|
| 288 | + 'form_prop_url_site' => 'Site URL', |
|
| 289 | + 'format_date_attendu' => 'Enter a date in jj/mm/aaaa format.', |
|
| 290 | + 'format_date_incorrecte' => 'The date or its format is incorrect.', |
|
| 291 | + 'format_heure_attendu' => 'Enter a time in hh:mm format.', |
|
| 292 | + 'format_heure_incorrecte' => 'The hour or its format is incorrect.', |
|
| 293 | + 'forum_non_inscrit' => 'Either you are not registered, or the address or password are wrong.', |
|
| 294 | + 'forum_par_auteur' => 'by @auteur@', |
|
| 295 | + 'forum_titre_erreur' => 'Error...', |
|
| 296 | 296 | |
| 297 | - // I |
|
| 298 | - 'ical_texte_rss_articles' => 'The site’s backend file for articles is:', |
|
| 299 | - 'ical_texte_rss_articles2' => 'You can also get backend files for individual sections on the site:', |
|
| 300 | - 'ical_texte_rss_breves' => 'Furthermore, there is a file containing the site’s news items. By selecting a section number, you can choose to get news items in that section only.', |
|
| 301 | - 'icone_a_suivre' => 'Launch pad', |
|
| 302 | - 'icone_admin_site' => 'Site administration', |
|
| 303 | - 'icone_agenda' => 'Calendar', |
|
| 304 | - 'icone_aide_ligne' => 'Help', |
|
| 305 | - 'icone_articles' => 'Articles', |
|
| 306 | - 'icone_auteurs' => 'Authors', |
|
| 307 | - 'icone_brouteur' => 'Quick browsing', |
|
| 308 | - 'icone_configuration_site' => 'Configuration', |
|
| 309 | - 'icone_configurer_site' => 'Configure your site', |
|
| 310 | - 'icone_creer_nouvel_auteur' => 'Create a new author', |
|
| 311 | - 'icone_creer_rubrique' => 'Create a section', |
|
| 312 | - 'icone_creer_sous_rubrique' => 'Create a subsection', |
|
| 313 | - 'icone_deconnecter' => 'Log out', |
|
| 314 | - 'icone_discussions' => 'Discussions', |
|
| 315 | - 'icone_doc_rubrique' => 'Documents attached', |
|
| 316 | - 'icone_ecrire_article' => 'Write a new article', |
|
| 317 | - 'icone_edition_site' => 'Edit site', |
|
| 318 | - 'icone_gestion_langues' => 'Language options', |
|
| 319 | - 'icone_informations_personnelles' => 'Personal information', |
|
| 320 | - 'icone_interface_complet' => 'full interface', |
|
| 321 | - 'icone_interface_simple' => 'Simplified interface', |
|
| 322 | - 'icone_maintenance_site' => 'Site maintenance', |
|
| 323 | - 'icone_messagerie_personnelle' => 'Private messages', |
|
| 324 | - 'icone_repartition_debut' => 'Show distribution from the start', |
|
| 325 | - 'icone_rubriques' => 'Sections', |
|
| 326 | - 'icone_sauver_site' => 'Site backup', |
|
| 327 | - 'icone_site_entier' => 'The entire site', |
|
| 328 | - 'icone_sites_references' => 'Referenced sites', |
|
| 329 | - 'icone_statistiques' => 'Site statistics', |
|
| 330 | - 'icone_suivi_activite' => 'Follow site activity', |
|
| 331 | - 'icone_suivi_actualite' => 'Site statistics', |
|
| 332 | - 'icone_suivi_pettions' => 'Manage petitions', |
|
| 333 | - 'icone_suivi_revisions' => 'Article revisions', |
|
| 334 | - 'icone_supprimer_document' => 'Delete this document', |
|
| 335 | - 'icone_supprimer_image' => 'Delete this image', |
|
| 336 | - 'icone_tous_articles' => 'All your articles', |
|
| 337 | - 'icone_tous_auteur' => 'All authors', |
|
| 338 | - 'icone_tous_visiteur' => 'All visitors', |
|
| 339 | - 'icone_visiter_site' => 'View the public site', |
|
| 340 | - 'icone_voir_en_ligne' => 'View online', |
|
| 341 | - 'img_indisponible' => 'image unavailable', |
|
| 342 | - 'impossible' => 'impossible', |
|
| 343 | - 'info_a_suivre' => 'LAUNCH PAD»', |
|
| 344 | - 'info_acces_interdit' => 'Access forbidden', |
|
| 345 | - 'info_acces_refuse' => 'Access denied', |
|
| 346 | - 'info_action' => 'Action: @action@', |
|
| 347 | - 'info_administrer_rubriques' => 'You can manage this section and any subsections', |
|
| 348 | - 'info_adresse_non_indiquee' => 'You did not specify an address to test!', |
|
| 349 | - 'info_aide' => 'HELP:', |
|
| 350 | - 'info_ajouter_mot' => 'Add keyword', |
|
| 351 | - 'info_annonce' => 'ANNOUNCEMENT', |
|
| 352 | - 'info_annonces_generales' => 'General announcements:', |
|
| 353 | - 'info_article_propose' => 'Article submitted', |
|
| 354 | - 'info_article_publie' => 'Article published', |
|
| 355 | - 'info_article_redaction' => 'Article in progress', |
|
| 356 | - 'info_article_refuse' => 'Article rejected', |
|
| 357 | - 'info_article_supprime' => 'Article deleted', |
|
| 358 | - 'info_articles' => 'Articles', |
|
| 359 | - 'info_articles_a_valider' => 'Articles awaiting validation', |
|
| 360 | - 'info_articles_nb' => '@nb@ articles', |
|
| 361 | - 'info_articles_proposes' => 'Articles submitted', |
|
| 362 | - 'info_articles_un' => '1 article', |
|
| 363 | - 'info_auteurs_nombre' => 'author(s):', |
|
| 364 | - 'info_authentification_ftp' => 'Authentication (by FTP).', |
|
| 365 | - 'info_breves_2' => 'news', |
|
| 366 | - 'info_breves_nb' => '@nb@ news items', |
|
| 367 | - 'info_breves_un' => '1 news item', |
|
| 368 | - 'info_connexion_refusee' => 'Connection denied', |
|
| 369 | - 'info_contact_developpeur' => 'Please contact a developer.', |
|
| 370 | - 'info_contenance' => 'This site contains:', |
|
| 371 | - 'info_contribution' => 'contributions', |
|
| 372 | - 'info_copyright' => '@spip@ is free software distributed @lien_gpl@.', |
|
| 373 | - 'info_copyright_doc' => 'For more visit <a href="@spipnet@">@spipnet_affiche@</a>.', |
|
| 374 | - 'info_copyright_gpl' => 'under the GPL license', |
|
| 375 | - 'info_cours_edition' => 'In progress', |
|
| 376 | - 'info_creer_repertoire' => 'Please create a file or a directory called:', |
|
| 377 | - 'info_creer_repertoire_2' => 'inside the sub-directory <b>@repertoire@</b>, then', |
|
| 378 | - 'info_creer_vignette' => 'automatic thumbnail creation', |
|
| 379 | - 'info_creerdansrubrique_non_autorise' => 'You don’t have sufficient rights to create content in this section', |
|
| 380 | - 'info_deplier' => 'Unfold', |
|
| 381 | - 'info_descriptif_nombre' => 'description(s):', |
|
| 382 | - 'info_description' => 'Description:', |
|
| 383 | - 'info_description_2' => 'Description:', |
|
| 384 | - 'info_dimension' => 'Size:', |
|
| 385 | - 'info_documents_nb' => '@nb@ documents', |
|
| 386 | - 'info_documents_un' => '1 document', |
|
| 387 | - 'info_ecire_message_prive' => 'Write a private message', |
|
| 388 | - 'info_email_invalide' => 'Invalid email address.', |
|
| 389 | - 'info_en_cours_validation' => 'Your articles in progress', |
|
| 390 | - 'info_en_ligne' => 'Online now:', |
|
| 391 | - 'info_envoyer_message_prive' => 'Send a private message to this author', |
|
| 392 | - 'info_erreur_requete' => 'Error in query:', |
|
| 393 | - 'info_erreur_squelette2' => 'No <b>@fichier@</b> template available ...', |
|
| 394 | - 'info_erreur_systeme' => 'System error (errno @errsys@)', |
|
| 395 | - 'info_erreur_systeme2' => 'The hard disk may be full or the database damaged. <br /> |
|
| 297 | + // I |
|
| 298 | + 'ical_texte_rss_articles' => 'The site’s backend file for articles is:', |
|
| 299 | + 'ical_texte_rss_articles2' => 'You can also get backend files for individual sections on the site:', |
|
| 300 | + 'ical_texte_rss_breves' => 'Furthermore, there is a file containing the site’s news items. By selecting a section number, you can choose to get news items in that section only.', |
|
| 301 | + 'icone_a_suivre' => 'Launch pad', |
|
| 302 | + 'icone_admin_site' => 'Site administration', |
|
| 303 | + 'icone_agenda' => 'Calendar', |
|
| 304 | + 'icone_aide_ligne' => 'Help', |
|
| 305 | + 'icone_articles' => 'Articles', |
|
| 306 | + 'icone_auteurs' => 'Authors', |
|
| 307 | + 'icone_brouteur' => 'Quick browsing', |
|
| 308 | + 'icone_configuration_site' => 'Configuration', |
|
| 309 | + 'icone_configurer_site' => 'Configure your site', |
|
| 310 | + 'icone_creer_nouvel_auteur' => 'Create a new author', |
|
| 311 | + 'icone_creer_rubrique' => 'Create a section', |
|
| 312 | + 'icone_creer_sous_rubrique' => 'Create a subsection', |
|
| 313 | + 'icone_deconnecter' => 'Log out', |
|
| 314 | + 'icone_discussions' => 'Discussions', |
|
| 315 | + 'icone_doc_rubrique' => 'Documents attached', |
|
| 316 | + 'icone_ecrire_article' => 'Write a new article', |
|
| 317 | + 'icone_edition_site' => 'Edit site', |
|
| 318 | + 'icone_gestion_langues' => 'Language options', |
|
| 319 | + 'icone_informations_personnelles' => 'Personal information', |
|
| 320 | + 'icone_interface_complet' => 'full interface', |
|
| 321 | + 'icone_interface_simple' => 'Simplified interface', |
|
| 322 | + 'icone_maintenance_site' => 'Site maintenance', |
|
| 323 | + 'icone_messagerie_personnelle' => 'Private messages', |
|
| 324 | + 'icone_repartition_debut' => 'Show distribution from the start', |
|
| 325 | + 'icone_rubriques' => 'Sections', |
|
| 326 | + 'icone_sauver_site' => 'Site backup', |
|
| 327 | + 'icone_site_entier' => 'The entire site', |
|
| 328 | + 'icone_sites_references' => 'Referenced sites', |
|
| 329 | + 'icone_statistiques' => 'Site statistics', |
|
| 330 | + 'icone_suivi_activite' => 'Follow site activity', |
|
| 331 | + 'icone_suivi_actualite' => 'Site statistics', |
|
| 332 | + 'icone_suivi_pettions' => 'Manage petitions', |
|
| 333 | + 'icone_suivi_revisions' => 'Article revisions', |
|
| 334 | + 'icone_supprimer_document' => 'Delete this document', |
|
| 335 | + 'icone_supprimer_image' => 'Delete this image', |
|
| 336 | + 'icone_tous_articles' => 'All your articles', |
|
| 337 | + 'icone_tous_auteur' => 'All authors', |
|
| 338 | + 'icone_tous_visiteur' => 'All visitors', |
|
| 339 | + 'icone_visiter_site' => 'View the public site', |
|
| 340 | + 'icone_voir_en_ligne' => 'View online', |
|
| 341 | + 'img_indisponible' => 'image unavailable', |
|
| 342 | + 'impossible' => 'impossible', |
|
| 343 | + 'info_a_suivre' => 'LAUNCH PAD»', |
|
| 344 | + 'info_acces_interdit' => 'Access forbidden', |
|
| 345 | + 'info_acces_refuse' => 'Access denied', |
|
| 346 | + 'info_action' => 'Action: @action@', |
|
| 347 | + 'info_administrer_rubriques' => 'You can manage this section and any subsections', |
|
| 348 | + 'info_adresse_non_indiquee' => 'You did not specify an address to test!', |
|
| 349 | + 'info_aide' => 'HELP:', |
|
| 350 | + 'info_ajouter_mot' => 'Add keyword', |
|
| 351 | + 'info_annonce' => 'ANNOUNCEMENT', |
|
| 352 | + 'info_annonces_generales' => 'General announcements:', |
|
| 353 | + 'info_article_propose' => 'Article submitted', |
|
| 354 | + 'info_article_publie' => 'Article published', |
|
| 355 | + 'info_article_redaction' => 'Article in progress', |
|
| 356 | + 'info_article_refuse' => 'Article rejected', |
|
| 357 | + 'info_article_supprime' => 'Article deleted', |
|
| 358 | + 'info_articles' => 'Articles', |
|
| 359 | + 'info_articles_a_valider' => 'Articles awaiting validation', |
|
| 360 | + 'info_articles_nb' => '@nb@ articles', |
|
| 361 | + 'info_articles_proposes' => 'Articles submitted', |
|
| 362 | + 'info_articles_un' => '1 article', |
|
| 363 | + 'info_auteurs_nombre' => 'author(s):', |
|
| 364 | + 'info_authentification_ftp' => 'Authentication (by FTP).', |
|
| 365 | + 'info_breves_2' => 'news', |
|
| 366 | + 'info_breves_nb' => '@nb@ news items', |
|
| 367 | + 'info_breves_un' => '1 news item', |
|
| 368 | + 'info_connexion_refusee' => 'Connection denied', |
|
| 369 | + 'info_contact_developpeur' => 'Please contact a developer.', |
|
| 370 | + 'info_contenance' => 'This site contains:', |
|
| 371 | + 'info_contribution' => 'contributions', |
|
| 372 | + 'info_copyright' => '@spip@ is free software distributed @lien_gpl@.', |
|
| 373 | + 'info_copyright_doc' => 'For more visit <a href="@spipnet@">@spipnet_affiche@</a>.', |
|
| 374 | + 'info_copyright_gpl' => 'under the GPL license', |
|
| 375 | + 'info_cours_edition' => 'In progress', |
|
| 376 | + 'info_creer_repertoire' => 'Please create a file or a directory called:', |
|
| 377 | + 'info_creer_repertoire_2' => 'inside the sub-directory <b>@repertoire@</b>, then', |
|
| 378 | + 'info_creer_vignette' => 'automatic thumbnail creation', |
|
| 379 | + 'info_creerdansrubrique_non_autorise' => 'You don’t have sufficient rights to create content in this section', |
|
| 380 | + 'info_deplier' => 'Unfold', |
|
| 381 | + 'info_descriptif_nombre' => 'description(s):', |
|
| 382 | + 'info_description' => 'Description:', |
|
| 383 | + 'info_description_2' => 'Description:', |
|
| 384 | + 'info_dimension' => 'Size:', |
|
| 385 | + 'info_documents_nb' => '@nb@ documents', |
|
| 386 | + 'info_documents_un' => '1 document', |
|
| 387 | + 'info_ecire_message_prive' => 'Write a private message', |
|
| 388 | + 'info_email_invalide' => 'Invalid email address.', |
|
| 389 | + 'info_en_cours_validation' => 'Your articles in progress', |
|
| 390 | + 'info_en_ligne' => 'Online now:', |
|
| 391 | + 'info_envoyer_message_prive' => 'Send a private message to this author', |
|
| 392 | + 'info_erreur_requete' => 'Error in query:', |
|
| 393 | + 'info_erreur_squelette2' => 'No <b>@fichier@</b> template available ...', |
|
| 394 | + 'info_erreur_systeme' => 'System error (errno @errsys@)', |
|
| 395 | + 'info_erreur_systeme2' => 'The hard disk may be full or the database damaged. <br /> |
|
| 396 | 396 | <span style="color:red;">Try <a href=\'@script@\'>repairing the database</a>, or contact your service provider.</span>', |
| 397 | - 'info_fini' => 'Done!', |
|
| 398 | - 'info_format_image' => 'Image format to be used for vignettes: @gd_formats@.', |
|
| 399 | - 'info_format_non_defini' => 'undefined format', |
|
| 400 | - 'info_grand_ecran' => 'Large display', |
|
| 401 | - 'info_image_aide' => 'HELP', |
|
| 402 | - 'info_image_process_titre' => 'How to create thumbnails', |
|
| 403 | - 'info_impossible_lire_page' => '<b>Error!</b> The page <tt><html>@test_proxy@</html></tt> cannot be viewed through the proxy', |
|
| 404 | - 'info_installation_systeme_publication' => 'Installing publication system...', |
|
| 405 | - 'info_installer_documents' => 'You can automatically install all documents in the folder @upload@.', |
|
| 406 | - 'info_installer_ftp' => 'As an administrator, you can install files via FTP to the folder @upload@ in order to select them directly from here.', |
|
| 407 | - 'info_installer_images' => 'You can install images in the formats JPEG, GIF, and PNG.', |
|
| 408 | - 'info_installer_images_dossier' => 'Install images in folder @upload@ if you want to select them here.', |
|
| 409 | - 'info_interface_complete' => 'full interface', |
|
| 410 | - 'info_interface_simple' => 'Simplified interface', |
|
| 411 | - 'info_joindre_document_article' => 'You can attach the following types of document to your article', |
|
| 412 | - 'info_joindre_document_rubrique' => 'You can add documents of the following types to this section ', |
|
| 413 | - 'info_joindre_documents_article' => 'You can attach documents of the following types to your article:', |
|
| 414 | - 'info_l_article' => 'the article', |
|
| 415 | - 'info_la_breve' => 'the news item', |
|
| 416 | - 'info_la_rubrique' => 'the section', |
|
| 417 | - 'info_langue_principale' => 'Main language for site', |
|
| 418 | - 'info_largeur_vignette' => '@largeur_vignette@ × @hauteur_vignette@ pixels', |
|
| 419 | - 'info_les_auteurs_1' => 'by @les_auteurs@', |
|
| 420 | - 'info_logo_format_interdit' => 'Only logos in these formats @formats@ are allowed.', |
|
| 421 | - 'info_logo_max_poids' => 'Logos must be less than @maxi@ (this file is @actuel@).', |
|
| 422 | - 'info_mail_fournisseur' => '[email protected]', |
|
| 423 | - 'info_message_2' => 'MESSAGE', |
|
| 424 | - 'info_message_supprime' => 'MESSAGE DELETED', |
|
| 425 | - 'info_messages_nb' => '@nb@ messages', |
|
| 426 | - 'info_messages_un' => '1 message', |
|
| 427 | - 'info_mise_en_ligne' => 'Published on:', |
|
| 428 | - 'info_modification_parametres_securite' => 'modifying security parameters', |
|
| 429 | - 'info_mois_courant' => 'During the month:', |
|
| 430 | - 'info_mot_cle_ajoute' => 'The following keyword was added to', |
|
| 431 | - 'info_multi_herit' => 'Default language', |
|
| 432 | - 'info_multi_langues_soulignees' => 'The <u>languages underlined</u> provide partial or total translations for all the interface texts. If you select these languages, many elements of the public site (dates, forms) will be translated automatically. As for the languages that are not underlined, those elements will be displayed using the site’s default language.', |
|
| 433 | - 'info_multilinguisme' => 'Multilingual', |
|
| 434 | - 'info_nom_non_utilisateurs_connectes' => 'Your name does not appear in the list of users online.', |
|
| 435 | - 'info_nom_utilisateurs_connectes' => 'Your name appears in the list of users online.', |
|
| 436 | - 'info_nombre_en_ligne' => 'Online now:', |
|
| 437 | - 'info_non_resultat' => 'No results for "@cherche_mot@"', |
|
| 438 | - 'info_non_utilisation_messagerie' => 'You are not using private messaging on this site.', |
|
| 439 | - 'info_nouveau_message' => 'YOU HAVE A NEW MESSAGE', |
|
| 440 | - 'info_nouveaux_messages' => 'YOU HAVE @total_messages@ NEW MESSAGES', |
|
| 441 | - 'info_numero_abbreviation' => 'No', |
|
| 442 | - 'info_obligatoire' => 'This information is required', |
|
| 443 | - 'info_page_actuelle' => 'Actual page', |
|
| 444 | - 'info_pense_bete' => 'MEMO', |
|
| 445 | - 'info_petit_ecran' => 'Small display', |
|
| 446 | - 'info_petition_close' => 'Petition closed', |
|
| 447 | - 'info_pixels' => 'pixels', |
|
| 448 | - 'info_plusieurs_mots_trouves' => 'Several keywords were found for "@cherche_mot@":', |
|
| 449 | - 'info_portfolio_automatique' => 'Automated portfolio:', |
|
| 450 | - 'info_premier_resultat' => '[First @debut_limit@ results out of @total@]', |
|
| 451 | - 'info_premier_resultat_sur' => '[First @debut_limit@ results out of @total@]', |
|
| 452 | - 'info_propose_1' => '[@nom_site_spip@] Submitted: @titre@', |
|
| 453 | - 'info_propose_2' => 'Article submitted |
|
| 397 | + 'info_fini' => 'Done!', |
|
| 398 | + 'info_format_image' => 'Image format to be used for vignettes: @gd_formats@.', |
|
| 399 | + 'info_format_non_defini' => 'undefined format', |
|
| 400 | + 'info_grand_ecran' => 'Large display', |
|
| 401 | + 'info_image_aide' => 'HELP', |
|
| 402 | + 'info_image_process_titre' => 'How to create thumbnails', |
|
| 403 | + 'info_impossible_lire_page' => '<b>Error!</b> The page <tt><html>@test_proxy@</html></tt> cannot be viewed through the proxy', |
|
| 404 | + 'info_installation_systeme_publication' => 'Installing publication system...', |
|
| 405 | + 'info_installer_documents' => 'You can automatically install all documents in the folder @upload@.', |
|
| 406 | + 'info_installer_ftp' => 'As an administrator, you can install files via FTP to the folder @upload@ in order to select them directly from here.', |
|
| 407 | + 'info_installer_images' => 'You can install images in the formats JPEG, GIF, and PNG.', |
|
| 408 | + 'info_installer_images_dossier' => 'Install images in folder @upload@ if you want to select them here.', |
|
| 409 | + 'info_interface_complete' => 'full interface', |
|
| 410 | + 'info_interface_simple' => 'Simplified interface', |
|
| 411 | + 'info_joindre_document_article' => 'You can attach the following types of document to your article', |
|
| 412 | + 'info_joindre_document_rubrique' => 'You can add documents of the following types to this section ', |
|
| 413 | + 'info_joindre_documents_article' => 'You can attach documents of the following types to your article:', |
|
| 414 | + 'info_l_article' => 'the article', |
|
| 415 | + 'info_la_breve' => 'the news item', |
|
| 416 | + 'info_la_rubrique' => 'the section', |
|
| 417 | + 'info_langue_principale' => 'Main language for site', |
|
| 418 | + 'info_largeur_vignette' => '@largeur_vignette@ × @hauteur_vignette@ pixels', |
|
| 419 | + 'info_les_auteurs_1' => 'by @les_auteurs@', |
|
| 420 | + 'info_logo_format_interdit' => 'Only logos in these formats @formats@ are allowed.', |
|
| 421 | + 'info_logo_max_poids' => 'Logos must be less than @maxi@ (this file is @actuel@).', |
|
| 422 | + 'info_mail_fournisseur' => '[email protected]', |
|
| 423 | + 'info_message_2' => 'MESSAGE', |
|
| 424 | + 'info_message_supprime' => 'MESSAGE DELETED', |
|
| 425 | + 'info_messages_nb' => '@nb@ messages', |
|
| 426 | + 'info_messages_un' => '1 message', |
|
| 427 | + 'info_mise_en_ligne' => 'Published on:', |
|
| 428 | + 'info_modification_parametres_securite' => 'modifying security parameters', |
|
| 429 | + 'info_mois_courant' => 'During the month:', |
|
| 430 | + 'info_mot_cle_ajoute' => 'The following keyword was added to', |
|
| 431 | + 'info_multi_herit' => 'Default language', |
|
| 432 | + 'info_multi_langues_soulignees' => 'The <u>languages underlined</u> provide partial or total translations for all the interface texts. If you select these languages, many elements of the public site (dates, forms) will be translated automatically. As for the languages that are not underlined, those elements will be displayed using the site’s default language.', |
|
| 433 | + 'info_multilinguisme' => 'Multilingual', |
|
| 434 | + 'info_nom_non_utilisateurs_connectes' => 'Your name does not appear in the list of users online.', |
|
| 435 | + 'info_nom_utilisateurs_connectes' => 'Your name appears in the list of users online.', |
|
| 436 | + 'info_nombre_en_ligne' => 'Online now:', |
|
| 437 | + 'info_non_resultat' => 'No results for "@cherche_mot@"', |
|
| 438 | + 'info_non_utilisation_messagerie' => 'You are not using private messaging on this site.', |
|
| 439 | + 'info_nouveau_message' => 'YOU HAVE A NEW MESSAGE', |
|
| 440 | + 'info_nouveaux_messages' => 'YOU HAVE @total_messages@ NEW MESSAGES', |
|
| 441 | + 'info_numero_abbreviation' => 'No', |
|
| 442 | + 'info_obligatoire' => 'This information is required', |
|
| 443 | + 'info_page_actuelle' => 'Actual page', |
|
| 444 | + 'info_pense_bete' => 'MEMO', |
|
| 445 | + 'info_petit_ecran' => 'Small display', |
|
| 446 | + 'info_petition_close' => 'Petition closed', |
|
| 447 | + 'info_pixels' => 'pixels', |
|
| 448 | + 'info_plusieurs_mots_trouves' => 'Several keywords were found for "@cherche_mot@":', |
|
| 449 | + 'info_portfolio_automatique' => 'Automated portfolio:', |
|
| 450 | + 'info_premier_resultat' => '[First @debut_limit@ results out of @total@]', |
|
| 451 | + 'info_premier_resultat_sur' => '[First @debut_limit@ results out of @total@]', |
|
| 452 | + 'info_propose_1' => '[@nom_site_spip@] Submitted: @titre@', |
|
| 453 | + 'info_propose_2' => 'Article submitted |
|
| 454 | 454 | -----------------', |
| 455 | - 'info_propose_3' => 'The article "@titre@" has been submitted for publication.', |
|
| 456 | - 'info_propose_4' => 'You are invited to review it and give your opinion', |
|
| 457 | - 'info_propose_5' => 'in the associated forum. It is available here:', |
|
| 458 | - 'info_publie_01' => 'The article "@titre@" was validated by @connect_nom@.', |
|
| 459 | - 'info_publie_1' => '[@nom_site_spip@] PUBLISHED: @titre@', |
|
| 460 | - 'info_publie_2' => 'Article published |
|
| 455 | + 'info_propose_3' => 'The article "@titre@" has been submitted for publication.', |
|
| 456 | + 'info_propose_4' => 'You are invited to review it and give your opinion', |
|
| 457 | + 'info_propose_5' => 'in the associated forum. It is available here:', |
|
| 458 | + 'info_publie_01' => 'The article "@titre@" was validated by @connect_nom@.', |
|
| 459 | + 'info_publie_1' => '[@nom_site_spip@] PUBLISHED: @titre@', |
|
| 460 | + 'info_publie_2' => 'Article published |
|
| 461 | 461 | -----------------', |
| 462 | - 'info_rechercher' => 'Search', |
|
| 463 | - 'info_rechercher_02' => 'Search:', |
|
| 464 | - 'info_remplacer_vignette' => 'Replace the default vignette by a customised logo:', |
|
| 465 | - 'info_rubriques_nb' => '@nb@ sections', |
|
| 466 | - 'info_rubriques_un' => '1 section', |
|
| 467 | - 'info_sans_titre_2' => 'untitled', |
|
| 468 | - 'info_selectionner_fichier' => 'You can select a file from the folder @upload@', |
|
| 469 | - 'info_selectionner_fichier_2' => 'Select a file:', |
|
| 470 | - 'info_sites_nb' => '@nb@ sites', |
|
| 471 | - 'info_sites_un' => '1 site', |
|
| 472 | - 'info_supprimer_vignette' => 'delete the vignette', |
|
| 473 | - 'info_symbole_bleu' => 'A <b>blue</b> symbol indicates a <b>memo</b>: i.e. a message for your personal use.', |
|
| 474 | - 'info_symbole_jaune' => 'A <b>yellow</b> symbol indicates an <b>announcement to all editors</b>: it can be edited by all administrators, and is visible to all editors.', |
|
| 475 | - 'info_symbole_vert' => 'A <b>green</b> symbol indicates the <b>messages exchanged with other users</b> of the site.', |
|
| 476 | - 'info_telecharger_nouveau_logo' => 'Upload a new logo:', |
|
| 477 | - 'info_telecharger_ordinateur' => 'Upload from your computer:', |
|
| 478 | - 'info_tous_resultats_enregistres' => '[all the results are recorded]', |
|
| 479 | - 'info_tout_afficher' => 'Show all', |
|
| 480 | - 'info_travaux_texte' => 'This site is not yet set up. Please come back later...', |
|
| 481 | - 'info_travaux_titre' => 'Site under construction', |
|
| 482 | - 'info_trop_resultat' => 'Too many results for "@cherche_mot@"; please refine the search.', |
|
| 483 | - 'info_utilisation_messagerie_interne' => 'You are using the internal message system of this site.', |
|
| 484 | - 'info_valider_lien' => 'validate this link', |
|
| 485 | - 'info_verifier_image' => ', please make sure your images have been transferred correctly.', |
|
| 486 | - 'info_vignette_defaut' => 'Default vignette', |
|
| 487 | - 'info_vignette_personnalisee' => 'Custom vignette', |
|
| 488 | - 'info_visite' => 'visit:', |
|
| 489 | - 'info_vos_rendez_vous' => 'Your future appointments', |
|
| 490 | - 'infos_vos_pense_bete' => 'Your memos', |
|
| 462 | + 'info_rechercher' => 'Search', |
|
| 463 | + 'info_rechercher_02' => 'Search:', |
|
| 464 | + 'info_remplacer_vignette' => 'Replace the default vignette by a customised logo:', |
|
| 465 | + 'info_rubriques_nb' => '@nb@ sections', |
|
| 466 | + 'info_rubriques_un' => '1 section', |
|
| 467 | + 'info_sans_titre_2' => 'untitled', |
|
| 468 | + 'info_selectionner_fichier' => 'You can select a file from the folder @upload@', |
|
| 469 | + 'info_selectionner_fichier_2' => 'Select a file:', |
|
| 470 | + 'info_sites_nb' => '@nb@ sites', |
|
| 471 | + 'info_sites_un' => '1 site', |
|
| 472 | + 'info_supprimer_vignette' => 'delete the vignette', |
|
| 473 | + 'info_symbole_bleu' => 'A <b>blue</b> symbol indicates a <b>memo</b>: i.e. a message for your personal use.', |
|
| 474 | + 'info_symbole_jaune' => 'A <b>yellow</b> symbol indicates an <b>announcement to all editors</b>: it can be edited by all administrators, and is visible to all editors.', |
|
| 475 | + 'info_symbole_vert' => 'A <b>green</b> symbol indicates the <b>messages exchanged with other users</b> of the site.', |
|
| 476 | + 'info_telecharger_nouveau_logo' => 'Upload a new logo:', |
|
| 477 | + 'info_telecharger_ordinateur' => 'Upload from your computer:', |
|
| 478 | + 'info_tous_resultats_enregistres' => '[all the results are recorded]', |
|
| 479 | + 'info_tout_afficher' => 'Show all', |
|
| 480 | + 'info_travaux_texte' => 'This site is not yet set up. Please come back later...', |
|
| 481 | + 'info_travaux_titre' => 'Site under construction', |
|
| 482 | + 'info_trop_resultat' => 'Too many results for "@cherche_mot@"; please refine the search.', |
|
| 483 | + 'info_utilisation_messagerie_interne' => 'You are using the internal message system of this site.', |
|
| 484 | + 'info_valider_lien' => 'validate this link', |
|
| 485 | + 'info_verifier_image' => ', please make sure your images have been transferred correctly.', |
|
| 486 | + 'info_vignette_defaut' => 'Default vignette', |
|
| 487 | + 'info_vignette_personnalisee' => 'Custom vignette', |
|
| 488 | + 'info_visite' => 'visit:', |
|
| 489 | + 'info_vos_rendez_vous' => 'Your future appointments', |
|
| 490 | + 'infos_vos_pense_bete' => 'Your memos', |
|
| 491 | 491 | |
| 492 | - // L |
|
| 493 | - 'label_ajout_id_rapide' => 'Quick addition', |
|
| 494 | - 'label_poids_fichier' => 'Size', |
|
| 495 | - 'label_ponctuer' => '@label@:', |
|
| 496 | - 'lien_afficher_icones_seuls' => 'Show only icons', |
|
| 497 | - 'lien_afficher_texte_icones' => 'Show icons and text', |
|
| 498 | - 'lien_afficher_texte_seul' => 'Show only text', |
|
| 499 | - 'lien_aller_a_la_derniere_page' => 'Go to the last page', |
|
| 500 | - 'lien_aller_a_la_page_nb' => 'Go to page @nb@', |
|
| 501 | - 'lien_aller_a_la_page_precedente' => 'Go to the previous page', |
|
| 502 | - 'lien_aller_a_la_page_suivante' => 'Go to the next page', |
|
| 503 | - 'lien_aller_a_la_premiere_page' => 'Go to the first page', |
|
| 504 | - 'lien_liberer' => 'release', |
|
| 505 | - 'lien_liberer_tous' => 'Release all', |
|
| 506 | - 'lien_nouvea_pense_bete' => 'NEW MEMO', |
|
| 507 | - 'lien_nouveau_message' => 'NEW MESSAGE', |
|
| 508 | - 'lien_nouvelle_annonce' => 'NEW ANNOUNCEMENT', |
|
| 509 | - 'lien_petitions' => 'PETITION', |
|
| 510 | - 'lien_popularite' => 'popularity: @popularite@%', |
|
| 511 | - 'lien_racine_site' => 'SITE ROOT', |
|
| 512 | - 'lien_reessayer' => 'try again', |
|
| 513 | - 'lien_repondre_message' => 'Reply to this message', |
|
| 514 | - 'lien_supprimer' => 'delete', |
|
| 515 | - 'lien_tout_afficher' => 'Show all', |
|
| 516 | - 'lien_visite_site' => 'visit this site', |
|
| 517 | - 'lien_visites' => '@visites@ visits', |
|
| 518 | - 'lien_voir_auteur' => 'Check this author', |
|
| 519 | - 'ligne' => 'Line', |
|
| 520 | - 'login' => 'Connection', |
|
| 521 | - 'login_acces_prive' => 'access to the private area', |
|
| 522 | - 'login_autre_identifiant' => 'use a different ID', |
|
| 523 | - 'login_cookie_accepte' => 'Please configure your browser to accept them for this site.', |
|
| 524 | - 'login_cookie_oblige' => 'For secure identification, your browser must accept cookies.', |
|
| 525 | - 'login_deconnexion_ok' => 'Logged out.', |
|
| 526 | - 'login_erreur_pass' => 'Wrong password.', |
|
| 527 | - 'login_espace_prive' => 'private area', |
|
| 528 | - 'login_identifiant_inconnu' => 'The identifier "@login@" is unknown.', |
|
| 529 | - 'login_login' => 'Login:', |
|
| 530 | - 'login_login2' => 'Login or e-mail address:', |
|
| 531 | - 'login_login_pass_incorrect' => '(Wrong login or password).', |
|
| 532 | - 'login_motpasseoublie' => 'password forgotten?', |
|
| 533 | - 'login_non_securise' => 'Caution, this form is not secure. |
|
| 492 | + // L |
|
| 493 | + 'label_ajout_id_rapide' => 'Quick addition', |
|
| 494 | + 'label_poids_fichier' => 'Size', |
|
| 495 | + 'label_ponctuer' => '@label@:', |
|
| 496 | + 'lien_afficher_icones_seuls' => 'Show only icons', |
|
| 497 | + 'lien_afficher_texte_icones' => 'Show icons and text', |
|
| 498 | + 'lien_afficher_texte_seul' => 'Show only text', |
|
| 499 | + 'lien_aller_a_la_derniere_page' => 'Go to the last page', |
|
| 500 | + 'lien_aller_a_la_page_nb' => 'Go to page @nb@', |
|
| 501 | + 'lien_aller_a_la_page_precedente' => 'Go to the previous page', |
|
| 502 | + 'lien_aller_a_la_page_suivante' => 'Go to the next page', |
|
| 503 | + 'lien_aller_a_la_premiere_page' => 'Go to the first page', |
|
| 504 | + 'lien_liberer' => 'release', |
|
| 505 | + 'lien_liberer_tous' => 'Release all', |
|
| 506 | + 'lien_nouvea_pense_bete' => 'NEW MEMO', |
|
| 507 | + 'lien_nouveau_message' => 'NEW MESSAGE', |
|
| 508 | + 'lien_nouvelle_annonce' => 'NEW ANNOUNCEMENT', |
|
| 509 | + 'lien_petitions' => 'PETITION', |
|
| 510 | + 'lien_popularite' => 'popularity: @popularite@%', |
|
| 511 | + 'lien_racine_site' => 'SITE ROOT', |
|
| 512 | + 'lien_reessayer' => 'try again', |
|
| 513 | + 'lien_repondre_message' => 'Reply to this message', |
|
| 514 | + 'lien_supprimer' => 'delete', |
|
| 515 | + 'lien_tout_afficher' => 'Show all', |
|
| 516 | + 'lien_visite_site' => 'visit this site', |
|
| 517 | + 'lien_visites' => '@visites@ visits', |
|
| 518 | + 'lien_voir_auteur' => 'Check this author', |
|
| 519 | + 'ligne' => 'Line', |
|
| 520 | + 'login' => 'Connection', |
|
| 521 | + 'login_acces_prive' => 'access to the private area', |
|
| 522 | + 'login_autre_identifiant' => 'use a different ID', |
|
| 523 | + 'login_cookie_accepte' => 'Please configure your browser to accept them for this site.', |
|
| 524 | + 'login_cookie_oblige' => 'For secure identification, your browser must accept cookies.', |
|
| 525 | + 'login_deconnexion_ok' => 'Logged out.', |
|
| 526 | + 'login_erreur_pass' => 'Wrong password.', |
|
| 527 | + 'login_espace_prive' => 'private area', |
|
| 528 | + 'login_identifiant_inconnu' => 'The identifier "@login@" is unknown.', |
|
| 529 | + 'login_login' => 'Login:', |
|
| 530 | + 'login_login2' => 'Login or e-mail address:', |
|
| 531 | + 'login_login_pass_incorrect' => '(Wrong login or password).', |
|
| 532 | + 'login_motpasseoublie' => 'password forgotten?', |
|
| 533 | + 'login_non_securise' => 'Caution, this form is not secure. |
|
| 534 | 534 | If you do not want your password to be open to |
| 535 | 535 | interception on the network, please activate Javascript |
| 536 | 536 | in your browser and', |
| 537 | - 'login_nouvelle_tentative' => 'New attempt', |
|
| 538 | - 'login_par_ici' => 'You are registered... this way...', |
|
| 539 | - 'login_pass2' => 'Password:', |
|
| 540 | - 'login_preferez_refuser' => '<b>If you prefer to refuse cookies</b>, there is another, less secure, method of connection available:', |
|
| 541 | - 'login_recharger' => 'reload this page', |
|
| 542 | - 'login_rester_identifie' => 'Remember me', |
|
| 543 | - 'login_retour_public' => 'Back to the public site', |
|
| 544 | - 'login_retour_site' => 'Back to the public site', |
|
| 545 | - 'login_retoursitepublic' => 'back to the public site', |
|
| 546 | - 'login_sans_cookie' => 'Identification without cookie', |
|
| 547 | - 'login_securise' => 'Secure login', |
|
| 548 | - 'login_sinscrire' => 'register', |
|
| 549 | - 'login_test_navigateur' => 'testing browser/reconnection', |
|
| 550 | - 'login_verifiez_navigateur' => '(However, check that your browser did not memorise your password...)', |
|
| 537 | + 'login_nouvelle_tentative' => 'New attempt', |
|
| 538 | + 'login_par_ici' => 'You are registered... this way...', |
|
| 539 | + 'login_pass2' => 'Password:', |
|
| 540 | + 'login_preferez_refuser' => '<b>If you prefer to refuse cookies</b>, there is another, less secure, method of connection available:', |
|
| 541 | + 'login_recharger' => 'reload this page', |
|
| 542 | + 'login_rester_identifie' => 'Remember me', |
|
| 543 | + 'login_retour_public' => 'Back to the public site', |
|
| 544 | + 'login_retour_site' => 'Back to the public site', |
|
| 545 | + 'login_retoursitepublic' => 'back to the public site', |
|
| 546 | + 'login_sans_cookie' => 'Identification without cookie', |
|
| 547 | + 'login_securise' => 'Secure login', |
|
| 548 | + 'login_sinscrire' => 'register', |
|
| 549 | + 'login_test_navigateur' => 'testing browser/reconnection', |
|
| 550 | + 'login_verifiez_navigateur' => '(However, check that your browser did not memorise your password...)', |
|
| 551 | 551 | |
| 552 | - // M |
|
| 553 | - 'masquer_colonne' => 'Hide this column', |
|
| 554 | - 'masquer_trad' => 'hide translations', |
|
| 555 | - 'message_nouveaux_identifiants_echec' => 'New identifiers could not be created.', |
|
| 556 | - 'message_nouveaux_identifiants_echec_envoi' => 'The new connection identifiers could not be sent.', |
|
| 557 | - 'message_nouveaux_identifiants_ok' => 'The new connection identifiers were sent to @email@.', |
|
| 558 | - 'module_fichiers_langues' => 'Language files', |
|
| 552 | + // M |
|
| 553 | + 'masquer_colonne' => 'Hide this column', |
|
| 554 | + 'masquer_trad' => 'hide translations', |
|
| 555 | + 'message_nouveaux_identifiants_echec' => 'New identifiers could not be created.', |
|
| 556 | + 'message_nouveaux_identifiants_echec_envoi' => 'The new connection identifiers could not be sent.', |
|
| 557 | + 'message_nouveaux_identifiants_ok' => 'The new connection identifiers were sent to @email@.', |
|
| 558 | + 'module_fichiers_langues' => 'Language files', |
|
| 559 | 559 | |
| 560 | - // N |
|
| 561 | - 'navigateur_pas_redirige' => 'If you are not automatically redirected, click here to continue.', |
|
| 562 | - 'numero' => 'Number', |
|
| 560 | + // N |
|
| 561 | + 'navigateur_pas_redirige' => 'If you are not automatically redirected, click here to continue.', |
|
| 562 | + 'numero' => 'Number', |
|
| 563 | 563 | |
| 564 | - // O |
|
| 565 | - 'occurence' => 'Instance', |
|
| 566 | - 'onglet_affacer_base' => 'Delete the database', |
|
| 567 | - 'onglet_auteur' => 'The author', |
|
| 568 | - 'onglet_contenu_site' => 'Site content', |
|
| 569 | - 'onglet_evolution_visite_mod' => 'Trend in visits', |
|
| 570 | - 'onglet_fonctions_avances' => 'Advanced functions', |
|
| 571 | - 'onglet_informations_personnelles' => 'Personal Information', |
|
| 572 | - 'onglet_interactivite' => 'Interactivity', |
|
| 573 | - 'onglet_messagerie' => 'Messaging', |
|
| 574 | - 'onglet_repartition_rubrique' => 'Distribution by section', |
|
| 575 | - 'onglet_save_restaur_base' => 'Backup/restore the database', |
|
| 576 | - 'onglet_vider_cache' => 'Empty the cache', |
|
| 564 | + // O |
|
| 565 | + 'occurence' => 'Instance', |
|
| 566 | + 'onglet_affacer_base' => 'Delete the database', |
|
| 567 | + 'onglet_auteur' => 'The author', |
|
| 568 | + 'onglet_contenu_site' => 'Site content', |
|
| 569 | + 'onglet_evolution_visite_mod' => 'Trend in visits', |
|
| 570 | + 'onglet_fonctions_avances' => 'Advanced functions', |
|
| 571 | + 'onglet_informations_personnelles' => 'Personal Information', |
|
| 572 | + 'onglet_interactivite' => 'Interactivity', |
|
| 573 | + 'onglet_messagerie' => 'Messaging', |
|
| 574 | + 'onglet_repartition_rubrique' => 'Distribution by section', |
|
| 575 | + 'onglet_save_restaur_base' => 'Backup/restore the database', |
|
| 576 | + 'onglet_vider_cache' => 'Empty the cache', |
|
| 577 | 577 | |
| 578 | - // P |
|
| 579 | - 'pass_choix_pass' => 'Please choose a new password:', |
|
| 580 | - 'pass_erreur' => 'Error', |
|
| 581 | - 'pass_erreur_acces_refuse' => '<b>Error:</b> you no longer have access to this site.', |
|
| 582 | - 'pass_erreur_code_inconnu' => '<b>Error:</b> this code does not match any visitors with access permission to this site.', |
|
| 583 | - 'pass_erreur_non_enregistre' => '<b>Error :</b> the address <tt>@email_oubli@</tt> is not registered on this site.', |
|
| 584 | - 'pass_erreur_non_valide' => '<b>Error :</b> the e-mail <tt>@email_oubli@</tt> is not valid!', |
|
| 585 | - 'pass_erreur_probleme_technique' => '<b>Error :</b> this e-mail could not be sent due to a technical problem.', |
|
| 586 | - 'pass_espace_prive_bla' => 'The private area of this site is open to |
|
| 578 | + // P |
|
| 579 | + 'pass_choix_pass' => 'Please choose a new password:', |
|
| 580 | + 'pass_erreur' => 'Error', |
|
| 581 | + 'pass_erreur_acces_refuse' => '<b>Error:</b> you no longer have access to this site.', |
|
| 582 | + 'pass_erreur_code_inconnu' => '<b>Error:</b> this code does not match any visitors with access permission to this site.', |
|
| 583 | + 'pass_erreur_non_enregistre' => '<b>Error :</b> the address <tt>@email_oubli@</tt> is not registered on this site.', |
|
| 584 | + 'pass_erreur_non_valide' => '<b>Error :</b> the e-mail <tt>@email_oubli@</tt> is not valid!', |
|
| 585 | + 'pass_erreur_probleme_technique' => '<b>Error :</b> this e-mail could not be sent due to a technical problem.', |
|
| 586 | + 'pass_espace_prive_bla' => 'The private area of this site is open to |
|
| 587 | 587 | visitors after registration. Once you have registered, |
| 588 | 588 | you can review the articles in progress, |
| 589 | 589 | submit articles and participate in forums.', |
| 590 | - 'pass_forum_bla' => 'You have requested to take part in a forum |
|
| 590 | + 'pass_forum_bla' => 'You have requested to take part in a forum |
|
| 591 | 591 | reserved for registered visitors.', |
| 592 | - 'pass_indiquez_cidessous' => 'Enter the email address with which you |
|
| 592 | + 'pass_indiquez_cidessous' => 'Enter the email address with which you |
|
| 593 | 593 | registered. You |
| 594 | 594 | will receive an email explaining how you |
| 595 | 595 | can retrieve your password.', |
| 596 | - 'pass_mail_passcookie' => '(this is an automated message) |
|
| 596 | + 'pass_mail_passcookie' => '(this is an automated message) |
|
| 597 | 597 | |
| 598 | 598 | To recover your access to the site |
| 599 | 599 | @nom_site_spip@ (@adresse_site@) |
@@ -604,146 +604,146 @@ discard block |
||
| 604 | 604 | You can then enter a new password |
| 605 | 605 | and log in to the site. |
| 606 | 606 | ', |
| 607 | - 'pass_mot_oublie' => 'Password forgotten', |
|
| 608 | - 'pass_nouveau_enregistre' => 'Your new password has been recorded.', |
|
| 609 | - 'pass_nouveau_pass' => 'New password', |
|
| 610 | - 'pass_ok' => 'OK', |
|
| 611 | - 'pass_oubli_mot' => 'Forgotten password', |
|
| 612 | - 'pass_procedure_changer' => 'In order to change your password, we have to check your identity first. Please enter the e-mail address associated with this account.', |
|
| 613 | - 'pass_quitter_fenetre' => 'Close this window', |
|
| 614 | - 'pass_rappel_login' => 'Reminder: your identifier (login) is "@login@".', |
|
| 615 | - 'pass_recevoir_mail' => 'A link to reset your password has been sent to your email address (if it is valid).', |
|
| 616 | - 'pass_retour_public' => 'Back to the public site', |
|
| 617 | - 'pass_rien_a_faire_ici' => 'Nothing to do here.', |
|
| 618 | - 'pass_vousinscrire' => 'Registering with the site', |
|
| 619 | - 'precedent' => 'previous', |
|
| 620 | - 'previsualisation' => 'Preview', |
|
| 621 | - 'previsualiser' => 'Show preview', |
|
| 607 | + 'pass_mot_oublie' => 'Password forgotten', |
|
| 608 | + 'pass_nouveau_enregistre' => 'Your new password has been recorded.', |
|
| 609 | + 'pass_nouveau_pass' => 'New password', |
|
| 610 | + 'pass_ok' => 'OK', |
|
| 611 | + 'pass_oubli_mot' => 'Forgotten password', |
|
| 612 | + 'pass_procedure_changer' => 'In order to change your password, we have to check your identity first. Please enter the e-mail address associated with this account.', |
|
| 613 | + 'pass_quitter_fenetre' => 'Close this window', |
|
| 614 | + 'pass_rappel_login' => 'Reminder: your identifier (login) is "@login@".', |
|
| 615 | + 'pass_recevoir_mail' => 'A link to reset your password has been sent to your email address (if it is valid).', |
|
| 616 | + 'pass_retour_public' => 'Back to the public site', |
|
| 617 | + 'pass_rien_a_faire_ici' => 'Nothing to do here.', |
|
| 618 | + 'pass_vousinscrire' => 'Registering with the site', |
|
| 619 | + 'precedent' => 'previous', |
|
| 620 | + 'previsualisation' => 'Preview', |
|
| 621 | + 'previsualiser' => 'Show preview', |
|
| 622 | 622 | |
| 623 | - // R |
|
| 624 | - 'retour' => 'Back', |
|
| 623 | + // R |
|
| 624 | + 'retour' => 'Back', |
|
| 625 | 625 | |
| 626 | - // S |
|
| 627 | - 'spip_conforme_dtd' => 'SPIP finds this page to be in compliance with its DOCTYPE:', |
|
| 628 | - 'squelette' => 'template', |
|
| 629 | - 'squelette_inclus_ligne' => 'included template, line', |
|
| 630 | - 'squelette_ligne' => 'template, line', |
|
| 631 | - 'stats_visites_et_popularite' => '@visites@ visits; popularity: @popularite@', |
|
| 632 | - 'suivant' => 'next', |
|
| 626 | + // S |
|
| 627 | + 'spip_conforme_dtd' => 'SPIP finds this page to be in compliance with its DOCTYPE:', |
|
| 628 | + 'squelette' => 'template', |
|
| 629 | + 'squelette_inclus_ligne' => 'included template, line', |
|
| 630 | + 'squelette_ligne' => 'template, line', |
|
| 631 | + 'stats_visites_et_popularite' => '@visites@ visits; popularity: @popularite@', |
|
| 632 | + 'suivant' => 'next', |
|
| 633 | 633 | |
| 634 | - // T |
|
| 635 | - 'taille_go' => '@taille@ Gb', |
|
| 636 | - 'taille_ko' => '@taille@ kb', |
|
| 637 | - 'taille_mo' => '@taille@ Mb', |
|
| 638 | - 'taille_octets' => '@taille@ bytes', |
|
| 639 | - 'texte_actualite_site_1' => 'When you are more familiar with the interface, click on "', |
|
| 640 | - 'texte_actualite_site_2' => 'full interface', |
|
| 641 | - 'texte_actualite_site_3' => '" to make more features available.', |
|
| 642 | - 'texte_creation_automatique_vignette' => 'Automatic creation of preview vignettes is enabled. If you use this form to install, images in the format(s) @gd_formats@, they will be coupled with a vignette whose maximum size is @taille_preview@ pixels.', |
|
| 643 | - 'texte_documents_associes' => 'The following documents are associated with the article,, |
|
| 634 | + // T |
|
| 635 | + 'taille_go' => '@taille@ Gb', |
|
| 636 | + 'taille_ko' => '@taille@ kb', |
|
| 637 | + 'taille_mo' => '@taille@ Mb', |
|
| 638 | + 'taille_octets' => '@taille@ bytes', |
|
| 639 | + 'texte_actualite_site_1' => 'When you are more familiar with the interface, click on "', |
|
| 640 | + 'texte_actualite_site_2' => 'full interface', |
|
| 641 | + 'texte_actualite_site_3' => '" to make more features available.', |
|
| 642 | + 'texte_creation_automatique_vignette' => 'Automatic creation of preview vignettes is enabled. If you use this form to install, images in the format(s) @gd_formats@, they will be coupled with a vignette whose maximum size is @taille_preview@ pixels.', |
|
| 643 | + 'texte_documents_associes' => 'The following documents are associated with the article,, |
|
| 644 | 644 | but they were not directly |
| 645 | 645 | inserted. Depending on the layout of the public site, |
| 646 | 646 | they may appear as attached documents.', |
| 647 | - 'texte_erreur_mise_niveau_base' => 'Database error during the upgrade. |
|
| 647 | + 'texte_erreur_mise_niveau_base' => 'Database error during the upgrade. |
|
| 648 | 648 | The image <b>@fichier@</b> did not pass (article @id_article@).<p> |
| 649 | 649 | Note this reference carefully, try the upgrade procedure again, |
| 650 | 650 | and check afterwards that the images still appear |
| 651 | 651 | in the articles.', |
| 652 | - 'texte_erreur_visiteur' => 'You have tried to enter the private area using an unauthorised login.', |
|
| 653 | - 'texte_inc_auth_1' => 'You used the login |
|
| 652 | + 'texte_erreur_visiteur' => 'You have tried to enter the private area using an unauthorised login.', |
|
| 653 | + 'texte_inc_auth_1' => 'You used the login |
|
| 654 | 654 | <b>@auth_login@</b>, but it does not exist in the database. |
| 655 | 655 | Try to', |
| 656 | - 'texte_inc_auth_2' => 'reconnect', |
|
| 657 | - 'texte_inc_auth_3' => ', having quit and |
|
| 656 | + 'texte_inc_auth_2' => 'reconnect', |
|
| 657 | + 'texte_inc_auth_3' => ', having quit and |
|
| 658 | 658 | restarted your browser if necessary.', |
| 659 | - 'texte_inc_config' => 'Changes made to the options on these pages have a great effect on |
|
| 659 | + 'texte_inc_config' => 'Changes made to the options on these pages have a great effect on |
|
| 660 | 660 | the functioning of the site. You are advised not to make any changes unless you are |
| 661 | 661 | familiar with how SPIP works. <br /><br /><b>In |
| 662 | 662 | general, you are strongly advised |
| 663 | 663 | to let the main webmaster of the site deal with these pages.</b>', |
| 664 | - 'texte_inc_meta_1' => 'The system encountered an error when trying to write the file <code>@fichier@</code>. As a site administrator, please', |
|
| 665 | - 'texte_inc_meta_2' => 'verify write permissions', |
|
| 666 | - 'texte_inc_meta_3' => 'of the directory <code>@repertoire@</code>.', |
|
| 667 | - 'texte_statut_en_cours_redaction' => 'editing in progress', |
|
| 668 | - 'texte_statut_poubelle' => 'to the dustbin', |
|
| 669 | - 'texte_statut_propose_evaluation' => 'submitted for evaluation', |
|
| 670 | - 'texte_statut_publie' => 'published online', |
|
| 671 | - 'texte_statut_refuse' => 'rejected', |
|
| 672 | - 'titre_ajouter_mot_cle' => 'ADD A KEYWORD:', |
|
| 673 | - 'titre_cadre_raccourcis' => 'SHORTCUTS:', |
|
| 674 | - 'titre_changer_couleur_interface' => 'Changing interface colour', |
|
| 675 | - 'titre_image_admin_article' => 'You can administrate this article', |
|
| 676 | - 'titre_image_administrateur' => 'Administrator', |
|
| 677 | - 'titre_image_aide' => 'Help on this item', |
|
| 678 | - 'titre_image_auteur_supprime' => 'Author deleted', |
|
| 679 | - 'titre_image_redacteur' => 'Editor without access', |
|
| 680 | - 'titre_image_redacteur_02' => 'Editor', |
|
| 681 | - 'titre_image_selecteur' => 'Display list', |
|
| 682 | - 'titre_image_visiteur' => 'Visitor', |
|
| 683 | - 'titre_joindre_document' => 'ATTACH A DOCUMENT', |
|
| 684 | - 'titre_mots_cles' => 'KEYWORDS', |
|
| 685 | - 'titre_probleme_technique' => 'Warning: a technical problem (SQL server) is preventing access to this part of the site. Thank you for your patience.', |
|
| 686 | - 'titre_publier_document' => 'PUBLISH A DOCUMENT IN THIS SECTION', |
|
| 687 | - 'titre_signatures_attente' => 'Signatures awaiting validation', |
|
| 688 | - 'titre_signatures_confirmees' => 'Signatures confirmed', |
|
| 689 | - 'titre_statistiques' => 'Site statistics', |
|
| 690 | - 'titre_titre_document' => 'Document title:', |
|
| 691 | - 'todo' => 'to come', |
|
| 692 | - 'trad_definir_reference' => 'Choose "@titre@" as a reference for translations', |
|
| 693 | - 'trad_reference' => '(reference for translations)', |
|
| 664 | + 'texte_inc_meta_1' => 'The system encountered an error when trying to write the file <code>@fichier@</code>. As a site administrator, please', |
|
| 665 | + 'texte_inc_meta_2' => 'verify write permissions', |
|
| 666 | + 'texte_inc_meta_3' => 'of the directory <code>@repertoire@</code>.', |
|
| 667 | + 'texte_statut_en_cours_redaction' => 'editing in progress', |
|
| 668 | + 'texte_statut_poubelle' => 'to the dustbin', |
|
| 669 | + 'texte_statut_propose_evaluation' => 'submitted for evaluation', |
|
| 670 | + 'texte_statut_publie' => 'published online', |
|
| 671 | + 'texte_statut_refuse' => 'rejected', |
|
| 672 | + 'titre_ajouter_mot_cle' => 'ADD A KEYWORD:', |
|
| 673 | + 'titre_cadre_raccourcis' => 'SHORTCUTS:', |
|
| 674 | + 'titre_changer_couleur_interface' => 'Changing interface colour', |
|
| 675 | + 'titre_image_admin_article' => 'You can administrate this article', |
|
| 676 | + 'titre_image_administrateur' => 'Administrator', |
|
| 677 | + 'titre_image_aide' => 'Help on this item', |
|
| 678 | + 'titre_image_auteur_supprime' => 'Author deleted', |
|
| 679 | + 'titre_image_redacteur' => 'Editor without access', |
|
| 680 | + 'titre_image_redacteur_02' => 'Editor', |
|
| 681 | + 'titre_image_selecteur' => 'Display list', |
|
| 682 | + 'titre_image_visiteur' => 'Visitor', |
|
| 683 | + 'titre_joindre_document' => 'ATTACH A DOCUMENT', |
|
| 684 | + 'titre_mots_cles' => 'KEYWORDS', |
|
| 685 | + 'titre_probleme_technique' => 'Warning: a technical problem (SQL server) is preventing access to this part of the site. Thank you for your patience.', |
|
| 686 | + 'titre_publier_document' => 'PUBLISH A DOCUMENT IN THIS SECTION', |
|
| 687 | + 'titre_signatures_attente' => 'Signatures awaiting validation', |
|
| 688 | + 'titre_signatures_confirmees' => 'Signatures confirmed', |
|
| 689 | + 'titre_statistiques' => 'Site statistics', |
|
| 690 | + 'titre_titre_document' => 'Document title:', |
|
| 691 | + 'todo' => 'to come', |
|
| 692 | + 'trad_definir_reference' => 'Choose "@titre@" as a reference for translations', |
|
| 693 | + 'trad_reference' => '(reference for translations)', |
|
| 694 | 694 | |
| 695 | - // U |
|
| 696 | - 'upload_limit' => 'This file is too big for the server: the maximum size allowed for <i>upload</i> is @max@.', |
|
| 695 | + // U |
|
| 696 | + 'upload_limit' => 'This file is too big for the server: the maximum size allowed for <i>upload</i> is @max@.', |
|
| 697 | 697 | |
| 698 | - // Z |
|
| 699 | - 'zbug_balise_b_aval' => ': B tag too late in loop', |
|
| 700 | - 'zbug_balise_inexistante' => 'Tag @balise@ wrongly declared for @from@', |
|
| 701 | - 'zbug_balise_sans_argument' => 'Missing argument in the @balise@ tag', |
|
| 702 | - 'zbug_boucle' => 'loop', |
|
| 703 | - 'zbug_boucle_recursive_undef' => 'undefined recursive loop: @nom@', |
|
| 704 | - 'zbug_calcul' => 'calculation', |
|
| 705 | - 'zbug_champ_hors_boucle' => 'Field @champ@ outside loop', |
|
| 706 | - 'zbug_champ_hors_critere' => 'Field @champ@ outside criterion @critere@', |
|
| 707 | - 'zbug_champ_hors_motif' => 'Field @champ@ outside context @motif@', |
|
| 708 | - 'zbug_code' => 'code', |
|
| 709 | - 'zbug_critere_inconnu' => 'Unknown criterion @critere@', |
|
| 710 | - 'zbug_critere_sur_table_sans_cle_primaire' => '{@critere@} on a table without atomic primary key', |
|
| 711 | - 'zbug_distant_interdit' => 'External data forbidden', |
|
| 712 | - 'zbug_doublon_table_sans_cle_primaire' => 'Duplicate entries on a table which does not have a simple primary key', |
|
| 713 | - 'zbug_doublon_table_sans_index' => 'Duplicate entries on a table without an index', |
|
| 714 | - 'zbug_erreur_boucle_double' => 'Loop @id@: double definition', |
|
| 715 | - 'zbug_erreur_boucle_fermant' => 'Loop @id@: missing closing tag', |
|
| 716 | - 'zbug_erreur_boucle_syntaxe' => 'Syntax error in loop (BOUCLE)', |
|
| 717 | - 'zbug_erreur_compilation' => 'Compilation error', |
|
| 718 | - 'zbug_erreur_execution_page' => 'Execution error', |
|
| 719 | - 'zbug_erreur_filtre' => 'Undefined filter @filtre@', |
|
| 720 | - 'zbug_erreur_filtre_nbarg_min' => '@filtre@ filter: @nb@ argument(s) missing', |
|
| 721 | - 'zbug_erreur_meme_parent' => '{meme_parent} only applies to loops (FORUMS) and (RUBRIQUES)', |
|
| 722 | - 'zbug_erreur_squelette' => 'Error(s) in template', |
|
| 723 | - 'zbug_hors_compilation' => 'Uncompiled', |
|
| 724 | - 'zbug_info_erreur_squelette' => 'Error in the site', |
|
| 725 | - 'zbug_inversion_ordre_inexistant' => 'Reversion of non-existent order', |
|
| 726 | - 'zbug_pagination_sans_critere' => '#PAGINATION tag without {pagination} criterion, or used in a recursive loop', |
|
| 727 | - 'zbug_parametres_inclus_incorrects' => 'Wrong inclusion parameter: @param@', |
|
| 728 | - 'zbug_profile' => 'Calculation time: @time@', |
|
| 729 | - 'zbug_resultat' => 'result', |
|
| 730 | - 'zbug_serveur_indefini' => 'Undefined SQL server', |
|
| 731 | - 'zbug_statistiques' => 'SQL query statistics in order of duration', |
|
| 732 | - 'zbug_table_inconnue' => 'Unknown SQL table "@table@"', |
|
| 733 | - 'zxml_connus_attributs' => 'known attributes', |
|
| 734 | - 'zxml_de' => 'from', |
|
| 735 | - 'zxml_inconnu_attribut' => 'unknown attribute', |
|
| 736 | - 'zxml_inconnu_balise' => 'unknown tag', |
|
| 737 | - 'zxml_inconnu_entite' => 'unknown entity', |
|
| 738 | - 'zxml_inconnu_id' => 'unknown ID', |
|
| 739 | - 'zxml_mais_de' => 'but from', |
|
| 740 | - 'zxml_non_conforme' => 'not true to the principle', |
|
| 741 | - 'zxml_non_fils' => 'is not a child of', |
|
| 742 | - 'zxml_nonvide_balise' => 'tag not empty', |
|
| 743 | - 'zxml_obligatoire_attribut' => 'required attribute absent in', |
|
| 744 | - 'zxml_succession_fils_incorrecte' => 'incorrect child inheritance', |
|
| 745 | - 'zxml_survoler' => 'to see the correct ones, hover with the cursor', |
|
| 746 | - 'zxml_valeur_attribut' => 'attribute value', |
|
| 747 | - 'zxml_vide_balise' => 'empty tag', |
|
| 748 | - 'zxml_vu' => 'seen before' |
|
| 698 | + // Z |
|
| 699 | + 'zbug_balise_b_aval' => ': B tag too late in loop', |
|
| 700 | + 'zbug_balise_inexistante' => 'Tag @balise@ wrongly declared for @from@', |
|
| 701 | + 'zbug_balise_sans_argument' => 'Missing argument in the @balise@ tag', |
|
| 702 | + 'zbug_boucle' => 'loop', |
|
| 703 | + 'zbug_boucle_recursive_undef' => 'undefined recursive loop: @nom@', |
|
| 704 | + 'zbug_calcul' => 'calculation', |
|
| 705 | + 'zbug_champ_hors_boucle' => 'Field @champ@ outside loop', |
|
| 706 | + 'zbug_champ_hors_critere' => 'Field @champ@ outside criterion @critere@', |
|
| 707 | + 'zbug_champ_hors_motif' => 'Field @champ@ outside context @motif@', |
|
| 708 | + 'zbug_code' => 'code', |
|
| 709 | + 'zbug_critere_inconnu' => 'Unknown criterion @critere@', |
|
| 710 | + 'zbug_critere_sur_table_sans_cle_primaire' => '{@critere@} on a table without atomic primary key', |
|
| 711 | + 'zbug_distant_interdit' => 'External data forbidden', |
|
| 712 | + 'zbug_doublon_table_sans_cle_primaire' => 'Duplicate entries on a table which does not have a simple primary key', |
|
| 713 | + 'zbug_doublon_table_sans_index' => 'Duplicate entries on a table without an index', |
|
| 714 | + 'zbug_erreur_boucle_double' => 'Loop @id@: double definition', |
|
| 715 | + 'zbug_erreur_boucle_fermant' => 'Loop @id@: missing closing tag', |
|
| 716 | + 'zbug_erreur_boucle_syntaxe' => 'Syntax error in loop (BOUCLE)', |
|
| 717 | + 'zbug_erreur_compilation' => 'Compilation error', |
|
| 718 | + 'zbug_erreur_execution_page' => 'Execution error', |
|
| 719 | + 'zbug_erreur_filtre' => 'Undefined filter @filtre@', |
|
| 720 | + 'zbug_erreur_filtre_nbarg_min' => '@filtre@ filter: @nb@ argument(s) missing', |
|
| 721 | + 'zbug_erreur_meme_parent' => '{meme_parent} only applies to loops (FORUMS) and (RUBRIQUES)', |
|
| 722 | + 'zbug_erreur_squelette' => 'Error(s) in template', |
|
| 723 | + 'zbug_hors_compilation' => 'Uncompiled', |
|
| 724 | + 'zbug_info_erreur_squelette' => 'Error in the site', |
|
| 725 | + 'zbug_inversion_ordre_inexistant' => 'Reversion of non-existent order', |
|
| 726 | + 'zbug_pagination_sans_critere' => '#PAGINATION tag without {pagination} criterion, or used in a recursive loop', |
|
| 727 | + 'zbug_parametres_inclus_incorrects' => 'Wrong inclusion parameter: @param@', |
|
| 728 | + 'zbug_profile' => 'Calculation time: @time@', |
|
| 729 | + 'zbug_resultat' => 'result', |
|
| 730 | + 'zbug_serveur_indefini' => 'Undefined SQL server', |
|
| 731 | + 'zbug_statistiques' => 'SQL query statistics in order of duration', |
|
| 732 | + 'zbug_table_inconnue' => 'Unknown SQL table "@table@"', |
|
| 733 | + 'zxml_connus_attributs' => 'known attributes', |
|
| 734 | + 'zxml_de' => 'from', |
|
| 735 | + 'zxml_inconnu_attribut' => 'unknown attribute', |
|
| 736 | + 'zxml_inconnu_balise' => 'unknown tag', |
|
| 737 | + 'zxml_inconnu_entite' => 'unknown entity', |
|
| 738 | + 'zxml_inconnu_id' => 'unknown ID', |
|
| 739 | + 'zxml_mais_de' => 'but from', |
|
| 740 | + 'zxml_non_conforme' => 'not true to the principle', |
|
| 741 | + 'zxml_non_fils' => 'is not a child of', |
|
| 742 | + 'zxml_nonvide_balise' => 'tag not empty', |
|
| 743 | + 'zxml_obligatoire_attribut' => 'required attribute absent in', |
|
| 744 | + 'zxml_succession_fils_incorrecte' => 'incorrect child inheritance', |
|
| 745 | + 'zxml_survoler' => 'to see the correct ones, hover with the cursor', |
|
| 746 | + 'zxml_valeur_attribut' => 'attribute value', |
|
| 747 | + 'zxml_vide_balise' => 'empty tag', |
|
| 748 | + 'zxml_vu' => 'seen before' |
|
| 749 | 749 | ); |