@@ -21,7 +21,7 @@ discard block |
||
| 21 | 21 | |
| 22 | 22 | |
| 23 | 23 | if (!defined('_ECRIRE_INC_VERSION')) { |
| 24 | - return; |
|
| 24 | + return; |
|
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | |
@@ -44,70 +44,70 @@ discard block |
||
| 44 | 44 | * @return array|string |
| 45 | 45 | */ |
| 46 | 46 | function action_inscrire_auteur_dist($statut, $mail_complet, $nom, $options = []) { |
| 47 | - if (!is_array($options)) { |
|
| 48 | - $options = ['id' => $options]; |
|
| 49 | - } |
|
| 50 | - |
|
| 51 | - if (function_exists('test_inscription')) { |
|
| 52 | - $f = 'test_inscription'; |
|
| 53 | - } else { |
|
| 54 | - $f = 'test_inscription_dist'; |
|
| 55 | - } |
|
| 56 | - $desc = $f($statut, $mail_complet, $nom, $options); |
|
| 57 | - |
|
| 58 | - // erreur ? |
|
| 59 | - if (!is_array($desc)) { |
|
| 60 | - return _T($desc); |
|
| 61 | - } |
|
| 62 | - |
|
| 63 | - include_spip('base/abstract_sql'); |
|
| 64 | - $res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email'])); |
|
| 65 | - // erreur ? |
|
| 66 | - if (!$res) { |
|
| 67 | - return _T('titre_probleme_technique'); |
|
| 68 | - } |
|
| 69 | - |
|
| 70 | - $row = sql_fetch($res); |
|
| 71 | - sql_free($res); |
|
| 72 | - if ($row) { |
|
| 73 | - if (isset($options['force_nouveau']) and $options['force_nouveau'] == true) { |
|
| 74 | - $desc['id_auteur'] = $row['id_auteur']; |
|
| 75 | - $desc = inscription_nouveau($desc); |
|
| 76 | - } else { |
|
| 77 | - $desc = $row; |
|
| 78 | - } |
|
| 79 | - } else // s'il n'existe pas deja, creer les identifiants |
|
| 80 | - { |
|
| 81 | - $desc = inscription_nouveau($desc); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - // erreur ? |
|
| 85 | - if (!is_array($desc)) { |
|
| 86 | - return $desc; |
|
| 87 | - } |
|
| 88 | - |
|
| 89 | - |
|
| 90 | - // generer le mot de passe (ou le refaire si compte inutilise) |
|
| 91 | - $desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']); |
|
| 92 | - |
|
| 93 | - // attribuer un jeton pour confirmation par clic sur un lien |
|
| 94 | - $desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']); |
|
| 95 | - |
|
| 96 | - // charger de suite cette fonction, pour ses utilitaires |
|
| 97 | - $envoyer_inscription = charger_fonction('envoyer_inscription', ''); |
|
| 98 | - [$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options); |
|
| 99 | - |
|
| 100 | - $notifications = charger_fonction('notifications', 'inc'); |
|
| 101 | - notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head); |
|
| 102 | - |
|
| 103 | - // Notifications |
|
| 104 | - $notifications( |
|
| 105 | - 'inscription', |
|
| 106 | - $desc['id_auteur'], |
|
| 107 | - ['nom' => $desc['nom'], 'email' => $desc['email']] |
|
| 108 | - ); |
|
| 109 | - |
|
| 110 | - return $desc; |
|
| 47 | + if (!is_array($options)) { |
|
| 48 | + $options = ['id' => $options]; |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + if (function_exists('test_inscription')) { |
|
| 52 | + $f = 'test_inscription'; |
|
| 53 | + } else { |
|
| 54 | + $f = 'test_inscription_dist'; |
|
| 55 | + } |
|
| 56 | + $desc = $f($statut, $mail_complet, $nom, $options); |
|
| 57 | + |
|
| 58 | + // erreur ? |
|
| 59 | + if (!is_array($desc)) { |
|
| 60 | + return _T($desc); |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + include_spip('base/abstract_sql'); |
|
| 64 | + $res = sql_select('statut, id_auteur, login, email, nom', 'spip_auteurs', 'email=' . sql_quote($desc['email'])); |
|
| 65 | + // erreur ? |
|
| 66 | + if (!$res) { |
|
| 67 | + return _T('titre_probleme_technique'); |
|
| 68 | + } |
|
| 69 | + |
|
| 70 | + $row = sql_fetch($res); |
|
| 71 | + sql_free($res); |
|
| 72 | + if ($row) { |
|
| 73 | + if (isset($options['force_nouveau']) and $options['force_nouveau'] == true) { |
|
| 74 | + $desc['id_auteur'] = $row['id_auteur']; |
|
| 75 | + $desc = inscription_nouveau($desc); |
|
| 76 | + } else { |
|
| 77 | + $desc = $row; |
|
| 78 | + } |
|
| 79 | + } else // s'il n'existe pas deja, creer les identifiants |
|
| 80 | + { |
|
| 81 | + $desc = inscription_nouveau($desc); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + // erreur ? |
|
| 85 | + if (!is_array($desc)) { |
|
| 86 | + return $desc; |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + |
|
| 90 | + // generer le mot de passe (ou le refaire si compte inutilise) |
|
| 91 | + $desc['pass'] = creer_pass_pour_auteur($desc['id_auteur']); |
|
| 92 | + |
|
| 93 | + // attribuer un jeton pour confirmation par clic sur un lien |
|
| 94 | + $desc['jeton'] = auteur_attribuer_jeton($desc['id_auteur']); |
|
| 95 | + |
|
| 96 | + // charger de suite cette fonction, pour ses utilitaires |
|
| 97 | + $envoyer_inscription = charger_fonction('envoyer_inscription', ''); |
|
| 98 | + [$sujet, $msg, $from, $head] = $envoyer_inscription($desc, $nom, $statut, $options); |
|
| 99 | + |
|
| 100 | + $notifications = charger_fonction('notifications', 'inc'); |
|
| 101 | + notifications_envoyer_mails($mail_complet, $msg, $sujet, $from, $head); |
|
| 102 | + |
|
| 103 | + // Notifications |
|
| 104 | + $notifications( |
|
| 105 | + 'inscription', |
|
| 106 | + $desc['id_auteur'], |
|
| 107 | + ['nom' => $desc['nom'], 'email' => $desc['email']] |
|
| 108 | + ); |
|
| 109 | + |
|
| 110 | + return $desc; |
|
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | |
@@ -130,23 +130,23 @@ discard block |
||
| 130 | 130 | * |
| 131 | 131 | */ |
| 132 | 132 | function test_inscription_dist($statut, $mail, $nom, $options) { |
| 133 | - include_spip('inc/filtres'); |
|
| 134 | - if (!$r = email_valide($mail)) { |
|
| 135 | - return 'info_email_invalide'; |
|
| 136 | - } |
|
| 137 | - $nom = trim(corriger_caracteres($nom)); |
|
| 138 | - $res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut]; |
|
| 139 | - if (isset($options['login'])) { |
|
| 140 | - $login = trim(corriger_caracteres($options['login'])); |
|
| 141 | - if ((strlen($login) >= _LOGIN_TROP_COURT) and (strlen($nom) <= 64)) { |
|
| 142 | - $res['login'] = $login; |
|
| 143 | - } |
|
| 144 | - } |
|
| 145 | - if (!isset($res['login']) and ((strlen($nom) < _LOGIN_TROP_COURT) or (strlen($nom) > 64))) { |
|
| 146 | - return 'ecrire:info_login_trop_court'; |
|
| 147 | - } |
|
| 148 | - |
|
| 149 | - return $res; |
|
| 133 | + include_spip('inc/filtres'); |
|
| 134 | + if (!$r = email_valide($mail)) { |
|
| 135 | + return 'info_email_invalide'; |
|
| 136 | + } |
|
| 137 | + $nom = trim(corriger_caracteres($nom)); |
|
| 138 | + $res = ['email' => $r, 'nom' => $nom, 'prefs' => $statut]; |
|
| 139 | + if (isset($options['login'])) { |
|
| 140 | + $login = trim(corriger_caracteres($options['login'])); |
|
| 141 | + if ((strlen($login) >= _LOGIN_TROP_COURT) and (strlen($nom) <= 64)) { |
|
| 142 | + $res['login'] = $login; |
|
| 143 | + } |
|
| 144 | + } |
|
| 145 | + if (!isset($res['login']) and ((strlen($nom) < _LOGIN_TROP_COURT) or (strlen($nom) > 64))) { |
|
| 146 | + return 'ecrire:info_login_trop_court'; |
|
| 147 | + } |
|
| 148 | + |
|
| 149 | + return $res; |
|
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | |
@@ -159,33 +159,33 @@ discard block |
||
| 159 | 159 | * @return mixed|string |
| 160 | 160 | */ |
| 161 | 161 | function inscription_nouveau($desc) { |
| 162 | - if (!isset($desc['login']) or !strlen($desc['login'])) { |
|
| 163 | - $desc['login'] = test_login($desc['nom'], $desc['email']); |
|
| 164 | - } |
|
| 162 | + if (!isset($desc['login']) or !strlen($desc['login'])) { |
|
| 163 | + $desc['login'] = test_login($desc['nom'], $desc['email']); |
|
| 164 | + } |
|
| 165 | 165 | |
| 166 | - $desc['statut'] = 'nouveau'; |
|
| 167 | - include_spip('action/editer_auteur'); |
|
| 168 | - if (isset($desc['id_auteur'])) { |
|
| 169 | - $id_auteur = $desc['id_auteur']; |
|
| 170 | - } else { |
|
| 171 | - $id_auteur = auteur_inserer(); |
|
| 172 | - } |
|
| 166 | + $desc['statut'] = 'nouveau'; |
|
| 167 | + include_spip('action/editer_auteur'); |
|
| 168 | + if (isset($desc['id_auteur'])) { |
|
| 169 | + $id_auteur = $desc['id_auteur']; |
|
| 170 | + } else { |
|
| 171 | + $id_auteur = auteur_inserer(); |
|
| 172 | + } |
|
| 173 | 173 | |
| 174 | - if (!$id_auteur) { |
|
| 175 | - return _T('titre_probleme_technique'); |
|
| 176 | - } |
|
| 174 | + if (!$id_auteur) { |
|
| 175 | + return _T('titre_probleme_technique'); |
|
| 176 | + } |
|
| 177 | 177 | |
| 178 | - $desc['lang'] = $GLOBALS['spip_lang']; |
|
| 178 | + $desc['lang'] = $GLOBALS['spip_lang']; |
|
| 179 | 179 | |
| 180 | - include_spip('inc/autoriser'); |
|
| 181 | - // lever l'autorisation pour pouvoir modifier le statut |
|
| 182 | - autoriser_exception('modifier', 'auteur', $id_auteur); |
|
| 183 | - auteur_modifier($id_auteur, $desc); |
|
| 184 | - autoriser_exception('modifier', 'auteur', $id_auteur, false); |
|
| 180 | + include_spip('inc/autoriser'); |
|
| 181 | + // lever l'autorisation pour pouvoir modifier le statut |
|
| 182 | + autoriser_exception('modifier', 'auteur', $id_auteur); |
|
| 183 | + auteur_modifier($id_auteur, $desc); |
|
| 184 | + autoriser_exception('modifier', 'auteur', $id_auteur, false); |
|
| 185 | 185 | |
| 186 | - $desc['id_auteur'] = $id_auteur; |
|
| 186 | + $desc['id_auteur'] = $id_auteur; |
|
| 187 | 187 | |
| 188 | - return $desc; |
|
| 188 | + return $desc; |
|
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | |
@@ -202,27 +202,27 @@ discard block |
||
| 202 | 202 | * @return string |
| 203 | 203 | */ |
| 204 | 204 | function test_login($nom, $mail) { |
| 205 | - include_spip('inc/charsets'); |
|
| 206 | - $nom = strtolower(translitteration($nom)); |
|
| 207 | - $login_base = preg_replace('/[^\w\d_]/', '_', $nom); |
|
| 208 | - |
|
| 209 | - // il faut eviter que le login soit vraiment trop court |
|
| 210 | - if (strlen($login_base) < 3) { |
|
| 211 | - $mail = strtolower(translitteration(preg_replace('/@.*/', '', $mail))); |
|
| 212 | - $login_base = preg_replace('/[^\w\d]/', '_', $mail); |
|
| 213 | - } |
|
| 214 | - if (strlen($login_base) < 3) { |
|
| 215 | - $login_base = 'user'; |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - $login = $login_base; |
|
| 219 | - |
|
| 220 | - for ($i = 1;; $i++) { |
|
| 221 | - if (!sql_countsel('spip_auteurs', "login='$login'")) { |
|
| 222 | - return $login; |
|
| 223 | - } |
|
| 224 | - $login = $login_base . $i; |
|
| 225 | - } |
|
| 205 | + include_spip('inc/charsets'); |
|
| 206 | + $nom = strtolower(translitteration($nom)); |
|
| 207 | + $login_base = preg_replace('/[^\w\d_]/', '_', $nom); |
|
| 208 | + |
|
| 209 | + // il faut eviter que le login soit vraiment trop court |
|
| 210 | + if (strlen($login_base) < 3) { |
|
| 211 | + $mail = strtolower(translitteration(preg_replace('/@.*/', '', $mail))); |
|
| 212 | + $login_base = preg_replace('/[^\w\d]/', '_', $mail); |
|
| 213 | + } |
|
| 214 | + if (strlen($login_base) < 3) { |
|
| 215 | + $login_base = 'user'; |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + $login = $login_base; |
|
| 219 | + |
|
| 220 | + for ($i = 1;; $i++) { |
|
| 221 | + if (!sql_countsel('spip_auteurs', "login='$login'")) { |
|
| 222 | + return $login; |
|
| 223 | + } |
|
| 224 | + $login = $login_base . $i; |
|
| 225 | + } |
|
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | |
@@ -240,26 +240,26 @@ discard block |
||
| 240 | 240 | */ |
| 241 | 241 | function envoyer_inscription_dist($desc, $nom, $mode, $options = []) { |
| 242 | 242 | |
| 243 | - $contexte = array_merge($desc, $options); |
|
| 244 | - $contexte['nom'] = $nom; |
|
| 245 | - $contexte['mode'] = $mode; |
|
| 246 | - $contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true); |
|
| 247 | - $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']); |
|
| 248 | - $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']); |
|
| 249 | - // S'il y a l'option redirect, on l'ajoute directement ici |
|
| 250 | - if (isset($options['redirect'])) { |
|
| 251 | - $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']); |
|
| 252 | - } |
|
| 253 | - |
|
| 254 | - $modele_mail = 'modeles/mail_inscription'; |
|
| 255 | - if (isset($options['modele_mail']) and $options['modele_mail']) { |
|
| 256 | - $modele_mail = $options['modele_mail']; |
|
| 257 | - } |
|
| 258 | - $message = recuperer_fond($modele_mail, $contexte); |
|
| 259 | - $from = ($options['from'] ?? ''); |
|
| 260 | - $head = ''; |
|
| 261 | - |
|
| 262 | - return ['', $message, $from, $head]; |
|
| 243 | + $contexte = array_merge($desc, $options); |
|
| 244 | + $contexte['nom'] = $nom; |
|
| 245 | + $contexte['mode'] = $mode; |
|
| 246 | + $contexte['url_confirm'] = generer_url_action('confirmer_inscription', '', true, true); |
|
| 247 | + $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'email', $desc['email']); |
|
| 248 | + $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'jeton', $desc['jeton']); |
|
| 249 | + // S'il y a l'option redirect, on l'ajoute directement ici |
|
| 250 | + if (isset($options['redirect'])) { |
|
| 251 | + $contexte['url_confirm'] = parametre_url($contexte['url_confirm'], 'redirect', $options['redirect']); |
|
| 252 | + } |
|
| 253 | + |
|
| 254 | + $modele_mail = 'modeles/mail_inscription'; |
|
| 255 | + if (isset($options['modele_mail']) and $options['modele_mail']) { |
|
| 256 | + $modele_mail = $options['modele_mail']; |
|
| 257 | + } |
|
| 258 | + $message = recuperer_fond($modele_mail, $contexte); |
|
| 259 | + $from = ($options['from'] ?? ''); |
|
| 260 | + $head = ''; |
|
| 261 | + |
|
| 262 | + return ['', $message, $from, $head]; |
|
| 263 | 263 | } |
| 264 | 264 | |
| 265 | 265 | |
@@ -270,12 +270,12 @@ discard block |
||
| 270 | 270 | * @return string |
| 271 | 271 | */ |
| 272 | 272 | function creer_pass_pour_auteur($id_auteur) { |
| 273 | - include_spip('inc/acces'); |
|
| 274 | - $pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur); |
|
| 275 | - include_spip('action/editer_auteur'); |
|
| 276 | - auteur_instituer($id_auteur, ['pass' => $pass]); |
|
| 273 | + include_spip('inc/acces'); |
|
| 274 | + $pass = creer_pass_aleatoire(max(_PASS_LONGUEUR_MINI, 16), $id_auteur); |
|
| 275 | + include_spip('action/editer_auteur'); |
|
| 276 | + auteur_instituer($id_auteur, ['pass' => $pass]); |
|
| 277 | 277 | |
| 278 | - return $pass; |
|
| 278 | + return $pass; |
|
| 279 | 279 | } |
| 280 | 280 | |
| 281 | 281 | /** |
@@ -288,17 +288,17 @@ discard block |
||
| 288 | 288 | * @return string |
| 289 | 289 | */ |
| 290 | 290 | function tester_statut_inscription($statut_tmp, $id) { |
| 291 | - include_spip('inc/autoriser'); |
|
| 292 | - if ($statut_tmp) { |
|
| 293 | - return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : ''; |
|
| 294 | - } elseif ( |
|
| 295 | - autoriser('inscrireauteur', $statut_tmp = '1comite', $id) |
|
| 296 | - or autoriser('inscrireauteur', $statut_tmp = '6forum', $id) |
|
| 297 | - ) { |
|
| 298 | - return $statut_tmp; |
|
| 299 | - } |
|
| 300 | - |
|
| 301 | - return ''; |
|
| 291 | + include_spip('inc/autoriser'); |
|
| 292 | + if ($statut_tmp) { |
|
| 293 | + return autoriser('inscrireauteur', $statut_tmp, $id) ? $statut_tmp : ''; |
|
| 294 | + } elseif ( |
|
| 295 | + autoriser('inscrireauteur', $statut_tmp = '1comite', $id) |
|
| 296 | + or autoriser('inscrireauteur', $statut_tmp = '6forum', $id) |
|
| 297 | + ) { |
|
| 298 | + return $statut_tmp; |
|
| 299 | + } |
|
| 300 | + |
|
| 301 | + return ''; |
|
| 302 | 302 | } |
| 303 | 303 | |
| 304 | 304 | |
@@ -312,35 +312,35 @@ discard block |
||
| 312 | 312 | * @return array |
| 313 | 313 | */ |
| 314 | 314 | function confirmer_statut_inscription($auteur) { |
| 315 | - // securite |
|
| 316 | - if ($auteur['statut'] != 'nouveau') { |
|
| 317 | - return $auteur; |
|
| 318 | - } |
|
| 319 | - |
|
| 320 | - $s = $auteur['prefs']; |
|
| 321 | - // securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize) |
|
| 322 | - if (!preg_match(',^\w+$,', $s)) { |
|
| 323 | - $s = '6forum'; |
|
| 324 | - } |
|
| 325 | - include_spip('inc/autoriser'); |
|
| 326 | - if (!autoriser('inscrireauteur', $s)) { |
|
| 327 | - return $auteur; |
|
| 328 | - } |
|
| 329 | - |
|
| 330 | - include_spip('inc/autoriser'); |
|
| 331 | - // accorder l'autorisation de modif du statut auteur |
|
| 332 | - autoriser_exception('modifier', 'auteur', $auteur['id_auteur']); |
|
| 333 | - include_spip('action/editer_auteur'); |
|
| 334 | - // changer le statut |
|
| 335 | - auteur_modifier($auteur['id_auteur'], ['statut' => $s]); |
|
| 336 | - unset($_COOKIE['spip_session']); // forcer la maj de la session |
|
| 337 | - // lever l'autorisation de modif du statut auteur |
|
| 338 | - autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false); |
|
| 339 | - |
|
| 340 | - // mettre a jour le statut |
|
| 341 | - $auteur['statut'] = $s; |
|
| 342 | - |
|
| 343 | - return $auteur; |
|
| 315 | + // securite |
|
| 316 | + if ($auteur['statut'] != 'nouveau') { |
|
| 317 | + return $auteur; |
|
| 318 | + } |
|
| 319 | + |
|
| 320 | + $s = $auteur['prefs']; |
|
| 321 | + // securite, au cas ou prefs aurait ete corrompu (ou deja ecrase par un tableau serialize) |
|
| 322 | + if (!preg_match(',^\w+$,', $s)) { |
|
| 323 | + $s = '6forum'; |
|
| 324 | + } |
|
| 325 | + include_spip('inc/autoriser'); |
|
| 326 | + if (!autoriser('inscrireauteur', $s)) { |
|
| 327 | + return $auteur; |
|
| 328 | + } |
|
| 329 | + |
|
| 330 | + include_spip('inc/autoriser'); |
|
| 331 | + // accorder l'autorisation de modif du statut auteur |
|
| 332 | + autoriser_exception('modifier', 'auteur', $auteur['id_auteur']); |
|
| 333 | + include_spip('action/editer_auteur'); |
|
| 334 | + // changer le statut |
|
| 335 | + auteur_modifier($auteur['id_auteur'], ['statut' => $s]); |
|
| 336 | + unset($_COOKIE['spip_session']); // forcer la maj de la session |
|
| 337 | + // lever l'autorisation de modif du statut auteur |
|
| 338 | + autoriser_exception('modifier', 'auteur', $auteur['id_auteur'], false); |
|
| 339 | + |
|
| 340 | + // mettre a jour le statut |
|
| 341 | + $auteur['statut'] = $s; |
|
| 342 | + |
|
| 343 | + return $auteur; |
|
| 344 | 344 | } |
| 345 | 345 | |
| 346 | 346 | |
@@ -354,20 +354,20 @@ discard block |
||
| 354 | 354 | * @return string |
| 355 | 355 | */ |
| 356 | 356 | function auteur_attribuer_jeton($id_auteur): string { |
| 357 | - include_spip('base/abstract_sql'); |
|
| 358 | - include_spip('inc/acces'); |
|
| 359 | - |
|
| 360 | - // s'assurer de l'unicite du jeton pour le couple (email,cookie) |
|
| 361 | - do { |
|
| 362 | - // Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer |
|
| 363 | - // tous les jetons connus pour vérifier le jeton d’un auteur. |
|
| 364 | - $public = substr(creer_uniqid(), 0, 7) . '.'; |
|
| 365 | - $jeton = $public . creer_uniqid(); |
|
| 366 | - $jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site()); |
|
| 367 | - sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . intval($id_auteur)); |
|
| 368 | - } while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1); |
|
| 369 | - |
|
| 370 | - return $jeton; |
|
| 357 | + include_spip('base/abstract_sql'); |
|
| 358 | + include_spip('inc/acces'); |
|
| 359 | + |
|
| 360 | + // s'assurer de l'unicite du jeton pour le couple (email,cookie) |
|
| 361 | + do { |
|
| 362 | + // Un morceau du jeton est lisible en bdd pour éviter de devoir déchiffrer |
|
| 363 | + // tous les jetons connus pour vérifier le jeton d’un auteur. |
|
| 364 | + $public = substr(creer_uniqid(), 0, 7) . '.'; |
|
| 365 | + $jeton = $public . creer_uniqid(); |
|
| 366 | + $jeton_chiffre_prefixe = $public . Chiffrement::chiffrer($jeton, SpipCles::secret_du_site()); |
|
| 367 | + sql_updateq('spip_auteurs', ['cookie_oubli' => $jeton_chiffre_prefixe], 'id_auteur=' . intval($id_auteur)); |
|
| 368 | + } while (sql_countsel('spip_auteurs', 'cookie_oubli=' . sql_quote($jeton_chiffre_prefixe, '', 'string')) > 1); |
|
| 369 | + |
|
| 370 | + return $jeton; |
|
| 371 | 371 | } |
| 372 | 372 | |
| 373 | 373 | /** |
@@ -381,19 +381,19 @@ discard block |
||
| 381 | 381 | * @return string|null |
| 382 | 382 | */ |
| 383 | 383 | function auteur_lire_jeton(int $id_auteur, bool $autoInit = false): ?string { |
| 384 | - include_spip('base/abstract_sql'); |
|
| 385 | - $jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur); |
|
| 386 | - if ($jeton_chiffre_prefixe) { |
|
| 387 | - $jeton_chiffre = substr($jeton_chiffre_prefixe, 8); |
|
| 388 | - $jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site()); |
|
| 389 | - if ($jeton) { |
|
| 390 | - return $jeton; |
|
| 391 | - } |
|
| 392 | - } |
|
| 393 | - if ($autoInit) { |
|
| 394 | - return auteur_attribuer_jeton($id_auteur); |
|
| 395 | - } |
|
| 396 | - return null; |
|
| 384 | + include_spip('base/abstract_sql'); |
|
| 385 | + $jeton_chiffre_prefixe = sql_getfetsel('cookie_oubli', 'spip_auteurs', 'id_auteur=' . $id_auteur); |
|
| 386 | + if ($jeton_chiffre_prefixe) { |
|
| 387 | + $jeton_chiffre = substr($jeton_chiffre_prefixe, 8); |
|
| 388 | + $jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site()); |
|
| 389 | + if ($jeton) { |
|
| 390 | + return $jeton; |
|
| 391 | + } |
|
| 392 | + } |
|
| 393 | + if ($autoInit) { |
|
| 394 | + return auteur_attribuer_jeton($id_auteur); |
|
| 395 | + } |
|
| 396 | + return null; |
|
| 397 | 397 | } |
| 398 | 398 | |
| 399 | 399 | /** |
@@ -403,24 +403,24 @@ discard block |
||
| 403 | 403 | * @return array|bool |
| 404 | 404 | */ |
| 405 | 405 | function auteur_verifier_jeton($jeton) { |
| 406 | - // refuser un jeton corrompu |
|
| 407 | - if (preg_match(',[^0-9a-f.],i', $jeton)) { |
|
| 408 | - return false; |
|
| 409 | - } |
|
| 410 | - |
|
| 411 | - include_spip('base/abstract_sql'); |
|
| 412 | - $public = substr($jeton, 0, 8); |
|
| 413 | - |
|
| 414 | - // Les auteurs qui ont un jetons ressemblant |
|
| 415 | - $auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%')); |
|
| 416 | - foreach ($auteurs as $auteur) { |
|
| 417 | - $jeton_chiffre = substr($auteur['cookie_oubli'], 8); |
|
| 418 | - $_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site()); |
|
| 419 | - if ($_jeton and hash_equals($jeton, $_jeton)) { |
|
| 420 | - return $auteur; |
|
| 421 | - } |
|
| 422 | - } |
|
| 423 | - return false; |
|
| 406 | + // refuser un jeton corrompu |
|
| 407 | + if (preg_match(',[^0-9a-f.],i', $jeton)) { |
|
| 408 | + return false; |
|
| 409 | + } |
|
| 410 | + |
|
| 411 | + include_spip('base/abstract_sql'); |
|
| 412 | + $public = substr($jeton, 0, 8); |
|
| 413 | + |
|
| 414 | + // Les auteurs qui ont un jetons ressemblant |
|
| 415 | + $auteurs = sql_allfetsel('*', 'spip_auteurs', 'cookie_oubli LIKE ' . sql_quote($public . '%')); |
|
| 416 | + foreach ($auteurs as $auteur) { |
|
| 417 | + $jeton_chiffre = substr($auteur['cookie_oubli'], 8); |
|
| 418 | + $_jeton = Chiffrement::dechiffrer($jeton_chiffre, SpipCles::secret_du_site()); |
|
| 419 | + if ($_jeton and hash_equals($jeton, $_jeton)) { |
|
| 420 | + return $auteur; |
|
| 421 | + } |
|
| 422 | + } |
|
| 423 | + return false; |
|
| 424 | 424 | } |
| 425 | 425 | |
| 426 | 426 | /** |
@@ -430,6 +430,6 @@ discard block |
||
| 430 | 430 | * @return bool |
| 431 | 431 | */ |
| 432 | 432 | function auteur_effacer_jeton($id_auteur) { |
| 433 | - include_spip('base/abstract_sql'); |
|
| 434 | - return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . intval($id_auteur)); |
|
| 433 | + include_spip('base/abstract_sql'); |
|
| 434 | + return sql_updateq('spip_auteurs', ['cookie_oubli' => ''], 'id_auteur=' . intval($id_auteur)); |
|
| 435 | 435 | } |
@@ -13,122 +13,122 @@ |
||
| 13 | 13 | |
| 14 | 14 | class SqliteRequeteur |
| 15 | 15 | { |
| 16 | - /** @var string texte de la requête */ |
|
| 17 | - public $query = ''; // la requete |
|
| 18 | - /** @var string Nom de la connexion */ |
|
| 19 | - public $serveur = ''; |
|
| 20 | - /** @var PDO Identifiant de la connexion SQLite */ |
|
| 21 | - public $link = ''; |
|
| 22 | - /** @var string Prefixe des tables SPIP */ |
|
| 23 | - public $prefixe = ''; |
|
| 24 | - /** @var string Nom de la base de donnée */ |
|
| 25 | - public $db = ''; |
|
| 26 | - /** @var bool Doit-on tracer les requetes (var_profile) ? */ |
|
| 27 | - public $tracer = false; // doit-on tracer les requetes (var_profile) |
|
| 28 | - |
|
| 29 | - /** @var string Version de SQLite (2 ou 3) */ |
|
| 30 | - public $sqlite_version = ''; |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * Constructeur |
|
| 34 | - * |
|
| 35 | - * @param string $serveur |
|
| 36 | - * @return bool |
|
| 37 | - */ |
|
| 38 | - public function __construct($serveur = '') |
|
| 39 | - { |
|
| 40 | - _sqlite_init(); |
|
| 41 | - $this->serveur = strtolower($serveur); |
|
| 42 | - |
|
| 43 | - if (!($this->link = _sqlite_link($this->serveur)) && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)) { |
|
| 44 | - spip_log('Aucune connexion sqlite (link)', 'sqlite.' . _LOG_ERREUR); |
|
| 45 | - |
|
| 46 | - return false; |
|
| 47 | - } |
|
| 48 | - |
|
| 49 | - $this->sqlite_version = _sqlite_is_version('', $this->link); |
|
| 50 | - |
|
| 51 | - $this->prefixe = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['prefixe']; |
|
| 52 | - $this->db = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['db']; |
|
| 53 | - |
|
| 54 | - // tracage des requetes ? |
|
| 55 | - $this->tracer = (isset($_GET['var_profile']) && $_GET['var_profile']); |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Lancer la requête transmise et faire le tracage si demandé |
|
| 60 | - * |
|
| 61 | - * @param string $query |
|
| 62 | - * Requête à exécuter |
|
| 63 | - * @param bool|null $tracer |
|
| 64 | - * true pour tracer la requête |
|
| 65 | - * @return bool|PDOStatement|array |
|
| 66 | - */ |
|
| 67 | - public function executer_requete($query, $tracer = null) |
|
| 68 | - { |
|
| 69 | - if (is_null($tracer)) { |
|
| 70 | - $tracer = $this->tracer; |
|
| 71 | - } |
|
| 72 | - $err = ''; |
|
| 73 | - $t = 0; |
|
| 74 | - if ($tracer or (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES)) { |
|
| 75 | - include_spip('public/tracer'); |
|
| 76 | - $t = trace_query_start(); |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - # spip_log("requete: $this->serveur >> $query",'sqlite.'._LOG_DEBUG); // boum ? pourquoi ? |
|
| 80 | - if ($this->link) { |
|
| 81 | - // memoriser la derniere erreur PHP vue |
|
| 82 | - $last_error = (function_exists('error_get_last') ? error_get_last() : ''); |
|
| 83 | - $e = null; |
|
| 84 | - // sauver la derniere requete |
|
| 85 | - $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['last'] = $query; |
|
| 86 | - $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['total_requetes']++; |
|
| 87 | - |
|
| 88 | - try { |
|
| 89 | - $r = $this->link->query($query); |
|
| 90 | - } catch (\PDOException $e) { |
|
| 91 | - spip_log('PDOException: ' . $e->getMessage(), 'sqlite.' . _LOG_DEBUG); |
|
| 92 | - $r = false; |
|
| 93 | - } |
|
| 94 | - |
|
| 95 | - // comptage : oblige de compter le nombre d'entrees retournees |
|
| 96 | - // par une requete SELECT |
|
| 97 | - // aucune autre solution ne donne le nombre attendu :( ! |
|
| 98 | - // particulierement s'il y a des LIMIT dans la requete. |
|
| 99 | - if ($r and strtoupper(substr(ltrim($query), 0, 6)) === 'SELECT') { |
|
| 100 | - // noter le link et la query pour faire le comptage *si* on en a besoin |
|
| 101 | - $r->spipSqliteRowCount = [$this->link, $query]; |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - // loger les warnings/erreurs eventuels de sqlite remontant dans PHP |
|
| 105 | - if ($e and $e instanceof \PDOException) { |
|
| 106 | - $err = strip_tags($e->getMessage()) . ' in ' . $e->getFile() . ' line ' . $e->getLine(); |
|
| 107 | - spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR); |
|
| 108 | - } elseif ($err = (function_exists('error_get_last') ? error_get_last() : '') and $err != $last_error) { |
|
| 109 | - $err = strip_tags($err['message']) . ' in ' . $err['file'] . ' line ' . $err['line']; |
|
| 110 | - spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR); |
|
| 111 | - } else { |
|
| 112 | - $err = ''; |
|
| 113 | - } |
|
| 114 | - } else { |
|
| 115 | - $r = false; |
|
| 116 | - } |
|
| 117 | - |
|
| 118 | - if (spip_sqlite_errno($this->serveur)) { |
|
| 119 | - $err .= spip_sqlite_error($query, $this->serveur); |
|
| 120 | - } |
|
| 121 | - |
|
| 122 | - return $t ? trace_query_end($query, $t, $r, $err, $this->serveur) : $r; |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - /** |
|
| 126 | - * Obtient l'identifiant de la dernière ligne insérée ou modifiée |
|
| 127 | - * |
|
| 128 | - * @return string|false |
|
| 129 | - **/ |
|
| 130 | - public function last_insert_id() |
|
| 131 | - { |
|
| 132 | - return $this->link->lastInsertId(); |
|
| 133 | - } |
|
| 16 | + /** @var string texte de la requête */ |
|
| 17 | + public $query = ''; // la requete |
|
| 18 | + /** @var string Nom de la connexion */ |
|
| 19 | + public $serveur = ''; |
|
| 20 | + /** @var PDO Identifiant de la connexion SQLite */ |
|
| 21 | + public $link = ''; |
|
| 22 | + /** @var string Prefixe des tables SPIP */ |
|
| 23 | + public $prefixe = ''; |
|
| 24 | + /** @var string Nom de la base de donnée */ |
|
| 25 | + public $db = ''; |
|
| 26 | + /** @var bool Doit-on tracer les requetes (var_profile) ? */ |
|
| 27 | + public $tracer = false; // doit-on tracer les requetes (var_profile) |
|
| 28 | + |
|
| 29 | + /** @var string Version de SQLite (2 ou 3) */ |
|
| 30 | + public $sqlite_version = ''; |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * Constructeur |
|
| 34 | + * |
|
| 35 | + * @param string $serveur |
|
| 36 | + * @return bool |
|
| 37 | + */ |
|
| 38 | + public function __construct($serveur = '') |
|
| 39 | + { |
|
| 40 | + _sqlite_init(); |
|
| 41 | + $this->serveur = strtolower($serveur); |
|
| 42 | + |
|
| 43 | + if (!($this->link = _sqlite_link($this->serveur)) && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)) { |
|
| 44 | + spip_log('Aucune connexion sqlite (link)', 'sqlite.' . _LOG_ERREUR); |
|
| 45 | + |
|
| 46 | + return false; |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + $this->sqlite_version = _sqlite_is_version('', $this->link); |
|
| 50 | + |
|
| 51 | + $this->prefixe = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['prefixe']; |
|
| 52 | + $this->db = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['db']; |
|
| 53 | + |
|
| 54 | + // tracage des requetes ? |
|
| 55 | + $this->tracer = (isset($_GET['var_profile']) && $_GET['var_profile']); |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Lancer la requête transmise et faire le tracage si demandé |
|
| 60 | + * |
|
| 61 | + * @param string $query |
|
| 62 | + * Requête à exécuter |
|
| 63 | + * @param bool|null $tracer |
|
| 64 | + * true pour tracer la requête |
|
| 65 | + * @return bool|PDOStatement|array |
|
| 66 | + */ |
|
| 67 | + public function executer_requete($query, $tracer = null) |
|
| 68 | + { |
|
| 69 | + if (is_null($tracer)) { |
|
| 70 | + $tracer = $this->tracer; |
|
| 71 | + } |
|
| 72 | + $err = ''; |
|
| 73 | + $t = 0; |
|
| 74 | + if ($tracer or (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES)) { |
|
| 75 | + include_spip('public/tracer'); |
|
| 76 | + $t = trace_query_start(); |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + # spip_log("requete: $this->serveur >> $query",'sqlite.'._LOG_DEBUG); // boum ? pourquoi ? |
|
| 80 | + if ($this->link) { |
|
| 81 | + // memoriser la derniere erreur PHP vue |
|
| 82 | + $last_error = (function_exists('error_get_last') ? error_get_last() : ''); |
|
| 83 | + $e = null; |
|
| 84 | + // sauver la derniere requete |
|
| 85 | + $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['last'] = $query; |
|
| 86 | + $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['total_requetes']++; |
|
| 87 | + |
|
| 88 | + try { |
|
| 89 | + $r = $this->link->query($query); |
|
| 90 | + } catch (\PDOException $e) { |
|
| 91 | + spip_log('PDOException: ' . $e->getMessage(), 'sqlite.' . _LOG_DEBUG); |
|
| 92 | + $r = false; |
|
| 93 | + } |
|
| 94 | + |
|
| 95 | + // comptage : oblige de compter le nombre d'entrees retournees |
|
| 96 | + // par une requete SELECT |
|
| 97 | + // aucune autre solution ne donne le nombre attendu :( ! |
|
| 98 | + // particulierement s'il y a des LIMIT dans la requete. |
|
| 99 | + if ($r and strtoupper(substr(ltrim($query), 0, 6)) === 'SELECT') { |
|
| 100 | + // noter le link et la query pour faire le comptage *si* on en a besoin |
|
| 101 | + $r->spipSqliteRowCount = [$this->link, $query]; |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + // loger les warnings/erreurs eventuels de sqlite remontant dans PHP |
|
| 105 | + if ($e and $e instanceof \PDOException) { |
|
| 106 | + $err = strip_tags($e->getMessage()) . ' in ' . $e->getFile() . ' line ' . $e->getLine(); |
|
| 107 | + spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR); |
|
| 108 | + } elseif ($err = (function_exists('error_get_last') ? error_get_last() : '') and $err != $last_error) { |
|
| 109 | + $err = strip_tags($err['message']) . ' in ' . $err['file'] . ' line ' . $err['line']; |
|
| 110 | + spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR); |
|
| 111 | + } else { |
|
| 112 | + $err = ''; |
|
| 113 | + } |
|
| 114 | + } else { |
|
| 115 | + $r = false; |
|
| 116 | + } |
|
| 117 | + |
|
| 118 | + if (spip_sqlite_errno($this->serveur)) { |
|
| 119 | + $err .= spip_sqlite_error($query, $this->serveur); |
|
| 120 | + } |
|
| 121 | + |
|
| 122 | + return $t ? trace_query_end($query, $t, $r, $err, $this->serveur) : $r; |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + /** |
|
| 126 | + * Obtient l'identifiant de la dernière ligne insérée ou modifiée |
|
| 127 | + * |
|
| 128 | + * @return string|false |
|
| 129 | + **/ |
|
| 130 | + public function last_insert_id() |
|
| 131 | + { |
|
| 132 | + return $this->link->lastInsertId(); |
|
| 133 | + } |
|
| 134 | 134 | } |
@@ -9,211 +9,211 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class SqliteTraducteur |
| 11 | 11 | { |
| 12 | - /** @var string $query texte de la requête */ |
|
| 13 | - public $query = ''; |
|
| 14 | - |
|
| 15 | - /** @var string $prefixe Préfixe des tables */ |
|
| 16 | - public $prefixe = ''; |
|
| 17 | - |
|
| 18 | - /** @var string $sqlite_version Version de sqlite (2 ou 3) */ |
|
| 19 | - public $sqlite_version = ''; |
|
| 20 | - |
|
| 21 | - /** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé |
|
| 22 | - * |
|
| 23 | - * @var array |
|
| 24 | - */ |
|
| 25 | - public $textes = []; |
|
| 26 | - |
|
| 27 | - /** |
|
| 28 | - * Constructeur |
|
| 29 | - * |
|
| 30 | - * @param string $query Requête à préparer |
|
| 31 | - * @param string $prefixe Prefixe des tables à utiliser |
|
| 32 | - * @param string $sqlite_version Version SQLite (2 ou 3) |
|
| 33 | - */ |
|
| 34 | - public function __construct($query, $prefixe, $sqlite_version) |
|
| 35 | - { |
|
| 36 | - $this->query = $query; |
|
| 37 | - $this->prefixe = $prefixe; |
|
| 38 | - $this->sqlite_version = $sqlite_version; |
|
| 39 | - } |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * Transformer la requete pour SQLite |
|
| 43 | - * |
|
| 44 | - * Enlève les textes, transforme la requête pour quelle soit |
|
| 45 | - * bien interprétée par SQLite, puis remet les textes |
|
| 46 | - * la fonction affecte `$this->query` |
|
| 47 | - */ |
|
| 48 | - public function traduire_requete() |
|
| 49 | - { |
|
| 50 | - // |
|
| 51 | - // 1) Protection des textes en les remplacant par des codes |
|
| 52 | - // |
|
| 53 | - // enlever les 'textes' et initialiser avec |
|
| 54 | - list($this->query, $textes) = query_echappe_textes($this->query); |
|
| 55 | - |
|
| 56 | - // |
|
| 57 | - // 2) Corrections de la requete |
|
| 58 | - // |
|
| 59 | - // Correction Create Database |
|
| 60 | - // Create Database -> requete ignoree |
|
| 61 | - if (strpos($this->query, 'CREATE DATABASE') === 0) { |
|
| 62 | - spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT); |
|
| 63 | - $this->query = 'SELECT 1'; |
|
| 64 | - } |
|
| 65 | - |
|
| 66 | - // Correction Insert Ignore |
|
| 67 | - // INSERT IGNORE -> insert (tout court et pas 'insert or replace') |
|
| 68 | - if (strpos($this->query, 'INSERT IGNORE') === 0) { |
|
| 69 | - spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG); |
|
| 70 | - $this->query = 'INSERT ' . substr($this->query, '13'); |
|
| 71 | - } |
|
| 72 | - |
|
| 73 | - // Correction des dates avec INTERVAL |
|
| 74 | - // utiliser sql_date_proche() de preference |
|
| 75 | - if (strpos($this->query, 'INTERVAL') !== false) { |
|
| 76 | - $this->query = preg_replace_callback( |
|
| 77 | - '/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U', |
|
| 78 | - [&$this, '_remplacerDateParTime'], |
|
| 79 | - $this->query |
|
| 80 | - ); |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - if (strpos($this->query, 'LEFT(') !== false) { |
|
| 84 | - $this->query = str_replace('LEFT(', '_LEFT(', $this->query); |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) { |
|
| 88 | - $this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query); |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - |
|
| 92 | - // Correction Using |
|
| 93 | - // USING (non reconnu en sqlite2) |
|
| 94 | - // problematique car la jointure ne se fait pas du coup. |
|
| 95 | - if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) { |
|
| 96 | - spip_log( |
|
| 97 | - "'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'", |
|
| 98 | - 'sqlite.' . _LOG_ERREUR |
|
| 99 | - ); |
|
| 100 | - $this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query); |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - // Correction Field |
|
| 104 | - // remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END |
|
| 105 | - if (strpos($this->query, 'FIELD') !== false) { |
|
| 106 | - $this->query = preg_replace_callback( |
|
| 107 | - '/FIELD\s*\(([^\)]*)\)/', |
|
| 108 | - [&$this, '_remplacerFieldParCase'], |
|
| 109 | - $this->query |
|
| 110 | - ); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - // Correction des noms de tables FROM |
|
| 114 | - // mettre les bons noms de table dans from, update, insert, replace... |
|
| 115 | - if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) { |
|
| 116 | - $suite = strstr($this->query, $regs[0]); |
|
| 117 | - $this->query = substr($this->query, 0, -strlen($suite)); |
|
| 118 | - } else { |
|
| 119 | - $suite = ''; |
|
| 120 | - } |
|
| 121 | - $pref = ($this->prefixe) ? $this->prefixe . '_' : ''; |
|
| 122 | - $this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite; |
|
| 123 | - |
|
| 124 | - // Correction zero AS x |
|
| 125 | - // pg n'aime pas 0+x AS alias, sqlite, dans le meme style, |
|
| 126 | - // n'apprecie pas du tout SELECT 0 as x ... ORDER BY x |
|
| 127 | - // il dit que x ne doit pas être un integer dans le order by ! |
|
| 128 | - // on remplace du coup x par vide() dans ce cas uniquement |
|
| 129 | - // |
|
| 130 | - // apparait dans public/vertebrer.php et dans le plugin menu aussi qui genere aussi ce genre de requete via un {par num #GET{tri_num}} |
|
| 131 | - // mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28) |
|
| 132 | - if ((strpos($this->query, '0 AS') !== false)) { |
|
| 133 | - // on ne remplace que dans ORDER BY ou GROUP BY |
|
| 134 | - if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) { |
|
| 135 | - $suite = strstr($this->query, $regs[0]); |
|
| 136 | - $this->query = substr($this->query, 0, -strlen($suite)); |
|
| 137 | - |
|
| 138 | - // on cherche les noms des x dans 0 AS x |
|
| 139 | - // on remplace dans $suite le nom par vide() |
|
| 140 | - preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER); |
|
| 141 | - foreach ($matches[1] as $m) { |
|
| 142 | - if (strpos($suite, $m) !== false) { |
|
| 143 | - $suite = preg_replace(",\b$m\b,", 'VIDE()', $suite); |
|
| 144 | - } |
|
| 145 | - } |
|
| 146 | - $this->query .= $suite; |
|
| 147 | - } |
|
| 148 | - } |
|
| 149 | - |
|
| 150 | - // Correction possible des divisions entieres |
|
| 151 | - // Le standard SQL (lequel? ou?) semble indiquer que |
|
| 152 | - // a/b=c doit donner c entier si a et b sont entiers 4/3=1. |
|
| 153 | - // C'est ce que retournent effectivement SQL Server et SQLite |
|
| 154 | - // Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333... |
|
| 155 | - // |
|
| 156 | - // On peut forcer la conversion en multipliant par 1.0 avant la division |
|
| 157 | - // /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus ! |
|
| 158 | - // cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228 |
|
| 159 | - // http://www.sqlite.org/cvstrac/tktview?tn=3202 |
|
| 160 | - // (4*1.0/3) n'est pas rendu dans ce cas ! |
|
| 161 | - # $this->query = str_replace('/','* 1.00 / ',$this->query); |
|
| 162 | - |
|
| 163 | - |
|
| 164 | - // Correction critere REGEXP, non reconnu en sqlite2 |
|
| 165 | - if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) { |
|
| 166 | - $this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query); |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - // |
|
| 170 | - // 3) Remise en place des textes d'origine |
|
| 171 | - // |
|
| 172 | - // Correction Antiquotes et echappements |
|
| 173 | - // ` => rien |
|
| 174 | - if (strpos($this->query, '`') !== false) { |
|
| 175 | - $this->query = str_replace('`', '', $this->query); |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - $this->query = query_reinjecte_textes($this->query, $textes); |
|
| 179 | - |
|
| 180 | - return $this->query; |
|
| 181 | - } |
|
| 182 | - |
|
| 183 | - /** |
|
| 184 | - * Callback pour remplacer `DATE_` / `INTERVAL` |
|
| 185 | - * par `DATE ... strtotime` |
|
| 186 | - * |
|
| 187 | - * @param array $matches Captures |
|
| 188 | - * @return string texte de date compris par SQLite |
|
| 189 | - */ |
|
| 190 | - public function _remplacerDateParTime($matches) |
|
| 191 | - { |
|
| 192 | - $op = strtoupper($matches[1] == 'ADD') ? '+' : '-'; |
|
| 193 | - |
|
| 194 | - return "datetime$matches[2] '$op$matches[3] $matches[4]')"; |
|
| 195 | - } |
|
| 196 | - |
|
| 197 | - /** |
|
| 198 | - * Callback pour remplacer `FIELD(table,i,j,k...)` |
|
| 199 | - * par `CASE WHEN table=i THEN n ... ELSE 0 END` |
|
| 200 | - * |
|
| 201 | - * @param array $matches Captures |
|
| 202 | - * @return string texte de liste ordonnée compris par SQLite |
|
| 203 | - */ |
|
| 204 | - public function _remplacerFieldParCase($matches) |
|
| 205 | - { |
|
| 206 | - $fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X) |
|
| 207 | - $t = explode(',', $fields); |
|
| 208 | - $index = array_shift($t); |
|
| 209 | - |
|
| 210 | - $res = ''; |
|
| 211 | - $n = 0; |
|
| 212 | - foreach ($t as $v) { |
|
| 213 | - $n++; |
|
| 214 | - $res .= "\nWHEN $index=$v THEN $n"; |
|
| 215 | - } |
|
| 216 | - |
|
| 217 | - return "CASE $res ELSE 0 END "; |
|
| 218 | - } |
|
| 12 | + /** @var string $query texte de la requête */ |
|
| 13 | + public $query = ''; |
|
| 14 | + |
|
| 15 | + /** @var string $prefixe Préfixe des tables */ |
|
| 16 | + public $prefixe = ''; |
|
| 17 | + |
|
| 18 | + /** @var string $sqlite_version Version de sqlite (2 ou 3) */ |
|
| 19 | + public $sqlite_version = ''; |
|
| 20 | + |
|
| 21 | + /** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé |
|
| 22 | + * |
|
| 23 | + * @var array |
|
| 24 | + */ |
|
| 25 | + public $textes = []; |
|
| 26 | + |
|
| 27 | + /** |
|
| 28 | + * Constructeur |
|
| 29 | + * |
|
| 30 | + * @param string $query Requête à préparer |
|
| 31 | + * @param string $prefixe Prefixe des tables à utiliser |
|
| 32 | + * @param string $sqlite_version Version SQLite (2 ou 3) |
|
| 33 | + */ |
|
| 34 | + public function __construct($query, $prefixe, $sqlite_version) |
|
| 35 | + { |
|
| 36 | + $this->query = $query; |
|
| 37 | + $this->prefixe = $prefixe; |
|
| 38 | + $this->sqlite_version = $sqlite_version; |
|
| 39 | + } |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * Transformer la requete pour SQLite |
|
| 43 | + * |
|
| 44 | + * Enlève les textes, transforme la requête pour quelle soit |
|
| 45 | + * bien interprétée par SQLite, puis remet les textes |
|
| 46 | + * la fonction affecte `$this->query` |
|
| 47 | + */ |
|
| 48 | + public function traduire_requete() |
|
| 49 | + { |
|
| 50 | + // |
|
| 51 | + // 1) Protection des textes en les remplacant par des codes |
|
| 52 | + // |
|
| 53 | + // enlever les 'textes' et initialiser avec |
|
| 54 | + list($this->query, $textes) = query_echappe_textes($this->query); |
|
| 55 | + |
|
| 56 | + // |
|
| 57 | + // 2) Corrections de la requete |
|
| 58 | + // |
|
| 59 | + // Correction Create Database |
|
| 60 | + // Create Database -> requete ignoree |
|
| 61 | + if (strpos($this->query, 'CREATE DATABASE') === 0) { |
|
| 62 | + spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT); |
|
| 63 | + $this->query = 'SELECT 1'; |
|
| 64 | + } |
|
| 65 | + |
|
| 66 | + // Correction Insert Ignore |
|
| 67 | + // INSERT IGNORE -> insert (tout court et pas 'insert or replace') |
|
| 68 | + if (strpos($this->query, 'INSERT IGNORE') === 0) { |
|
| 69 | + spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG); |
|
| 70 | + $this->query = 'INSERT ' . substr($this->query, '13'); |
|
| 71 | + } |
|
| 72 | + |
|
| 73 | + // Correction des dates avec INTERVAL |
|
| 74 | + // utiliser sql_date_proche() de preference |
|
| 75 | + if (strpos($this->query, 'INTERVAL') !== false) { |
|
| 76 | + $this->query = preg_replace_callback( |
|
| 77 | + '/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U', |
|
| 78 | + [&$this, '_remplacerDateParTime'], |
|
| 79 | + $this->query |
|
| 80 | + ); |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + if (strpos($this->query, 'LEFT(') !== false) { |
|
| 84 | + $this->query = str_replace('LEFT(', '_LEFT(', $this->query); |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) { |
|
| 88 | + $this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query); |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + |
|
| 92 | + // Correction Using |
|
| 93 | + // USING (non reconnu en sqlite2) |
|
| 94 | + // problematique car la jointure ne se fait pas du coup. |
|
| 95 | + if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) { |
|
| 96 | + spip_log( |
|
| 97 | + "'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'", |
|
| 98 | + 'sqlite.' . _LOG_ERREUR |
|
| 99 | + ); |
|
| 100 | + $this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query); |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + // Correction Field |
|
| 104 | + // remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END |
|
| 105 | + if (strpos($this->query, 'FIELD') !== false) { |
|
| 106 | + $this->query = preg_replace_callback( |
|
| 107 | + '/FIELD\s*\(([^\)]*)\)/', |
|
| 108 | + [&$this, '_remplacerFieldParCase'], |
|
| 109 | + $this->query |
|
| 110 | + ); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + // Correction des noms de tables FROM |
|
| 114 | + // mettre les bons noms de table dans from, update, insert, replace... |
|
| 115 | + if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) { |
|
| 116 | + $suite = strstr($this->query, $regs[0]); |
|
| 117 | + $this->query = substr($this->query, 0, -strlen($suite)); |
|
| 118 | + } else { |
|
| 119 | + $suite = ''; |
|
| 120 | + } |
|
| 121 | + $pref = ($this->prefixe) ? $this->prefixe . '_' : ''; |
|
| 122 | + $this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite; |
|
| 123 | + |
|
| 124 | + // Correction zero AS x |
|
| 125 | + // pg n'aime pas 0+x AS alias, sqlite, dans le meme style, |
|
| 126 | + // n'apprecie pas du tout SELECT 0 as x ... ORDER BY x |
|
| 127 | + // il dit que x ne doit pas être un integer dans le order by ! |
|
| 128 | + // on remplace du coup x par vide() dans ce cas uniquement |
|
| 129 | + // |
|
| 130 | + // apparait dans public/vertebrer.php et dans le plugin menu aussi qui genere aussi ce genre de requete via un {par num #GET{tri_num}} |
|
| 131 | + // mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28) |
|
| 132 | + if ((strpos($this->query, '0 AS') !== false)) { |
|
| 133 | + // on ne remplace que dans ORDER BY ou GROUP BY |
|
| 134 | + if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) { |
|
| 135 | + $suite = strstr($this->query, $regs[0]); |
|
| 136 | + $this->query = substr($this->query, 0, -strlen($suite)); |
|
| 137 | + |
|
| 138 | + // on cherche les noms des x dans 0 AS x |
|
| 139 | + // on remplace dans $suite le nom par vide() |
|
| 140 | + preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER); |
|
| 141 | + foreach ($matches[1] as $m) { |
|
| 142 | + if (strpos($suite, $m) !== false) { |
|
| 143 | + $suite = preg_replace(",\b$m\b,", 'VIDE()', $suite); |
|
| 144 | + } |
|
| 145 | + } |
|
| 146 | + $this->query .= $suite; |
|
| 147 | + } |
|
| 148 | + } |
|
| 149 | + |
|
| 150 | + // Correction possible des divisions entieres |
|
| 151 | + // Le standard SQL (lequel? ou?) semble indiquer que |
|
| 152 | + // a/b=c doit donner c entier si a et b sont entiers 4/3=1. |
|
| 153 | + // C'est ce que retournent effectivement SQL Server et SQLite |
|
| 154 | + // Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333... |
|
| 155 | + // |
|
| 156 | + // On peut forcer la conversion en multipliant par 1.0 avant la division |
|
| 157 | + // /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus ! |
|
| 158 | + // cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228 |
|
| 159 | + // http://www.sqlite.org/cvstrac/tktview?tn=3202 |
|
| 160 | + // (4*1.0/3) n'est pas rendu dans ce cas ! |
|
| 161 | + # $this->query = str_replace('/','* 1.00 / ',$this->query); |
|
| 162 | + |
|
| 163 | + |
|
| 164 | + // Correction critere REGEXP, non reconnu en sqlite2 |
|
| 165 | + if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) { |
|
| 166 | + $this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query); |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + // |
|
| 170 | + // 3) Remise en place des textes d'origine |
|
| 171 | + // |
|
| 172 | + // Correction Antiquotes et echappements |
|
| 173 | + // ` => rien |
|
| 174 | + if (strpos($this->query, '`') !== false) { |
|
| 175 | + $this->query = str_replace('`', '', $this->query); |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + $this->query = query_reinjecte_textes($this->query, $textes); |
|
| 179 | + |
|
| 180 | + return $this->query; |
|
| 181 | + } |
|
| 182 | + |
|
| 183 | + /** |
|
| 184 | + * Callback pour remplacer `DATE_` / `INTERVAL` |
|
| 185 | + * par `DATE ... strtotime` |
|
| 186 | + * |
|
| 187 | + * @param array $matches Captures |
|
| 188 | + * @return string texte de date compris par SQLite |
|
| 189 | + */ |
|
| 190 | + public function _remplacerDateParTime($matches) |
|
| 191 | + { |
|
| 192 | + $op = strtoupper($matches[1] == 'ADD') ? '+' : '-'; |
|
| 193 | + |
|
| 194 | + return "datetime$matches[2] '$op$matches[3] $matches[4]')"; |
|
| 195 | + } |
|
| 196 | + |
|
| 197 | + /** |
|
| 198 | + * Callback pour remplacer `FIELD(table,i,j,k...)` |
|
| 199 | + * par `CASE WHEN table=i THEN n ... ELSE 0 END` |
|
| 200 | + * |
|
| 201 | + * @param array $matches Captures |
|
| 202 | + * @return string texte de liste ordonnée compris par SQLite |
|
| 203 | + */ |
|
| 204 | + public function _remplacerFieldParCase($matches) |
|
| 205 | + { |
|
| 206 | + $fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X) |
|
| 207 | + $t = explode(',', $fields); |
|
| 208 | + $index = array_shift($t); |
|
| 209 | + |
|
| 210 | + $res = ''; |
|
| 211 | + $n = 0; |
|
| 212 | + foreach ($t as $v) { |
|
| 213 | + $n++; |
|
| 214 | + $res .= "\nWHEN $index=$v THEN $n"; |
|
| 215 | + } |
|
| 216 | + |
|
| 217 | + return "CASE $res ELSE 0 END "; |
|
| 218 | + } |
|
| 219 | 219 | } |
@@ -8,119 +8,119 @@ |
||
| 8 | 8 | **/ |
| 9 | 9 | class Sqlite |
| 10 | 10 | { |
| 11 | - /** @var SqliteRequeteur[] Liste des instances de requêteurs créés */ |
|
| 12 | - public static $requeteurs = []; |
|
| 13 | - /** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */ |
|
| 14 | - public static $transaction_en_cours = []; |
|
| 11 | + /** @var SqliteRequeteur[] Liste des instances de requêteurs créés */ |
|
| 12 | + public static $requeteurs = []; |
|
| 13 | + /** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */ |
|
| 14 | + public static $transaction_en_cours = []; |
|
| 15 | 15 | |
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * Retourne une unique instance du requêteur |
|
| 19 | - * |
|
| 20 | - * Retourne une instance unique du requêteur pour une connexion SQLite |
|
| 21 | - * donnée |
|
| 22 | - * |
|
| 23 | - * @param string $serveur |
|
| 24 | - * Nom du connecteur |
|
| 25 | - * @return SqliteRequeteur |
|
| 26 | - * Instance unique du requêteur |
|
| 27 | - **/ |
|
| 28 | - public static function requeteur($serveur) |
|
| 29 | - { |
|
| 30 | - if (!isset(static::$requeteurs[$serveur])) { |
|
| 31 | - static::$requeteurs[$serveur] = new SqliteRequeteur($serveur); |
|
| 32 | - } |
|
| 17 | + /** |
|
| 18 | + * Retourne une unique instance du requêteur |
|
| 19 | + * |
|
| 20 | + * Retourne une instance unique du requêteur pour une connexion SQLite |
|
| 21 | + * donnée |
|
| 22 | + * |
|
| 23 | + * @param string $serveur |
|
| 24 | + * Nom du connecteur |
|
| 25 | + * @return SqliteRequeteur |
|
| 26 | + * Instance unique du requêteur |
|
| 27 | + **/ |
|
| 28 | + public static function requeteur($serveur) |
|
| 29 | + { |
|
| 30 | + if (!isset(static::$requeteurs[$serveur])) { |
|
| 31 | + static::$requeteurs[$serveur] = new SqliteRequeteur($serveur); |
|
| 32 | + } |
|
| 33 | 33 | |
| 34 | - return static::$requeteurs[$serveur]; |
|
| 35 | - } |
|
| 34 | + return static::$requeteurs[$serveur]; |
|
| 35 | + } |
|
| 36 | 36 | |
| 37 | - /** |
|
| 38 | - * Prépare le texte d'une requête avant son exécution |
|
| 39 | - * |
|
| 40 | - * Adapte la requête au format plus ou moins MySQL par un format |
|
| 41 | - * compris de SQLite. |
|
| 42 | - * |
|
| 43 | - * Change les préfixes de tables SPIP par ceux véritables |
|
| 44 | - * |
|
| 45 | - * @param string $query Requête à préparer |
|
| 46 | - * @param string $serveur Nom de la connexion |
|
| 47 | - * @return string Requête préparée |
|
| 48 | - */ |
|
| 49 | - public static function traduire_requete($query, $serveur) |
|
| 50 | - { |
|
| 51 | - $requeteur = static::requeteur($serveur); |
|
| 52 | - $traducteur = new SqliteTraducteur($query, $requeteur->prefixe, $requeteur->sqlite_version); |
|
| 37 | + /** |
|
| 38 | + * Prépare le texte d'une requête avant son exécution |
|
| 39 | + * |
|
| 40 | + * Adapte la requête au format plus ou moins MySQL par un format |
|
| 41 | + * compris de SQLite. |
|
| 42 | + * |
|
| 43 | + * Change les préfixes de tables SPIP par ceux véritables |
|
| 44 | + * |
|
| 45 | + * @param string $query Requête à préparer |
|
| 46 | + * @param string $serveur Nom de la connexion |
|
| 47 | + * @return string Requête préparée |
|
| 48 | + */ |
|
| 49 | + public static function traduire_requete($query, $serveur) |
|
| 50 | + { |
|
| 51 | + $requeteur = static::requeteur($serveur); |
|
| 52 | + $traducteur = new SqliteTraducteur($query, $requeteur->prefixe, $requeteur->sqlite_version); |
|
| 53 | 53 | |
| 54 | - return $traducteur->traduire_requete(); |
|
| 55 | - } |
|
| 54 | + return $traducteur->traduire_requete(); |
|
| 55 | + } |
|
| 56 | 56 | |
| 57 | - /** |
|
| 58 | - * Démarre une transaction |
|
| 59 | - * |
|
| 60 | - * @param string $serveur Nom de la connexion |
|
| 61 | - **/ |
|
| 62 | - public static function demarrer_transaction($serveur) |
|
| 63 | - { |
|
| 64 | - Sqlite::executer_requete('BEGIN TRANSACTION', $serveur); |
|
| 65 | - Sqlite::$transaction_en_cours[$serveur] = true; |
|
| 66 | - } |
|
| 57 | + /** |
|
| 58 | + * Démarre une transaction |
|
| 59 | + * |
|
| 60 | + * @param string $serveur Nom de la connexion |
|
| 61 | + **/ |
|
| 62 | + public static function demarrer_transaction($serveur) |
|
| 63 | + { |
|
| 64 | + Sqlite::executer_requete('BEGIN TRANSACTION', $serveur); |
|
| 65 | + Sqlite::$transaction_en_cours[$serveur] = true; |
|
| 66 | + } |
|
| 67 | 67 | |
| 68 | - /** |
|
| 69 | - * Exécute la requête donnée |
|
| 70 | - * |
|
| 71 | - * @param string $query Requête |
|
| 72 | - * @param string $serveur Nom de la connexion |
|
| 73 | - * @param null|bool $tracer Demander des statistiques (temps) ? |
|
| 74 | - **/ |
|
| 75 | - public static function executer_requete($query, $serveur, $tracer = null) |
|
| 76 | - { |
|
| 77 | - $requeteur = Sqlite::requeteur($serveur); |
|
| 68 | + /** |
|
| 69 | + * Exécute la requête donnée |
|
| 70 | + * |
|
| 71 | + * @param string $query Requête |
|
| 72 | + * @param string $serveur Nom de la connexion |
|
| 73 | + * @param null|bool $tracer Demander des statistiques (temps) ? |
|
| 74 | + **/ |
|
| 75 | + public static function executer_requete($query, $serveur, $tracer = null) |
|
| 76 | + { |
|
| 77 | + $requeteur = Sqlite::requeteur($serveur); |
|
| 78 | 78 | |
| 79 | - return $requeteur->executer_requete($query, $tracer); |
|
| 80 | - } |
|
| 79 | + return $requeteur->executer_requete($query, $tracer); |
|
| 80 | + } |
|
| 81 | 81 | |
| 82 | - /** |
|
| 83 | - * Obtient l'identifiant de la dernière ligne insérée ou modifiée |
|
| 84 | - * |
|
| 85 | - * @param string $serveur Nom de la connexion |
|
| 86 | - * return int Identifiant |
|
| 87 | - **/ |
|
| 88 | - public static function last_insert_id($serveur) |
|
| 89 | - { |
|
| 90 | - $requeteur = Sqlite::requeteur($serveur); |
|
| 82 | + /** |
|
| 83 | + * Obtient l'identifiant de la dernière ligne insérée ou modifiée |
|
| 84 | + * |
|
| 85 | + * @param string $serveur Nom de la connexion |
|
| 86 | + * return int Identifiant |
|
| 87 | + **/ |
|
| 88 | + public static function last_insert_id($serveur) |
|
| 89 | + { |
|
| 90 | + $requeteur = Sqlite::requeteur($serveur); |
|
| 91 | 91 | |
| 92 | - return $requeteur->last_insert_id($serveur); |
|
| 93 | - } |
|
| 92 | + return $requeteur->last_insert_id($serveur); |
|
| 93 | + } |
|
| 94 | 94 | |
| 95 | - /** |
|
| 96 | - * Annule une transaction |
|
| 97 | - * |
|
| 98 | - * @param string $serveur Nom de la connexion |
|
| 99 | - **/ |
|
| 100 | - public static function annuler_transaction($serveur) |
|
| 101 | - { |
|
| 102 | - Sqlite::executer_requete('ROLLBACK', $serveur); |
|
| 103 | - Sqlite::$transaction_en_cours[$serveur] = false; |
|
| 104 | - } |
|
| 95 | + /** |
|
| 96 | + * Annule une transaction |
|
| 97 | + * |
|
| 98 | + * @param string $serveur Nom de la connexion |
|
| 99 | + **/ |
|
| 100 | + public static function annuler_transaction($serveur) |
|
| 101 | + { |
|
| 102 | + Sqlite::executer_requete('ROLLBACK', $serveur); |
|
| 103 | + Sqlite::$transaction_en_cours[$serveur] = false; |
|
| 104 | + } |
|
| 105 | 105 | |
| 106 | - /** |
|
| 107 | - * Termine une transaction |
|
| 108 | - * |
|
| 109 | - * @param string $serveur Nom de la connexion |
|
| 110 | - **/ |
|
| 111 | - public static function finir_transaction($serveur) |
|
| 112 | - { |
|
| 113 | - // si pas de transaction en cours, ne rien faire et le dire |
|
| 114 | - if ( |
|
| 115 | - !isset(Sqlite::$transaction_en_cours[$serveur]) |
|
| 116 | - or Sqlite::$transaction_en_cours[$serveur] == false |
|
| 117 | - ) { |
|
| 118 | - return false; |
|
| 119 | - } |
|
| 120 | - // sinon fermer la transaction et retourner true |
|
| 121 | - Sqlite::executer_requete('COMMIT', $serveur); |
|
| 122 | - Sqlite::$transaction_en_cours[$serveur] = false; |
|
| 106 | + /** |
|
| 107 | + * Termine une transaction |
|
| 108 | + * |
|
| 109 | + * @param string $serveur Nom de la connexion |
|
| 110 | + **/ |
|
| 111 | + public static function finir_transaction($serveur) |
|
| 112 | + { |
|
| 113 | + // si pas de transaction en cours, ne rien faire et le dire |
|
| 114 | + if ( |
|
| 115 | + !isset(Sqlite::$transaction_en_cours[$serveur]) |
|
| 116 | + or Sqlite::$transaction_en_cours[$serveur] == false |
|
| 117 | + ) { |
|
| 118 | + return false; |
|
| 119 | + } |
|
| 120 | + // sinon fermer la transaction et retourner true |
|
| 121 | + Sqlite::executer_requete('COMMIT', $serveur); |
|
| 122 | + Sqlite::$transaction_en_cours[$serveur] = false; |
|
| 123 | 123 | |
| 124 | - return true; |
|
| 125 | - } |
|
| 124 | + return true; |
|
| 125 | + } |
|
| 126 | 126 | } |
@@ -7,21 +7,21 @@ |
||
| 7 | 7 | * @internal |
| 8 | 8 | */ |
| 9 | 9 | class Collection { |
| 10 | - private array $vars = []; |
|
| 10 | + private array $vars = []; |
|
| 11 | 11 | |
| 12 | - public function add(string $var, string $value) { |
|
| 13 | - $this->vars[$var] = $value; |
|
| 14 | - } |
|
| 12 | + public function add(string $var, string $value) { |
|
| 13 | + $this->vars[$var] = $value; |
|
| 14 | + } |
|
| 15 | 15 | |
| 16 | - public function getString(): string { |
|
| 17 | - $string = ''; |
|
| 18 | - foreach ($this->vars as $key => $value) { |
|
| 19 | - $string .= "$key: $value;\n"; |
|
| 20 | - } |
|
| 21 | - return $string; |
|
| 22 | - } |
|
| 16 | + public function getString(): string { |
|
| 17 | + $string = ''; |
|
| 18 | + foreach ($this->vars as $key => $value) { |
|
| 19 | + $string .= "$key: $value;\n"; |
|
| 20 | + } |
|
| 21 | + return $string; |
|
| 22 | + } |
|
| 23 | 23 | |
| 24 | - public function __toString(): string { |
|
| 25 | - return $this->getString(); |
|
| 26 | - } |
|
| 24 | + public function __toString(): string { |
|
| 25 | + return $this->getString(); |
|
| 26 | + } |
|
| 27 | 27 | } |
@@ -7,102 +7,102 @@ |
||
| 7 | 7 | */ |
| 8 | 8 | class Champ |
| 9 | 9 | { |
| 10 | - /** Type de noeud */ |
|
| 11 | - public string $type = 'champ'; |
|
| 12 | - |
|
| 13 | - /** Nom du champ demandé. Exemple 'ID_ARTICLE' */ |
|
| 14 | - public ?string $nom_champ; |
|
| 15 | - |
|
| 16 | - /** Identifiant de la boucle parente si explicité */ |
|
| 17 | - public ?string $nom_boucle = ''; |
|
| 18 | - |
|
| 19 | - /** |
|
| 20 | - * Partie optionnelle avant |
|
| 21 | - * |
|
| 22 | - * @var null|string|array |
|
| 23 | - */ |
|
| 24 | - public $avant; |
|
| 25 | - |
|
| 26 | - /** |
|
| 27 | - * Partie optionnelle après |
|
| 28 | - * |
|
| 29 | - * @var null|string|array |
|
| 30 | - */ |
|
| 31 | - public $apres; |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * Étoiles : annuler des automatismes |
|
| 35 | - * |
|
| 36 | - * - '*' annule les filtres automatiques |
|
| 37 | - * - '**' annule en plus les protections de scripts |
|
| 38 | - */ |
|
| 39 | - public ?string $etoile; |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * Arguments et filtres explicites sur la balise |
|
| 43 | - * |
|
| 44 | - * - $param[0] contient les arguments de la balise |
|
| 45 | - * - $param[1..n] contient les filtres à appliquer à la balise |
|
| 46 | - * |
|
| 47 | - * FIXME: type unique. |
|
| 48 | - * @var false|array |
|
| 49 | - * - false: erreur de syntaxe |
|
| 50 | - */ |
|
| 51 | - public $param = []; |
|
| 52 | - |
|
| 53 | - /** Source des filtres (compatibilité) (?) */ |
|
| 54 | - public array $fonctions = []; |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * Identifiant de la boucle |
|
| 58 | - * |
|
| 59 | - * @var string |
|
| 60 | - */ |
|
| 61 | - public $id_boucle = ''; |
|
| 62 | - |
|
| 63 | - /** |
|
| 64 | - * AST du squelette, liste de toutes les boucles |
|
| 65 | - * |
|
| 66 | - * @var Boucle[] |
|
| 67 | - */ |
|
| 68 | - public array $boucles; |
|
| 69 | - |
|
| 70 | - /** Alias de table d'application de la requête ou nom complet de la table SQL */ |
|
| 71 | - public ?string $type_requete; |
|
| 72 | - |
|
| 73 | - /** Résultat de la compilation: toujours une expression PHP */ |
|
| 74 | - public string $code = ''; |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * Interdire les scripts |
|
| 78 | - * |
|
| 79 | - * false si on est sûr de cette balise |
|
| 80 | - * |
|
| 81 | - * @see interdire_scripts() |
|
| 82 | - */ |
|
| 83 | - public bool $interdire_scripts = true; |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * Description du squelette |
|
| 87 | - * |
|
| 88 | - * Sert pour la gestion d'erreur et la production de code dependant du contexte |
|
| 89 | - * |
|
| 90 | - * Peut contenir les index : |
|
| 91 | - * |
|
| 92 | - * - nom : Nom du fichier de cache |
|
| 93 | - * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser) |
|
| 94 | - * - sourcefile : Chemin du squelette |
|
| 95 | - * - squelette : Code du squelette |
|
| 96 | - * - id_mere : Identifiant de la boucle parente |
|
| 97 | - * - documents : Pour embed et img dans les textes |
|
| 98 | - * - session : Pour un cache sessionné par auteur |
|
| 99 | - * - niv : Niveau de tabulation |
|
| 100 | - */ |
|
| 101 | - public array $descr = []; |
|
| 102 | - |
|
| 103 | - /** Numéro de ligne dans le code source du squelette*/ |
|
| 104 | - public int $ligne = 0; |
|
| 105 | - |
|
| 106 | - /** Drapeau pour reperer les balises calculées par une fonction explicite */ |
|
| 107 | - public bool $balise_calculee = false; |
|
| 10 | + /** Type de noeud */ |
|
| 11 | + public string $type = 'champ'; |
|
| 12 | + |
|
| 13 | + /** Nom du champ demandé. Exemple 'ID_ARTICLE' */ |
|
| 14 | + public ?string $nom_champ; |
|
| 15 | + |
|
| 16 | + /** Identifiant de la boucle parente si explicité */ |
|
| 17 | + public ?string $nom_boucle = ''; |
|
| 18 | + |
|
| 19 | + /** |
|
| 20 | + * Partie optionnelle avant |
|
| 21 | + * |
|
| 22 | + * @var null|string|array |
|
| 23 | + */ |
|
| 24 | + public $avant; |
|
| 25 | + |
|
| 26 | + /** |
|
| 27 | + * Partie optionnelle après |
|
| 28 | + * |
|
| 29 | + * @var null|string|array |
|
| 30 | + */ |
|
| 31 | + public $apres; |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * Étoiles : annuler des automatismes |
|
| 35 | + * |
|
| 36 | + * - '*' annule les filtres automatiques |
|
| 37 | + * - '**' annule en plus les protections de scripts |
|
| 38 | + */ |
|
| 39 | + public ?string $etoile; |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * Arguments et filtres explicites sur la balise |
|
| 43 | + * |
|
| 44 | + * - $param[0] contient les arguments de la balise |
|
| 45 | + * - $param[1..n] contient les filtres à appliquer à la balise |
|
| 46 | + * |
|
| 47 | + * FIXME: type unique. |
|
| 48 | + * @var false|array |
|
| 49 | + * - false: erreur de syntaxe |
|
| 50 | + */ |
|
| 51 | + public $param = []; |
|
| 52 | + |
|
| 53 | + /** Source des filtres (compatibilité) (?) */ |
|
| 54 | + public array $fonctions = []; |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * Identifiant de la boucle |
|
| 58 | + * |
|
| 59 | + * @var string |
|
| 60 | + */ |
|
| 61 | + public $id_boucle = ''; |
|
| 62 | + |
|
| 63 | + /** |
|
| 64 | + * AST du squelette, liste de toutes les boucles |
|
| 65 | + * |
|
| 66 | + * @var Boucle[] |
|
| 67 | + */ |
|
| 68 | + public array $boucles; |
|
| 69 | + |
|
| 70 | + /** Alias de table d'application de la requête ou nom complet de la table SQL */ |
|
| 71 | + public ?string $type_requete; |
|
| 72 | + |
|
| 73 | + /** Résultat de la compilation: toujours une expression PHP */ |
|
| 74 | + public string $code = ''; |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * Interdire les scripts |
|
| 78 | + * |
|
| 79 | + * false si on est sûr de cette balise |
|
| 80 | + * |
|
| 81 | + * @see interdire_scripts() |
|
| 82 | + */ |
|
| 83 | + public bool $interdire_scripts = true; |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * Description du squelette |
|
| 87 | + * |
|
| 88 | + * Sert pour la gestion d'erreur et la production de code dependant du contexte |
|
| 89 | + * |
|
| 90 | + * Peut contenir les index : |
|
| 91 | + * |
|
| 92 | + * - nom : Nom du fichier de cache |
|
| 93 | + * - gram : Nom de la grammaire du squelette (détermine le phraseur à utiliser) |
|
| 94 | + * - sourcefile : Chemin du squelette |
|
| 95 | + * - squelette : Code du squelette |
|
| 96 | + * - id_mere : Identifiant de la boucle parente |
|
| 97 | + * - documents : Pour embed et img dans les textes |
|
| 98 | + * - session : Pour un cache sessionné par auteur |
|
| 99 | + * - niv : Niveau de tabulation |
|
| 100 | + */ |
|
| 101 | + public array $descr = []; |
|
| 102 | + |
|
| 103 | + /** Numéro de ligne dans le code source du squelette*/ |
|
| 104 | + public int $ligne = 0; |
|
| 105 | + |
|
| 106 | + /** Drapeau pour reperer les balises calculées par une fonction explicite */ |
|
| 107 | + public bool $balise_calculee = false; |
|
| 108 | 108 | } |
@@ -7,57 +7,57 @@ |
||
| 7 | 7 | * privée ou dans un de ses sous menus |
| 8 | 8 | */ |
| 9 | 9 | class Bouton { |
| 10 | - /** L'icone à mettre dans le bouton */ |
|
| 11 | - public string $icone; |
|
| 12 | - |
|
| 13 | - /** Le nom de l'entrée d'i18n associé */ |
|
| 14 | - public string $libelle; |
|
| 15 | - |
|
| 16 | - /** @var null|string L'URL de la page (null => ?exec=nom) */ |
|
| 17 | - public $url = null; |
|
| 18 | - |
|
| 19 | - /** @var null|string|array Arguments supplementaires de l'URL */ |
|
| 20 | - public $urlArg = null; |
|
| 21 | - |
|
| 22 | - /** @var null|string URL du javascript */ |
|
| 23 | - public $url2 = null; |
|
| 24 | - |
|
| 25 | - /** @var null|string Pour ouvrir dans une fenetre a part */ |
|
| 26 | - public $target = null; |
|
| 27 | - |
|
| 28 | - /** Sous-barre de boutons / onglets */ |
|
| 29 | - public array $sousmenu = []; |
|
| 30 | - |
|
| 31 | - /** Position dans le menu */ |
|
| 32 | - public int $position = 0; |
|
| 33 | - |
|
| 34 | - /** Entrée favorite (sa position dans les favoris) ? */ |
|
| 35 | - public int $favori = 0; |
|
| 36 | - |
|
| 37 | - |
|
| 38 | - /** |
|
| 39 | - * Définit un bouton |
|
| 40 | - * |
|
| 41 | - * @param string $icone |
|
| 42 | - * L'icone à mettre dans le bouton |
|
| 43 | - * @param string $libelle |
|
| 44 | - * Le nom de l'entrée i18n associé |
|
| 45 | - * @param null|string $url |
|
| 46 | - * L'URL de la page |
|
| 47 | - * @param null|string|array $urlArg |
|
| 48 | - * Arguments supplémentaires de l'URL |
|
| 49 | - * @param null|string $url2 |
|
| 50 | - * URL du javascript |
|
| 51 | - * @param null|mixed $target |
|
| 52 | - * Pour ouvrir une fenêtre à part |
|
| 53 | - */ |
|
| 54 | - public function __construct($icone, $libelle, $url = null, $urlArg = null, $url2 = null, $target = null) { |
|
| 55 | - $this->icone = $icone; |
|
| 56 | - $this->libelle = $libelle; |
|
| 57 | - $this->url = $url; |
|
| 58 | - $this->urlArg = $urlArg; |
|
| 59 | - $this->url2 = $url2; |
|
| 60 | - $this->target = $target; |
|
| 61 | - } |
|
| 10 | + /** L'icone à mettre dans le bouton */ |
|
| 11 | + public string $icone; |
|
| 12 | + |
|
| 13 | + /** Le nom de l'entrée d'i18n associé */ |
|
| 14 | + public string $libelle; |
|
| 15 | + |
|
| 16 | + /** @var null|string L'URL de la page (null => ?exec=nom) */ |
|
| 17 | + public $url = null; |
|
| 18 | + |
|
| 19 | + /** @var null|string|array Arguments supplementaires de l'URL */ |
|
| 20 | + public $urlArg = null; |
|
| 21 | + |
|
| 22 | + /** @var null|string URL du javascript */ |
|
| 23 | + public $url2 = null; |
|
| 24 | + |
|
| 25 | + /** @var null|string Pour ouvrir dans une fenetre a part */ |
|
| 26 | + public $target = null; |
|
| 27 | + |
|
| 28 | + /** Sous-barre de boutons / onglets */ |
|
| 29 | + public array $sousmenu = []; |
|
| 30 | + |
|
| 31 | + /** Position dans le menu */ |
|
| 32 | + public int $position = 0; |
|
| 33 | + |
|
| 34 | + /** Entrée favorite (sa position dans les favoris) ? */ |
|
| 35 | + public int $favori = 0; |
|
| 36 | + |
|
| 37 | + |
|
| 38 | + /** |
|
| 39 | + * Définit un bouton |
|
| 40 | + * |
|
| 41 | + * @param string $icone |
|
| 42 | + * L'icone à mettre dans le bouton |
|
| 43 | + * @param string $libelle |
|
| 44 | + * Le nom de l'entrée i18n associé |
|
| 45 | + * @param null|string $url |
|
| 46 | + * L'URL de la page |
|
| 47 | + * @param null|string|array $urlArg |
|
| 48 | + * Arguments supplémentaires de l'URL |
|
| 49 | + * @param null|string $url2 |
|
| 50 | + * URL du javascript |
|
| 51 | + * @param null|mixed $target |
|
| 52 | + * Pour ouvrir une fenêtre à part |
|
| 53 | + */ |
|
| 54 | + public function __construct($icone, $libelle, $url = null, $urlArg = null, $url2 = null, $target = null) { |
|
| 55 | + $this->icone = $icone; |
|
| 56 | + $this->libelle = $libelle; |
|
| 57 | + $this->url = $url; |
|
| 58 | + $this->urlArg = $urlArg; |
|
| 59 | + $this->url2 = $url2; |
|
| 60 | + $this->target = $target; |
|
| 61 | + } |
|
| 62 | 62 | } |
| 63 | 63 | |
@@ -3,16 +3,16 @@ |
||
| 3 | 3 | namespace Spip\I18n; |
| 4 | 4 | |
| 5 | 5 | class Description { |
| 6 | - /** @var string code de langue (hors module) */ |
|
| 7 | - public $code; |
|
| 8 | - /** @var string nom du module de langue */ |
|
| 9 | - public $module; |
|
| 10 | - /** @var string langue de la traduction */ |
|
| 11 | - public $langue; |
|
| 12 | - /** @var string traduction */ |
|
| 13 | - public $texte; |
|
| 14 | - /** @var string var mode particulier appliqué ? */ |
|
| 15 | - public $mode; |
|
| 16 | - /** @var bool Corrections des textes appliqué ? */ |
|
| 17 | - public $corrections = false; |
|
| 6 | + /** @var string code de langue (hors module) */ |
|
| 7 | + public $code; |
|
| 8 | + /** @var string nom du module de langue */ |
|
| 9 | + public $module; |
|
| 10 | + /** @var string langue de la traduction */ |
|
| 11 | + public $langue; |
|
| 12 | + /** @var string traduction */ |
|
| 13 | + public $texte; |
|
| 14 | + /** @var string var mode particulier appliqué ? */ |
|
| 15 | + public $mode; |
|
| 16 | + /** @var bool Corrections des textes appliqué ? */ |
|
| 17 | + public $corrections = false; |
|
| 18 | 18 | } |