Completed
Push — master ( d593dc...91e0b1 )
by cam
01:24
created
ecrire/exec/upgrade.php 1 patch
Indentation   +63 added lines, -63 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 include_spip('inc/actions');
@@ -30,70 +30,70 @@  discard block
 block discarded – undo
30 30
  **/
31 31
 function exec_upgrade_dist() {
32 32
 
33
-	if (!_FILE_CONNECT) {
34
-		redirige_url_ecrire('install');
35
-	}
33
+    if (!_FILE_CONNECT) {
34
+        redirige_url_ecrire('install');
35
+    }
36 36
 
37
-	// Si reinstallation necessaire, message ad hoc
38
-	if (_request('reinstall') == 'oui') {
39
-		include_spip('inc/minipres');
40
-		$r = minipres(
41
-			_T('titre_page_upgrade'),
42
-			'<p><b>'
43
-			. _T('texte_nouvelle_version_spip_1')
44
-			. '</b><p> '
45
-			. _T(
46
-				'texte_nouvelle_version_spip_2',
47
-				['connect' => '<tt>' . _FILE_CONNECT . '</tt>']
48
-			)
49
-			. generer_form_ecrire(
50
-				'upgrade',
51
-				"<input type='hidden' name='reinstall' value='non' />",
52
-				'',
53
-				_T('bouton_relancer_installation')
54
-			)
55
-		);
56
-		echo $r;
57
-	} elseif (_request('fin')) {
58
-		include_spip('inc/plugin');
59
-		actualise_plugins_actifs();
60
-		include_spip('inc/headers');
61
-		$res = generer_url_ecrire('admin_plugin', 'var_mode=recalcul');
62
-		echo redirige_formulaire($res);
63
-	} else {
64
-		if (!isset($GLOBALS['meta']['version_installee'])) {
65
-			$GLOBALS['meta']['version_installee'] = 0.0;
66
-		} else {
67
-			$GLOBALS['meta']['version_installee'] =
68
-				(double)str_replace(',', '.', $GLOBALS['meta']['version_installee']);
69
-		}
70
-		# NB: str_replace car, sur club-internet, il semble que version_installe soit
71
-		# enregistree au format '1,812' et non '1.812'
37
+    // Si reinstallation necessaire, message ad hoc
38
+    if (_request('reinstall') == 'oui') {
39
+        include_spip('inc/minipres');
40
+        $r = minipres(
41
+            _T('titre_page_upgrade'),
42
+            '<p><b>'
43
+            . _T('texte_nouvelle_version_spip_1')
44
+            . '</b><p> '
45
+            . _T(
46
+                'texte_nouvelle_version_spip_2',
47
+                ['connect' => '<tt>' . _FILE_CONNECT . '</tt>']
48
+            )
49
+            . generer_form_ecrire(
50
+                'upgrade',
51
+                "<input type='hidden' name='reinstall' value='non' />",
52
+                '',
53
+                _T('bouton_relancer_installation')
54
+            )
55
+        );
56
+        echo $r;
57
+    } elseif (_request('fin')) {
58
+        include_spip('inc/plugin');
59
+        actualise_plugins_actifs();
60
+        include_spip('inc/headers');
61
+        $res = generer_url_ecrire('admin_plugin', 'var_mode=recalcul');
62
+        echo redirige_formulaire($res);
63
+    } else {
64
+        if (!isset($GLOBALS['meta']['version_installee'])) {
65
+            $GLOBALS['meta']['version_installee'] = 0.0;
66
+        } else {
67
+            $GLOBALS['meta']['version_installee'] =
68
+                (double)str_replace(',', '.', $GLOBALS['meta']['version_installee']);
69
+        }
70
+        # NB: str_replace car, sur club-internet, il semble que version_installe soit
71
+        # enregistree au format '1,812' et non '1.812'
72 72
 
73
-		// Erreur downgrade
74
-		// (cas de double installation de fichiers SPIP sur une meme base)
75
-		if ($GLOBALS['spip_version_base'] < $GLOBALS['meta']['version_installee']) {
76
-			$commentaire = _T('info_mise_a_niveau_base_2');
77
-		} // Commentaire standard upgrade
78
-		else {
79
-			$commentaire = _T('texte_mise_a_niveau_base_1');
80
-		}
73
+        // Erreur downgrade
74
+        // (cas de double installation de fichiers SPIP sur une meme base)
75
+        if ($GLOBALS['spip_version_base'] < $GLOBALS['meta']['version_installee']) {
76
+            $commentaire = _T('info_mise_a_niveau_base_2');
77
+        } // Commentaire standard upgrade
78
+        else {
79
+            $commentaire = _T('texte_mise_a_niveau_base_1');
80
+        }
81 81
 
82
-		$commentaire .= '<br />[' . $GLOBALS['meta']['version_installee'] . '/' . $GLOBALS['spip_version_base'] . ']';
82
+        $commentaire .= '<br />[' . $GLOBALS['meta']['version_installee'] . '/' . $GLOBALS['spip_version_base'] . ']';
83 83
 
84
-		$_POST['reinstall'] = 'non'; // pour copy_request dans admin
85
-		include_spip('inc/headers');
86
-		$admin = charger_fonction('admin', 'inc');
87
-		$res = $admin('upgrade', _T('info_mise_a_niveau_base'), $commentaire);
88
-		if ($res) {
89
-			echo $res;
90
-		} else {
91
-			// effacer les alea pour forcer leur relecture
92
-			// si jamais ils ont change pendant l'upgrade
93
-			unset($GLOBALS['meta']['alea_ephemere']);
94
-			unset($GLOBALS['meta']['alea_ephemere_ancien']);
95
-			$res = redirige_action_auteur('purger', 'cache', 'upgrade', 'fin=oui', true);
96
-			echo redirige_formulaire($res);
97
-		}
98
-	}
84
+        $_POST['reinstall'] = 'non'; // pour copy_request dans admin
85
+        include_spip('inc/headers');
86
+        $admin = charger_fonction('admin', 'inc');
87
+        $res = $admin('upgrade', _T('info_mise_a_niveau_base'), $commentaire);
88
+        if ($res) {
89
+            echo $res;
90
+        } else {
91
+            // effacer les alea pour forcer leur relecture
92
+            // si jamais ils ont change pendant l'upgrade
93
+            unset($GLOBALS['meta']['alea_ephemere']);
94
+            unset($GLOBALS['meta']['alea_ephemere_ancien']);
95
+            $res = redirige_action_auteur('purger', 'cache', 'upgrade', 'fin=oui', true);
96
+            echo redirige_formulaire($res);
97
+        }
98
+    }
99 99
 }
Please login to merge, or discard this patch.
ecrire/exec/admin_plugin.php 1 patch
Indentation   +200 added lines, -200 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 include_spip('inc/config');
@@ -37,26 +37,26 @@  discard block
 block discarded – undo
37 37
  */
38 38
 function exec_admin_plugin_dist($retour = '') {
39 39
 
40
-	if (!autoriser('configurer', '_plugins')) {
41
-		include_spip('inc/minipres');
42
-		echo minipres();
43
-	} else {
44
-		// on fait la verif du path avant tout,
45
-		// et l'installation des qu'on est dans la colonne principale
46
-		// si jamais la liste des plugins actifs change, il faut faire un refresh du hit
47
-		// pour etre sur que les bons fichiers seront charges lors de l'install
48
-		$new = actualise_plugins_actifs();
49
-		if ($new and _request('actualise') < 2) {
50
-			include_spip('inc/headers');
51
-			if (isset($GLOBALS['fichier_php_compile_recent'])) {
52
-				// attendre eventuellement l'invalidation du cache opcode
53
-				spip_attend_invalidation_opcode_cache($GLOBALS['fichier_php_compile_recent']);
54
-			}
55
-			redirige_par_entete(parametre_url(self(), 'actualise', _request('actualise') + 1, '&'));
56
-		} else {
57
-			admin_plug_args(_request('voir'), _request('erreur'), _request('format'));
58
-		}
59
-	}
40
+    if (!autoriser('configurer', '_plugins')) {
41
+        include_spip('inc/minipres');
42
+        echo minipres();
43
+    } else {
44
+        // on fait la verif du path avant tout,
45
+        // et l'installation des qu'on est dans la colonne principale
46
+        // si jamais la liste des plugins actifs change, il faut faire un refresh du hit
47
+        // pour etre sur que les bons fichiers seront charges lors de l'install
48
+        $new = actualise_plugins_actifs();
49
+        if ($new and _request('actualise') < 2) {
50
+            include_spip('inc/headers');
51
+            if (isset($GLOBALS['fichier_php_compile_recent'])) {
52
+                // attendre eventuellement l'invalidation du cache opcode
53
+                spip_attend_invalidation_opcode_cache($GLOBALS['fichier_php_compile_recent']);
54
+            }
55
+            redirige_par_entete(parametre_url(self(), 'actualise', _request('actualise') + 1, '&'));
56
+        } else {
57
+            admin_plug_args(_request('voir'), _request('erreur'), _request('format'));
58
+        }
59
+    }
60 60
 }
61 61
 
62 62
 /**
@@ -81,129 +81,129 @@  discard block
 block discarded – undo
81 81
  *     Format d'affichage (liste ou arborescence)
82 82
  **/
83 83
 function admin_plug_args($quoi, $erreur, $format) {
84
-	if (!$quoi) {
85
-		$quoi = 'actifs';
86
-	}
87
-	// empecher l'affichage des erreurs dans le bandeau, on le donne ensuite
88
-	// format brut par plugin
89
-	$GLOBALS['erreurs_activation_raw'] = plugin_donne_erreurs(true, false);
90
-	// format resume mis en forme
91
-	$erreur_activation = plugin_donne_erreurs();
92
-	$commencer_page = charger_fonction('commencer_page', 'inc');
93
-	echo $commencer_page(_T('icone_admin_plugin'), 'configuration', 'plugin');
94
-
95
-	echo debut_gauche('plugin', true);
96
-	echo recuperer_fond('prive/squelettes/navigation/configurer', ['exec' => 'admin_plugin']);
97
-
98
-	echo pipeline(
99
-		'affiche_gauche',
100
-		[
101
-			'args' => ['exec' => 'admin_plugin'],
102
-			'data' => afficher_librairies()
103
-		]
104
-	);
105
-
106
-	echo debut_droite('plugin', true);
107
-	echo gros_titre(_T('icone_admin_plugin'), '', false);
108
-
109
-	// Barre d'onglets de premier niveau
110
-	echo barre_onglets('plugins', 'plugins_actifs');
111
-	// Barre d'onglets de second niveau
112
-	$onglet2 = $quoi == 'actifs' ? 'plugins_actifs' : 'admin_plugin';
113
-	echo debut_onglet('onglets_simple second');
114
-	echo onglet(_T('plugins_tous_liste'), generer_url_ecrire('admin_plugin', 'voir=tous'), 'admin_plugin', $onglet2);
115
-	echo onglet(_T('plugins_actifs_liste'), generer_url_ecrire('admin_plugin'), 'plugins_actifs', $onglet2);
116
-	echo fin_onglet();
117
-
118
-	// message d'erreur au retour d'une operation
119
-	if ($erreur) {
120
-		echo "<div class='error'>$erreur</div>";
121
-	}
122
-	if ($erreur_activation) {
123
-		echo "<div class='error'>$erreur_activation</div>";
124
-	}
125
-
126
-	// la mise a jour de cette meta a ete faite par ecrire_plugin_actifs
127
-	$actifs = unserialize($GLOBALS['meta']['plugin']);
128
-	$lcpa = $actifs + unserialize($GLOBALS['meta']['plugin_attente']);
129
-
130
-	// Les affichages se basent sur le repertoire, pas sur le nom
131
-	$actifs = liste_chemin_plugin($actifs, '');
132
-	if (defined('_DIR_PLUGINS_SUPPL')) {
133
-		$lcpas = liste_chemin_plugin($lcpa, _DIR_PLUGINS_SUPPL);
134
-	}
135
-	$lcpa = liste_chemin_plugin($lcpa);
136
-
137
-	// on installe les plugins maintenant,
138
-	// cela permet aux scripts d'install de faire des affichages (moches...)
139
-	plugin_installes_meta();
140
-
141
-	echo "<div class='liste-plugins formulaire_spip'>";
142
-	echo debut_cadre_trait_couleur('plugin-24.png', true, '', _T('plugins_liste'), 'plugins');
143
-
144
-	if ($quoi !== 'actifs') {
145
-		$lpf = liste_plugin_files();
146
-		if ($lpf) {
147
-			echo '<p>' . _T('texte_presente_plugin') . '</p>';
148
-		} else {
149
-			if (!@is_dir(_DIR_PLUGINS)) {
150
-				echo '<p>' . _T('plugin_info_automatique_ftp', ['rep' => joli_repertoire(_DIR_PLUGINS)])
151
-					. ' &mdash; ' . _T('plugin_info_automatique_creer') . '</p>';
152
-			}
153
-		}
154
-		$lcpaffiche = $lpf;
155
-		if (defined('_DIR_PLUGINS_SUPPL')) {
156
-			$lcpaffichesup = liste_plugin_files(_DIR_PLUGINS_SUPPL);
157
-		}
158
-	} else {
159
-		// la liste
160
-		// $quoi=='actifs'
161
-		$lcpaffiche = $lcpa;
162
-		if (defined('_DIR_PLUGINS_SUPPL')) {
163
-			$lcpaffichesup = $lcpas;
164
-		}
165
-	}
166
-
167
-	if ($quoi == 'actifs' or $lpf) {
168
-		$nb = count($lcpa);
169
-		if (defined('_DIR_PLUGINS_SUPPL')) {
170
-			$nb += count($lcpas);
171
-		}
172
-		echo '<h3>' . sinon(
173
-			singulier_ou_pluriel($nb, 'plugins_actif_un', 'plugins_actifs', 'count'),
174
-			_T('plugins_actif_aucun')
175
-		) . '</h3>';
176
-	}
177
-
178
-	if (empty($format)) {
179
-		$format = 'liste';
180
-	} elseif (!in_array($format, ['liste', 'repertoires'])) {
181
-		$format = 'repertoires';
182
-	}
183
-
184
-	$afficher = charger_fonction("afficher_$format", 'plugins');
185
-	$corps = $afficher(self(), $lcpaffiche, $lcpa, $actifs);
186
-	if (defined('_DIR_PLUGINS_SUPPL')) {
187
-		$corps .= $afficher(self(), $lcpaffichesup, $lcpas, $actifs, _DIR_PLUGINS_SUPPL);
188
-	}
189
-
190
-	if ($corps) {
191
-		$corps .= "\n<div class='boutons' style='display:none;'>"
192
-			. "<input type='submit' class='submit save' value='" . _T('bouton_enregistrer')
193
-			. "' />"
194
-			. '</div>';
195
-	}
196
-
197
-	echo redirige_action_post('activer_plugins', 'activer', 'admin_plugin', '', $corps);
198
-
199
-	echo fin_cadre_trait_couleur(true);
200
-
201
-	if ($quoi == 'actifs') {
202
-		echo affiche_les_plugins_verrouilles($actifs);
203
-	}
204
-	echo '</div>';
205
-
206
-	echo http_script("
84
+    if (!$quoi) {
85
+        $quoi = 'actifs';
86
+    }
87
+    // empecher l'affichage des erreurs dans le bandeau, on le donne ensuite
88
+    // format brut par plugin
89
+    $GLOBALS['erreurs_activation_raw'] = plugin_donne_erreurs(true, false);
90
+    // format resume mis en forme
91
+    $erreur_activation = plugin_donne_erreurs();
92
+    $commencer_page = charger_fonction('commencer_page', 'inc');
93
+    echo $commencer_page(_T('icone_admin_plugin'), 'configuration', 'plugin');
94
+
95
+    echo debut_gauche('plugin', true);
96
+    echo recuperer_fond('prive/squelettes/navigation/configurer', ['exec' => 'admin_plugin']);
97
+
98
+    echo pipeline(
99
+        'affiche_gauche',
100
+        [
101
+            'args' => ['exec' => 'admin_plugin'],
102
+            'data' => afficher_librairies()
103
+        ]
104
+    );
105
+
106
+    echo debut_droite('plugin', true);
107
+    echo gros_titre(_T('icone_admin_plugin'), '', false);
108
+
109
+    // Barre d'onglets de premier niveau
110
+    echo barre_onglets('plugins', 'plugins_actifs');
111
+    // Barre d'onglets de second niveau
112
+    $onglet2 = $quoi == 'actifs' ? 'plugins_actifs' : 'admin_plugin';
113
+    echo debut_onglet('onglets_simple second');
114
+    echo onglet(_T('plugins_tous_liste'), generer_url_ecrire('admin_plugin', 'voir=tous'), 'admin_plugin', $onglet2);
115
+    echo onglet(_T('plugins_actifs_liste'), generer_url_ecrire('admin_plugin'), 'plugins_actifs', $onglet2);
116
+    echo fin_onglet();
117
+
118
+    // message d'erreur au retour d'une operation
119
+    if ($erreur) {
120
+        echo "<div class='error'>$erreur</div>";
121
+    }
122
+    if ($erreur_activation) {
123
+        echo "<div class='error'>$erreur_activation</div>";
124
+    }
125
+
126
+    // la mise a jour de cette meta a ete faite par ecrire_plugin_actifs
127
+    $actifs = unserialize($GLOBALS['meta']['plugin']);
128
+    $lcpa = $actifs + unserialize($GLOBALS['meta']['plugin_attente']);
129
+
130
+    // Les affichages se basent sur le repertoire, pas sur le nom
131
+    $actifs = liste_chemin_plugin($actifs, '');
132
+    if (defined('_DIR_PLUGINS_SUPPL')) {
133
+        $lcpas = liste_chemin_plugin($lcpa, _DIR_PLUGINS_SUPPL);
134
+    }
135
+    $lcpa = liste_chemin_plugin($lcpa);
136
+
137
+    // on installe les plugins maintenant,
138
+    // cela permet aux scripts d'install de faire des affichages (moches...)
139
+    plugin_installes_meta();
140
+
141
+    echo "<div class='liste-plugins formulaire_spip'>";
142
+    echo debut_cadre_trait_couleur('plugin-24.png', true, '', _T('plugins_liste'), 'plugins');
143
+
144
+    if ($quoi !== 'actifs') {
145
+        $lpf = liste_plugin_files();
146
+        if ($lpf) {
147
+            echo '<p>' . _T('texte_presente_plugin') . '</p>';
148
+        } else {
149
+            if (!@is_dir(_DIR_PLUGINS)) {
150
+                echo '<p>' . _T('plugin_info_automatique_ftp', ['rep' => joli_repertoire(_DIR_PLUGINS)])
151
+                    . ' &mdash; ' . _T('plugin_info_automatique_creer') . '</p>';
152
+            }
153
+        }
154
+        $lcpaffiche = $lpf;
155
+        if (defined('_DIR_PLUGINS_SUPPL')) {
156
+            $lcpaffichesup = liste_plugin_files(_DIR_PLUGINS_SUPPL);
157
+        }
158
+    } else {
159
+        // la liste
160
+        // $quoi=='actifs'
161
+        $lcpaffiche = $lcpa;
162
+        if (defined('_DIR_PLUGINS_SUPPL')) {
163
+            $lcpaffichesup = $lcpas;
164
+        }
165
+    }
166
+
167
+    if ($quoi == 'actifs' or $lpf) {
168
+        $nb = count($lcpa);
169
+        if (defined('_DIR_PLUGINS_SUPPL')) {
170
+            $nb += count($lcpas);
171
+        }
172
+        echo '<h3>' . sinon(
173
+            singulier_ou_pluriel($nb, 'plugins_actif_un', 'plugins_actifs', 'count'),
174
+            _T('plugins_actif_aucun')
175
+        ) . '</h3>';
176
+    }
177
+
178
+    if (empty($format)) {
179
+        $format = 'liste';
180
+    } elseif (!in_array($format, ['liste', 'repertoires'])) {
181
+        $format = 'repertoires';
182
+    }
183
+
184
+    $afficher = charger_fonction("afficher_$format", 'plugins');
185
+    $corps = $afficher(self(), $lcpaffiche, $lcpa, $actifs);
186
+    if (defined('_DIR_PLUGINS_SUPPL')) {
187
+        $corps .= $afficher(self(), $lcpaffichesup, $lcpas, $actifs, _DIR_PLUGINS_SUPPL);
188
+    }
189
+
190
+    if ($corps) {
191
+        $corps .= "\n<div class='boutons' style='display:none;'>"
192
+            . "<input type='submit' class='submit save' value='" . _T('bouton_enregistrer')
193
+            . "' />"
194
+            . '</div>';
195
+    }
196
+
197
+    echo redirige_action_post('activer_plugins', 'activer', 'admin_plugin', '', $corps);
198
+
199
+    echo fin_cadre_trait_couleur(true);
200
+
201
+    if ($quoi == 'actifs') {
202
+        echo affiche_les_plugins_verrouilles($actifs);
203
+    }
204
+    echo '</div>';
205
+
206
+    echo http_script("
207 207
 	jQuery(function(){
208 208
 		jQuery('.plugins li.item a[rel=info]').click(function(){
209 209
 			var li = jQuery(this).parents('li').eq(0);
@@ -229,15 +229,15 @@  discard block
 block discarded – undo
229 229
 	});
230 230
 	");
231 231
 
232
-	echo pipeline(
233
-		'affiche_milieu',
234
-		[
235
-			'args' => ['exec' => 'admin_plugin'],
236
-			'data' => ''
237
-		]
238
-	);
232
+    echo pipeline(
233
+        'affiche_milieu',
234
+        [
235
+            'args' => ['exec' => 'admin_plugin'],
236
+            'data' => ''
237
+        ]
238
+    );
239 239
 
240
-	echo fin_gauche(), fin_page();
240
+    echo fin_gauche(), fin_page();
241 241
 }
242 242
 
243 243
 /**
@@ -251,23 +251,23 @@  discard block
 block discarded – undo
251 251
  *     Code HTML
252 252
  **/
253 253
 function affiche_les_plugins_verrouilles($actifs) {
254
-	if ((!$liste = liste_plugin_files(_DIR_PLUGINS_DIST))) {
255
-		return '';
256
-	}
257
-
258
-	$afficher = charger_fonction('afficher_liste', 'plugins');
259
-	$liste = $afficher(self(), $liste, [], $actifs, _DIR_PLUGINS_DIST);
260
-
261
-	return
262
-		"<div id='plugins_dist'>"
263
-		. debut_cadre_trait_couleur('', true, '', _T('plugins_liste_dist'), 'liste_plugins_dist')
264
-		. '<p>'
265
-		. _T('plugin_info_plugins_dist_1', ['plugins_dist' => joli_repertoire(_DIR_PLUGINS_DIST)])
266
-		. '<br />' . _T('plugin_info_plugins_dist_2')
267
-		. '</p>'
268
-		. $liste
269
-		. fin_cadre_trait_couleur(true)
270
-		. "</div>\n";
254
+    if ((!$liste = liste_plugin_files(_DIR_PLUGINS_DIST))) {
255
+        return '';
256
+    }
257
+
258
+    $afficher = charger_fonction('afficher_liste', 'plugins');
259
+    $liste = $afficher(self(), $liste, [], $actifs, _DIR_PLUGINS_DIST);
260
+
261
+    return
262
+        "<div id='plugins_dist'>"
263
+        . debut_cadre_trait_couleur('', true, '', _T('plugins_liste_dist'), 'liste_plugins_dist')
264
+        . '<p>'
265
+        . _T('plugin_info_plugins_dist_1', ['plugins_dist' => joli_repertoire(_DIR_PLUGINS_DIST)])
266
+        . '<br />' . _T('plugin_info_plugins_dist_2')
267
+        . '</p>'
268
+        . $liste
269
+        . fin_cadre_trait_couleur(true)
270
+        . "</div>\n";
271 271
 }
272 272
 
273 273
 /**
@@ -279,19 +279,19 @@  discard block
 block discarded – undo
279 279
  */
280 280
 function afficher_librairies() {
281 281
 
282
-	if (!$libs = liste_librairies()) {
283
-		return '';
284
-	}
285
-	ksort($libs);
286
-	$res = debut_cadre_enfonce('', true, '', _T('plugin_librairies_installees'));
287
-	$res .= '<dl>';
288
-	foreach ($libs as $lib => $rep) {
289
-		$res .= "<dt>$lib</dt><dd>" . joli_repertoire($rep) . "</dd>\n";
290
-	}
291
-	$res .= '</dl>';
292
-	$res .= fin_cadre_enfonce(true);
293
-
294
-	return $res;
282
+    if (!$libs = liste_librairies()) {
283
+        return '';
284
+    }
285
+    ksort($libs);
286
+    $res = debut_cadre_enfonce('', true, '', _T('plugin_librairies_installees'));
287
+    $res .= '<dl>';
288
+    foreach ($libs as $lib => $rep) {
289
+        $res .= "<dt>$lib</dt><dd>" . joli_repertoire($rep) . "</dd>\n";
290
+    }
291
+    $res .= '</dl>';
292
+    $res .= fin_cadre_enfonce(true);
293
+
294
+    return $res;
295 295
 }
296 296
 
297 297
 
@@ -302,22 +302,22 @@  discard block
 block discarded – undo
302 302
  *     Tableau (nom de la lib => repertoire , ...)
303 303
  */
304 304
 function liste_librairies() {
305
-	$libs = [];
306
-	foreach (array_reverse(creer_chemin()) as $d) {
307
-		if (
308
-			is_dir($dir = $d . 'lib/')
309
-			and $t = opendir($dir)
310
-		) {
311
-			while (($f = readdir($t)) !== false) {
312
-				if (
313
-					$f[0] != '.'
314
-					and is_dir("$dir/$f")
315
-				) {
316
-					$libs[$f] = $dir;
317
-				}
318
-			}
319
-		}
320
-	}
321
-
322
-	return $libs;
305
+    $libs = [];
306
+    foreach (array_reverse(creer_chemin()) as $d) {
307
+        if (
308
+            is_dir($dir = $d . 'lib/')
309
+            and $t = opendir($dir)
310
+        ) {
311
+            while (($f = readdir($t)) !== false) {
312
+                if (
313
+                    $f[0] != '.'
314
+                    and is_dir("$dir/$f")
315
+                ) {
316
+                    $libs[$f] = $dir;
317
+                }
318
+            }
319
+        }
320
+    }
321
+
322
+    return $libs;
323 323
 }
Please login to merge, or discard this patch.
ecrire/exec/selectionner.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -16,7 +16,7 @@  discard block
 block discarded – undo
16 16
  * @package SPIP\Core\Rubriques
17 17
  **/
18 18
 if (!defined('_ECRIRE_INC_VERSION')) {
19
-	return;
19
+    return;
20 20
 }
21 21
 
22 22
 include_spip('inc/actions');
@@ -28,21 +28,21 @@  discard block
 block discarded – undo
28 28
  * @uses ajax_retour()
29 29
  **/
30 30
 function exec_selectionner_dist() {
31
-	$id = intval(_request('id'));
32
-	$exclus = intval(_request('exclus'));
33
-	$type = _request('type');
34
-	$rac = _request('racine');
35
-	$do = _request('do');
36
-	if (preg_match('/^\w*$/', $do)) {
37
-		if (!$do) {
38
-			$do = 'aff';
39
-		}
31
+    $id = intval(_request('id'));
32
+    $exclus = intval(_request('exclus'));
33
+    $type = _request('type');
34
+    $rac = _request('racine');
35
+    $do = _request('do');
36
+    if (preg_match('/^\w*$/', $do)) {
37
+        if (!$do) {
38
+            $do = 'aff';
39
+        }
40 40
 
41
-		$selectionner = charger_fonction('selectionner', 'inc');
41
+        $selectionner = charger_fonction('selectionner', 'inc');
42 42
 
43
-		$r = $selectionner($id, 'choix_parent', $exclus, $rac, $type != 'breve', $do);
44
-	} else {
45
-		$r = '';
46
-	}
47
-	ajax_retour($r);
43
+        $r = $selectionner($id, 'choix_parent', $exclus, $rac, $type != 'breve', $do);
44
+    } else {
45
+        $r = '';
46
+    }
47
+    ajax_retour($r);
48 48
 }
Please login to merge, or discard this patch.
ecrire/exec/base_delete_all.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -17,40 +17,40 @@
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 /**
24 24
  * Exec de la page de destruction des tables de SPIP
25 25
  **/
26 26
 function exec_base_delete_all_dist() {
27
-	include_spip('inc/autoriser');
28
-	if (!autoriser('detruire')) {
29
-		include_spip('inc/minipres');
30
-		echo minipres();
31
-	} else {
32
-		include_spip('base/dump');
33
-		$res = base_lister_toutes_tables('', [], [], true);
34
-		if (!$res) {
35
-			include_spip('inc/minipres');
36
-			spip_log('Erreur base de donnees');
37
-			echo minipres(
38
-				_T('info_travaux_titre'),
39
-				_T('titre_probleme_technique') . '<p><tt>' . sql_errno() . ' ' . sql_error() . '</tt></p>'
40
-			);
41
-		} else {
42
-			$res = base_saisie_tables('delete', $res);
43
-			include_spip('inc/headers');
44
-			$res = "\n<ol style='text-align:left'><li>\n" .
45
-				join("</li>\n<li>", $res) .
46
-				'</li></ol>';
47
-			$admin = charger_fonction('admin', 'inc');
48
-			$res = $admin('delete_all', _T('titre_page_delete_all'), $res);
49
-			if (!$res) {
50
-				redirige_url_ecrire('install', '');
51
-			} else {
52
-				echo $res;
53
-			}
54
-		}
55
-	}
27
+    include_spip('inc/autoriser');
28
+    if (!autoriser('detruire')) {
29
+        include_spip('inc/minipres');
30
+        echo minipres();
31
+    } else {
32
+        include_spip('base/dump');
33
+        $res = base_lister_toutes_tables('', [], [], true);
34
+        if (!$res) {
35
+            include_spip('inc/minipres');
36
+            spip_log('Erreur base de donnees');
37
+            echo minipres(
38
+                _T('info_travaux_titre'),
39
+                _T('titre_probleme_technique') . '<p><tt>' . sql_errno() . ' ' . sql_error() . '</tt></p>'
40
+            );
41
+        } else {
42
+            $res = base_saisie_tables('delete', $res);
43
+            include_spip('inc/headers');
44
+            $res = "\n<ol style='text-align:left'><li>\n" .
45
+                join("</li>\n<li>", $res) .
46
+                '</li></ol>';
47
+            $admin = charger_fonction('admin', 'inc');
48
+            $res = $admin('delete_all', _T('titre_page_delete_all'), $res);
49
+            if (!$res) {
50
+                redirige_url_ecrire('install', '');
51
+            } else {
52
+                echo $res;
53
+            }
54
+        }
55
+    }
56 56
 }
Please login to merge, or discard this patch.
ecrire/exec/fond.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@  discard block
 block discarded – undo
21 21
  */
22 22
 
23 23
 if (!defined('_ECRIRE_INC_VERSION')) {
24
-	return;
24
+    return;
25 25
 }
26 26
 
27 27
 
@@ -29,16 +29,16 @@  discard block
 block discarded – undo
29 29
 $GLOBALS['delais'] = 0;// pas de cache !
30 30
 // Securite
31 31
 if (strstr($fond, '/')) {
32
-	if (
33
-		!include_spip('inc/autoriser')
34
-		or !autoriser('webmestre')
35
-	) {
36
-		include_spip('inc/minipres');
37
-		echo minipres();
38
-		exit;
39
-	}
32
+    if (
33
+        !include_spip('inc/autoriser')
34
+        or !autoriser('webmestre')
35
+    ) {
36
+        include_spip('inc/minipres');
37
+        echo minipres();
38
+        exit;
39
+    }
40 40
 } else {
41
-	$fond = "prive/squelettes/$fond";
41
+    $fond = "prive/squelettes/$fond";
42 42
 }
43 43
 
44 44
 // quelques inclusions et ini prealables
@@ -50,8 +50,8 @@  discard block
 block discarded – undo
50 50
  * @todo supprimer cette fonction vide ?
51 51
  **/
52 52
 function shutdown_error() {
53
-	// si on arrive ici avec un tampon non ferme : erreur fatale
54
-	/*	if (ob_get_level()){
53
+    // si on arrive ici avec un tampon non ferme : erreur fatale
54
+    /*	if (ob_get_level()){
55 55
 			// envoyer tous les tampons
56 56
 			while (ob_get_level())
57 57
 				ob_end_flush();
Please login to merge, or discard this patch.
ecrire/req/pg.exp.php 1 patch
Indentation   +1176 added lines, -1176 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  */
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 define('_DEFAULT_DB', 'spip');
@@ -32,130 +32,130 @@  discard block
 block discarded – undo
32 32
 
33 33
 // https://code.spip.net/@req_pg_dist
34 34
 function req_pg_dist($addr, $port, $login, $pass, $db = '', $prefixe = '') {
35
-	static $last_connect = [];
36
-	if (!extension_loaded('pgsql')) {
37
-		return false;
38
-	}
39
-
40
-	// si provient de selectdb
41
-	if (empty($addr) && empty($port) && empty($login) && empty($pass)) {
42
-		foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
43
-			$$a = $last_connect[$a];
44
-		}
45
-	}
46
-	@list($host, $p) = explode(';', $addr);
47
-	if ($p > 0) {
48
-		$port = " port=$p";
49
-	} else {
50
-		$port = '';
51
-	}
52
-	$erreurs = [];
53
-	if ($db) {
54
-		@$link = pg_connect("host=$host$port dbname=$db user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW);
55
-	} elseif (!@$link = pg_connect("host=$host$port user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW)) {
56
-		$erreurs[] = pg_last_error();
57
-		if (@$link = pg_connect("host=$host$port dbname=$login user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW)) {
58
-			$db = $login;
59
-		} else {
60
-			$erreurs[] = pg_last_error();
61
-			$db = _DEFAULT_DB;
62
-			$link = pg_connect("host=$host$port dbname=$db user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW);
63
-		}
64
-	}
65
-	if (!$link) {
66
-		$erreurs[] = pg_last_error();
67
-		foreach ($erreurs as $e) {
68
-			spip_log('Echec pg_connect. Erreur : ' . $e, 'pg.' . _LOG_HS);
69
-		}
70
-
71
-		return false;
72
-	}
73
-
74
-	if ($link) {
75
-		$last_connect = [
76
-			'addr' => $addr,
77
-			'port' => $port,
78
-			'login' => $login,
79
-			'pass' => $pass,
80
-			'db' => $db,
81
-			'prefixe' => $prefixe,
82
-		];
83
-	}
84
-
85
-	spip_log(
86
-		"Connexion vers $host, base $db, prefixe $prefixe " . ($link ? 'operationnelle' : 'impossible'),
87
-		'pg.' . _LOG_DEBUG
88
-	);
89
-
90
-	return !$link ? false : [
91
-		'db' => $db,
92
-		'prefixe' => $prefixe ? $prefixe : $db,
93
-		'link' => $link,
94
-	];
35
+    static $last_connect = [];
36
+    if (!extension_loaded('pgsql')) {
37
+        return false;
38
+    }
39
+
40
+    // si provient de selectdb
41
+    if (empty($addr) && empty($port) && empty($login) && empty($pass)) {
42
+        foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
43
+            $$a = $last_connect[$a];
44
+        }
45
+    }
46
+    @list($host, $p) = explode(';', $addr);
47
+    if ($p > 0) {
48
+        $port = " port=$p";
49
+    } else {
50
+        $port = '';
51
+    }
52
+    $erreurs = [];
53
+    if ($db) {
54
+        @$link = pg_connect("host=$host$port dbname=$db user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW);
55
+    } elseif (!@$link = pg_connect("host=$host$port user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW)) {
56
+        $erreurs[] = pg_last_error();
57
+        if (@$link = pg_connect("host=$host$port dbname=$login user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW)) {
58
+            $db = $login;
59
+        } else {
60
+            $erreurs[] = pg_last_error();
61
+            $db = _DEFAULT_DB;
62
+            $link = pg_connect("host=$host$port dbname=$db user=$login password='$pass'", PGSQL_CONNECT_FORCE_NEW);
63
+        }
64
+    }
65
+    if (!$link) {
66
+        $erreurs[] = pg_last_error();
67
+        foreach ($erreurs as $e) {
68
+            spip_log('Echec pg_connect. Erreur : ' . $e, 'pg.' . _LOG_HS);
69
+        }
70
+
71
+        return false;
72
+    }
73
+
74
+    if ($link) {
75
+        $last_connect = [
76
+            'addr' => $addr,
77
+            'port' => $port,
78
+            'login' => $login,
79
+            'pass' => $pass,
80
+            'db' => $db,
81
+            'prefixe' => $prefixe,
82
+        ];
83
+    }
84
+
85
+    spip_log(
86
+        "Connexion vers $host, base $db, prefixe $prefixe " . ($link ? 'operationnelle' : 'impossible'),
87
+        'pg.' . _LOG_DEBUG
88
+    );
89
+
90
+    return !$link ? false : [
91
+        'db' => $db,
92
+        'prefixe' => $prefixe ? $prefixe : $db,
93
+        'link' => $link,
94
+    ];
95 95
 }
96 96
 
97 97
 $GLOBALS['spip_pg_functions_1'] = [
98
-	'alter' => 'spip_pg_alter',
99
-	'count' => 'spip_pg_count',
100
-	'countsel' => 'spip_pg_countsel',
101
-	'create' => 'spip_pg_create',
102
-	'create_base' => 'spip_pg_create_base',
103
-	'create_view' => 'spip_pg_create_view',
104
-	'date_proche' => 'spip_pg_date_proche',
105
-	'delete' => 'spip_pg_delete',
106
-	'drop_table' => 'spip_pg_drop_table',
107
-	'drop_view' => 'spip_pg_drop_view',
108
-	'errno' => 'spip_pg_errno',
109
-	'error' => 'spip_pg_error',
110
-	'explain' => 'spip_pg_explain',
111
-	'fetch' => 'spip_pg_fetch',
112
-	'seek' => 'spip_pg_seek',
113
-	'free' => 'spip_pg_free',
114
-	'hex' => 'spip_pg_hex',
115
-	'in' => 'spip_pg_in',
116
-	'insert' => 'spip_pg_insert',
117
-	'insertq' => 'spip_pg_insertq',
118
-	'insertq_multi' => 'spip_pg_insertq_multi',
119
-	'listdbs' => 'spip_pg_listdbs',
120
-	'multi' => 'spip_pg_multi',
121
-	'optimize' => 'spip_pg_optimize',
122
-	'query' => 'spip_pg_query',
123
-	'quote' => 'spip_pg_quote',
124
-	'replace' => 'spip_pg_replace',
125
-	'replace_multi' => 'spip_pg_replace_multi',
126
-	'select' => 'spip_pg_select',
127
-	'selectdb' => 'spip_pg_selectdb',
128
-	'set_connect_charset' => 'spip_pg_set_connect_charset',
129
-	'showbase' => 'spip_pg_showbase',
130
-	'showtable' => 'spip_pg_showtable',
131
-	'update' => 'spip_pg_update',
132
-	'updateq' => 'spip_pg_updateq',
98
+    'alter' => 'spip_pg_alter',
99
+    'count' => 'spip_pg_count',
100
+    'countsel' => 'spip_pg_countsel',
101
+    'create' => 'spip_pg_create',
102
+    'create_base' => 'spip_pg_create_base',
103
+    'create_view' => 'spip_pg_create_view',
104
+    'date_proche' => 'spip_pg_date_proche',
105
+    'delete' => 'spip_pg_delete',
106
+    'drop_table' => 'spip_pg_drop_table',
107
+    'drop_view' => 'spip_pg_drop_view',
108
+    'errno' => 'spip_pg_errno',
109
+    'error' => 'spip_pg_error',
110
+    'explain' => 'spip_pg_explain',
111
+    'fetch' => 'spip_pg_fetch',
112
+    'seek' => 'spip_pg_seek',
113
+    'free' => 'spip_pg_free',
114
+    'hex' => 'spip_pg_hex',
115
+    'in' => 'spip_pg_in',
116
+    'insert' => 'spip_pg_insert',
117
+    'insertq' => 'spip_pg_insertq',
118
+    'insertq_multi' => 'spip_pg_insertq_multi',
119
+    'listdbs' => 'spip_pg_listdbs',
120
+    'multi' => 'spip_pg_multi',
121
+    'optimize' => 'spip_pg_optimize',
122
+    'query' => 'spip_pg_query',
123
+    'quote' => 'spip_pg_quote',
124
+    'replace' => 'spip_pg_replace',
125
+    'replace_multi' => 'spip_pg_replace_multi',
126
+    'select' => 'spip_pg_select',
127
+    'selectdb' => 'spip_pg_selectdb',
128
+    'set_connect_charset' => 'spip_pg_set_connect_charset',
129
+    'showbase' => 'spip_pg_showbase',
130
+    'showtable' => 'spip_pg_showtable',
131
+    'update' => 'spip_pg_update',
132
+    'updateq' => 'spip_pg_updateq',
133 133
 ];
134 134
 
135 135
 // Par ou ca passe une fois les traductions faites
136 136
 // https://code.spip.net/@spip_pg_trace_query
137 137
 function spip_pg_trace_query($query, $serveur = '') {
138
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
139
-	$prefixe = $connexion['prefixe'];
140
-	$link = $connexion['link'];
141
-	$db = $connexion['db'];
142
-
143
-	if (isset($_GET['var_profile'])) {
144
-		include_spip('public/tracer');
145
-		$t = trace_query_start();
146
-		$e = '';
147
-	} else {
148
-		$t = 0;
149
-	}
150
-
151
-	$connexion['last'] = $query;
152
-	$r = spip_pg_query_simple($link, $query);
153
-
154
-	// Log de l'erreur eventuelle
155
-	if ($e = spip_pg_errno($serveur)) {
156
-		$e .= spip_pg_error($query, $serveur);
157
-	} // et du fautif
158
-	return $t ? trace_query_end($query, $t, $r, $e, $serveur) : $r;
138
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
139
+    $prefixe = $connexion['prefixe'];
140
+    $link = $connexion['link'];
141
+    $db = $connexion['db'];
142
+
143
+    if (isset($_GET['var_profile'])) {
144
+        include_spip('public/tracer');
145
+        $t = trace_query_start();
146
+        $e = '';
147
+    } else {
148
+        $t = 0;
149
+    }
150
+
151
+    $connexion['last'] = $query;
152
+    $r = spip_pg_query_simple($link, $query);
153
+
154
+    // Log de l'erreur eventuelle
155
+    if ($e = spip_pg_errno($serveur)) {
156
+        $e .= spip_pg_error($query, $serveur);
157
+    } // et du fautif
158
+    return $t ? trace_query_end($query, $t, $r, $e, $serveur) : $r;
159 159
 }
160 160
 
161 161
 // Fonction de requete generale quand on est sur que c'est SQL standard.
@@ -163,30 +163,30 @@  discard block
 block discarded – undo
163 163
 
164 164
 // https://code.spip.net/@spip_pg_query
165 165
 function spip_pg_query($query, $serveur = '', $requeter = true) {
166
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
167
-	$prefixe = $connexion['prefixe'];
168
-	$link = $connexion['link'];
169
-	$db = $connexion['db'];
170
-
171
-	if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/i', $query, $regs)) {
172
-		$suite = strstr($query, $regs[0]);
173
-		$query = substr($query, 0, -strlen($suite));
174
-	} else {
175
-		$suite = '';
176
-	}
177
-	$query = preg_replace('/([,\s])spip_/', '\1' . $prefixe . '_', $query) . $suite;
178
-
179
-	// renvoyer la requete inerte si demandee
180
-	if (!$requeter) {
181
-		return $query;
182
-	}
183
-
184
-	return spip_pg_trace_query($query, $serveur);
166
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
167
+    $prefixe = $connexion['prefixe'];
168
+    $link = $connexion['link'];
169
+    $db = $connexion['db'];
170
+
171
+    if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/i', $query, $regs)) {
172
+        $suite = strstr($query, $regs[0]);
173
+        $query = substr($query, 0, -strlen($suite));
174
+    } else {
175
+        $suite = '';
176
+    }
177
+    $query = preg_replace('/([,\s])spip_/', '\1' . $prefixe . '_', $query) . $suite;
178
+
179
+    // renvoyer la requete inerte si demandee
180
+    if (!$requeter) {
181
+        return $query;
182
+    }
183
+
184
+    return spip_pg_trace_query($query, $serveur);
185 185
 }
186 186
 
187 187
 function spip_pg_query_simple($link, $query) {
188
-	#spip_log(var_export($query,true), 'pg.'._LOG_DEBUG);
189
-	return pg_query($link, $query);
188
+    #spip_log(var_export($query,true), 'pg.'._LOG_DEBUG);
189
+    return pg_query($link, $query);
190 190
 }
191 191
 
192 192
 /*
@@ -198,199 +198,199 @@  discard block
 block discarded – undo
198 198
  * de requetes showtable intempestives
199 199
  */
200 200
 function spip_pg_ajouter_champs_timestamp($table, $couples, $desc = '', $serveur = '') {
201
-	static $tables = [];
202
-
203
-	if (!isset($tables[$table])) {
204
-		if (!$desc) {
205
-			$trouver_table = charger_fonction('trouver_table', 'base');
206
-			$desc = $trouver_table($table, $serveur);
207
-			// si pas de description, on ne fait rien, ou on die() ?
208
-			if (!$desc) {
209
-				return $couples;
210
-			}
211
-		}
212
-
213
-		// recherche des champs avec simplement 'TIMESTAMP'
214
-		// cependant, il faudra peut etre etendre
215
-		// avec la gestion de DEFAULT et ON UPDATE
216
-		// mais ceux-ci ne sont pas utilises dans le core
217
-		$tables[$table] = [];
218
-		foreach ($desc['field'] as $k => $v) {
219
-			$v = strtolower(ltrim($v));
220
-			// ne pas ajouter de timestamp now() si un default est specifie
221
-			if (strpos($v, 'timestamp') === 0 and strpos($v, 'default') === false) {
222
-				$tables[$table][] = $k;
223
-			}
224
-		}
225
-	}
226
-
227
-	// ajout des champs type 'timestamp' absents
228
-	foreach ($tables[$table] as $maj) {
229
-		if (!array_key_exists($maj, $couples)) {
230
-			$couples[$maj] = 'NOW()';
231
-		}
232
-	}
233
-
234
-	return $couples;
201
+    static $tables = [];
202
+
203
+    if (!isset($tables[$table])) {
204
+        if (!$desc) {
205
+            $trouver_table = charger_fonction('trouver_table', 'base');
206
+            $desc = $trouver_table($table, $serveur);
207
+            // si pas de description, on ne fait rien, ou on die() ?
208
+            if (!$desc) {
209
+                return $couples;
210
+            }
211
+        }
212
+
213
+        // recherche des champs avec simplement 'TIMESTAMP'
214
+        // cependant, il faudra peut etre etendre
215
+        // avec la gestion de DEFAULT et ON UPDATE
216
+        // mais ceux-ci ne sont pas utilises dans le core
217
+        $tables[$table] = [];
218
+        foreach ($desc['field'] as $k => $v) {
219
+            $v = strtolower(ltrim($v));
220
+            // ne pas ajouter de timestamp now() si un default est specifie
221
+            if (strpos($v, 'timestamp') === 0 and strpos($v, 'default') === false) {
222
+                $tables[$table][] = $k;
223
+            }
224
+        }
225
+    }
226
+
227
+    // ajout des champs type 'timestamp' absents
228
+    foreach ($tables[$table] as $maj) {
229
+        if (!array_key_exists($maj, $couples)) {
230
+            $couples[$maj] = 'NOW()';
231
+        }
232
+    }
233
+
234
+    return $couples;
235 235
 }
236 236
 
237 237
 
238 238
 // Alter en PG ne traite pas les index
239 239
 // https://code.spip.net/@spip_pg_alter
240 240
 function spip_pg_alter($query, $serveur = '', $requeter = true) {
241
-	// il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
242
-	// tout en cassant en deux alter distincts "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"...
243
-	// ou revoir l'api de sql_alter en creant un
244
-	// sql_alter_table($table,array($actions));
245
-	if (!preg_match('/\s*((\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
246
-		spip_log("$query mal comprise", 'pg.' . _LOG_ERREUR);
247
-
248
-		return false;
249
-	}
250
-	$debut = $regs[1];
251
-	$table = $regs[3];
252
-	$suite = $regs[4];
253
-	$todo = explode(',', $suite);
254
-	// on remet les morceaux dechires ensembles... que c'est laid !
255
-	$todo2 = [];
256
-	$i = 0;
257
-	$ouverte = false;
258
-	while ($do = array_shift($todo)) {
259
-		$todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
260
-		$o = (false !== strpos($do, '('));
261
-		$f = (false !== strpos($do, ')'));
262
-		if ($o and !$f) {
263
-			$ouverte = true;
264
-		} elseif ($f) {
265
-			$ouverte = false;
266
-		}
267
-		if (!$ouverte) {
268
-			$i++;
269
-		}
270
-	}
271
-	$todo = $todo2;
272
-	$query = $debut . ' ' . array_shift($todo);
273
-
274
-	if (!preg_match('/^\s*(IGNORE\s*)?TABLE\s+(\w+)\s+(ADD|DROP|CHANGE|MODIFY|RENAME)\s*(.*)$/is', $query, $r)) {
275
-		spip_log("$query incompris", 'pg.' . _LOG_ERREUR);
276
-	} else {
277
-		if ($r[1]) {
278
-			spip_log("j'ignore IGNORE dans $query", 'pg.' . _LOG_AVERTISSEMENT);
279
-		}
280
-		$f = 'spip_pg_alter_' . strtolower($r[3]);
281
-		if (function_exists($f)) {
282
-			$f($r[2], $r[4], $serveur, $requeter);
283
-		} else {
284
-			spip_log("$query non prevu", 'pg.' . _LOG_ERREUR);
285
-		}
286
-	}
287
-	// Alter a plusieurs args. Faudrait optimiser.
288
-	if ($todo) {
289
-		spip_pg_alter("TABLE $table " . join(',', $todo));
290
-	}
241
+    // il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
242
+    // tout en cassant en deux alter distincts "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"...
243
+    // ou revoir l'api de sql_alter en creant un
244
+    // sql_alter_table($table,array($actions));
245
+    if (!preg_match('/\s*((\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
246
+        spip_log("$query mal comprise", 'pg.' . _LOG_ERREUR);
247
+
248
+        return false;
249
+    }
250
+    $debut = $regs[1];
251
+    $table = $regs[3];
252
+    $suite = $regs[4];
253
+    $todo = explode(',', $suite);
254
+    // on remet les morceaux dechires ensembles... que c'est laid !
255
+    $todo2 = [];
256
+    $i = 0;
257
+    $ouverte = false;
258
+    while ($do = array_shift($todo)) {
259
+        $todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
260
+        $o = (false !== strpos($do, '('));
261
+        $f = (false !== strpos($do, ')'));
262
+        if ($o and !$f) {
263
+            $ouverte = true;
264
+        } elseif ($f) {
265
+            $ouverte = false;
266
+        }
267
+        if (!$ouverte) {
268
+            $i++;
269
+        }
270
+    }
271
+    $todo = $todo2;
272
+    $query = $debut . ' ' . array_shift($todo);
273
+
274
+    if (!preg_match('/^\s*(IGNORE\s*)?TABLE\s+(\w+)\s+(ADD|DROP|CHANGE|MODIFY|RENAME)\s*(.*)$/is', $query, $r)) {
275
+        spip_log("$query incompris", 'pg.' . _LOG_ERREUR);
276
+    } else {
277
+        if ($r[1]) {
278
+            spip_log("j'ignore IGNORE dans $query", 'pg.' . _LOG_AVERTISSEMENT);
279
+        }
280
+        $f = 'spip_pg_alter_' . strtolower($r[3]);
281
+        if (function_exists($f)) {
282
+            $f($r[2], $r[4], $serveur, $requeter);
283
+        } else {
284
+            spip_log("$query non prevu", 'pg.' . _LOG_ERREUR);
285
+        }
286
+    }
287
+    // Alter a plusieurs args. Faudrait optimiser.
288
+    if ($todo) {
289
+        spip_pg_alter("TABLE $table " . join(',', $todo));
290
+    }
291 291
 }
292 292
 
293 293
 // https://code.spip.net/@spip_pg_alter_change
294 294
 function spip_pg_alter_change($table, $arg, $serveur = '', $requeter = true) {
295
-	if (!preg_match('/^`?(\w+)`?\s+`?(\w+)`?\s+(.*?)\s*(DEFAULT .*?)?(NOT\s+NULL)?\s*(DEFAULT .*?)?$/i', $arg, $r)) {
296
-		spip_log("alter change: $arg  incompris", 'pg.' . _LOG_ERREUR);
297
-	} else {
298
-		list(, $old, $new, $type, $default, $null, $def2) = $r;
299
-		$actions = ["ALTER $old TYPE " . mysql2pg_type($type)];
300
-		if ($null) {
301
-			$actions[] = "ALTER $old SET NOT NULL";
302
-		} else {
303
-			$actions[] = "ALTER $old DROP NOT NULL";
304
-		}
305
-
306
-		if ($d = ($default ? $default : $def2)) {
307
-			$actions[] = "ALTER $old SET $d";
308
-		} else {
309
-			$actions[] = "ALTER $old DROP DEFAULT";
310
-		}
311
-
312
-		spip_pg_query("ALTER TABLE $table " . join(', ', $actions));
313
-
314
-		if ($old != $new) {
315
-			spip_pg_query("ALTER TABLE $table RENAME $old TO $new", $serveur);
316
-		}
317
-	}
295
+    if (!preg_match('/^`?(\w+)`?\s+`?(\w+)`?\s+(.*?)\s*(DEFAULT .*?)?(NOT\s+NULL)?\s*(DEFAULT .*?)?$/i', $arg, $r)) {
296
+        spip_log("alter change: $arg  incompris", 'pg.' . _LOG_ERREUR);
297
+    } else {
298
+        list(, $old, $new, $type, $default, $null, $def2) = $r;
299
+        $actions = ["ALTER $old TYPE " . mysql2pg_type($type)];
300
+        if ($null) {
301
+            $actions[] = "ALTER $old SET NOT NULL";
302
+        } else {
303
+            $actions[] = "ALTER $old DROP NOT NULL";
304
+        }
305
+
306
+        if ($d = ($default ? $default : $def2)) {
307
+            $actions[] = "ALTER $old SET $d";
308
+        } else {
309
+            $actions[] = "ALTER $old DROP DEFAULT";
310
+        }
311
+
312
+        spip_pg_query("ALTER TABLE $table " . join(', ', $actions));
313
+
314
+        if ($old != $new) {
315
+            spip_pg_query("ALTER TABLE $table RENAME $old TO $new", $serveur);
316
+        }
317
+    }
318 318
 }
319 319
 
320 320
 // https://code.spip.net/@spip_pg_alter_add
321 321
 function spip_pg_alter_add($table, $arg, $serveur = '', $requeter = true) {
322
-	if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*(.*)$/', $arg, $r)) {
323
-		spip_log("alter add $arg  incompris", 'pg.' . _LOG_ERREUR);
324
-
325
-		return null;
326
-	}
327
-	if (!$r[1] or $r[1] == 'COLUMN') {
328
-		preg_match('/`?(\w+)`?(.*)/', $r[2], $m);
329
-		if (preg_match('/^(.*)(BEFORE|AFTER|FIRST)(.*)$/is', $m[2], $n)) {
330
-			$m[2] = $n[1];
331
-		}
332
-
333
-		return spip_pg_query("ALTER TABLE $table ADD " . $m[1] . ' ' . mysql2pg_type($m[2]), $serveur, $requeter);
334
-	} elseif ($r[1][0] == 'P') {
335
-		// la primary peut etre sur plusieurs champs
336
-		$r[2] = trim(str_replace('`', '', $r[2]));
337
-		$m = ($r[2][0] == '(') ? substr($r[2], 1, -1) : $r[2];
338
-
339
-		return spip_pg_query(
340
-			"ALTER TABLE $table ADD CONSTRAINT $table" . '_pkey PRIMARY KEY (' . $m . ')',
341
-			$serveur,
342
-			$requeter
343
-		);
344
-	} else {
345
-		preg_match('/([^\s,]*)\s*(.*)?/', $r[2], $m);
346
-		// peut etre "(colonne)" ou "nom_index (colonnes)"
347
-		// bug potentiel si qqn met "(colonne, colonne)"
348
-		//
349
-		// nom_index (colonnes)
350
-		if ($m[2]) {
351
-			$colonnes = substr($m[2], 1, -1);
352
-			$nom_index = $m[1];
353
-		} else {
354
-			// (colonne)
355
-			if ($m[1][0] == '(') {
356
-				$colonnes = substr($m[1], 1, -1);
357
-				if (false !== strpos(',', $colonnes)) {
358
-					spip_log('PG : Erreur, impossible de creer un index sur plusieurs colonnes'
359
-						. " sans qu'il ait de nom ($table, ($colonnes))", 'pg.' . _LOG_ERREUR);
360
-				} else {
361
-					$nom_index = $colonnes;
362
-				}
363
-			} // nom_index
364
-			else {
365
-				$nom_index = $colonnes = $m[1];
366
-			}
367
-		}
368
-
369
-		return spip_pg_create_index($nom_index, $table, $colonnes, $serveur, $requeter);
370
-	}
322
+    if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*(.*)$/', $arg, $r)) {
323
+        spip_log("alter add $arg  incompris", 'pg.' . _LOG_ERREUR);
324
+
325
+        return null;
326
+    }
327
+    if (!$r[1] or $r[1] == 'COLUMN') {
328
+        preg_match('/`?(\w+)`?(.*)/', $r[2], $m);
329
+        if (preg_match('/^(.*)(BEFORE|AFTER|FIRST)(.*)$/is', $m[2], $n)) {
330
+            $m[2] = $n[1];
331
+        }
332
+
333
+        return spip_pg_query("ALTER TABLE $table ADD " . $m[1] . ' ' . mysql2pg_type($m[2]), $serveur, $requeter);
334
+    } elseif ($r[1][0] == 'P') {
335
+        // la primary peut etre sur plusieurs champs
336
+        $r[2] = trim(str_replace('`', '', $r[2]));
337
+        $m = ($r[2][0] == '(') ? substr($r[2], 1, -1) : $r[2];
338
+
339
+        return spip_pg_query(
340
+            "ALTER TABLE $table ADD CONSTRAINT $table" . '_pkey PRIMARY KEY (' . $m . ')',
341
+            $serveur,
342
+            $requeter
343
+        );
344
+    } else {
345
+        preg_match('/([^\s,]*)\s*(.*)?/', $r[2], $m);
346
+        // peut etre "(colonne)" ou "nom_index (colonnes)"
347
+        // bug potentiel si qqn met "(colonne, colonne)"
348
+        //
349
+        // nom_index (colonnes)
350
+        if ($m[2]) {
351
+            $colonnes = substr($m[2], 1, -1);
352
+            $nom_index = $m[1];
353
+        } else {
354
+            // (colonne)
355
+            if ($m[1][0] == '(') {
356
+                $colonnes = substr($m[1], 1, -1);
357
+                if (false !== strpos(',', $colonnes)) {
358
+                    spip_log('PG : Erreur, impossible de creer un index sur plusieurs colonnes'
359
+                        . " sans qu'il ait de nom ($table, ($colonnes))", 'pg.' . _LOG_ERREUR);
360
+                } else {
361
+                    $nom_index = $colonnes;
362
+                }
363
+            } // nom_index
364
+            else {
365
+                $nom_index = $colonnes = $m[1];
366
+            }
367
+        }
368
+
369
+        return spip_pg_create_index($nom_index, $table, $colonnes, $serveur, $requeter);
370
+    }
371 371
 }
372 372
 
373 373
 // https://code.spip.net/@spip_pg_alter_drop
374 374
 function spip_pg_alter_drop($table, $arg, $serveur = '', $requeter = true) {
375
-	if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*`?(\w*)`?/', $arg, $r)) {
376
-		spip_log("alter drop: $arg  incompris", 'pg.' . _LOG_ERREUR);
377
-	} else {
378
-		if (!$r[1] or $r[1] == 'COLUMN') {
379
-			return spip_pg_query("ALTER TABLE $table DROP " . $r[2], $serveur);
380
-		} elseif ($r[1][0] == 'P') {
381
-			return spip_pg_query("ALTER TABLE $table DROP CONSTRAINT $table" . '_pkey', $serveur);
382
-		} else {
383
-			return spip_pg_query('DROP INDEX ' . $table . '_' . $r[2], $serveur);
384
-		}
385
-	}
375
+    if (!preg_match('/^(COLUMN|INDEX|KEY|PRIMARY\s+KEY|)\s*`?(\w*)`?/', $arg, $r)) {
376
+        spip_log("alter drop: $arg  incompris", 'pg.' . _LOG_ERREUR);
377
+    } else {
378
+        if (!$r[1] or $r[1] == 'COLUMN') {
379
+            return spip_pg_query("ALTER TABLE $table DROP " . $r[2], $serveur);
380
+        } elseif ($r[1][0] == 'P') {
381
+            return spip_pg_query("ALTER TABLE $table DROP CONSTRAINT $table" . '_pkey', $serveur);
382
+        } else {
383
+            return spip_pg_query('DROP INDEX ' . $table . '_' . $r[2], $serveur);
384
+        }
385
+    }
386 386
 }
387 387
 
388 388
 function spip_pg_alter_modify($table, $arg, $serveur = '', $requeter = true) {
389
-	if (!preg_match('/^`?(\w+)`?\s+(.*)$/', $arg, $r)) {
390
-		spip_log("alter modify: $arg  incompris", 'pg.' . _LOG_ERREUR);
391
-	} else {
392
-		return spip_pg_alter_change($table, $r[1] . ' ' . $arg, $serveur = '', $requeter = true);
393
-	}
389
+    if (!preg_match('/^`?(\w+)`?\s+(.*)$/', $arg, $r)) {
390
+        spip_log("alter modify: $arg  incompris", 'pg.' . _LOG_ERREUR);
391
+    } else {
392
+        return spip_pg_alter_change($table, $r[1] . ' ' . $arg, $serveur = '', $requeter = true);
393
+    }
394 394
 }
395 395
 
396 396
 // attention (en pg) :
@@ -398,17 +398,17 @@  discard block
 block discarded – undo
398 398
 // - alter table A rename X to Y = changer le nom de la colonne X en Y
399 399
 // pour l'instant, traiter simplement RENAME TO X
400 400
 function spip_pg_alter_rename($table, $arg, $serveur = '', $requeter = true) {
401
-	$rename = '';
402
-	// si TO, mais pas au debut
403
-	if (!stripos($arg, 'TO ')) {
404
-		$rename = $arg;
405
-	} elseif (preg_match('/^(TO)\s*`?(\w*)`?/', $arg, $r)) {
406
-		$rename = $r[2];
407
-	} else {
408
-		spip_log("alter rename: $arg  incompris", 'pg.' . _LOG_ERREUR);
409
-	}
410
-
411
-	return $rename ? spip_pg_query("ALTER TABLE $table RENAME TO $rename") : false;
401
+    $rename = '';
402
+    // si TO, mais pas au debut
403
+    if (!stripos($arg, 'TO ')) {
404
+        $rename = $arg;
405
+    } elseif (preg_match('/^(TO)\s*`?(\w*)`?/', $arg, $r)) {
406
+        $rename = $r[2];
407
+    } else {
408
+        spip_log("alter rename: $arg  incompris", 'pg.' . _LOG_ERREUR);
409
+    }
410
+
411
+    return $rename ? spip_pg_query("ALTER TABLE $table RENAME TO $rename") : false;
412 412
 }
413 413
 
414 414
 
@@ -424,60 +424,60 @@  discard block
 block discarded – undo
424 424
  * @return bool ou requete
425 425
  */
426 426
 function spip_pg_create_index($nom, $table, $champs, $serveur = '', $requeter = true) {
427
-	if (!($nom or $table or $champs)) {
428
-		spip_log(
429
-			"Champ manquant pour creer un index pg ($nom, $table, (" . @join(',', $champs) . '))',
430
-			'pg.' . _LOG_ERREUR
431
-		);
432
-
433
-		return false;
434
-	}
435
-
436
-	$nom = str_replace('`', '', $nom);
437
-	$champs = str_replace('`', '', $champs);
438
-
439
-	// PG ne differentie pas noms des index en fonction des tables
440
-	// il faut donc creer des noms uniques d'index pour une base pg
441
-	$nom = $table . '_' . $nom;
442
-	// enlever d'eventuelles parentheses deja presentes sur champs
443
-	if (!is_array($champs)) {
444
-		if ($champs[0] == '(') {
445
-			$champs = substr($champs, 1, -1);
446
-		}
447
-		$champs = [$champs];
448
-	}
449
-	$query = "CREATE INDEX $nom ON $table (" . join(',', $champs) . ')';
450
-	if (!$requeter) {
451
-		return $query;
452
-	}
453
-	$res = spip_pg_query($query, $serveur, $requeter);
454
-
455
-	return $res;
427
+    if (!($nom or $table or $champs)) {
428
+        spip_log(
429
+            "Champ manquant pour creer un index pg ($nom, $table, (" . @join(',', $champs) . '))',
430
+            'pg.' . _LOG_ERREUR
431
+        );
432
+
433
+        return false;
434
+    }
435
+
436
+    $nom = str_replace('`', '', $nom);
437
+    $champs = str_replace('`', '', $champs);
438
+
439
+    // PG ne differentie pas noms des index en fonction des tables
440
+    // il faut donc creer des noms uniques d'index pour une base pg
441
+    $nom = $table . '_' . $nom;
442
+    // enlever d'eventuelles parentheses deja presentes sur champs
443
+    if (!is_array($champs)) {
444
+        if ($champs[0] == '(') {
445
+            $champs = substr($champs, 1, -1);
446
+        }
447
+        $champs = [$champs];
448
+    }
449
+    $query = "CREATE INDEX $nom ON $table (" . join(',', $champs) . ')';
450
+    if (!$requeter) {
451
+        return $query;
452
+    }
453
+    $res = spip_pg_query($query, $serveur, $requeter);
454
+
455
+    return $res;
456 456
 }
457 457
 
458 458
 
459 459
 // https://code.spip.net/@spip_pg_explain
460 460
 function spip_pg_explain($query, $serveur = '', $requeter = true) {
461
-	if (strpos(ltrim($query), 'SELECT') !== 0) {
462
-		return [];
463
-	}
464
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
465
-	$prefixe = $connexion['prefixe'];
466
-	$link = $connexion['link'];
467
-	if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) {
468
-		$suite = strstr($query, $regs[0]);
469
-		$query = substr($query, 0, -strlen($suite));
470
-	} else {
471
-		$suite = '';
472
-	}
473
-	$query = 'EXPLAIN ' . preg_replace('/([,\s])spip_/', '\1' . $prefixe . '_', $query) . $suite;
474
-
475
-	if (!$requeter) {
476
-		return $query;
477
-	}
478
-	$r = spip_pg_query_simple($link, $query);
479
-
480
-	return spip_pg_fetch($r, null, $serveur);
461
+    if (strpos(ltrim($query), 'SELECT') !== 0) {
462
+        return [];
463
+    }
464
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
465
+    $prefixe = $connexion['prefixe'];
466
+    $link = $connexion['link'];
467
+    if (preg_match('/\s(SET|VALUES|WHERE)\s/i', $query, $regs)) {
468
+        $suite = strstr($query, $regs[0]);
469
+        $query = substr($query, 0, -strlen($suite));
470
+    } else {
471
+        $suite = '';
472
+    }
473
+    $query = 'EXPLAIN ' . preg_replace('/([,\s])spip_/', '\1' . $prefixe . '_', $query) . $suite;
474
+
475
+    if (!$requeter) {
476
+        return $query;
477
+    }
478
+    $r = spip_pg_query_simple($link, $query);
479
+
480
+    return spip_pg_fetch($r, null, $serveur);
481 481
 }
482 482
 
483 483
 
@@ -496,94 +496,94 @@  discard block
 block discarded – undo
496 496
  *     - False en cas d'erreur.
497 497
  **/
498 498
 function spip_pg_selectdb($db, $serveur = '', $requeter = true) {
499
-	// se connecter a la base indiquee
500
-	// avec les identifiants connus
501
-	$index = $serveur ? strtolower($serveur) : 0;
502
-
503
-	if ($link = spip_connect_db('', '', '', '', $db, 'pg', '', '')) {
504
-		if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
505
-			return $db;
506
-		}
507
-	} else {
508
-		return false;
509
-	}
499
+    // se connecter a la base indiquee
500
+    // avec les identifiants connus
501
+    $index = $serveur ? strtolower($serveur) : 0;
502
+
503
+    if ($link = spip_connect_db('', '', '', '', $db, 'pg', '', '')) {
504
+        if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
505
+            return $db;
506
+        }
507
+    } else {
508
+        return false;
509
+    }
510 510
 }
511 511
 
512 512
 // Qu'une seule base pour le moment
513 513
 
514 514
 // https://code.spip.net/@spip_pg_listdbs
515 515
 function spip_pg_listdbs($serveur) {
516
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
517
-	$link = $connexion['link'];
518
-	$dbs = [];
519
-	$res = spip_pg_query_simple($link, 'select * From pg_database');
520
-	while ($row = pg_fetch_array($res, null, PGSQL_NUM)) {
521
-		$dbs[] = reset($row);
522
-	}
523
-
524
-	return $dbs;
516
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
517
+    $link = $connexion['link'];
518
+    $dbs = [];
519
+    $res = spip_pg_query_simple($link, 'select * From pg_database');
520
+    while ($row = pg_fetch_array($res, null, PGSQL_NUM)) {
521
+        $dbs[] = reset($row);
522
+    }
523
+
524
+    return $dbs;
525 525
 }
526 526
 
527 527
 // https://code.spip.net/@spip_pg_select
528 528
 function spip_pg_select(
529
-	$select,
530
-	$from,
531
-	$where = '',
532
-	$groupby = [],
533
-	$orderby = '',
534
-	$limit = '',
535
-	$having = '',
536
-	$serveur = '',
537
-	$requeter = true
529
+    $select,
530
+    $from,
531
+    $where = '',
532
+    $groupby = [],
533
+    $orderby = '',
534
+    $limit = '',
535
+    $having = '',
536
+    $serveur = '',
537
+    $requeter = true
538 538
 ) {
539 539
 
540
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
541
-	$prefixe = $connexion['prefixe'];
542
-	$link = $connexion['link'];
543
-	$db = $connexion['db'];
544
-
545
-	$limit = preg_match('/^\s*(([0-9]+),)?\s*([0-9]+)\s*$/', $limit, $limatch);
546
-	if ($limit) {
547
-		$offset = $limatch[2];
548
-		$count = $limatch[3];
549
-	}
550
-
551
-	$select = spip_pg_frommysql($select);
552
-
553
-	// si pas de tri explicitement demande, le GROUP BY ne
554
-	// contient que la clef primaire.
555
-	// lui ajouter alors le champ de tri par defaut
556
-	if (preg_match('/FIELD\(([a-z]+\.[a-z]+),/i', $orderby[0], $groupbyplus)) {
557
-		$groupby[] = $groupbyplus[1];
558
-	}
559
-
560
-	$orderby = spip_pg_orderby($orderby, $select);
561
-
562
-	if ($having) {
563
-		if (is_array($having)) {
564
-			$having = join("\n\tAND ", array_map('calculer_pg_where', $having));
565
-		}
566
-	}
567
-	$from = spip_pg_from($from, $prefixe);
568
-	$query = 'SELECT ' . $select
569
-		. (!$from ? '' : "\nFROM $from")
570
-		. (!$where ? '' : ("\nWHERE " . (!is_array($where) ? calculer_pg_where($where) : (join(
571
-			"\n\tAND ",
572
-			array_map('calculer_pg_where', $where)
573
-		)))))
574
-		. spip_pg_groupby($groupby, $from, $select)
575
-		. (!$having ? '' : "\nHAVING $having")
576
-		. ($orderby ? ("\nORDER BY $orderby") : '')
577
-		. (!$limit ? '' : (" LIMIT $count" . (!$offset ? '' : " OFFSET $offset")));
578
-
579
-	// renvoyer la requete inerte si demandee
580
-	if ($requeter === false) {
581
-		return $query;
582
-	}
583
-
584
-	$r = spip_pg_trace_query($query, $serveur);
585
-
586
-	return $r ? $r : $query;
540
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
541
+    $prefixe = $connexion['prefixe'];
542
+    $link = $connexion['link'];
543
+    $db = $connexion['db'];
544
+
545
+    $limit = preg_match('/^\s*(([0-9]+),)?\s*([0-9]+)\s*$/', $limit, $limatch);
546
+    if ($limit) {
547
+        $offset = $limatch[2];
548
+        $count = $limatch[3];
549
+    }
550
+
551
+    $select = spip_pg_frommysql($select);
552
+
553
+    // si pas de tri explicitement demande, le GROUP BY ne
554
+    // contient que la clef primaire.
555
+    // lui ajouter alors le champ de tri par defaut
556
+    if (preg_match('/FIELD\(([a-z]+\.[a-z]+),/i', $orderby[0], $groupbyplus)) {
557
+        $groupby[] = $groupbyplus[1];
558
+    }
559
+
560
+    $orderby = spip_pg_orderby($orderby, $select);
561
+
562
+    if ($having) {
563
+        if (is_array($having)) {
564
+            $having = join("\n\tAND ", array_map('calculer_pg_where', $having));
565
+        }
566
+    }
567
+    $from = spip_pg_from($from, $prefixe);
568
+    $query = 'SELECT ' . $select
569
+        . (!$from ? '' : "\nFROM $from")
570
+        . (!$where ? '' : ("\nWHERE " . (!is_array($where) ? calculer_pg_where($where) : (join(
571
+            "\n\tAND ",
572
+            array_map('calculer_pg_where', $where)
573
+        )))))
574
+        . spip_pg_groupby($groupby, $from, $select)
575
+        . (!$having ? '' : "\nHAVING $having")
576
+        . ($orderby ? ("\nORDER BY $orderby") : '')
577
+        . (!$limit ? '' : (" LIMIT $count" . (!$offset ? '' : " OFFSET $offset")));
578
+
579
+    // renvoyer la requete inerte si demandee
580
+    if ($requeter === false) {
581
+        return $query;
582
+    }
583
+
584
+    $r = spip_pg_trace_query($query, $serveur);
585
+
586
+    return $r ? $r : $query;
587 587
 ;
588 588
 }
589 589
 
@@ -592,27 +592,27 @@  discard block
 block discarded – undo
592 592
 
593 593
 // https://code.spip.net/@spip_pg_from
594 594
 function spip_pg_from($from, $prefixe) {
595
-	if (is_array($from)) {
596
-		$from = spip_pg_select_as($from);
597
-	}
595
+    if (is_array($from)) {
596
+        $from = spip_pg_select_as($from);
597
+    }
598 598
 
599
-	return !$prefixe ? $from : preg_replace('/(\b)spip_/', '\1' . $prefixe . '_', $from);
599
+    return !$prefixe ? $from : preg_replace('/(\b)spip_/', '\1' . $prefixe . '_', $from);
600 600
 }
601 601
 
602 602
 // https://code.spip.net/@spip_pg_orderby
603 603
 function spip_pg_orderby($order, $select) {
604
-	$res = [];
605
-	$arg = (is_array($order) ? $order : preg_split('/\s*,\s*/', $order));
606
-
607
-	foreach ($arg as $v) {
608
-		if (preg_match('/(case\s+.*?else\s+0\s+end)\s*AS\s+' . $v . '/', $select, $m)) {
609
-			$res[] = $m[1];
610
-		} else {
611
-			$res[] = $v;
612
-		}
613
-	}
614
-
615
-	return spip_pg_frommysql(join(',', $res));
604
+    $res = [];
605
+    $arg = (is_array($order) ? $order : preg_split('/\s*,\s*/', $order));
606
+
607
+    foreach ($arg as $v) {
608
+        if (preg_match('/(case\s+.*?else\s+0\s+end)\s*AS\s+' . $v . '/', $select, $m)) {
609
+            $res[] = $m[1];
610
+        } else {
611
+            $res[] = $v;
612
+        }
613
+    }
614
+
615
+    return spip_pg_frommysql(join(',', $res));
616 616
 }
617 617
 
618 618
 // Conversion a l'arrach' des jointures MySQL en jointures PG
@@ -621,56 +621,56 @@  discard block
 block discarded – undo
621 621
 
622 622
 // https://code.spip.net/@spip_pg_groupby
623 623
 function spip_pg_groupby($groupby, $from, $select) {
624
-	$join = strpos($from, ',');
625
-	// ismplifier avant de decouper
626
-	if (is_string($select)) { // fct SQL sur colonne et constante apostrophee ==> la colonne
627
-	$select = preg_replace('/\w+\(\s*([^(),\']*),\s*\'[^\']*\'[^)]*\)/', '\\1', $select);
628
-	}
629
-
630
-	if ($join or $groupby) {
631
-		$join = is_array($select) ? $select : explode(', ', $select);
632
-	}
633
-	if ($join) {
634
-		// enlever les 0 as points, '', ...
635
-		foreach ($join as $k => $v) {
636
-			$v = str_replace('DISTINCT ', '', $v);
637
-			// fct SQL sur colonne et constante apostrophee ==> la colonne
638
-			$v = preg_replace('/\w+\(\s*([^(),\']*),\s*\'[^\']*\'[^)]*\)/', '\\1', $v);
639
-			$v = preg_replace('/CAST\(\s*([^(),\' ]*\s+)as\s*\w+\)/', '\\1', $v);
640
-			// resultat d'agregat ne sont pas a mettre dans le groupby
641
-			$v = preg_replace('/(SUM|COUNT|MAX|MIN|UPPER)\([^)]+\)(\s*AS\s+\w+)\s*,?/i', '', $v);
642
-			// idem sans AS (fetch numerique)
643
-			$v = preg_replace('/(SUM|COUNT|MAX|MIN|UPPER)\([^)]+\)\s*,?/i', '', $v);
644
-			// des AS simples : on garde le cote droit du AS
645
-			$v = preg_replace('/^.*\sAS\s+(\w+)\s*$/i', '\\1', $v);
646
-			// ne reste plus que les vrais colonnes, ou des constantes a virer
647
-			if (preg_match(',^[\'"],', $v) or is_numeric($v)) {
648
-				unset($join[$k]);
649
-			} else {
650
-				$join[$k] = trim($v);
651
-			}
652
-		}
653
-		$join = array_diff($join, ['']);
654
-		$join = implode(',', $join);
655
-	}
656
-	if (is_array($groupby)) {
657
-		$groupby = join(',', $groupby);
658
-	}
659
-	if ($join) {
660
-		$groupby = $groupby ? "$groupby, $join" : $join;
661
-	}
662
-	if (!$groupby) {
663
-		return '';
664
-	}
665
-
666
-	$groupby = spip_pg_frommysql($groupby);
667
-	// Ne pas mettre dans le Group-By des valeurs numeriques
668
-	// issue de prepare_recherche
669
-	$groupby = preg_replace('/^\s*\d+\s+AS\s+\w+\s*,?\s*/i', '', $groupby);
670
-	$groupby = preg_replace('/,\s*\d+\s+AS\s+\w+\s*/i', '', $groupby);
671
-	$groupby = preg_replace('/\s+AS\s+\w+\s*/i', '', $groupby);
672
-
673
-	return "\nGROUP BY $groupby";
624
+    $join = strpos($from, ',');
625
+    // ismplifier avant de decouper
626
+    if (is_string($select)) { // fct SQL sur colonne et constante apostrophee ==> la colonne
627
+    $select = preg_replace('/\w+\(\s*([^(),\']*),\s*\'[^\']*\'[^)]*\)/', '\\1', $select);
628
+    }
629
+
630
+    if ($join or $groupby) {
631
+        $join = is_array($select) ? $select : explode(', ', $select);
632
+    }
633
+    if ($join) {
634
+        // enlever les 0 as points, '', ...
635
+        foreach ($join as $k => $v) {
636
+            $v = str_replace('DISTINCT ', '', $v);
637
+            // fct SQL sur colonne et constante apostrophee ==> la colonne
638
+            $v = preg_replace('/\w+\(\s*([^(),\']*),\s*\'[^\']*\'[^)]*\)/', '\\1', $v);
639
+            $v = preg_replace('/CAST\(\s*([^(),\' ]*\s+)as\s*\w+\)/', '\\1', $v);
640
+            // resultat d'agregat ne sont pas a mettre dans le groupby
641
+            $v = preg_replace('/(SUM|COUNT|MAX|MIN|UPPER)\([^)]+\)(\s*AS\s+\w+)\s*,?/i', '', $v);
642
+            // idem sans AS (fetch numerique)
643
+            $v = preg_replace('/(SUM|COUNT|MAX|MIN|UPPER)\([^)]+\)\s*,?/i', '', $v);
644
+            // des AS simples : on garde le cote droit du AS
645
+            $v = preg_replace('/^.*\sAS\s+(\w+)\s*$/i', '\\1', $v);
646
+            // ne reste plus que les vrais colonnes, ou des constantes a virer
647
+            if (preg_match(',^[\'"],', $v) or is_numeric($v)) {
648
+                unset($join[$k]);
649
+            } else {
650
+                $join[$k] = trim($v);
651
+            }
652
+        }
653
+        $join = array_diff($join, ['']);
654
+        $join = implode(',', $join);
655
+    }
656
+    if (is_array($groupby)) {
657
+        $groupby = join(',', $groupby);
658
+    }
659
+    if ($join) {
660
+        $groupby = $groupby ? "$groupby, $join" : $join;
661
+    }
662
+    if (!$groupby) {
663
+        return '';
664
+    }
665
+
666
+    $groupby = spip_pg_frommysql($groupby);
667
+    // Ne pas mettre dans le Group-By des valeurs numeriques
668
+    // issue de prepare_recherche
669
+    $groupby = preg_replace('/^\s*\d+\s+AS\s+\w+\s*,?\s*/i', '', $groupby);
670
+    $groupby = preg_replace('/,\s*\d+\s+AS\s+\w+\s*/i', '', $groupby);
671
+    $groupby = preg_replace('/\s+AS\s+\w+\s*/i', '', $groupby);
672
+
673
+    return "\nGROUP BY $groupby";
674 674
 }
675 675
 
676 676
 // Conversion des operateurs MySQL en PG
@@ -682,507 +682,507 @@  discard block
 block discarded – undo
682 682
 
683 683
 // https://code.spip.net/@spip_pg_frommysql
684 684
 function spip_pg_frommysql($arg) {
685
-	if (is_array($arg)) {
686
-		$arg = join(', ', $arg);
687
-	}
688
-
689
-	$res = spip_pg_fromfield($arg);
690
-
691
-	$res = preg_replace('/\brand[(][)]/i', 'random()', $res);
692
-
693
-	$res = preg_replace(
694
-		'/\b0\.0[+]([a-zA-Z0-9_.]+)\s*/',
695
-		'CAST(substring(\1, \'^ *[0-9.]+\') as float)',
696
-		$res
697
-	);
698
-	$res = preg_replace(
699
-		'/\b0[+]([a-zA-Z0-9_.]+)\s*/',
700
-		'CAST(substring(\1, \'^ *[0-9]+\') as int)',
701
-		$res
702
-	);
703
-	$res = preg_replace(
704
-		'/\bconv[(]([^,]*)[^)]*[)]/i',
705
-		'CAST(substring(\1, \'^ *[0-9]+\') as int)',
706
-		$res
707
-	);
708
-
709
-	$res = preg_replace(
710
-		'/UNIX_TIMESTAMP\s*[(]\s*[)]/',
711
-		' EXTRACT(epoch FROM NOW())',
712
-		$res
713
-	);
714
-
715
-	// la fonction md5(integer) n'est pas connu en pg
716
-	// il faut donc forcer les types en text (cas de md5(id_article))
717
-	$res = preg_replace(
718
-		'/md5\s*[(]([^)]*)[)]/i',
719
-		'MD5(CAST(\1 AS text))',
720
-		$res
721
-	);
722
-
723
-	$res = preg_replace(
724
-		'/UNIX_TIMESTAMP\s*[(]([^)]*)[)]/',
725
-		' EXTRACT(epoch FROM \1)',
726
-		$res
727
-	);
728
-
729
-	$res = preg_replace(
730
-		'/\bDAYOFMONTH\s*[(]([^()]*([(][^()]*[)][^()]*)*[^)]*)[)]/',
731
-		' EXTRACT(day FROM \1)',
732
-		$res
733
-	);
734
-
735
-	$res = preg_replace(
736
-		'/\bMONTH\s*[(]([^()]*([(][^)]*[)][^()]*)*[^)]*)[)]/',
737
-		' EXTRACT(month FROM \1)',
738
-		$res
739
-	);
740
-
741
-	$res = preg_replace(
742
-		'/\bYEAR\s*[(]([^()]*([(][^)]*[)][^()]*)*[^)]*)[)]/',
743
-		' EXTRACT(year FROM \1)',
744
-		$res
745
-	);
746
-
747
-	$res = preg_replace(
748
-		'/TO_DAYS\s*[(]([^()]*([(][^)]*[)][()]*)*)[)]/',
749
-		' EXTRACT(day FROM \1 - \'0001-01-01\')',
750
-		$res
751
-	);
752
-
753
-	$res = preg_replace('/(EXTRACT[(][^ ]* FROM *)"([^"]*)"/', '\1\'\2\'', $res);
754
-
755
-	$res = preg_replace('/DATE_FORMAT\s*[(]([^,]*),\s*\'%Y%m%d\'[)]/', 'to_char(\1, \'YYYYMMDD\')', $res);
756
-
757
-	$res = preg_replace('/DATE_FORMAT\s*[(]([^,]*),\s*\'%Y%m\'[)]/', 'to_char(\1, \'YYYYMM\')', $res);
758
-
759
-	$res = preg_replace('/DATE_SUB\s*[(]([^,]*),/', '(\1 -', $res);
760
-	$res = preg_replace('/DATE_ADD\s*[(]([^,]*),/', '(\1 +', $res);
761
-	$res = preg_replace('/INTERVAL\s+(\d+\s+\w+)/', 'INTERVAL \'\1\'', $res);
762
-	$res = preg_replace('/([+<>-]=?)\s*(\'\d+-\d+-\d+\s+\d+:\d+(:\d+)\')/', '\1 timestamp \2', $res);
763
-	$res = preg_replace('/(\'\d+-\d+-\d+\s+\d+:\d+:\d+\')\s*([+<>-]=?)/', 'timestamp \1 \2', $res);
764
-
765
-	$res = preg_replace('/([+<>-]=?)\s*(\'\d+-\d+-\d+\')/', '\1 timestamp \2', $res);
766
-	$res = preg_replace('/(\'\d+-\d+-\d+\')\s*([+<>-]=?)/', 'timestamp \1 \2', $res);
767
-
768
-	$res = preg_replace('/(timestamp .\d+)-00-/', '\1-01-', $res);
769
-	$res = preg_replace('/(timestamp .\d+-\d+)-00/', '\1-01', $res);
685
+    if (is_array($arg)) {
686
+        $arg = join(', ', $arg);
687
+    }
688
+
689
+    $res = spip_pg_fromfield($arg);
690
+
691
+    $res = preg_replace('/\brand[(][)]/i', 'random()', $res);
692
+
693
+    $res = preg_replace(
694
+        '/\b0\.0[+]([a-zA-Z0-9_.]+)\s*/',
695
+        'CAST(substring(\1, \'^ *[0-9.]+\') as float)',
696
+        $res
697
+    );
698
+    $res = preg_replace(
699
+        '/\b0[+]([a-zA-Z0-9_.]+)\s*/',
700
+        'CAST(substring(\1, \'^ *[0-9]+\') as int)',
701
+        $res
702
+    );
703
+    $res = preg_replace(
704
+        '/\bconv[(]([^,]*)[^)]*[)]/i',
705
+        'CAST(substring(\1, \'^ *[0-9]+\') as int)',
706
+        $res
707
+    );
708
+
709
+    $res = preg_replace(
710
+        '/UNIX_TIMESTAMP\s*[(]\s*[)]/',
711
+        ' EXTRACT(epoch FROM NOW())',
712
+        $res
713
+    );
714
+
715
+    // la fonction md5(integer) n'est pas connu en pg
716
+    // il faut donc forcer les types en text (cas de md5(id_article))
717
+    $res = preg_replace(
718
+        '/md5\s*[(]([^)]*)[)]/i',
719
+        'MD5(CAST(\1 AS text))',
720
+        $res
721
+    );
722
+
723
+    $res = preg_replace(
724
+        '/UNIX_TIMESTAMP\s*[(]([^)]*)[)]/',
725
+        ' EXTRACT(epoch FROM \1)',
726
+        $res
727
+    );
728
+
729
+    $res = preg_replace(
730
+        '/\bDAYOFMONTH\s*[(]([^()]*([(][^()]*[)][^()]*)*[^)]*)[)]/',
731
+        ' EXTRACT(day FROM \1)',
732
+        $res
733
+    );
734
+
735
+    $res = preg_replace(
736
+        '/\bMONTH\s*[(]([^()]*([(][^)]*[)][^()]*)*[^)]*)[)]/',
737
+        ' EXTRACT(month FROM \1)',
738
+        $res
739
+    );
740
+
741
+    $res = preg_replace(
742
+        '/\bYEAR\s*[(]([^()]*([(][^)]*[)][^()]*)*[^)]*)[)]/',
743
+        ' EXTRACT(year FROM \1)',
744
+        $res
745
+    );
746
+
747
+    $res = preg_replace(
748
+        '/TO_DAYS\s*[(]([^()]*([(][^)]*[)][()]*)*)[)]/',
749
+        ' EXTRACT(day FROM \1 - \'0001-01-01\')',
750
+        $res
751
+    );
752
+
753
+    $res = preg_replace('/(EXTRACT[(][^ ]* FROM *)"([^"]*)"/', '\1\'\2\'', $res);
754
+
755
+    $res = preg_replace('/DATE_FORMAT\s*[(]([^,]*),\s*\'%Y%m%d\'[)]/', 'to_char(\1, \'YYYYMMDD\')', $res);
756
+
757
+    $res = preg_replace('/DATE_FORMAT\s*[(]([^,]*),\s*\'%Y%m\'[)]/', 'to_char(\1, \'YYYYMM\')', $res);
758
+
759
+    $res = preg_replace('/DATE_SUB\s*[(]([^,]*),/', '(\1 -', $res);
760
+    $res = preg_replace('/DATE_ADD\s*[(]([^,]*),/', '(\1 +', $res);
761
+    $res = preg_replace('/INTERVAL\s+(\d+\s+\w+)/', 'INTERVAL \'\1\'', $res);
762
+    $res = preg_replace('/([+<>-]=?)\s*(\'\d+-\d+-\d+\s+\d+:\d+(:\d+)\')/', '\1 timestamp \2', $res);
763
+    $res = preg_replace('/(\'\d+-\d+-\d+\s+\d+:\d+:\d+\')\s*([+<>-]=?)/', 'timestamp \1 \2', $res);
764
+
765
+    $res = preg_replace('/([+<>-]=?)\s*(\'\d+-\d+-\d+\')/', '\1 timestamp \2', $res);
766
+    $res = preg_replace('/(\'\d+-\d+-\d+\')\s*([+<>-]=?)/', 'timestamp \1 \2', $res);
767
+
768
+    $res = preg_replace('/(timestamp .\d+)-00-/', '\1-01-', $res);
769
+    $res = preg_replace('/(timestamp .\d+-\d+)-00/', '\1-01', $res);
770 770
 # correct en theorie mais produit des debordements arithmetiques
771 771
 #	$res = preg_replace("/(EXTRACT[(][^ ]* FROM *)(timestamp *'[^']*' *[+-] *timestamp *'[^']*') *[)]/", '\2', $res);
772
-	$res = preg_replace("/(EXTRACT[(][^ ]* FROM *)('[^']*')/", '\1 timestamp \2', $res);
773
-	$res = preg_replace('/\sLIKE\s+/', ' ILIKE ', $res);
772
+    $res = preg_replace("/(EXTRACT[(][^ ]* FROM *)('[^']*')/", '\1 timestamp \2', $res);
773
+    $res = preg_replace('/\sLIKE\s+/', ' ILIKE ', $res);
774 774
 
775
-	return str_replace('REGEXP', '~', $res);
775
+    return str_replace('REGEXP', '~', $res);
776 776
 }
777 777
 
778 778
 // https://code.spip.net/@spip_pg_fromfield
779 779
 function spip_pg_fromfield($arg) {
780
-	while (preg_match('/^(.*?)FIELD\s*\(([^,]*)((,[^,)]*)*)\)/', $arg, $m)) {
781
-		preg_match_all('/,([^,]*)/', $m[3], $r, PREG_PATTERN_ORDER);
782
-		$res = '';
783
-		$n = 0;
784
-		$index = $m[2];
785
-		foreach ($r[1] as $v) {
786
-			$n++;
787
-			$res .= "\nwhen $index=$v then $n";
788
-		}
789
-		$arg = $m[1] . "case $res else 0 end "
790
-			. substr($arg, strlen($m[0]));
791
-	}
792
-
793
-	return $arg;
780
+    while (preg_match('/^(.*?)FIELD\s*\(([^,]*)((,[^,)]*)*)\)/', $arg, $m)) {
781
+        preg_match_all('/,([^,]*)/', $m[3], $r, PREG_PATTERN_ORDER);
782
+        $res = '';
783
+        $n = 0;
784
+        $index = $m[2];
785
+        foreach ($r[1] as $v) {
786
+            $n++;
787
+            $res .= "\nwhen $index=$v then $n";
788
+        }
789
+        $arg = $m[1] . "case $res else 0 end "
790
+            . substr($arg, strlen($m[0]));
791
+    }
792
+
793
+    return $arg;
794 794
 }
795 795
 
796 796
 // https://code.spip.net/@calculer_pg_where
797 797
 function calculer_pg_where($v) {
798
-	if (!is_array($v)) {
799
-		return spip_pg_frommysql($v);
800
-	}
801
-
802
-	$op = str_replace('REGEXP', '~', array_shift($v));
803
-	if (!($n = count($v))) {
804
-		return $op;
805
-	} else {
806
-		$arg = calculer_pg_where(array_shift($v));
807
-		if ($n == 1) {
808
-			return "$op($arg)";
809
-		} else {
810
-			$arg2 = calculer_pg_where(array_shift($v));
811
-			if ($n == 2) {
812
-				return "($arg $op $arg2)";
813
-			} else {
814
-				return "($arg $op ($arg2) : $v[0])";
815
-			}
816
-		}
817
-	}
798
+    if (!is_array($v)) {
799
+        return spip_pg_frommysql($v);
800
+    }
801
+
802
+    $op = str_replace('REGEXP', '~', array_shift($v));
803
+    if (!($n = count($v))) {
804
+        return $op;
805
+    } else {
806
+        $arg = calculer_pg_where(array_shift($v));
807
+        if ($n == 1) {
808
+            return "$op($arg)";
809
+        } else {
810
+            $arg2 = calculer_pg_where(array_shift($v));
811
+            if ($n == 2) {
812
+                return "($arg $op $arg2)";
813
+            } else {
814
+                return "($arg $op ($arg2) : $v[0])";
815
+            }
816
+        }
817
+    }
818 818
 }
819 819
 
820 820
 
821 821
 // https://code.spip.net/@calculer_pg_expression
822 822
 function calculer_pg_expression($expression, $v, $join = 'AND') {
823
-	if (empty($v)) {
824
-		return '';
825
-	}
823
+    if (empty($v)) {
824
+        return '';
825
+    }
826 826
 
827
-	$exp = "\n$expression ";
827
+    $exp = "\n$expression ";
828 828
 
829
-	if (!is_array($v)) {
830
-		$v = [$v];
831
-	}
829
+    if (!is_array($v)) {
830
+        $v = [$v];
831
+    }
832 832
 
833
-	if (strtoupper($join) === 'AND') {
834
-		return $exp . join("\n\t$join ", array_map('calculer_pg_where', $v));
835
-	} else {
836
-		return $exp . join($join, $v);
837
-	}
833
+    if (strtoupper($join) === 'AND') {
834
+        return $exp . join("\n\t$join ", array_map('calculer_pg_where', $v));
835
+    } else {
836
+        return $exp . join($join, $v);
837
+    }
838 838
 }
839 839
 
840 840
 // https://code.spip.net/@spip_pg_select_as
841 841
 function spip_pg_select_as($args) {
842
-	$argsas = '';
843
-	foreach ($args as $k => $v) {
844
-		if (substr($k, -1) == '@') {
845
-			// c'est une jointure qui se refere au from precedent
846
-			// pas de virgule
847
-			$argsas .= '  ' . $v;
848
-		} else {
849
-			$as = '';
850
-			//  spip_log("$k : $v", _LOG_DEBUG);
851
-			if (!is_numeric($k)) {
852
-				if (preg_match('/\.(.*)$/', $k, $r)) {
853
-					$v = $k;
854
-				} elseif ($v != $k) {
855
-					$p = strpos($v, ' ');
856
-					if ($p) {
857
-						$v = substr($v, 0, $p) . " AS $k" . substr($v, $p);
858
-					} else {
859
-						$as = " AS $k";
860
-					}
861
-				}
862
-			}
863
-			// spip_log("subs $k : $v avec $as", _LOG_DEBUG);
864
-			// if (strpos($v, 'JOIN') === false)  $argsas .= ', ';
865
-			$argsas .= ', ' . $v . $as;
866
-		}
867
-	}
868
-
869
-	return substr($argsas, 2);
842
+    $argsas = '';
843
+    foreach ($args as $k => $v) {
844
+        if (substr($k, -1) == '@') {
845
+            // c'est une jointure qui se refere au from precedent
846
+            // pas de virgule
847
+            $argsas .= '  ' . $v;
848
+        } else {
849
+            $as = '';
850
+            //  spip_log("$k : $v", _LOG_DEBUG);
851
+            if (!is_numeric($k)) {
852
+                if (preg_match('/\.(.*)$/', $k, $r)) {
853
+                    $v = $k;
854
+                } elseif ($v != $k) {
855
+                    $p = strpos($v, ' ');
856
+                    if ($p) {
857
+                        $v = substr($v, 0, $p) . " AS $k" . substr($v, $p);
858
+                    } else {
859
+                        $as = " AS $k";
860
+                    }
861
+                }
862
+            }
863
+            // spip_log("subs $k : $v avec $as", _LOG_DEBUG);
864
+            // if (strpos($v, 'JOIN') === false)  $argsas .= ', ';
865
+            $argsas .= ', ' . $v . $as;
866
+        }
867
+    }
868
+
869
+    return substr($argsas, 2);
870 870
 }
871 871
 
872 872
 // https://code.spip.net/@spip_pg_fetch
873 873
 function spip_pg_fetch($res, $t = '', $serveur = '', $requeter = true) {
874 874
 
875
-	if ($res) {
876
-		$res = pg_fetch_array($res, null, PGSQL_ASSOC);
877
-	}
875
+    if ($res) {
876
+        $res = pg_fetch_array($res, null, PGSQL_ASSOC);
877
+    }
878 878
 
879
-	return $res;
879
+    return $res;
880 880
 }
881 881
 
882 882
 function spip_pg_seek($r, $row_number, $serveur = '', $requeter = true) {
883
-	if ($r) {
884
-		return pg_result_seek($r, $row_number);
885
-	}
883
+    if ($r) {
884
+        return pg_result_seek($r, $row_number);
885
+    }
886 886
 }
887 887
 
888 888
 
889 889
 // https://code.spip.net/@spip_pg_countsel
890 890
 function spip_pg_countsel(
891
-	$from = [],
892
-	$where = [],
893
-	$groupby = [],
894
-	$having = [],
895
-	$serveur = '',
896
-	$requeter = true
891
+    $from = [],
892
+    $where = [],
893
+    $groupby = [],
894
+    $having = [],
895
+    $serveur = '',
896
+    $requeter = true
897 897
 ) {
898
-	$c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
899
-	$r = spip_pg_select("COUNT($c)", $from, $where, '', '', '', $having, $serveur, $requeter);
900
-	if (!$requeter) {
901
-		return $r;
902
-	}
903
-	if (!is_resource($r)) {
904
-		return 0;
905
-	}
906
-	list($c) = pg_fetch_array($r, null, PGSQL_NUM);
907
-
908
-	return $c;
898
+    $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
899
+    $r = spip_pg_select("COUNT($c)", $from, $where, '', '', '', $having, $serveur, $requeter);
900
+    if (!$requeter) {
901
+        return $r;
902
+    }
903
+    if (!is_resource($r)) {
904
+        return 0;
905
+    }
906
+    list($c) = pg_fetch_array($r, null, PGSQL_NUM);
907
+
908
+    return $c;
909 909
 }
910 910
 
911 911
 // https://code.spip.net/@spip_pg_count
912 912
 function spip_pg_count($res, $serveur = '', $requeter = true) {
913
-	return !$res ? 0 : pg_numrows($res);
913
+    return !$res ? 0 : pg_numrows($res);
914 914
 }
915 915
 
916 916
 // https://code.spip.net/@spip_pg_free
917 917
 function spip_pg_free($res, $serveur = '', $requeter = true) {
918
-	// rien a faire en postgres
918
+    // rien a faire en postgres
919 919
 }
920 920
 
921 921
 // https://code.spip.net/@spip_pg_delete
922 922
 function spip_pg_delete($table, $where = '', $serveur = '', $requeter = true) {
923 923
 
924
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
925
-	$table = prefixer_table_spip($table, $connexion['prefixe']);
924
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
925
+    $table = prefixer_table_spip($table, $connexion['prefixe']);
926 926
 
927
-	$query = calculer_pg_expression('DELETE FROM', $table, ',')
928
-		. calculer_pg_expression('WHERE', $where, 'AND');
927
+    $query = calculer_pg_expression('DELETE FROM', $table, ',')
928
+        . calculer_pg_expression('WHERE', $where, 'AND');
929 929
 
930
-	// renvoyer la requete inerte si demandee
931
-	if (!$requeter) {
932
-		return $query;
933
-	}
930
+    // renvoyer la requete inerte si demandee
931
+    if (!$requeter) {
932
+        return $query;
933
+    }
934 934
 
935
-	$res = spip_pg_trace_query($query, $serveur);
936
-	if ($res) {
937
-		return pg_affected_rows($res);
938
-	} else {
939
-		return false;
940
-	}
935
+    $res = spip_pg_trace_query($query, $serveur);
936
+    if ($res) {
937
+        return pg_affected_rows($res);
938
+    } else {
939
+        return false;
940
+    }
941 941
 }
942 942
 
943 943
 // https://code.spip.net/@spip_pg_insert
944 944
 function spip_pg_insert($table, $champs, $valeurs, $desc = [], $serveur = '', $requeter = true) {
945
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
946
-	$prefixe = $connexion['prefixe'];
947
-	$link = $connexion['link'];
948
-
949
-	if (!$desc) {
950
-		$desc = description_table($table, $serveur);
951
-	}
952
-	$seq = spip_pg_sequence($table, true);
953
-	// si pas de cle primaire dans l'insertion, renvoyer curval
954
-	if (!preg_match(",\b$seq\b,", $champs)) {
955
-		$seq = spip_pg_sequence($table);
956
-		$seq = prefixer_table_spip($seq, $prefixe);
957
-		$seq = "currval('$seq')";
958
-	}
959
-
960
-	$table = prefixer_table_spip($table, $prefixe);
961
-	$ret = !$seq ? '' : (" RETURNING $seq");
962
-	$ins = (strlen($champs) < 3)
963
-		? ' DEFAULT VALUES'
964
-		: "$champs VALUES $valeurs";
965
-	$q = "INSERT INTO $table $ins $ret";
966
-	if (!$requeter) {
967
-		return $q;
968
-	}
969
-	$connexion['last'] = $q;
970
-	$r = spip_pg_query_simple($link, $q);
945
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
946
+    $prefixe = $connexion['prefixe'];
947
+    $link = $connexion['link'];
948
+
949
+    if (!$desc) {
950
+        $desc = description_table($table, $serveur);
951
+    }
952
+    $seq = spip_pg_sequence($table, true);
953
+    // si pas de cle primaire dans l'insertion, renvoyer curval
954
+    if (!preg_match(",\b$seq\b,", $champs)) {
955
+        $seq = spip_pg_sequence($table);
956
+        $seq = prefixer_table_spip($seq, $prefixe);
957
+        $seq = "currval('$seq')";
958
+    }
959
+
960
+    $table = prefixer_table_spip($table, $prefixe);
961
+    $ret = !$seq ? '' : (" RETURNING $seq");
962
+    $ins = (strlen($champs) < 3)
963
+        ? ' DEFAULT VALUES'
964
+        : "$champs VALUES $valeurs";
965
+    $q = "INSERT INTO $table $ins $ret";
966
+    if (!$requeter) {
967
+        return $q;
968
+    }
969
+    $connexion['last'] = $q;
970
+    $r = spip_pg_query_simple($link, $q);
971 971
 #	spip_log($q,'pg.'._LOG_DEBUG);
972
-	if ($r) {
973
-		if (!$ret) {
974
-			return 0;
975
-		}
976
-		if ($r2 = pg_fetch_array($r, null, PGSQL_NUM)) {
977
-			return $r2[0];
978
-		}
979
-	}
980
-
981
-	return false;
972
+    if ($r) {
973
+        if (!$ret) {
974
+            return 0;
975
+        }
976
+        if ($r2 = pg_fetch_array($r, null, PGSQL_NUM)) {
977
+            return $r2[0];
978
+        }
979
+    }
980
+
981
+    return false;
982 982
 }
983 983
 
984 984
 // https://code.spip.net/@spip_pg_insertq
985 985
 function spip_pg_insertq($table, $couples = [], $desc = [], $serveur = '', $requeter = true) {
986 986
 
987
-	if (!$desc) {
988
-		$desc = description_table($table, $serveur);
989
-	}
990
-	if (!$desc) {
991
-		die("$table insertion sans description");
992
-	}
993
-	$fields = $desc['field'];
994
-
995
-	foreach ($couples as $champ => $val) {
996
-		$couples[$champ] = spip_pg_cite($val, $fields[$champ]);
997
-	}
998
-
999
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1000
-	$couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1001
-
1002
-	return spip_pg_insert(
1003
-		$table,
1004
-		'(' . join(',', array_keys($couples)) . ')',
1005
-		'(' . join(',', $couples) . ')',
1006
-		$desc,
1007
-		$serveur,
1008
-		$requeter
1009
-	);
987
+    if (!$desc) {
988
+        $desc = description_table($table, $serveur);
989
+    }
990
+    if (!$desc) {
991
+        die("$table insertion sans description");
992
+    }
993
+    $fields = $desc['field'];
994
+
995
+    foreach ($couples as $champ => $val) {
996
+        $couples[$champ] = spip_pg_cite($val, $fields[$champ]);
997
+    }
998
+
999
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1000
+    $couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1001
+
1002
+    return spip_pg_insert(
1003
+        $table,
1004
+        '(' . join(',', array_keys($couples)) . ')',
1005
+        '(' . join(',', $couples) . ')',
1006
+        $desc,
1007
+        $serveur,
1008
+        $requeter
1009
+    );
1010 1010
 }
1011 1011
 
1012 1012
 
1013 1013
 // https://code.spip.net/@spip_pg_insertq_multi
1014 1014
 function spip_pg_insertq_multi($table, $tab_couples = [], $desc = [], $serveur = '', $requeter = true) {
1015 1015
 
1016
-	if (!$desc) {
1017
-		$desc = description_table($table, $serveur);
1018
-	}
1019
-	if (!$desc) {
1020
-		die("$table insertion sans description");
1021
-	}
1022
-	$fields = isset($desc['field']) ? $desc['field'] : [];
1023
-
1024
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1025
-	// une premiere fois pour ajouter maj dans les cles
1026
-	$c = isset($tab_couples[0]) ? $tab_couples[0] : [];
1027
-	$les_cles = spip_pg_ajouter_champs_timestamp($table, $c, $desc, $serveur);
1028
-
1029
-	$cles = '(' . join(',', array_keys($les_cles)) . ')';
1030
-	$valeurs = [];
1031
-	foreach ($tab_couples as $couples) {
1032
-		foreach ($couples as $champ => $val) {
1033
-			$couples[$champ] = spip_pg_cite($val, $fields[$champ]);
1034
-		}
1035
-		// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1036
-		$couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1037
-
1038
-		$valeurs[] = '(' . join(',', $couples) . ')';
1039
-	}
1040
-	$valeurs = implode(', ', $valeurs);
1041
-
1042
-	return spip_pg_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1016
+    if (!$desc) {
1017
+        $desc = description_table($table, $serveur);
1018
+    }
1019
+    if (!$desc) {
1020
+        die("$table insertion sans description");
1021
+    }
1022
+    $fields = isset($desc['field']) ? $desc['field'] : [];
1023
+
1024
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1025
+    // une premiere fois pour ajouter maj dans les cles
1026
+    $c = isset($tab_couples[0]) ? $tab_couples[0] : [];
1027
+    $les_cles = spip_pg_ajouter_champs_timestamp($table, $c, $desc, $serveur);
1028
+
1029
+    $cles = '(' . join(',', array_keys($les_cles)) . ')';
1030
+    $valeurs = [];
1031
+    foreach ($tab_couples as $couples) {
1032
+        foreach ($couples as $champ => $val) {
1033
+            $couples[$champ] = spip_pg_cite($val, $fields[$champ]);
1034
+        }
1035
+        // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1036
+        $couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1037
+
1038
+        $valeurs[] = '(' . join(',', $couples) . ')';
1039
+    }
1040
+    $valeurs = implode(', ', $valeurs);
1041
+
1042
+    return spip_pg_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1043 1043
 }
1044 1044
 
1045 1045
 
1046 1046
 // https://code.spip.net/@spip_pg_update
1047 1047
 function spip_pg_update($table, $couples, $where = '', $desc = '', $serveur = '', $requeter = true) {
1048 1048
 
1049
-	if (!$couples) {
1050
-		return;
1051
-	}
1052
-	$connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1053
-	$table = prefixer_table_spip($table, $connexion['prefixe']);
1049
+    if (!$couples) {
1050
+        return;
1051
+    }
1052
+    $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1053
+    $table = prefixer_table_spip($table, $connexion['prefixe']);
1054 1054
 
1055
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1056
-	$couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1055
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1056
+    $couples = spip_pg_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1057 1057
 
1058
-	$set = [];
1059
-	foreach ($couples as $champ => $val) {
1060
-		$set[] = $champ . '=' . $val;
1061
-	}
1058
+    $set = [];
1059
+    foreach ($couples as $champ => $val) {
1060
+        $set[] = $champ . '=' . $val;
1061
+    }
1062 1062
 
1063
-	$query = calculer_pg_expression('UPDATE', $table, ',')
1064
-		. calculer_pg_expression('SET', $set, ',')
1065
-		. calculer_pg_expression('WHERE', $where, 'AND');
1063
+    $query = calculer_pg_expression('UPDATE', $table, ',')
1064
+        . calculer_pg_expression('SET', $set, ',')
1065
+        . calculer_pg_expression('WHERE', $where, 'AND');
1066 1066
 
1067
-	// renvoyer la requete inerte si demandee
1068
-	if (!$requeter) {
1069
-		return $query;
1070
-	}
1067
+    // renvoyer la requete inerte si demandee
1068
+    if (!$requeter) {
1069
+        return $query;
1070
+    }
1071 1071
 
1072
-	return spip_pg_trace_query($query, $serveur);
1072
+    return spip_pg_trace_query($query, $serveur);
1073 1073
 }
1074 1074
 
1075 1075
 // idem, mais les valeurs sont des constantes a mettre entre apostrophes
1076 1076
 // sauf les expressions de date lorsqu'il s'agit de fonctions SQL (NOW etc)
1077 1077
 // https://code.spip.net/@spip_pg_updateq
1078 1078
 function spip_pg_updateq($table, $couples, $where = '', $desc = [], $serveur = '', $requeter = true) {
1079
-	if (!$couples) {
1080
-		return;
1081
-	}
1082
-	if (!$desc) {
1083
-		$desc = description_table($table, $serveur);
1084
-	}
1085
-	$fields = $desc['field'];
1086
-	foreach ($couples as $k => $val) {
1087
-		$couples[$k] = spip_pg_cite($val, $fields[$k]);
1088
-	}
1089
-
1090
-	return spip_pg_update($table, $couples, $where, $desc, $serveur, $requeter);
1079
+    if (!$couples) {
1080
+        return;
1081
+    }
1082
+    if (!$desc) {
1083
+        $desc = description_table($table, $serveur);
1084
+    }
1085
+    $fields = $desc['field'];
1086
+    foreach ($couples as $k => $val) {
1087
+        $couples[$k] = spip_pg_cite($val, $fields[$k]);
1088
+    }
1089
+
1090
+    return spip_pg_update($table, $couples, $where, $desc, $serveur, $requeter);
1091 1091
 }
1092 1092
 
1093 1093
 
1094 1094
 // https://code.spip.net/@spip_pg_replace
1095 1095
 function spip_pg_replace($table, $values, $desc, $serveur = '', $requeter = true) {
1096
-	if (!$values) {
1097
-		spip_log("replace vide $table", 'pg.' . _LOG_AVERTISSEMENT);
1098
-
1099
-		return 0;
1100
-	}
1101
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1102
-	$prefixe = $connexion['prefixe'];
1103
-	$link = $connexion['link'];
1104
-
1105
-	if (!$desc) {
1106
-		$desc = description_table($table, $serveur);
1107
-	}
1108
-	if (!$desc) {
1109
-		die("$table insertion sans description");
1110
-	}
1111
-	$prim = $desc['key']['PRIMARY KEY'];
1112
-	$ids = preg_split('/,\s*/', $prim);
1113
-	$noprims = $prims = [];
1114
-	foreach ($values as $k => $v) {
1115
-		$values[$k] = $v = spip_pg_cite($v, $desc['field'][$k]);
1116
-
1117
-		if (!in_array($k, $ids)) {
1118
-			$noprims[$k] = "$k=$v";
1119
-		} else {
1120
-			$prims[$k] = "$k=$v";
1121
-		}
1122
-	}
1123
-
1124
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1125
-	$values = spip_pg_ajouter_champs_timestamp($table, $values, $desc, $serveur);
1126
-
1127
-	$where = join(' AND ', $prims);
1128
-	if (!$where) {
1129
-		return spip_pg_insert(
1130
-			$table,
1131
-			'(' . join(',', array_keys($values)) . ')',
1132
-			'(' . join(',', $values) . ')',
1133
-			$desc,
1134
-			$serveur
1135
-		);
1136
-	}
1137
-	$couples = join(',', $noprims);
1138
-
1139
-	$seq = spip_pg_sequence($table);
1140
-	$table = prefixer_table_spip($table, $prefixe);
1141
-	$seq = prefixer_table_spip($seq, $prefixe);
1142
-
1143
-	$connexion['last'] = $q = "UPDATE $table SET $couples WHERE $where";
1144
-	if ($couples) {
1145
-		$couples = spip_pg_query_simple($link, $q);
1096
+    if (!$values) {
1097
+        spip_log("replace vide $table", 'pg.' . _LOG_AVERTISSEMENT);
1098
+
1099
+        return 0;
1100
+    }
1101
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1102
+    $prefixe = $connexion['prefixe'];
1103
+    $link = $connexion['link'];
1104
+
1105
+    if (!$desc) {
1106
+        $desc = description_table($table, $serveur);
1107
+    }
1108
+    if (!$desc) {
1109
+        die("$table insertion sans description");
1110
+    }
1111
+    $prim = $desc['key']['PRIMARY KEY'];
1112
+    $ids = preg_split('/,\s*/', $prim);
1113
+    $noprims = $prims = [];
1114
+    foreach ($values as $k => $v) {
1115
+        $values[$k] = $v = spip_pg_cite($v, $desc['field'][$k]);
1116
+
1117
+        if (!in_array($k, $ids)) {
1118
+            $noprims[$k] = "$k=$v";
1119
+        } else {
1120
+            $prims[$k] = "$k=$v";
1121
+        }
1122
+    }
1123
+
1124
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1125
+    $values = spip_pg_ajouter_champs_timestamp($table, $values, $desc, $serveur);
1126
+
1127
+    $where = join(' AND ', $prims);
1128
+    if (!$where) {
1129
+        return spip_pg_insert(
1130
+            $table,
1131
+            '(' . join(',', array_keys($values)) . ')',
1132
+            '(' . join(',', $values) . ')',
1133
+            $desc,
1134
+            $serveur
1135
+        );
1136
+    }
1137
+    $couples = join(',', $noprims);
1138
+
1139
+    $seq = spip_pg_sequence($table);
1140
+    $table = prefixer_table_spip($table, $prefixe);
1141
+    $seq = prefixer_table_spip($seq, $prefixe);
1142
+
1143
+    $connexion['last'] = $q = "UPDATE $table SET $couples WHERE $where";
1144
+    if ($couples) {
1145
+        $couples = spip_pg_query_simple($link, $q);
1146 1146
 #	  spip_log($q,'pg.'._LOG_DEBUG);
1147
-		if (!$couples) {
1148
-			return false;
1149
-		}
1150
-		$couples = pg_affected_rows($couples);
1151
-	}
1152
-	if (!$couples) {
1153
-		$ret = !$seq ? '' :
1154
-			(" RETURNING nextval('$seq') < $prim");
1155
-		$connexion['last'] = $q = "INSERT INTO $table (" . join(',', array_keys($values)) . ') VALUES (' . join(
1156
-			',',
1157
-			$values
1158
-		) . ")$ret";
1159
-		$couples = spip_pg_query_simple($link, $q);
1160
-		if (!$couples) {
1161
-			return false;
1162
-		} elseif ($ret) {
1163
-			$r = pg_fetch_array($couples, null, PGSQL_NUM);
1164
-			if ($r[0]) {
1165
-				$connexion['last'] = $q = "SELECT setval('$seq', $prim) from $table";
1166
-				// Le code de SPIP met parfois la sequence a 0 (dans l'import)
1167
-				// MySQL n'en dit rien, on fait pareil pour PG
1168
-				$r = @pg_query($link, $q);
1169
-			}
1170
-		}
1171
-	}
1172
-
1173
-	return $couples;
1147
+        if (!$couples) {
1148
+            return false;
1149
+        }
1150
+        $couples = pg_affected_rows($couples);
1151
+    }
1152
+    if (!$couples) {
1153
+        $ret = !$seq ? '' :
1154
+            (" RETURNING nextval('$seq') < $prim");
1155
+        $connexion['last'] = $q = "INSERT INTO $table (" . join(',', array_keys($values)) . ') VALUES (' . join(
1156
+            ',',
1157
+            $values
1158
+        ) . ")$ret";
1159
+        $couples = spip_pg_query_simple($link, $q);
1160
+        if (!$couples) {
1161
+            return false;
1162
+        } elseif ($ret) {
1163
+            $r = pg_fetch_array($couples, null, PGSQL_NUM);
1164
+            if ($r[0]) {
1165
+                $connexion['last'] = $q = "SELECT setval('$seq', $prim) from $table";
1166
+                // Le code de SPIP met parfois la sequence a 0 (dans l'import)
1167
+                // MySQL n'en dit rien, on fait pareil pour PG
1168
+                $r = @pg_query($link, $q);
1169
+            }
1170
+        }
1171
+    }
1172
+
1173
+    return $couples;
1174 1174
 }
1175 1175
 
1176 1176
 
1177 1177
 // https://code.spip.net/@spip_pg_replace_multi
1178 1178
 function spip_pg_replace_multi($table, $tab_couples, $desc = [], $serveur = '', $requeter = true) {
1179
-	// boucler pour traiter chaque requete independemment
1180
-	foreach ($tab_couples as $couples) {
1181
-		$retour = spip_pg_replace($table, $couples, $desc, $serveur, $requeter);
1182
-	}
1179
+    // boucler pour traiter chaque requete independemment
1180
+    foreach ($tab_couples as $couples) {
1181
+        $retour = spip_pg_replace($table, $couples, $desc, $serveur, $requeter);
1182
+    }
1183 1183
 
1184
-	// renvoie le dernier id
1185
-	return $retour;
1184
+    // renvoie le dernier id
1185
+    return $retour;
1186 1186
 }
1187 1187
 
1188 1188
 
@@ -1192,20 +1192,20 @@  discard block
 block discarded – undo
1192 1192
 // https://code.spip.net/@spip_pg_sequence
1193 1193
 function spip_pg_sequence($table, $raw = false) {
1194 1194
 
1195
-	include_spip('base/serial');
1196
-	if (!isset($GLOBALS['tables_principales'][$table])) {
1197
-		return false;
1198
-	}
1199
-	$desc = $GLOBALS['tables_principales'][$table];
1200
-	$prim = @$desc['key']['PRIMARY KEY'];
1201
-	if (
1202
-		!preg_match('/^\w+$/', $prim)
1203
-		or strpos($desc['field'][$prim], 'int') === false
1204
-	) {
1205
-		return '';
1206
-	} else {
1207
-		return $raw ? $prim : $table . '_' . $prim . '_seq';
1208
-	}
1195
+    include_spip('base/serial');
1196
+    if (!isset($GLOBALS['tables_principales'][$table])) {
1197
+        return false;
1198
+    }
1199
+    $desc = $GLOBALS['tables_principales'][$table];
1200
+    $prim = @$desc['key']['PRIMARY KEY'];
1201
+    if (
1202
+        !preg_match('/^\w+$/', $prim)
1203
+        or strpos($desc['field'][$prim], 'int') === false
1204
+    ) {
1205
+        return '';
1206
+    } else {
1207
+        return $raw ? $prim : $table . '_' . $prim . '_seq';
1208
+    }
1209 1209
 }
1210 1210
 
1211 1211
 // Explicite les conversions de Mysql d'une valeur $v de type $t
@@ -1213,65 +1213,65 @@  discard block
 block discarded – undo
1213 1213
 
1214 1214
 // https://code.spip.net/@spip_pg_cite
1215 1215
 function spip_pg_cite($v, $t) {
1216
-	if (is_null($v)) {
1217
-		return 'NULL';
1218
-	} // null php se traduit en NULL SQL
1219
-
1220
-	if (sql_test_date($t)) {
1221
-		if ($v and (strpos('0123456789', $v[0]) === false)) {
1222
-			return spip_pg_frommysql($v);
1223
-		} else {
1224
-			if (strncmp($v, '0000', 4) == 0) {
1225
-				$v = '0001' . substr($v, 4);
1226
-			}
1227
-			if (strpos($v, '-00-00') === 4) {
1228
-				$v = substr($v, 0, 4) . '-01-01' . substr($v, 10);
1229
-			}
1230
-
1231
-			return "timestamp '$v'";
1232
-		}
1233
-	} elseif (!sql_test_int($t)) {
1234
-		return ("'" . pg_escape_string($v) . "'");
1235
-	} elseif (is_numeric($v) or (strpos($v, 'CAST(') === 0)) {
1236
-		return $v;
1237
-	} elseif ($v[0] == '0' and $v[1] !== 'x' and ctype_xdigit(substr($v, 1))) {
1238
-		return substr($v, 1);
1239
-	} else {
1240
-		spip_log("Warning: '$v'  n'est pas de type $t", 'pg.' . _LOG_AVERTISSEMENT);
1241
-
1242
-		return intval($v);
1243
-	}
1216
+    if (is_null($v)) {
1217
+        return 'NULL';
1218
+    } // null php se traduit en NULL SQL
1219
+
1220
+    if (sql_test_date($t)) {
1221
+        if ($v and (strpos('0123456789', $v[0]) === false)) {
1222
+            return spip_pg_frommysql($v);
1223
+        } else {
1224
+            if (strncmp($v, '0000', 4) == 0) {
1225
+                $v = '0001' . substr($v, 4);
1226
+            }
1227
+            if (strpos($v, '-00-00') === 4) {
1228
+                $v = substr($v, 0, 4) . '-01-01' . substr($v, 10);
1229
+            }
1230
+
1231
+            return "timestamp '$v'";
1232
+        }
1233
+    } elseif (!sql_test_int($t)) {
1234
+        return ("'" . pg_escape_string($v) . "'");
1235
+    } elseif (is_numeric($v) or (strpos($v, 'CAST(') === 0)) {
1236
+        return $v;
1237
+    } elseif ($v[0] == '0' and $v[1] !== 'x' and ctype_xdigit(substr($v, 1))) {
1238
+        return substr($v, 1);
1239
+    } else {
1240
+        spip_log("Warning: '$v'  n'est pas de type $t", 'pg.' . _LOG_AVERTISSEMENT);
1241
+
1242
+        return intval($v);
1243
+    }
1244 1244
 }
1245 1245
 
1246 1246
 // https://code.spip.net/@spip_pg_hex
1247 1247
 function spip_pg_hex($v) {
1248
-	return "CAST(x'" . $v . "' as bigint)";
1248
+    return "CAST(x'" . $v . "' as bigint)";
1249 1249
 }
1250 1250
 
1251 1251
 function spip_pg_quote($v, $type = '') {
1252
-	if (!is_array($v)) {
1253
-		return spip_pg_cite($v, $type);
1254
-	}
1255
-	// si c'est un tableau, le parcourir en propageant le type
1256
-	foreach ($v as $k => $r) {
1257
-		$v[$k] = spip_pg_quote($r, $type);
1258
-	}
1259
-
1260
-	return join(',', $v);
1252
+    if (!is_array($v)) {
1253
+        return spip_pg_cite($v, $type);
1254
+    }
1255
+    // si c'est un tableau, le parcourir en propageant le type
1256
+    foreach ($v as $k => $r) {
1257
+        $v[$k] = spip_pg_quote($r, $type);
1258
+    }
1259
+
1260
+    return join(',', $v);
1261 1261
 }
1262 1262
 
1263 1263
 function spip_pg_date_proche($champ, $interval, $unite) {
1264
-	return '('
1265
-	. $champ
1266
-	. (($interval <= 0) ? '>' : '<')
1267
-	. (($interval <= 0) ? 'DATE_SUB' : 'DATE_ADD')
1268
-	. '('
1269
-	. sql_quote(date('Y-m-d H:i:s'))
1270
-	. ', INTERVAL '
1271
-	. (($interval > 0) ? $interval : (0 - $interval))
1272
-	. ' '
1273
-	. $unite
1274
-	. '))';
1264
+    return '('
1265
+    . $champ
1266
+    . (($interval <= 0) ? '>' : '<')
1267
+    . (($interval <= 0) ? 'DATE_SUB' : 'DATE_ADD')
1268
+    . '('
1269
+    . sql_quote(date('Y-m-d H:i:s'))
1270
+    . ', INTERVAL '
1271
+    . (($interval > 0) ? $interval : (0 - $interval))
1272
+    . ' '
1273
+    . $unite
1274
+    . '))';
1275 1275
 }
1276 1276
 
1277 1277
 // https://code.spip.net/@spip_pg_in
@@ -1279,69 +1279,69 @@  discard block
 block discarded – undo
1279 1279
 //
1280 1280
 // IN (...) souvent limite a 255  elements, d'ou cette fonction assistante
1281 1281
 //
1282
-	// s'il n'y a pas de valeur, eviter de produire un IN vide: PG rale.
1283
-	if (!$valeurs) {
1284
-		return $not ? '0=0' : '0=1';
1285
-	}
1286
-	if (strpos($valeurs, "CAST(x'") !== false) {
1287
-		return "($val=" . join("OR $val=", explode(',', $valeurs)) . ')';
1288
-	}
1289
-	$n = $i = 0;
1290
-	$in_sql = '';
1291
-	while ($n = strpos($valeurs, ',', $n + 1)) {
1292
-		if ((++$i) >= 255) {
1293
-			$in_sql .= "($val $not IN (" .
1294
-				substr($valeurs, 0, $n) .
1295
-				"))\n" .
1296
-				($not ? "AND\t" : "OR\t");
1297
-			$valeurs = substr($valeurs, $n + 1);
1298
-			$i = $n = 0;
1299
-		}
1300
-	}
1301
-	$in_sql .= "($val $not IN ($valeurs))";
1302
-
1303
-	return "($in_sql)";
1282
+    // s'il n'y a pas de valeur, eviter de produire un IN vide: PG rale.
1283
+    if (!$valeurs) {
1284
+        return $not ? '0=0' : '0=1';
1285
+    }
1286
+    if (strpos($valeurs, "CAST(x'") !== false) {
1287
+        return "($val=" . join("OR $val=", explode(',', $valeurs)) . ')';
1288
+    }
1289
+    $n = $i = 0;
1290
+    $in_sql = '';
1291
+    while ($n = strpos($valeurs, ',', $n + 1)) {
1292
+        if ((++$i) >= 255) {
1293
+            $in_sql .= "($val $not IN (" .
1294
+                substr($valeurs, 0, $n) .
1295
+                "))\n" .
1296
+                ($not ? "AND\t" : "OR\t");
1297
+            $valeurs = substr($valeurs, $n + 1);
1298
+            $i = $n = 0;
1299
+        }
1300
+    }
1301
+    $in_sql .= "($val $not IN ($valeurs))";
1302
+
1303
+    return "($in_sql)";
1304 1304
 }
1305 1305
 
1306 1306
 // https://code.spip.net/@spip_pg_error
1307 1307
 function spip_pg_error($query = '', $serveur = '', $requeter = true) {
1308
-	$link = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]['link'];
1309
-	$s = $link ? pg_last_error($link) : pg_last_error();
1310
-	if ($s) {
1311
-		$s = str_replace('ERROR', 'errcode: 1000 ', $s);
1312
-		spip_log("$s - $query", 'pg.' . _LOG_ERREUR);
1313
-	}
1314
-
1315
-	return $s;
1308
+    $link = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]['link'];
1309
+    $s = $link ? pg_last_error($link) : pg_last_error();
1310
+    if ($s) {
1311
+        $s = str_replace('ERROR', 'errcode: 1000 ', $s);
1312
+        spip_log("$s - $query", 'pg.' . _LOG_ERREUR);
1313
+    }
1314
+
1315
+    return $s;
1316 1316
 }
1317 1317
 
1318 1318
 // https://code.spip.net/@spip_pg_errno
1319 1319
 function spip_pg_errno($serveur = '') {
1320
-	// il faudrait avoir la derniere ressource retournee et utiliser
1321
-	// http://fr2.php.net/manual/fr/function.pg-result-error.php
1322
-	return 0;
1320
+    // il faudrait avoir la derniere ressource retournee et utiliser
1321
+    // http://fr2.php.net/manual/fr/function.pg-result-error.php
1322
+    return 0;
1323 1323
 }
1324 1324
 
1325 1325
 // https://code.spip.net/@spip_pg_drop_table
1326 1326
 function spip_pg_drop_table($table, $exist = '', $serveur = '', $requeter = true) {
1327
-	if ($exist) {
1328
-		$exist = ' IF EXISTS';
1329
-	}
1330
-	if (spip_pg_query("DROP TABLE$exist $table", $serveur, $requeter)) {
1331
-		return true;
1332
-	} else {
1333
-		return false;
1334
-	}
1327
+    if ($exist) {
1328
+        $exist = ' IF EXISTS';
1329
+    }
1330
+    if (spip_pg_query("DROP TABLE$exist $table", $serveur, $requeter)) {
1331
+        return true;
1332
+    } else {
1333
+        return false;
1334
+    }
1335 1335
 }
1336 1336
 
1337 1337
 // supprime une vue
1338 1338
 // https://code.spip.net/@spip_pg_drop_view
1339 1339
 function spip_pg_drop_view($view, $exist = '', $serveur = '', $requeter = true) {
1340
-	if ($exist) {
1341
-		$exist = ' IF EXISTS';
1342
-	}
1340
+    if ($exist) {
1341
+        $exist = ' IF EXISTS';
1342
+    }
1343 1343
 
1344
-	return spip_pg_query("DROP VIEW$exist $view", $serveur, $requeter);
1344
+    return spip_pg_query("DROP VIEW$exist $view", $serveur, $requeter);
1345 1345
 }
1346 1346
 
1347 1347
 /**
@@ -1358,41 +1358,41 @@  discard block
 block discarded – undo
1358 1358
  *     Ressource à utiliser avec sql_fetch()
1359 1359
  **/
1360 1360
 function spip_pg_showbase($match, $serveur = '', $requeter = true) {
1361
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1362
-	$link = $connexion['link'];
1363
-	$connexion['last'] = $q = 'SELECT tablename FROM pg_tables WHERE tablename ILIKE ' . _q($match);
1361
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1362
+    $link = $connexion['link'];
1363
+    $connexion['last'] = $q = 'SELECT tablename FROM pg_tables WHERE tablename ILIKE ' . _q($match);
1364 1364
 
1365
-	return spip_pg_query_simple($link, $q);
1365
+    return spip_pg_query_simple($link, $q);
1366 1366
 }
1367 1367
 
1368 1368
 // https://code.spip.net/@spip_pg_showtable
1369 1369
 function spip_pg_showtable($nom_table, $serveur = '', $requeter = true) {
1370
-	$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1371
-	$link = $connexion['link'];
1372
-	$connexion['last'] = $q = 'SELECT column_name, column_default, data_type FROM information_schema.columns WHERE table_name ILIKE ' . _q($nom_table);
1373
-
1374
-	$res = spip_pg_query_simple($link, $q);
1375
-	if (!$res) {
1376
-		return false;
1377
-	}
1378
-
1379
-	// etrangement, $res peut ne rien contenir, mais arriver ici...
1380
-	// il faut en tenir compte dans le return
1381
-	$fields = [];
1382
-	while ($field = pg_fetch_array($res, null, PGSQL_NUM)) {
1383
-		$fields[$field[0]] = $field[2] . (!$field[1] ? '' : (' DEFAULT ' . $field[1]));
1384
-	}
1385
-	$connexion['last'] = $q = 'SELECT indexdef FROM pg_indexes WHERE tablename ILIKE ' . _q($nom_table);
1386
-	$res = spip_pg_query_simple($link, $q);
1387
-	$keys = [];
1388
-	while ($index = pg_fetch_array($res, null, PGSQL_NUM)) {
1389
-		if (preg_match('/CREATE\s+(UNIQUE\s+)?INDEX\s([^\s]+).*\((.*)\)$/', $index[0], $r)) {
1390
-			$nom = str_replace($nom_table . '_', '', $r[2]);
1391
-			$keys[($r[1] ? 'PRIMARY KEY' : ('KEY ' . $nom))] = $r[3];
1392
-		}
1393
-	}
1394
-
1395
-	return count($fields) ? ['field' => $fields, 'key' => $keys] : false;
1370
+    $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1371
+    $link = $connexion['link'];
1372
+    $connexion['last'] = $q = 'SELECT column_name, column_default, data_type FROM information_schema.columns WHERE table_name ILIKE ' . _q($nom_table);
1373
+
1374
+    $res = spip_pg_query_simple($link, $q);
1375
+    if (!$res) {
1376
+        return false;
1377
+    }
1378
+
1379
+    // etrangement, $res peut ne rien contenir, mais arriver ici...
1380
+    // il faut en tenir compte dans le return
1381
+    $fields = [];
1382
+    while ($field = pg_fetch_array($res, null, PGSQL_NUM)) {
1383
+        $fields[$field[0]] = $field[2] . (!$field[1] ? '' : (' DEFAULT ' . $field[1]));
1384
+    }
1385
+    $connexion['last'] = $q = 'SELECT indexdef FROM pg_indexes WHERE tablename ILIKE ' . _q($nom_table);
1386
+    $res = spip_pg_query_simple($link, $q);
1387
+    $keys = [];
1388
+    while ($index = pg_fetch_array($res, null, PGSQL_NUM)) {
1389
+        if (preg_match('/CREATE\s+(UNIQUE\s+)?INDEX\s([^\s]+).*\((.*)\)$/', $index[0], $r)) {
1390
+            $nom = str_replace($nom_table . '_', '', $r[2]);
1391
+            $keys[($r[1] ? 'PRIMARY KEY' : ('KEY ' . $nom))] = $r[3];
1392
+        }
1393
+    }
1394
+
1395
+    return count($fields) ? ['field' => $fields, 'key' => $keys] : false;
1396 1396
 }
1397 1397
 
1398 1398
 // Fonction de creation d'une table SQL nommee $nom
@@ -1404,118 +1404,118 @@  discard block
 block discarded – undo
1404 1404
 // https://code.spip.net/@spip_pg_create
1405 1405
 function spip_pg_create($nom, $champs, $cles, $autoinc = false, $temporary = false, $serveur = '', $requeter = true) {
1406 1406
 
1407
-	$connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1408
-	$link = $connexion['link'];
1409
-	$nom = prefixer_table_spip($nom, $connexion['prefixe']);
1410
-
1411
-	$query = $prim = $prim_name = $v = $s = $p = '';
1412
-	$keys = [];
1413
-
1414
-	// certains plugins declarent les tables  (permet leur inclusion dans le dump)
1415
-	// sans les renseigner (laisse le compilo recuperer la description)
1416
-	if (!is_array($champs) || !is_array($cles)) {
1417
-		return;
1418
-	}
1419
-
1420
-	foreach ($cles as $k => $v) {
1421
-		if (strpos($k, 'KEY ') === 0) {
1422
-			$n = str_replace('`', '', $k);
1423
-			$v = str_replace('`', '"', $v);
1424
-			$i = $nom . preg_replace('/KEY +/', '_', $n);
1425
-			if ($k != $n) {
1426
-				$i = "\"$i\"";
1427
-			}
1428
-			$keys[] = "CREATE INDEX $i ON $nom ($v);";
1429
-		} elseif (strpos($k, 'UNIQUE ') === 0) {
1430
-			$k = preg_replace('/^UNIQUE +/', '', $k);
1431
-			$prim .= "$s\n\t\tCONSTRAINT " . str_replace('`', '"', $k) . " UNIQUE ($v)";
1432
-		} else {
1433
-			$prim .= "$s\n\t\t" . str_replace('`', '"', $k) . " ($v)";
1434
-		}
1435
-		if ($k == 'PRIMARY KEY') {
1436
-			$prim_name = $v;
1437
-		}
1438
-		$s = ',';
1439
-	}
1440
-	$s = '';
1441
-
1442
-	$character_set = '';
1443
-	if (@$GLOBALS['meta']['charset_sql_base']) {
1444
-		$character_set .= ' CHARACTER SET ' . $GLOBALS['meta']['charset_sql_base'];
1445
-	}
1446
-	if (@$GLOBALS['meta']['charset_collation_sql_base']) {
1447
-		$character_set .= ' COLLATE ' . $GLOBALS['meta']['charset_collation_sql_base'];
1448
-	}
1449
-
1450
-	foreach ($champs as $k => $v) {
1451
-		$k = str_replace('`', '"', $k);
1452
-		if (preg_match(',([a-z]*\s*(\(\s*[0-9]*\s*\))?(\s*binary)?),i', $v, $defs)) {
1453
-			if (preg_match(',(char|text),i', $defs[1]) and !preg_match(',binary,i', $defs[1])) {
1454
-				$v = $defs[1] . $character_set . ' ' . substr($v, strlen($defs[1]));
1455
-			}
1456
-		}
1457
-
1458
-		$query .= "$s\n\t\t$k "
1459
-			. (($autoinc && ($prim_name == $k) && preg_match(',\b(big|small|medium|tiny)?int\b,i', $v))
1460
-				? ' bigserial'
1461
-				: mysql2pg_type($v)
1462
-			);
1463
-		$s = ',';
1464
-	}
1465
-	$temporary = $temporary ? 'TEMPORARY' : '';
1466
-
1467
-	// En l'absence de "if not exists" en PG, on neutralise les erreurs
1468
-
1469
-	$q = "CREATE $temporary TABLE $nom ($query" . ($prim ? ",$prim" : '') . ')' .
1470
-		($character_set ? " DEFAULT $character_set" : '')
1471
-		. "\n";
1472
-
1473
-	if (!$requeter) {
1474
-		return $q;
1475
-	}
1476
-	$connexion['last'] = $q;
1477
-	$r = @pg_query($link, $q);
1478
-
1479
-	if (!$r) {
1480
-		spip_log("Impossible de creer cette table: $q", 'pg.' . _LOG_ERREUR);
1481
-	} else {
1482
-		foreach ($keys as $index) {
1483
-			pg_query($link, $index);
1484
-		}
1485
-	}
1486
-
1487
-	return $r;
1407
+    $connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
1408
+    $link = $connexion['link'];
1409
+    $nom = prefixer_table_spip($nom, $connexion['prefixe']);
1410
+
1411
+    $query = $prim = $prim_name = $v = $s = $p = '';
1412
+    $keys = [];
1413
+
1414
+    // certains plugins declarent les tables  (permet leur inclusion dans le dump)
1415
+    // sans les renseigner (laisse le compilo recuperer la description)
1416
+    if (!is_array($champs) || !is_array($cles)) {
1417
+        return;
1418
+    }
1419
+
1420
+    foreach ($cles as $k => $v) {
1421
+        if (strpos($k, 'KEY ') === 0) {
1422
+            $n = str_replace('`', '', $k);
1423
+            $v = str_replace('`', '"', $v);
1424
+            $i = $nom . preg_replace('/KEY +/', '_', $n);
1425
+            if ($k != $n) {
1426
+                $i = "\"$i\"";
1427
+            }
1428
+            $keys[] = "CREATE INDEX $i ON $nom ($v);";
1429
+        } elseif (strpos($k, 'UNIQUE ') === 0) {
1430
+            $k = preg_replace('/^UNIQUE +/', '', $k);
1431
+            $prim .= "$s\n\t\tCONSTRAINT " . str_replace('`', '"', $k) . " UNIQUE ($v)";
1432
+        } else {
1433
+            $prim .= "$s\n\t\t" . str_replace('`', '"', $k) . " ($v)";
1434
+        }
1435
+        if ($k == 'PRIMARY KEY') {
1436
+            $prim_name = $v;
1437
+        }
1438
+        $s = ',';
1439
+    }
1440
+    $s = '';
1441
+
1442
+    $character_set = '';
1443
+    if (@$GLOBALS['meta']['charset_sql_base']) {
1444
+        $character_set .= ' CHARACTER SET ' . $GLOBALS['meta']['charset_sql_base'];
1445
+    }
1446
+    if (@$GLOBALS['meta']['charset_collation_sql_base']) {
1447
+        $character_set .= ' COLLATE ' . $GLOBALS['meta']['charset_collation_sql_base'];
1448
+    }
1449
+
1450
+    foreach ($champs as $k => $v) {
1451
+        $k = str_replace('`', '"', $k);
1452
+        if (preg_match(',([a-z]*\s*(\(\s*[0-9]*\s*\))?(\s*binary)?),i', $v, $defs)) {
1453
+            if (preg_match(',(char|text),i', $defs[1]) and !preg_match(',binary,i', $defs[1])) {
1454
+                $v = $defs[1] . $character_set . ' ' . substr($v, strlen($defs[1]));
1455
+            }
1456
+        }
1457
+
1458
+        $query .= "$s\n\t\t$k "
1459
+            . (($autoinc && ($prim_name == $k) && preg_match(',\b(big|small|medium|tiny)?int\b,i', $v))
1460
+                ? ' bigserial'
1461
+                : mysql2pg_type($v)
1462
+            );
1463
+        $s = ',';
1464
+    }
1465
+    $temporary = $temporary ? 'TEMPORARY' : '';
1466
+
1467
+    // En l'absence de "if not exists" en PG, on neutralise les erreurs
1468
+
1469
+    $q = "CREATE $temporary TABLE $nom ($query" . ($prim ? ",$prim" : '') . ')' .
1470
+        ($character_set ? " DEFAULT $character_set" : '')
1471
+        . "\n";
1472
+
1473
+    if (!$requeter) {
1474
+        return $q;
1475
+    }
1476
+    $connexion['last'] = $q;
1477
+    $r = @pg_query($link, $q);
1478
+
1479
+    if (!$r) {
1480
+        spip_log("Impossible de creer cette table: $q", 'pg.' . _LOG_ERREUR);
1481
+    } else {
1482
+        foreach ($keys as $index) {
1483
+            pg_query($link, $index);
1484
+        }
1485
+    }
1486
+
1487
+    return $r;
1488 1488
 }
1489 1489
 
1490 1490
 
1491 1491
 function spip_pg_create_base($nom, $serveur = '', $requeter = true) {
1492
-	return spip_pg_query("CREATE DATABASE $nom", $serveur, $requeter);
1492
+    return spip_pg_query("CREATE DATABASE $nom", $serveur, $requeter);
1493 1493
 }
1494 1494
 
1495 1495
 // Fonction de creation d'une vue SQL nommee $nom
1496 1496
 // https://code.spip.net/@spip_pg_create_view
1497 1497
 function spip_pg_create_view($nom, $query_select, $serveur = '', $requeter = true) {
1498
-	if (!$query_select) {
1499
-		return false;
1500
-	}
1501
-	// vue deja presente
1502
-	if (sql_showtable($nom, false, $serveur)) {
1503
-		if ($requeter) {
1504
-			spip_log("Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)", 'pg.' . _LOG_ERREUR);
1505
-		}
1498
+    if (!$query_select) {
1499
+        return false;
1500
+    }
1501
+    // vue deja presente
1502
+    if (sql_showtable($nom, false, $serveur)) {
1503
+        if ($requeter) {
1504
+            spip_log("Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)", 'pg.' . _LOG_ERREUR);
1505
+        }
1506 1506
 
1507
-		return false;
1508
-	}
1507
+        return false;
1508
+    }
1509 1509
 
1510
-	$query = "CREATE VIEW $nom AS " . $query_select;
1510
+    $query = "CREATE VIEW $nom AS " . $query_select;
1511 1511
 
1512
-	return spip_pg_query($query, $serveur, $requeter);
1512
+    return spip_pg_query($query, $serveur, $requeter);
1513 1513
 }
1514 1514
 
1515 1515
 
1516 1516
 // https://code.spip.net/@spip_pg_set_connect_charset
1517 1517
 function spip_pg_set_connect_charset($charset, $serveur = '', $requeter = true) {
1518
-	spip_log('changement de charset sql a ecrire en PG', 'pg.' . _LOG_ERREUR);
1518
+    spip_log('changement de charset sql a ecrire en PG', 'pg.' . _LOG_ERREUR);
1519 1519
 }
1520 1520
 
1521 1521
 
@@ -1529,7 +1529,7 @@  discard block
 block discarded – undo
1529 1529
  **/
1530 1530
 // https://code.spip.net/@spip_sqlite_optimize
1531 1531
 function spip_pg_optimize($table, $serveur = '', $requeter = true) {
1532
-	return spip_pg_query('VACUUM ' . $table, $serveur, $requeter);
1532
+    return spip_pg_query('VACUUM ' . $table, $serveur, $requeter);
1533 1533
 }
1534 1534
 
1535 1535
 // Selectionner la sous-chaine dans $objet
@@ -1537,13 +1537,13 @@  discard block
 block discarded – undo
1537 1537
 
1538 1538
 // https://code.spip.net/@spip_pg_multi
1539 1539
 function spip_pg_multi($objet, $lang) {
1540
-	$r = 'regexp_replace('
1541
-		. $objet
1542
-		. ",'<multi>.*[[]"
1543
-		. $lang
1544
-		. "[]]([^[]*).*</multi>', E'\\\\1') AS multi";
1540
+    $r = 'regexp_replace('
1541
+        . $objet
1542
+        . ",'<multi>.*[[]"
1543
+        . $lang
1544
+        . "[]]([^[]*).*</multi>', E'\\\\1') AS multi";
1545 1545
 
1546
-	return $r;
1546
+    return $r;
1547 1547
 }
1548 1548
 
1549 1549
 // Palanquee d'idiosyncrasies MySQL dans les creations de table
@@ -1551,31 +1551,31 @@  discard block
 block discarded – undo
1551 1551
 
1552 1552
 // https://code.spip.net/@mysql2pg_type
1553 1553
 function mysql2pg_type($v) {
1554
-	$remplace = [
1555
-		'/auto_increment/i' => '', // non reconnu
1556
-		'/bigint/i' => 'bigint',
1557
-		'/mediumint/i' => 'mediumint',
1558
-		'/smallint/i' => 'smallint',
1559
-		'/tinyint/i' => 'int',
1560
-		'/int\s*[(]\s*\d+\s*[)]/i' => 'int',
1561
-		'/longtext/i' => 'text',
1562
-		'/mediumtext/i' => 'text',
1563
-		'/tinytext/i' => 'text',
1564
-		'/longblob/i' => 'text',
1565
-		'/0000-00-00/' => '0001-01-01',
1566
-		'/datetime/i' => 'timestamp',
1567
-		'/unsigned/i' => '',
1568
-		'/double/i' => 'double precision',
1569
-		'/VARCHAR\((\d+)\)\s+BINARY/i' => 'varchar(\1)',
1570
-		'/ENUM *[(][^)]*[)]/i' => 'varchar(255)',
1571
-		'/(timestamp .* )ON .*$/is' => '\\1',
1572
-	];
1573
-
1574
-	return preg_replace(array_keys($remplace), array_values($remplace), $v);
1554
+    $remplace = [
1555
+        '/auto_increment/i' => '', // non reconnu
1556
+        '/bigint/i' => 'bigint',
1557
+        '/mediumint/i' => 'mediumint',
1558
+        '/smallint/i' => 'smallint',
1559
+        '/tinyint/i' => 'int',
1560
+        '/int\s*[(]\s*\d+\s*[)]/i' => 'int',
1561
+        '/longtext/i' => 'text',
1562
+        '/mediumtext/i' => 'text',
1563
+        '/tinytext/i' => 'text',
1564
+        '/longblob/i' => 'text',
1565
+        '/0000-00-00/' => '0001-01-01',
1566
+        '/datetime/i' => 'timestamp',
1567
+        '/unsigned/i' => '',
1568
+        '/double/i' => 'double precision',
1569
+        '/VARCHAR\((\d+)\)\s+BINARY/i' => 'varchar(\1)',
1570
+        '/ENUM *[(][^)]*[)]/i' => 'varchar(255)',
1571
+        '/(timestamp .* )ON .*$/is' => '\\1',
1572
+    ];
1573
+
1574
+    return preg_replace(array_keys($remplace), array_values($remplace), $v);
1575 1575
 }
1576 1576
 
1577 1577
 // Renvoie false si on n'a pas les fonctions pg (pour l'install)
1578 1578
 // https://code.spip.net/@spip_versions_pg
1579 1579
 function spip_versions_pg() {
1580
-	return function_exists('pg_connect');
1580
+    return function_exists('pg_connect');
1581 1581
 }
Please login to merge, or discard this patch.
ecrire/req/sqlite_generique.php 1 patch
Indentation   +1985 added lines, -1985 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  */
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 
24 24
 // TODO: get/set_caracteres ?
@@ -42,91 +42,91 @@  discard block
 block discarded – undo
42 42
  * @return array|bool
43 43
  */
44 44
 function req_sqlite_dist($addr, $port, $login, $pass, $db = '', $prefixe = '', $sqlite_version = '') {
45
-	static $last_connect = [];
46
-
47
-	// si provient de selectdb
48
-	// un code pour etre sur que l'on vient de select_db()
49
-	if (strpos($db, $code = '@selectdb@') !== false) {
50
-		foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
51
-			$$a = $last_connect[$a];
52
-		}
53
-		$db = str_replace($code, '', $db);
54
-	}
55
-
56
-	/*
45
+    static $last_connect = [];
46
+
47
+    // si provient de selectdb
48
+    // un code pour etre sur que l'on vient de select_db()
49
+    if (strpos($db, $code = '@selectdb@') !== false) {
50
+        foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
51
+            $$a = $last_connect[$a];
52
+        }
53
+        $db = str_replace($code, '', $db);
54
+    }
55
+
56
+    /*
57 57
 	 * En sqlite, seule l'adresse du fichier est importante.
58 58
 	 * Ce sera $db le nom,
59 59
 	 * le path est $addr
60 60
 	 * (_DIR_DB si $addr est vide)
61 61
 	 */
62
-	_sqlite_init();
63
-
64
-	// determiner le dossier de la base : $addr ou _DIR_DB
65
-	$f = _DIR_DB;
66
-	if ($addr and strpos($addr, '/') !== false) {
67
-		$f = rtrim($addr, '/') . '/';
68
-	}
69
-
70
-	// un nom de base demande et impossible d'obtenir la base, on s'en va :
71
-	// il faut que la base existe ou que le repertoire parent soit writable
72
-	if ($db and !is_file($f .= $db . '.sqlite') and !is_writable(dirname($f))) {
73
-		spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.' . _LOG_HS);
74
-
75
-		return false;
76
-	}
77
-
78
-	// charger les modules sqlite au besoin
79
-	if (!_sqlite_charger_version($sqlite_version)) {
80
-		spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.' . _LOG_HS);
81
-
82
-		return false;
83
-	}
84
-
85
-	// chargement des constantes
86
-	// il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
87
-	$define = 'spip_sqlite' . $sqlite_version . '_constantes';
88
-	$define();
89
-
90
-	$ok = false;
91
-	if (!$db) {
92
-		// si pas de db ->
93
-		// base temporaire tant qu'on ne connait pas son vrai nom
94
-		// pour tester la connexion
95
-		$db = '_sqlite' . $sqlite_version . '_install';
96
-		$tmp = _DIR_DB . $db . '.sqlite';
97
-		$ok = $link = new \PDO("sqlite:$tmp");
98
-	} else {
99
-		// Ouvrir (eventuellement creer la base)
100
-		$ok = $link = new \PDO("sqlite:$f");
101
-	}
102
-
103
-	if (!$ok) {
104
-		$e = _sqlite_last_error_from_link($link);
105
-		spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f : $e", 'sqlite.' . _LOG_HS);
106
-
107
-		return false;
108
-	}
109
-
110
-	if ($link) {
111
-		$last_connect = [
112
-			'addr' => $addr,
113
-			'port' => $port,
114
-			'login' => $login,
115
-			'pass' => $pass,
116
-			'db' => $db,
117
-			'prefixe' => $prefixe,
118
-		];
119
-		// etre sur qu'on definit bien les fonctions a chaque nouvelle connexion
120
-		include_spip('req/sqlite_fonctions');
121
-		_sqlite_init_functions($link);
122
-	}
123
-
124
-	return [
125
-		'db' => $db,
126
-		'prefixe' => $prefixe ? $prefixe : $db,
127
-		'link' => $link,
128
-		'total_requetes' => 0,
129
-	];
62
+    _sqlite_init();
63
+
64
+    // determiner le dossier de la base : $addr ou _DIR_DB
65
+    $f = _DIR_DB;
66
+    if ($addr and strpos($addr, '/') !== false) {
67
+        $f = rtrim($addr, '/') . '/';
68
+    }
69
+
70
+    // un nom de base demande et impossible d'obtenir la base, on s'en va :
71
+    // il faut que la base existe ou que le repertoire parent soit writable
72
+    if ($db and !is_file($f .= $db . '.sqlite') and !is_writable(dirname($f))) {
73
+        spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.' . _LOG_HS);
74
+
75
+        return false;
76
+    }
77
+
78
+    // charger les modules sqlite au besoin
79
+    if (!_sqlite_charger_version($sqlite_version)) {
80
+        spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.' . _LOG_HS);
81
+
82
+        return false;
83
+    }
84
+
85
+    // chargement des constantes
86
+    // il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
87
+    $define = 'spip_sqlite' . $sqlite_version . '_constantes';
88
+    $define();
89
+
90
+    $ok = false;
91
+    if (!$db) {
92
+        // si pas de db ->
93
+        // base temporaire tant qu'on ne connait pas son vrai nom
94
+        // pour tester la connexion
95
+        $db = '_sqlite' . $sqlite_version . '_install';
96
+        $tmp = _DIR_DB . $db . '.sqlite';
97
+        $ok = $link = new \PDO("sqlite:$tmp");
98
+    } else {
99
+        // Ouvrir (eventuellement creer la base)
100
+        $ok = $link = new \PDO("sqlite:$f");
101
+    }
102
+
103
+    if (!$ok) {
104
+        $e = _sqlite_last_error_from_link($link);
105
+        spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f : $e", 'sqlite.' . _LOG_HS);
106
+
107
+        return false;
108
+    }
109
+
110
+    if ($link) {
111
+        $last_connect = [
112
+            'addr' => $addr,
113
+            'port' => $port,
114
+            'login' => $login,
115
+            'pass' => $pass,
116
+            'db' => $db,
117
+            'prefixe' => $prefixe,
118
+        ];
119
+        // etre sur qu'on definit bien les fonctions a chaque nouvelle connexion
120
+        include_spip('req/sqlite_fonctions');
121
+        _sqlite_init_functions($link);
122
+    }
123
+
124
+    return [
125
+        'db' => $db,
126
+        'prefixe' => $prefixe ? $prefixe : $db,
127
+        'link' => $link,
128
+        'total_requetes' => 0,
129
+    ];
130 130
 }
131 131
 
132 132
 
@@ -145,14 +145,14 @@  discard block
 block discarded – undo
145 145
  *    Resultat de la requete
146 146
  */
147 147
 function spip_sqlite_query($query, $serveur = '', $requeter = true) {
148
-	#spip_log("spip_sqlite_query() > $query",'sqlite.'._LOG_DEBUG);
149
-	#_sqlite_init(); // fait la premiere fois dans spip_sqlite
150
-	$query = spip_sqlite::traduire_requete($query, $serveur);
151
-	if (!$requeter) {
152
-		return $query;
153
-	}
148
+    #spip_log("spip_sqlite_query() > $query",'sqlite.'._LOG_DEBUG);
149
+    #_sqlite_init(); // fait la premiere fois dans spip_sqlite
150
+    $query = spip_sqlite::traduire_requete($query, $serveur);
151
+    if (!$requeter) {
152
+        return $query;
153
+    }
154 154
 
155
-	return spip_sqlite::executer_requete($query, $serveur);
155
+    return spip_sqlite::executer_requete($query, $serveur);
156 156
 }
157 157
 
158 158
 
@@ -169,11 +169,11 @@  discard block
 block discarded – undo
169 169
  */
170 170
 function spip_sqlite_alter($query, $serveur = '', $requeter = true) {
171 171
 
172
-	$query = spip_sqlite_query("ALTER $query", $serveur, false);
173
-	// traduire la requete pour recuperer les bons noms de table
174
-	$query = spip_sqlite::traduire_requete($query, $serveur);
172
+    $query = spip_sqlite_query("ALTER $query", $serveur, false);
173
+    // traduire la requete pour recuperer les bons noms de table
174
+    $query = spip_sqlite::traduire_requete($query, $serveur);
175 175
 
176
-	/*
176
+    /*
177 177
 		 * la il faut faire les transformations
178 178
 		 * si ALTER TABLE x (DROP|CHANGE) y
179 179
 		 *
@@ -182,251 +182,251 @@  discard block
 block discarded – undo
182 182
 		 * 3) faire chaque requete independemment
183 183
 		 */
184 184
 
185
-	// 1
186
-	if (preg_match('/\s*(ALTER(\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
187
-		$debut = $regs[1];
188
-		$table = $regs[3];
189
-		$suite = $regs[4];
190
-	} else {
191
-		spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.' . _LOG_ERREUR);
192
-
193
-		return false;
194
-	}
195
-
196
-	// 2
197
-	// il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
198
-	// tout en cassant "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... en deux
199
-	// ou revoir l'api de sql_alter en creant un
200
-	// sql_alter_table($table,array($actions));
201
-	$todo = explode(',', $suite);
202
-
203
-	// on remet les morceaux dechires ensembles... que c'est laid !
204
-	$todo2 = [];
205
-	$i = 0;
206
-	$ouverte = false;
207
-	while ($do = array_shift($todo)) {
208
-		$todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
209
-		$o = (false !== strpos($do, '('));
210
-		$f = (false !== strpos($do, ')'));
211
-		if ($o and !$f) {
212
-			$ouverte = true;
213
-		} elseif ($f) {
214
-			$ouverte = false;
215
-		}
216
-		if (!$ouverte) {
217
-			$i++;
218
-		}
219
-	}
220
-
221
-	// 3
222
-	$resultats = [];
223
-	foreach ($todo2 as $do) {
224
-		$do = trim($do);
225
-		if (
226
-			!preg_match('/(DROP PRIMARY KEY|DROP KEY|DROP INDEX|DROP COLUMN|DROP'
227
-			. '|CHANGE COLUMN|CHANGE|MODIFY|RENAME TO|RENAME'
228
-			. '|ADD PRIMARY KEY|ADD KEY|ADD INDEX|ADD UNIQUE KEY|ADD UNIQUE'
229
-			. '|ADD COLUMN|ADD'
230
-			. ')\s*([^\s]*)\s*(.*)?/i', $do, $matches)
231
-		) {
232
-			spip_log(
233
-				"SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)",
234
-				'sqlite.' . _LOG_ERREUR
235
-			);
236
-
237
-			return false;
238
-		}
239
-
240
-		$cle = strtoupper($matches[1]);
241
-		$colonne_origine = $matches[2];
242
-		$colonne_destination = '';
243
-
244
-		$def = $matches[3];
245
-
246
-		// eluder une eventuelle clause before|after|first inutilisable
247
-		$defr = rtrim(preg_replace('/(BEFORE|AFTER|FIRST)(.*)$/is', '', $def));
248
-		$defo = $defr; // garder la def d'origine pour certains cas
249
-		// remplacer les definitions venant de mysql
250
-		$defr = _sqlite_remplacements_definitions_table($defr);
251
-
252
-		// reinjecter dans le do
253
-		$do = str_replace($def, $defr, $do);
254
-		$def = $defr;
255
-
256
-		switch ($cle) {
257
-			// suppression d'un index
258
-			case 'DROP KEY':
259
-			case 'DROP INDEX':
260
-				$nom_index = $colonne_origine;
261
-				spip_sqlite_drop_index($nom_index, $table, $serveur);
262
-				break;
263
-
264
-			// suppression d'une pk
265
-			case 'DROP PRIMARY KEY':
266
-				if (
267
-					!_sqlite_modifier_table(
268
-						$table,
269
-						$colonne_origine,
270
-						['key' => ['PRIMARY KEY' => '']],
271
-						$serveur
272
-					)
273
-				) {
274
-					return false;
275
-				}
276
-				break;
277
-			// suppression d'une colonne
278
-			case 'DROP COLUMN':
279
-			case 'DROP':
280
-				if (
281
-					!_sqlite_modifier_table(
282
-						$table,
283
-						[$colonne_origine => ''],
284
-						[],
285
-						$serveur
286
-					)
287
-				) {
288
-					return false;
289
-				}
290
-				break;
291
-
292
-			case 'CHANGE COLUMN':
293
-			case 'CHANGE':
294
-				// recuperer le nom de la future colonne
295
-				// on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
296
-				// en tenant compte de la cle primaire (ce qui est mieux)
297
-				$def = trim($defo);
298
-				$colonne_destination = substr($def, 0, strpos($def, ' '));
299
-				$def = substr($def, strlen($colonne_destination) + 1);
300
-
301
-				if (
302
-					!_sqlite_modifier_table(
303
-						$table,
304
-						[$colonne_origine => $colonne_destination],
305
-						['field' => [$colonne_destination => $def]],
306
-						$serveur
307
-					)
308
-				) {
309
-					return false;
310
-				}
311
-				break;
312
-
313
-			case 'MODIFY':
314
-				// on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
315
-				// en tenant compte de la cle primaire (ce qui est mieux)
316
-				if (
317
-					!_sqlite_modifier_table(
318
-						$table,
319
-						$colonne_origine,
320
-						['field' => [$colonne_origine => $defo]],
321
-						$serveur
322
-					)
323
-				) {
324
-					return false;
325
-				}
326
-				break;
327
-
328
-			// pas geres en sqlite2
329
-			case 'RENAME':
330
-				$do = 'RENAME TO' . substr($do, 6);
331
-			case 'RENAME TO':
332
-				if (!spip_sqlite::executer_requete("$debut $do", $serveur)) {
333
-					spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.' . _LOG_ERREUR);
334
-
335
-					return false;
336
-				}
337
-				break;
338
-
339
-			// ajout d'une pk
340
-			case 'ADD PRIMARY KEY':
341
-				$pk = trim(substr($do, 16));
342
-				$pk = ($pk[0] == '(') ? substr($pk, 1, -1) : $pk;
343
-				if (
344
-					!_sqlite_modifier_table(
345
-						$table,
346
-						$colonne_origine,
347
-						['key' => ['PRIMARY KEY' => $pk]],
348
-						$serveur
349
-					)
350
-				) {
351
-					return false;
352
-				}
353
-				break;
354
-			// ajout d'un index
355
-			case 'ADD UNIQUE KEY':
356
-			case 'ADD UNIQUE':
357
-				$unique = true;
358
-			case 'ADD INDEX':
359
-			case 'ADD KEY':
360
-				if (!isset($unique)) {
361
-					$unique = false;
362
-				}
363
-				// peut etre "(colonne)" ou "nom_index (colonnes)"
364
-				// bug potentiel si qqn met "(colonne, colonne)"
365
-				//
366
-				// nom_index (colonnes)
367
-				if ($def) {
368
-					$colonnes = substr($def, 1, -1);
369
-					$nom_index = $colonne_origine;
370
-				} else {
371
-					// (colonne)
372
-					if ($colonne_origine[0] == '(') {
373
-						$colonnes = substr($colonne_origine, 1, -1);
374
-						if (false !== strpos(',', $colonnes)) {
375
-							spip_log('SQLite : Erreur, impossible de creer un index sur plusieurs colonnes'
376
-								. " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.' . _LOG_ERREUR);
377
-							break;
378
-						} else {
379
-							$nom_index = $colonnes;
380
-						}
381
-					} // nom_index
382
-					else {
383
-						$nom_index = $colonnes = $colonne_origine;
384
-					}
385
-				}
386
-				spip_sqlite_create_index($nom_index, $table, $colonnes, $unique, $serveur);
387
-				break;
388
-
389
-			// pas geres en sqlite2
390
-			case 'ADD COLUMN':
391
-				$do = 'ADD' . substr($do, 10);
392
-			case 'ADD':
393
-			default:
394
-				if (!preg_match(',primary\s+key,i', $do)) {
395
-					if (!spip_sqlite::executer_requete("$debut $do", $serveur)) {
396
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
397
-
398
-						return false;
399
-					}
400
-					break;
401
-				}
402
-				// ou si la colonne est aussi primary key
403
-				// cas du add id_truc int primary key
404
-				// ajout d'une colonne qui passe en primary key directe
405
-				else {
406
-					$def = trim(substr($do, 3));
407
-					$colonne_ajoutee = substr($def, 0, strpos($def, ' '));
408
-					$def = substr($def, strlen($colonne_ajoutee) + 1);
409
-					$opts = [];
410
-					if (preg_match(',primary\s+key,i', $def)) {
411
-						$opts['key'] = ['PRIMARY KEY' => $colonne_ajoutee];
412
-						$def = preg_replace(',primary\s+key,i', '', $def);
413
-					}
414
-					$opts['field'] = [$colonne_ajoutee => $def];
415
-					if (!_sqlite_modifier_table($table, [$colonne_ajoutee], $opts, $serveur)) {
416
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
417
-
418
-						return false;
419
-					}
420
-				}
421
-				break;
422
-		}
423
-		// tout est bon, ouf !
424
-		spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.' . _LOG_INFO);
425
-	}
426
-
427
-	spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.' . _LOG_INFO);
428
-
429
-	return true;
185
+    // 1
186
+    if (preg_match('/\s*(ALTER(\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
187
+        $debut = $regs[1];
188
+        $table = $regs[3];
189
+        $suite = $regs[4];
190
+    } else {
191
+        spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.' . _LOG_ERREUR);
192
+
193
+        return false;
194
+    }
195
+
196
+    // 2
197
+    // il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
198
+    // tout en cassant "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... en deux
199
+    // ou revoir l'api de sql_alter en creant un
200
+    // sql_alter_table($table,array($actions));
201
+    $todo = explode(',', $suite);
202
+
203
+    // on remet les morceaux dechires ensembles... que c'est laid !
204
+    $todo2 = [];
205
+    $i = 0;
206
+    $ouverte = false;
207
+    while ($do = array_shift($todo)) {
208
+        $todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
209
+        $o = (false !== strpos($do, '('));
210
+        $f = (false !== strpos($do, ')'));
211
+        if ($o and !$f) {
212
+            $ouverte = true;
213
+        } elseif ($f) {
214
+            $ouverte = false;
215
+        }
216
+        if (!$ouverte) {
217
+            $i++;
218
+        }
219
+    }
220
+
221
+    // 3
222
+    $resultats = [];
223
+    foreach ($todo2 as $do) {
224
+        $do = trim($do);
225
+        if (
226
+            !preg_match('/(DROP PRIMARY KEY|DROP KEY|DROP INDEX|DROP COLUMN|DROP'
227
+            . '|CHANGE COLUMN|CHANGE|MODIFY|RENAME TO|RENAME'
228
+            . '|ADD PRIMARY KEY|ADD KEY|ADD INDEX|ADD UNIQUE KEY|ADD UNIQUE'
229
+            . '|ADD COLUMN|ADD'
230
+            . ')\s*([^\s]*)\s*(.*)?/i', $do, $matches)
231
+        ) {
232
+            spip_log(
233
+                "SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)",
234
+                'sqlite.' . _LOG_ERREUR
235
+            );
236
+
237
+            return false;
238
+        }
239
+
240
+        $cle = strtoupper($matches[1]);
241
+        $colonne_origine = $matches[2];
242
+        $colonne_destination = '';
243
+
244
+        $def = $matches[3];
245
+
246
+        // eluder une eventuelle clause before|after|first inutilisable
247
+        $defr = rtrim(preg_replace('/(BEFORE|AFTER|FIRST)(.*)$/is', '', $def));
248
+        $defo = $defr; // garder la def d'origine pour certains cas
249
+        // remplacer les definitions venant de mysql
250
+        $defr = _sqlite_remplacements_definitions_table($defr);
251
+
252
+        // reinjecter dans le do
253
+        $do = str_replace($def, $defr, $do);
254
+        $def = $defr;
255
+
256
+        switch ($cle) {
257
+            // suppression d'un index
258
+            case 'DROP KEY':
259
+            case 'DROP INDEX':
260
+                $nom_index = $colonne_origine;
261
+                spip_sqlite_drop_index($nom_index, $table, $serveur);
262
+                break;
263
+
264
+            // suppression d'une pk
265
+            case 'DROP PRIMARY KEY':
266
+                if (
267
+                    !_sqlite_modifier_table(
268
+                        $table,
269
+                        $colonne_origine,
270
+                        ['key' => ['PRIMARY KEY' => '']],
271
+                        $serveur
272
+                    )
273
+                ) {
274
+                    return false;
275
+                }
276
+                break;
277
+            // suppression d'une colonne
278
+            case 'DROP COLUMN':
279
+            case 'DROP':
280
+                if (
281
+                    !_sqlite_modifier_table(
282
+                        $table,
283
+                        [$colonne_origine => ''],
284
+                        [],
285
+                        $serveur
286
+                    )
287
+                ) {
288
+                    return false;
289
+                }
290
+                break;
291
+
292
+            case 'CHANGE COLUMN':
293
+            case 'CHANGE':
294
+                // recuperer le nom de la future colonne
295
+                // on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
296
+                // en tenant compte de la cle primaire (ce qui est mieux)
297
+                $def = trim($defo);
298
+                $colonne_destination = substr($def, 0, strpos($def, ' '));
299
+                $def = substr($def, strlen($colonne_destination) + 1);
300
+
301
+                if (
302
+                    !_sqlite_modifier_table(
303
+                        $table,
304
+                        [$colonne_origine => $colonne_destination],
305
+                        ['field' => [$colonne_destination => $def]],
306
+                        $serveur
307
+                    )
308
+                ) {
309
+                    return false;
310
+                }
311
+                break;
312
+
313
+            case 'MODIFY':
314
+                // on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
315
+                // en tenant compte de la cle primaire (ce qui est mieux)
316
+                if (
317
+                    !_sqlite_modifier_table(
318
+                        $table,
319
+                        $colonne_origine,
320
+                        ['field' => [$colonne_origine => $defo]],
321
+                        $serveur
322
+                    )
323
+                ) {
324
+                    return false;
325
+                }
326
+                break;
327
+
328
+            // pas geres en sqlite2
329
+            case 'RENAME':
330
+                $do = 'RENAME TO' . substr($do, 6);
331
+            case 'RENAME TO':
332
+                if (!spip_sqlite::executer_requete("$debut $do", $serveur)) {
333
+                    spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.' . _LOG_ERREUR);
334
+
335
+                    return false;
336
+                }
337
+                break;
338
+
339
+            // ajout d'une pk
340
+            case 'ADD PRIMARY KEY':
341
+                $pk = trim(substr($do, 16));
342
+                $pk = ($pk[0] == '(') ? substr($pk, 1, -1) : $pk;
343
+                if (
344
+                    !_sqlite_modifier_table(
345
+                        $table,
346
+                        $colonne_origine,
347
+                        ['key' => ['PRIMARY KEY' => $pk]],
348
+                        $serveur
349
+                    )
350
+                ) {
351
+                    return false;
352
+                }
353
+                break;
354
+            // ajout d'un index
355
+            case 'ADD UNIQUE KEY':
356
+            case 'ADD UNIQUE':
357
+                $unique = true;
358
+            case 'ADD INDEX':
359
+            case 'ADD KEY':
360
+                if (!isset($unique)) {
361
+                    $unique = false;
362
+                }
363
+                // peut etre "(colonne)" ou "nom_index (colonnes)"
364
+                // bug potentiel si qqn met "(colonne, colonne)"
365
+                //
366
+                // nom_index (colonnes)
367
+                if ($def) {
368
+                    $colonnes = substr($def, 1, -1);
369
+                    $nom_index = $colonne_origine;
370
+                } else {
371
+                    // (colonne)
372
+                    if ($colonne_origine[0] == '(') {
373
+                        $colonnes = substr($colonne_origine, 1, -1);
374
+                        if (false !== strpos(',', $colonnes)) {
375
+                            spip_log('SQLite : Erreur, impossible de creer un index sur plusieurs colonnes'
376
+                                . " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.' . _LOG_ERREUR);
377
+                            break;
378
+                        } else {
379
+                            $nom_index = $colonnes;
380
+                        }
381
+                    } // nom_index
382
+                    else {
383
+                        $nom_index = $colonnes = $colonne_origine;
384
+                    }
385
+                }
386
+                spip_sqlite_create_index($nom_index, $table, $colonnes, $unique, $serveur);
387
+                break;
388
+
389
+            // pas geres en sqlite2
390
+            case 'ADD COLUMN':
391
+                $do = 'ADD' . substr($do, 10);
392
+            case 'ADD':
393
+            default:
394
+                if (!preg_match(',primary\s+key,i', $do)) {
395
+                    if (!spip_sqlite::executer_requete("$debut $do", $serveur)) {
396
+                        spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
397
+
398
+                        return false;
399
+                    }
400
+                    break;
401
+                }
402
+                // ou si la colonne est aussi primary key
403
+                // cas du add id_truc int primary key
404
+                // ajout d'une colonne qui passe en primary key directe
405
+                else {
406
+                    $def = trim(substr($do, 3));
407
+                    $colonne_ajoutee = substr($def, 0, strpos($def, ' '));
408
+                    $def = substr($def, strlen($colonne_ajoutee) + 1);
409
+                    $opts = [];
410
+                    if (preg_match(',primary\s+key,i', $def)) {
411
+                        $opts['key'] = ['PRIMARY KEY' => $colonne_ajoutee];
412
+                        $def = preg_replace(',primary\s+key,i', '', $def);
413
+                    }
414
+                    $opts['field'] = [$colonne_ajoutee => $def];
415
+                    if (!_sqlite_modifier_table($table, [$colonne_ajoutee], $opts, $serveur)) {
416
+                        spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
417
+
418
+                        return false;
419
+                    }
420
+                }
421
+                break;
422
+        }
423
+        // tout est bon, ouf !
424
+        spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.' . _LOG_INFO);
425
+    }
426
+
427
+    spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.' . _LOG_INFO);
428
+
429
+    return true;
430 430
 }
431 431
 
432 432
 
@@ -449,38 +449,38 @@  discard block
 block discarded – undo
449 449
  *     - true si la requête réussie, false sinon.
450 450
  */
451 451
 function spip_sqlite_create(
452
-	$nom,
453
-	$champs,
454
-	$cles,
455
-	$autoinc = false,
456
-	$temporary = false,
457
-	$serveur = '',
458
-	$requeter = true
452
+    $nom,
453
+    $champs,
454
+    $cles,
455
+    $autoinc = false,
456
+    $temporary = false,
457
+    $serveur = '',
458
+    $requeter = true
459 459
 ) {
460
-	$query = _sqlite_requete_create($nom, $champs, $cles, $autoinc, $temporary, $ifnotexists = true, $serveur, $requeter);
461
-	if (!$query) {
462
-		return false;
463
-	}
464
-	$res = spip_sqlite_query($query, $serveur, $requeter);
465
-
466
-	// SQLite ne cree pas les KEY sur les requetes CREATE TABLE
467
-	// il faut donc les faire creer ensuite
468
-	if (!$requeter) {
469
-		return $res;
470
-	}
471
-
472
-	$ok = $res ? true : false;
473
-	if ($ok) {
474
-		foreach ($cles as $k => $v) {
475
-			if (preg_match(',^(UNIQUE KEY|KEY|UNIQUE)\s,i', $k, $m)) {
476
-				$index = trim(substr($k, strlen($m[1])));
477
-				$unique = (strlen($m[1]) > 3);
478
-				$ok &= spip_sqlite_create_index($index, $nom, $v, $unique, $serveur);
479
-			}
480
-		}
481
-	}
482
-
483
-	return $ok ? true : false;
460
+    $query = _sqlite_requete_create($nom, $champs, $cles, $autoinc, $temporary, $ifnotexists = true, $serveur, $requeter);
461
+    if (!$query) {
462
+        return false;
463
+    }
464
+    $res = spip_sqlite_query($query, $serveur, $requeter);
465
+
466
+    // SQLite ne cree pas les KEY sur les requetes CREATE TABLE
467
+    // il faut donc les faire creer ensuite
468
+    if (!$requeter) {
469
+        return $res;
470
+    }
471
+
472
+    $ok = $res ? true : false;
473
+    if ($ok) {
474
+        foreach ($cles as $k => $v) {
475
+            if (preg_match(',^(UNIQUE KEY|KEY|UNIQUE)\s,i', $k, $m)) {
476
+                $index = trim(substr($k, strlen($m[1])));
477
+                $unique = (strlen($m[1]) > 3);
478
+                $ok &= spip_sqlite_create_index($index, $nom, $v, $unique, $serveur);
479
+            }
480
+        }
481
+    }
482
+
483
+    return $ok ? true : false;
484 484
 }
485 485
 
486 486
 /**
@@ -493,21 +493,21 @@  discard block
 block discarded – undo
493 493
  * @return bool true si la base est créee.
494 494
  **/
495 495
 function spip_sqlite_create_base($nom, $serveur = '', $option = true) {
496
-	$f = $nom . '.sqlite';
497
-	if (strpos($nom, '/') === false) {
498
-		$f = _DIR_DB . $f;
499
-	}
496
+    $f = $nom . '.sqlite';
497
+    if (strpos($nom, '/') === false) {
498
+        $f = _DIR_DB . $f;
499
+    }
500 500
 
501
-	$ok = new \PDO("sqlite:$f");
501
+    $ok = new \PDO("sqlite:$f");
502 502
 
503
-	if ($ok) {
504
-		unset($ok);
503
+    if ($ok) {
504
+        unset($ok);
505 505
 
506
-		return true;
507
-	}
508
-	unset($ok);
506
+        return true;
507
+    }
508
+    unset($ok);
509 509
 
510
-	return false;
510
+    return false;
511 511
 }
512 512
 
513 513
 
@@ -528,22 +528,22 @@  discard block
 block discarded – undo
528 528
  *     - string texte de la requête si $requeter vaut false
529 529
  */
530 530
 function spip_sqlite_create_view($nom, $query_select, $serveur = '', $requeter = true) {
531
-	if (!$query_select) {
532
-		return false;
533
-	}
534
-	// vue deja presente
535
-	if (sql_showtable($nom, false, $serveur)) {
536
-		spip_log(
537
-			"Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)",
538
-			'sqlite.' . _LOG_ERREUR
539
-		);
531
+    if (!$query_select) {
532
+        return false;
533
+    }
534
+    // vue deja presente
535
+    if (sql_showtable($nom, false, $serveur)) {
536
+        spip_log(
537
+            "Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)",
538
+            'sqlite.' . _LOG_ERREUR
539
+        );
540 540
 
541
-		return false;
542
-	}
541
+        return false;
542
+    }
543 543
 
544
-	$query = "CREATE VIEW $nom AS " . $query_select;
544
+    $query = "CREATE VIEW $nom AS " . $query_select;
545 545
 
546
-	return spip_sqlite_query($query, $serveur, $requeter);
546
+    return spip_sqlite_query($query, $serveur, $requeter);
547 547
 }
548 548
 
549 549
 /**
@@ -565,54 +565,54 @@  discard block
 block discarded – undo
565 565
  *    string : requête, false si erreur, true sinon.
566 566
  */
567 567
 function spip_sqlite_create_index($nom, $table, $champs, $unique = '', $serveur = '', $requeter = true) {
568
-	if (!($nom or $table or $champs)) {
569
-		spip_log(
570
-			"Champ manquant pour creer un index sqlite ($nom, $table, (" . join(',', $champs) . '))',
571
-			'sqlite.' . _LOG_ERREUR
572
-		);
573
-
574
-		return false;
575
-	}
576
-
577
-	// SQLite ne differentie pas noms des index en fonction des tables
578
-	// il faut donc creer des noms uniques d'index pour une base sqlite
579
-	$nom = $table . '_' . $nom;
580
-	// enlever d'eventuelles parentheses deja presentes sur champs
581
-	if (!is_array($champs)) {
582
-		if ($champs[0] == '(') {
583
-			$champs = substr($champs, 1, -1);
584
-		}
585
-		$champs = [$champs];
586
-		// supprimer l'info de longueur d'index mysql en fin de champ
587
-		$champs = preg_replace(',\(\d+\)$,', '', $champs);
588
-	}
589
-
590
-	$ifnotexists = '';
591
-	$version = spip_sqlite_fetch(spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur), '', $serveur);
592
-	if (!function_exists('spip_version_compare')) {
593
-		include_spip('plugins/installer');
594
-	}
595
-
596
-	if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
597
-		$ifnotexists = ' IF NOT EXISTS';
598
-	} else {
599
-		/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
600
-		$a = spip_sqlite_showtable($table, $serveur);
601
-		if (isset($a['key']['KEY ' . $nom])) {
602
-			return true;
603
-		}
604
-	}
605
-
606
-	$query = 'CREATE ' . ($unique ? 'UNIQUE ' : '') . "INDEX$ifnotexists $nom ON $table (" . join(',', $champs) . ')';
607
-	$res = spip_sqlite_query($query, $serveur, $requeter);
608
-	if (!$requeter) {
609
-		return $res;
610
-	}
611
-	if ($res) {
612
-		return true;
613
-	} else {
614
-		return false;
615
-	}
568
+    if (!($nom or $table or $champs)) {
569
+        spip_log(
570
+            "Champ manquant pour creer un index sqlite ($nom, $table, (" . join(',', $champs) . '))',
571
+            'sqlite.' . _LOG_ERREUR
572
+        );
573
+
574
+        return false;
575
+    }
576
+
577
+    // SQLite ne differentie pas noms des index en fonction des tables
578
+    // il faut donc creer des noms uniques d'index pour une base sqlite
579
+    $nom = $table . '_' . $nom;
580
+    // enlever d'eventuelles parentheses deja presentes sur champs
581
+    if (!is_array($champs)) {
582
+        if ($champs[0] == '(') {
583
+            $champs = substr($champs, 1, -1);
584
+        }
585
+        $champs = [$champs];
586
+        // supprimer l'info de longueur d'index mysql en fin de champ
587
+        $champs = preg_replace(',\(\d+\)$,', '', $champs);
588
+    }
589
+
590
+    $ifnotexists = '';
591
+    $version = spip_sqlite_fetch(spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur), '', $serveur);
592
+    if (!function_exists('spip_version_compare')) {
593
+        include_spip('plugins/installer');
594
+    }
595
+
596
+    if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
597
+        $ifnotexists = ' IF NOT EXISTS';
598
+    } else {
599
+        /* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
600
+        $a = spip_sqlite_showtable($table, $serveur);
601
+        if (isset($a['key']['KEY ' . $nom])) {
602
+            return true;
603
+        }
604
+    }
605
+
606
+    $query = 'CREATE ' . ($unique ? 'UNIQUE ' : '') . "INDEX$ifnotexists $nom ON $table (" . join(',', $champs) . ')';
607
+    $res = spip_sqlite_query($query, $serveur, $requeter);
608
+    if (!$requeter) {
609
+        return $res;
610
+    }
611
+    if ($res) {
612
+        return true;
613
+    } else {
614
+        return false;
615
+    }
616 616
 }
617 617
 
618 618
 /**
@@ -629,31 +629,31 @@  discard block
 block discarded – undo
629 629
  * @return int                 Nombre de lignes
630 630
  */
631 631
 function spip_sqlite_count($r, $serveur = '', $requeter = true) {
632
-	if (!$r) {
633
-		return 0;
634
-	}
635
-
636
-	// select ou autre (insert, update,...) ?
637
-	// (link,requete) a compter
638
-	if (is_array($r->spipSqliteRowCount)) {
639
-		list($link, $query) = $r->spipSqliteRowCount;
640
-		// amelioration possible a tester intensivement : pas de order by pour compter !
641
-		// $query = preg_replace(",ORDER BY .+(LIMIT\s|HAVING\s|GROUP BY\s|$),Uims","\\1",$query);
642
-		$query = "SELECT count(*) as zzzzsqlitecount FROM ($query)";
643
-		$l = $link->query($query);
644
-		$i = 0;
645
-		if ($l and $z = $l->fetch()) {
646
-			$i = $z['zzzzsqlitecount'];
647
-		}
648
-		$r->spipSqliteRowCount = $i;
649
-	}
650
-	if (isset($r->spipSqliteRowCount)) {
651
-		// Ce compte est faux s'il y a des limit dans la requete :(
652
-		// il retourne le nombre d'enregistrements sans le limit
653
-		return $r->spipSqliteRowCount;
654
-	} else {
655
-		return $r->rowCount();
656
-	}
632
+    if (!$r) {
633
+        return 0;
634
+    }
635
+
636
+    // select ou autre (insert, update,...) ?
637
+    // (link,requete) a compter
638
+    if (is_array($r->spipSqliteRowCount)) {
639
+        list($link, $query) = $r->spipSqliteRowCount;
640
+        // amelioration possible a tester intensivement : pas de order by pour compter !
641
+        // $query = preg_replace(",ORDER BY .+(LIMIT\s|HAVING\s|GROUP BY\s|$),Uims","\\1",$query);
642
+        $query = "SELECT count(*) as zzzzsqlitecount FROM ($query)";
643
+        $l = $link->query($query);
644
+        $i = 0;
645
+        if ($l and $z = $l->fetch()) {
646
+            $i = $z['zzzzsqlitecount'];
647
+        }
648
+        $r->spipSqliteRowCount = $i;
649
+    }
650
+    if (isset($r->spipSqliteRowCount)) {
651
+        // Ce compte est faux s'il y a des limit dans la requete :(
652
+        // il retourne le nombre d'enregistrements sans le limit
653
+        return $r->spipSqliteRowCount;
654
+    } else {
655
+        return $r->rowCount();
656
+    }
657 657
 }
658 658
 
659 659
 
@@ -672,30 +672,30 @@  discard block
 block discarded – undo
672 672
  *     - false si la requête a échouée
673 673
  **/
674 674
 function spip_sqlite_countsel(
675
-	$from = [],
676
-	$where = [],
677
-	$groupby = '',
678
-	$having = [],
679
-	$serveur = '',
680
-	$requeter = true
675
+    $from = [],
676
+    $where = [],
677
+    $groupby = '',
678
+    $having = [],
679
+    $serveur = '',
680
+    $requeter = true
681 681
 ) {
682
-	$c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
683
-	$r = spip_sqlite_select(
684
-		"COUNT($c)",
685
-		$from,
686
-		$where,
687
-		'',
688
-		'',
689
-		'',
690
-		$having,
691
-		$serveur,
692
-		$requeter
693
-	);
694
-	if ((is_resource($r) or is_object($r)) && $requeter) { // ressource : sqlite2, object : sqlite3
695
-		list($r) = spip_sqlite_fetch($r, SPIP_SQLITE3_NUM, $serveur);
696
-	}
697
-
698
-	return $r;
682
+    $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
683
+    $r = spip_sqlite_select(
684
+        "COUNT($c)",
685
+        $from,
686
+        $where,
687
+        '',
688
+        '',
689
+        '',
690
+        $having,
691
+        $serveur,
692
+        $requeter
693
+    );
694
+    if ((is_resource($r) or is_object($r)) && $requeter) { // ressource : sqlite2, object : sqlite3
695
+        list($r) = spip_sqlite_fetch($r, SPIP_SQLITE3_NUM, $serveur);
696
+    }
697
+
698
+    return $r;
699 699
 }
700 700
 
701 701
 
@@ -712,24 +712,24 @@  discard block
 block discarded – undo
712 712
  *     - False en cas d'erreur.
713 713
  **/
714 714
 function spip_sqlite_delete($table, $where = '', $serveur = '', $requeter = true) {
715
-	$res = spip_sqlite_query(
716
-		_sqlite_calculer_expression('DELETE FROM', $table, ',')
717
-		. _sqlite_calculer_expression('WHERE', $where),
718
-		$serveur,
719
-		$requeter
720
-	);
715
+    $res = spip_sqlite_query(
716
+        _sqlite_calculer_expression('DELETE FROM', $table, ',')
717
+        . _sqlite_calculer_expression('WHERE', $where),
718
+        $serveur,
719
+        $requeter
720
+    );
721 721
 
722
-	// renvoyer la requete inerte si demandee
723
-	if (!$requeter) {
724
-		return $res;
725
-	}
722
+    // renvoyer la requete inerte si demandee
723
+    if (!$requeter) {
724
+        return $res;
725
+    }
726 726
 
727
-	if ($res) {
728
-		$link = _sqlite_link($serveur);
729
-		return $res->rowCount();
730
-	} else {
731
-		return false;
732
-	}
727
+    if ($res) {
728
+        $link = _sqlite_link($serveur);
729
+        return $res->rowCount();
730
+    } else {
731
+        return false;
732
+    }
733 733
 }
734 734
 
735 735
 
@@ -745,15 +745,15 @@  discard block
 block discarded – undo
745 745
  *     - true si la requête a réussie, false sinon
746 746
  */
747 747
 function spip_sqlite_drop_table($table, $exist = '', $serveur = '', $requeter = true) {
748
-	if ($exist) {
749
-		$exist = ' IF EXISTS';
750
-	}
748
+    if ($exist) {
749
+        $exist = ' IF EXISTS';
750
+    }
751 751
 
752
-	if (spip_sqlite_query("DROP TABLE$exist $table", $serveur, $requeter)) {
753
-		return true;
754
-	} else {
755
-		return false;
756
-	}
752
+    if (spip_sqlite_query("DROP TABLE$exist $table", $serveur, $requeter)) {
753
+        return true;
754
+    } else {
755
+        return false;
756
+    }
757 757
 }
758 758
 
759 759
 
@@ -769,11 +769,11 @@  discard block
 block discarded – undo
769 769
  *     - true si la requête a réussie, false sinon
770 770
  */
771 771
 function spip_sqlite_drop_view($view, $exist = '', $serveur = '', $requeter = true) {
772
-	if ($exist) {
773
-		$exist = ' IF EXISTS';
774
-	}
772
+    if ($exist) {
773
+        $exist = ' IF EXISTS';
774
+    }
775 775
 
776
-	return spip_sqlite_query("DROP VIEW$exist $view", $serveur, $requeter);
776
+    return spip_sqlite_query("DROP VIEW$exist $view", $serveur, $requeter);
777 777
 }
778 778
 
779 779
 /**
@@ -787,20 +787,20 @@  discard block
 block discarded – undo
787 787
  * @return bool ou requete
788 788
  */
789 789
 function spip_sqlite_drop_index($nom, $table, $serveur = '', $requeter = true) {
790
-	if (!($nom or $table)) {
791
-		spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.' . _LOG_ERREUR);
790
+    if (!($nom or $table)) {
791
+        spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.' . _LOG_ERREUR);
792 792
 
793
-		return false;
794
-	}
793
+        return false;
794
+    }
795 795
 
796
-	// SQLite ne differentie pas noms des index en fonction des tables
797
-	// il faut donc creer des noms uniques d'index pour une base sqlite
798
-	$index = $table . '_' . $nom;
799
-	$exist = ' IF EXISTS';
796
+    // SQLite ne differentie pas noms des index en fonction des tables
797
+    // il faut donc creer des noms uniques d'index pour une base sqlite
798
+    $index = $table . '_' . $nom;
799
+    $exist = ' IF EXISTS';
800 800
 
801
-	$query = "DROP INDEX$exist $index";
801
+    $query = "DROP INDEX$exist $index";
802 802
 
803
-	return spip_sqlite_query($query, $serveur, $requeter);
803
+    return spip_sqlite_query($query, $serveur, $requeter);
804 804
 }
805 805
 
806 806
 /**
@@ -816,28 +816,28 @@  discard block
 block discarded – undo
816 816
  *     Erreur eventuelle
817 817
  **/
818 818
 function spip_sqlite_error($query = '', $serveur = '') {
819
-	$link = _sqlite_link($serveur);
819
+    $link = _sqlite_link($serveur);
820 820
 
821
-	if ($link) {
822
-		$errs = $link->errorInfo();
823
-		$s = _sqlite_last_error_from_link($link);
824
-	} else {
825
-		$s = ': aucune ressource sqlite (link)';
826
-	}
827
-	if ($s) {
828
-		$trace = debug_backtrace();
829
-		if ($trace[0]['function'] != 'spip_sqlite_error') {
830
-			spip_log("$s - $query - " . sql_error_backtrace(), 'sqlite.' . _LOG_ERREUR);
831
-		}
832
-	}
821
+    if ($link) {
822
+        $errs = $link->errorInfo();
823
+        $s = _sqlite_last_error_from_link($link);
824
+    } else {
825
+        $s = ': aucune ressource sqlite (link)';
826
+    }
827
+    if ($s) {
828
+        $trace = debug_backtrace();
829
+        if ($trace[0]['function'] != 'spip_sqlite_error') {
830
+            spip_log("$s - $query - " . sql_error_backtrace(), 'sqlite.' . _LOG_ERREUR);
831
+        }
832
+    }
833 833
 
834
-	return $s;
834
+    return $s;
835 835
 }
836 836
 
837 837
 function _sqlite_last_error_from_link($link) {
838
-	if ($link) {
839
-		$errs = $link->errorInfo();
840
-		/*
838
+    if ($link) {
839
+        $errs = $link->errorInfo();
840
+        /*
841 841
 			$errs[0]
842 842
 				numero SQLState ('HY000' souvent lors d'une erreur)
843 843
 				http://www.easysoft.com/developer/interfaces/odbc/sqlstate_status_return_codes.html
@@ -847,11 +847,11 @@  discard block
 block discarded – undo
847 847
 			$errs[2]
848 848
 				Le texte du message d'erreur
849 849
 		*/
850
-		if (ltrim($errs[0], '0')) { // 00000 si pas d'erreur
851
-			return "$errs[2]";
852
-		}
853
-	}
854
-	return '';
850
+        if (ltrim($errs[0], '0')) { // 00000 si pas d'erreur
851
+            return "$errs[2]";
852
+        }
853
+    }
854
+    return '';
855 855
 }
856 856
 
857 857
 /**
@@ -868,23 +868,23 @@  discard block
 block discarded – undo
868 868
  *    'HY000/1' : numéro de l'erreur SQLState / numéro d'erreur interne SQLite (en sqlite 3)
869 869
  **/
870 870
 function spip_sqlite_errno($serveur = '') {
871
-	$link = _sqlite_link($serveur);
871
+    $link = _sqlite_link($serveur);
872 872
 
873
-	if ($link) {
874
-		$t = $link->errorInfo();
875
-		$s = ltrim($t[0], '0'); // 00000 si pas d'erreur
876
-		if ($s) {
877
-			$s .= ' / ' . $t[1];
878
-		} // ajoute l'erreur du moteur SQLite
879
-	} else {
880
-		$s = ': aucune ressource sqlite (link)';
881
-	}
873
+    if ($link) {
874
+        $t = $link->errorInfo();
875
+        $s = ltrim($t[0], '0'); // 00000 si pas d'erreur
876
+        if ($s) {
877
+            $s .= ' / ' . $t[1];
878
+        } // ajoute l'erreur du moteur SQLite
879
+    } else {
880
+        $s = ': aucune ressource sqlite (link)';
881
+    }
882 882
 
883
-	if ($s) {
884
-		spip_log("Erreur sqlite $s", 'sqlite.' . _LOG_ERREUR);
885
-	}
883
+    if ($s) {
884
+        spip_log("Erreur sqlite $s", 'sqlite.' . _LOG_ERREUR);
885
+    }
886 886
 
887
-	return $s ? $s : 0;
887
+    return $s ? $s : 0;
888 888
 }
889 889
 
890 890
 
@@ -900,19 +900,19 @@  discard block
 block discarded – undo
900 900
  *     - false si on a pas pu avoir d'explication
901 901
  */
902 902
 function spip_sqlite_explain($query, $serveur = '', $requeter = true) {
903
-	if (strpos(ltrim($query), 'SELECT') !== 0) {
904
-		return [];
905
-	}
903
+    if (strpos(ltrim($query), 'SELECT') !== 0) {
904
+        return [];
905
+    }
906 906
 
907
-	$query = spip_sqlite::traduire_requete($query, $serveur);
908
-	$query = 'EXPLAIN ' . $query;
909
-	if (!$requeter) {
910
-		return $query;
911
-	}
912
-	// on ne trace pas ces requetes, sinon on obtient un tracage sans fin...
913
-	$r = spip_sqlite::executer_requete($query, $serveur, false);
907
+    $query = spip_sqlite::traduire_requete($query, $serveur);
908
+    $query = 'EXPLAIN ' . $query;
909
+    if (!$requeter) {
910
+        return $query;
911
+    }
912
+    // on ne trace pas ces requetes, sinon on obtient un tracage sans fin...
913
+    $r = spip_sqlite::executer_requete($query, $serveur, false);
914 914
 
915
-	return $r ? spip_sqlite_fetch($r, null, $serveur) : false; // hum ? etrange ca... a verifier
915
+    return $r ? spip_sqlite_fetch($r, null, $serveur) : false; // hum ? etrange ca... a verifier
916 916
 }
917 917
 
918 918
 
@@ -929,30 +929,30 @@  discard block
 block discarded – undo
929 929
  */
930 930
 function spip_sqlite_fetch($r, $t = '', $serveur = '', $requeter = true) {
931 931
 
932
-	$link = _sqlite_link($serveur);
933
-	$t = $t ? $t : SPIP_SQLITE3_ASSOC;
932
+    $link = _sqlite_link($serveur);
933
+    $t = $t ? $t : SPIP_SQLITE3_ASSOC;
934 934
 
935
-	$retour = false;
936
-	if ($r) {
937
-		$retour = $r->fetch($t);
938
-	}
935
+    $retour = false;
936
+    if ($r) {
937
+        $retour = $r->fetch($t);
938
+    }
939 939
 
940
-	// Renvoie des 'table.titre' au lieu de 'titre' tout court ! pff !
941
-	// suppression de 'table.' pour toutes les cles (c'est un peu violent !)
942
-	// c'est couteux : on ne verifie que la premiere ligne pour voir si on le fait ou non
943
-	if (
944
-		$retour
945
-		and strpos(implode('', array_keys($retour)), '.') !== false
946
-	) {
947
-		foreach ($retour as $cle => $val) {
948
-			if (($pos = strpos($cle, '.')) !== false) {
949
-				$retour[substr($cle, $pos + 1)] = &$retour[$cle];
950
-				unset($retour[$cle]);
951
-			}
952
-		}
953
-	}
940
+    // Renvoie des 'table.titre' au lieu de 'titre' tout court ! pff !
941
+    // suppression de 'table.' pour toutes les cles (c'est un peu violent !)
942
+    // c'est couteux : on ne verifie que la premiere ligne pour voir si on le fait ou non
943
+    if (
944
+        $retour
945
+        and strpos(implode('', array_keys($retour)), '.') !== false
946
+    ) {
947
+        foreach ($retour as $cle => $val) {
948
+            if (($pos = strpos($cle, '.')) !== false) {
949
+                $retour[substr($cle, $pos + 1)] = &$retour[$cle];
950
+                unset($retour[$cle]);
951
+            }
952
+        }
953
+    }
954 954
 
955
-	return $retour;
955
+    return $retour;
956 956
 }
957 957
 
958 958
 /**
@@ -965,8 +965,8 @@  discard block
 block discarded – undo
965 965
  * @return bool True si déplacement réussi, false sinon.
966 966
  **/
967 967
 function spip_sqlite_seek($r, $row_number, $serveur = '', $requeter = true) {
968
-	// encore un truc de bien fichu : PDO ne PEUT PAS faire de seek ou de rewind...
969
-	return false;
968
+    // encore un truc de bien fichu : PDO ne PEUT PAS faire de seek ou de rewind...
969
+    return false;
970 970
 }
971 971
 
972 972
 
@@ -982,10 +982,10 @@  discard block
 block discarded – undo
982 982
  * @return bool                True si réussi
983 983
  */
984 984
 function spip_sqlite_free(&$r, $serveur = '', $requeter = true) {
985
-	unset($r);
985
+    unset($r);
986 986
 
987
-	return true;
988
-	//return sqlite_free_result($r);
987
+    return true;
988
+    //return sqlite_free_result($r);
989 989
 }
990 990
 
991 991
 
@@ -1000,8 +1000,8 @@  discard block
 block discarded – undo
1000 1000
  * @return void
1001 1001
  */
1002 1002
 function spip_sqlite_get_charset($charset = [], $serveur = '', $requeter = true) {
1003
-	//$c = !$charset ? '' : (" LIKE "._q($charset['charset']));
1004
-	//return spip_sqlite_fetch(sqlite_query(_sqlite_link($serveur), "SHOW CHARACTER SET$c"), NULL, $serveur);
1003
+    //$c = !$charset ? '' : (" LIKE "._q($charset['charset']));
1004
+    //return spip_sqlite_fetch(sqlite_query(_sqlite_link($serveur), "SHOW CHARACTER SET$c"), NULL, $serveur);
1005 1005
 }
1006 1006
 
1007 1007
 
@@ -1016,7 +1016,7 @@  discard block
 block discarded – undo
1016 1016
  *     Valeur hexadécimale pour SQLite
1017 1017
  **/
1018 1018
 function spip_sqlite_hex($v) {
1019
-	return hexdec($v);
1019
+    return hexdec($v);
1020 1020
 }
1021 1021
 
1022 1022
 
@@ -1038,7 +1038,7 @@  discard block
 block discarded – undo
1038 1038
  *     Expression de requête SQL
1039 1039
  **/
1040 1040
 function spip_sqlite_in($val, $valeurs, $not = '', $serveur = '', $requeter = true) {
1041
-	return "($val $not IN ($valeurs))";
1041
+    return "($val $not IN ($valeurs))";
1042 1042
 }
1043 1043
 
1044 1044
 
@@ -1066,20 +1066,20 @@  discard block
 block discarded – undo
1066 1066
  **/
1067 1067
 function spip_sqlite_insert($table, $champs, $valeurs, $desc = [], $serveur = '', $requeter = true) {
1068 1068
 
1069
-	$query = "INSERT INTO $table " . ($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1070
-	if ($r = spip_sqlite_query($query, $serveur, $requeter)) {
1071
-		if (!$requeter) {
1072
-			return $r;
1073
-		}
1074
-		$nb = spip_sqlite::last_insert_id($serveur);
1075
-	} else {
1076
-		$nb = false;
1077
-	}
1069
+    $query = "INSERT INTO $table " . ($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1070
+    if ($r = spip_sqlite_query($query, $serveur, $requeter)) {
1071
+        if (!$requeter) {
1072
+            return $r;
1073
+        }
1074
+        $nb = spip_sqlite::last_insert_id($serveur);
1075
+    } else {
1076
+        $nb = false;
1077
+    }
1078 1078
 
1079
-	$err = spip_sqlite_error($query, $serveur);
1079
+    $err = spip_sqlite_error($query, $serveur);
1080 1080
 
1081
-	// cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1082
-	return isset($_GET['var_profile']) ? $r : $nb;
1081
+    // cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1082
+    return isset($_GET['var_profile']) ? $r : $nb;
1083 1083
 }
1084 1084
 
1085 1085
 
@@ -1104,28 +1104,28 @@  discard block
 block discarded – undo
1104 1104
  *     - Tableau de description de la requête et du temps d'exécution, si var_profile activé
1105 1105
  **/
1106 1106
 function spip_sqlite_insertq($table, $couples = [], $desc = [], $serveur = '', $requeter = true) {
1107
-	if (!$desc) {
1108
-		$desc = description_table($table, $serveur);
1109
-	}
1110
-	if (!$desc) {
1111
-		die("$table insertion sans description");
1112
-	}
1113
-	$fields = isset($desc['field']) ? $desc['field'] : [];
1107
+    if (!$desc) {
1108
+        $desc = description_table($table, $serveur);
1109
+    }
1110
+    if (!$desc) {
1111
+        die("$table insertion sans description");
1112
+    }
1113
+    $fields = isset($desc['field']) ? $desc['field'] : [];
1114 1114
 
1115
-	foreach ($couples as $champ => $val) {
1116
-		$couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1117
-	}
1115
+    foreach ($couples as $champ => $val) {
1116
+        $couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1117
+    }
1118 1118
 
1119
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1120
-	$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1119
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1120
+    $couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1121 1121
 
1122
-	$cles = $valeurs = '';
1123
-	if (count($couples)) {
1124
-		$cles = '(' . join(',', array_keys($couples)) . ')';
1125
-		$valeurs = '(' . join(',', $couples) . ')';
1126
-	}
1122
+    $cles = $valeurs = '';
1123
+    if (count($couples)) {
1124
+        $cles = '(' . join(',', array_keys($couples)) . ')';
1125
+        $valeurs = '(' . join(',', $couples) . ')';
1126
+    }
1127 1127
 
1128
-	return spip_sqlite_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1128
+    return spip_sqlite_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1129 1129
 }
1130 1130
 
1131 1131
 
@@ -1149,70 +1149,70 @@  discard block
 block discarded – undo
1149 1149
  *     - False en cas d'erreur.
1150 1150
  **/
1151 1151
 function spip_sqlite_insertq_multi($table, $tab_couples = [], $desc = [], $serveur = '', $requeter = true) {
1152
-	if (!$desc) {
1153
-		$desc = description_table($table, $serveur);
1154
-	}
1155
-	if (!$desc) {
1156
-		die("$table insertion sans description");
1157
-	}
1158
-	if (!isset($desc['field'])) {
1159
-		$desc['field'] = [];
1160
-	}
1161
-
1162
-	// recuperer les champs 'timestamp' pour mise a jour auto de ceux-ci
1163
-	$maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1164
-
1165
-	// seul le nom de la table est a traduire ici :
1166
-	// le faire une seule fois au debut
1167
-	$query_start = "INSERT INTO $table ";
1168
-	$query_start = spip_sqlite::traduire_requete($query_start, $serveur);
1169
-
1170
-	// ouvrir une transaction
1171
-	if ($requeter) {
1172
-		spip_sqlite::demarrer_transaction($serveur);
1173
-	}
1174
-
1175
-	while ($couples = array_shift($tab_couples)) {
1176
-		foreach ($couples as $champ => $val) {
1177
-			$couples[$champ] = _sqlite_calculer_cite($val, $desc['field'][$champ]);
1178
-		}
1179
-
1180
-		// inserer les champs timestamp par defaut
1181
-		$couples = array_merge($maj, $couples);
1182
-
1183
-		$champs = $valeurs = '';
1184
-		if (count($couples)) {
1185
-			$champs = '(' . join(',', array_keys($couples)) . ')';
1186
-			$valeurs = '(' . join(',', $couples) . ')';
1187
-			$query = $query_start . "$champs VALUES $valeurs";
1188
-		} else {
1189
-			$query = $query_start . 'DEFAULT VALUES';
1190
-		}
1191
-
1192
-		if ($requeter) {
1193
-			$retour = spip_sqlite::executer_requete($query, $serveur);
1194
-		}
1195
-
1196
-		// sur le dernier couple uniquement
1197
-		if (!count($tab_couples)) {
1198
-			$nb = 0;
1199
-			if ($requeter) {
1200
-				$nb = spip_sqlite::last_insert_id($serveur);
1201
-			} else {
1202
-				return $query;
1203
-			}
1204
-		}
1205
-
1206
-		$err = spip_sqlite_error($query, $serveur);
1207
-	}
1208
-
1209
-	if ($requeter) {
1210
-		spip_sqlite::finir_transaction($serveur);
1211
-	}
1212
-
1213
-	// renvoie le dernier id d'autoincrement ajoute
1214
-	// cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1215
-	return isset($_GET['var_profile']) ? $retour : $nb;
1152
+    if (!$desc) {
1153
+        $desc = description_table($table, $serveur);
1154
+    }
1155
+    if (!$desc) {
1156
+        die("$table insertion sans description");
1157
+    }
1158
+    if (!isset($desc['field'])) {
1159
+        $desc['field'] = [];
1160
+    }
1161
+
1162
+    // recuperer les champs 'timestamp' pour mise a jour auto de ceux-ci
1163
+    $maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1164
+
1165
+    // seul le nom de la table est a traduire ici :
1166
+    // le faire une seule fois au debut
1167
+    $query_start = "INSERT INTO $table ";
1168
+    $query_start = spip_sqlite::traduire_requete($query_start, $serveur);
1169
+
1170
+    // ouvrir une transaction
1171
+    if ($requeter) {
1172
+        spip_sqlite::demarrer_transaction($serveur);
1173
+    }
1174
+
1175
+    while ($couples = array_shift($tab_couples)) {
1176
+        foreach ($couples as $champ => $val) {
1177
+            $couples[$champ] = _sqlite_calculer_cite($val, $desc['field'][$champ]);
1178
+        }
1179
+
1180
+        // inserer les champs timestamp par defaut
1181
+        $couples = array_merge($maj, $couples);
1182
+
1183
+        $champs = $valeurs = '';
1184
+        if (count($couples)) {
1185
+            $champs = '(' . join(',', array_keys($couples)) . ')';
1186
+            $valeurs = '(' . join(',', $couples) . ')';
1187
+            $query = $query_start . "$champs VALUES $valeurs";
1188
+        } else {
1189
+            $query = $query_start . 'DEFAULT VALUES';
1190
+        }
1191
+
1192
+        if ($requeter) {
1193
+            $retour = spip_sqlite::executer_requete($query, $serveur);
1194
+        }
1195
+
1196
+        // sur le dernier couple uniquement
1197
+        if (!count($tab_couples)) {
1198
+            $nb = 0;
1199
+            if ($requeter) {
1200
+                $nb = spip_sqlite::last_insert_id($serveur);
1201
+            } else {
1202
+                return $query;
1203
+            }
1204
+        }
1205
+
1206
+        $err = spip_sqlite_error($query, $serveur);
1207
+    }
1208
+
1209
+    if ($requeter) {
1210
+        spip_sqlite::finir_transaction($serveur);
1211
+    }
1212
+
1213
+    // renvoie le dernier id d'autoincrement ajoute
1214
+    // cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1215
+    return isset($_GET['var_profile']) ? $retour : $nb;
1216 1216
 }
1217 1217
 
1218 1218
 
@@ -1227,7 +1227,7 @@  discard block
 block discarded – undo
1227 1227
  *     Toujours true.
1228 1228
  **/
1229 1229
 function spip_sqlite_preferer_transaction($serveur = '', $requeter = true) {
1230
-	return true;
1230
+    return true;
1231 1231
 }
1232 1232
 
1233 1233
 /**
@@ -1244,12 +1244,12 @@  discard block
 block discarded – undo
1244 1244
  *     string si texte de la requête demandé, true sinon
1245 1245
  **/
1246 1246
 function spip_sqlite_demarrer_transaction($serveur = '', $requeter = true) {
1247
-	if (!$requeter) {
1248
-		return 'BEGIN TRANSACTION';
1249
-	}
1250
-	spip_sqlite::demarrer_transaction($serveur);
1247
+    if (!$requeter) {
1248
+        return 'BEGIN TRANSACTION';
1249
+    }
1250
+    spip_sqlite::demarrer_transaction($serveur);
1251 1251
 
1252
-	return true;
1252
+    return true;
1253 1253
 }
1254 1254
 
1255 1255
 /**
@@ -1263,12 +1263,12 @@  discard block
 block discarded – undo
1263 1263
  *     string si texte de la requête demandé, true sinon
1264 1264
  **/
1265 1265
 function spip_sqlite_terminer_transaction($serveur = '', $requeter = true) {
1266
-	if (!$requeter) {
1267
-		return 'COMMIT';
1268
-	}
1269
-	spip_sqlite::finir_transaction($serveur);
1266
+    if (!$requeter) {
1267
+        return 'COMMIT';
1268
+    }
1269
+    spip_sqlite::finir_transaction($serveur);
1270 1270
 
1271
-	return true;
1271
+    return true;
1272 1272
 }
1273 1273
 
1274 1274
 
@@ -1283,27 +1283,27 @@  discard block
 block discarded – undo
1283 1283
  *     Liste des noms de bases
1284 1284
  **/
1285 1285
 function spip_sqlite_listdbs($serveur = '', $requeter = true) {
1286
-	_sqlite_init();
1286
+    _sqlite_init();
1287 1287
 
1288
-	if (!is_dir($d = substr(_DIR_DB, 0, -1))) {
1289
-		return [];
1290
-	}
1288
+    if (!is_dir($d = substr(_DIR_DB, 0, -1))) {
1289
+        return [];
1290
+    }
1291 1291
 
1292
-	include_spip('inc/flock');
1293
-	$bases = preg_files($d, $pattern = '(.*)\.sqlite$');
1294
-	$bds = [];
1292
+    include_spip('inc/flock');
1293
+    $bases = preg_files($d, $pattern = '(.*)\.sqlite$');
1294
+    $bds = [];
1295 1295
 
1296
-	foreach ($bases as $b) {
1297
-		// pas de bases commencant pas sqlite
1298
-		// (on s'en sert pour l'installation pour simuler la presence d'un serveur)
1299
-		// les bases sont de la forme _sqliteX_tmp_spip_install.sqlite
1300
-		if (strpos($b, '_sqlite')) {
1301
-			continue;
1302
-		}
1303
-		$bds[] = preg_replace(";.*/$pattern;iS", '$1', $b);
1304
-	}
1296
+    foreach ($bases as $b) {
1297
+        // pas de bases commencant pas sqlite
1298
+        // (on s'en sert pour l'installation pour simuler la presence d'un serveur)
1299
+        // les bases sont de la forme _sqliteX_tmp_spip_install.sqlite
1300
+        if (strpos($b, '_sqlite')) {
1301
+            continue;
1302
+        }
1303
+        $bds[] = preg_replace(";.*/$pattern;iS", '$1', $b);
1304
+    }
1305 1305
 
1306
-	return $bds;
1306
+    return $bds;
1307 1307
 }
1308 1308
 
1309 1309
 
@@ -1318,9 +1318,9 @@  discard block
 block discarded – undo
1318 1318
  * @return string       Texte de sélection pour la requête
1319 1319
  */
1320 1320
 function spip_sqlite_multi($objet, $lang) {
1321
-	$r = 'EXTRAIRE_MULTI(' . $objet . ", '" . $lang . "') AS multi";
1321
+    $r = 'EXTRAIRE_MULTI(' . $objet . ", '" . $lang . "') AS multi";
1322 1322
 
1323
-	return $r;
1323
+    return $r;
1324 1324
 }
1325 1325
 
1326 1326
 
@@ -1337,15 +1337,15 @@  discard block
 block discarded – undo
1337 1337
  * @return bool|string true / false / requete
1338 1338
  **/
1339 1339
 function spip_sqlite_optimize($table, $serveur = '', $requeter = true) {
1340
-	static $do = false;
1341
-	if ($requeter and $do) {
1342
-		return true;
1343
-	}
1344
-	if ($requeter) {
1345
-		$do = true;
1346
-	}
1340
+    static $do = false;
1341
+    if ($requeter and $do) {
1342
+        return true;
1343
+    }
1344
+    if ($requeter) {
1345
+        $do = true;
1346
+    }
1347 1347
 
1348
-	return spip_sqlite_query('VACUUM', $serveur, $requeter);
1348
+    return spip_sqlite_query('VACUUM', $serveur, $requeter);
1349 1349
 }
1350 1350
 
1351 1351
 
@@ -1362,15 +1362,15 @@  discard block
 block discarded – undo
1362 1362
  *    Donnée prête à être utilisée par le gestionnaire SQL
1363 1363
  */
1364 1364
 function spip_sqlite_quote($v, $type = '') {
1365
-	if (!is_array($v)) {
1366
-		return _sqlite_calculer_cite($v, $type);
1367
-	}
1368
-	// si c'est un tableau, le parcourir en propageant le type
1369
-	foreach ($v as $k => $r) {
1370
-		$v[$k] = spip_sqlite_quote($r, $type);
1371
-	}
1365
+    if (!is_array($v)) {
1366
+        return _sqlite_calculer_cite($v, $type);
1367
+    }
1368
+    // si c'est un tableau, le parcourir en propageant le type
1369
+    foreach ($v as $k => $r) {
1370
+        $v[$k] = spip_sqlite_quote($r, $type);
1371
+    }
1372 1372
 
1373
-	return join(',', $v);
1373
+    return join(',', $v);
1374 1374
 }
1375 1375
 
1376 1376
 
@@ -1387,9 +1387,9 @@  discard block
 block discarded – undo
1387 1387
  *     Expression SQL
1388 1388
  **/
1389 1389
 function spip_sqlite_date_proche($champ, $interval, $unite) {
1390
-	$op = (($interval <= 0) ? '>' : '<');
1390
+    $op = (($interval <= 0) ? '>' : '<');
1391 1391
 
1392
-	return "($champ $op datetime('" . date('Y-m-d H:i:s') . "', '$interval $unite'))";
1392
+    return "($champ $op datetime('" . date('Y-m-d H:i:s') . "', '$interval $unite'))";
1393 1393
 }
1394 1394
 
1395 1395
 
@@ -1407,48 +1407,48 @@  discard block
 block discarded – undo
1407 1407
  *     l'état de la table après la réparation
1408 1408
  */
1409 1409
 function spip_sqlite_repair($table, $serveur = '', $requeter = true) {
1410
-	if (
1411
-		$desc = spip_sqlite_showtable($table, $serveur)
1412
-		and isset($desc['field'])
1413
-		and is_array($desc['field'])
1414
-	) {
1415
-		foreach ($desc['field'] as $c => $d) {
1416
-			if (
1417
-				preg_match(',^(tinytext|mediumtext|text|longtext|varchar|char),i', $d)
1418
-				and stripos($d, 'NOT NULL') !== false
1419
-				and stripos($d, 'DEFAULT') === false
1420
-				/* pas touche aux cles primaires */
1421
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1422
-			) {
1423
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT ''", $serveur);
1424
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1425
-			}
1426
-			if (
1427
-				preg_match(',^(INTEGER),i', $d)
1428
-				and stripos($d, 'NOT NULL') !== false
1429
-				and stripos($d, 'DEFAULT') === false
1430
-				/* pas touche aux cles primaires */
1431
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1432
-			) {
1433
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0'", $serveur);
1434
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1435
-			}
1436
-			if (
1437
-				preg_match(',^(datetime),i', $d)
1438
-				and stripos($d, 'NOT NULL') !== false
1439
-				and stripos($d, 'DEFAULT') === false
1440
-				/* pas touche aux cles primaires */
1441
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1442
-			) {
1443
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0000-00-00 00:00:00'", $serveur);
1444
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1445
-			}
1446
-		}
1447
-
1448
-		return [' OK '];
1449
-	}
1450
-
1451
-	return [' ERROR '];
1410
+    if (
1411
+        $desc = spip_sqlite_showtable($table, $serveur)
1412
+        and isset($desc['field'])
1413
+        and is_array($desc['field'])
1414
+    ) {
1415
+        foreach ($desc['field'] as $c => $d) {
1416
+            if (
1417
+                preg_match(',^(tinytext|mediumtext|text|longtext|varchar|char),i', $d)
1418
+                and stripos($d, 'NOT NULL') !== false
1419
+                and stripos($d, 'DEFAULT') === false
1420
+                /* pas touche aux cles primaires */
1421
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1422
+            ) {
1423
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT ''", $serveur);
1424
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1425
+            }
1426
+            if (
1427
+                preg_match(',^(INTEGER),i', $d)
1428
+                and stripos($d, 'NOT NULL') !== false
1429
+                and stripos($d, 'DEFAULT') === false
1430
+                /* pas touche aux cles primaires */
1431
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1432
+            ) {
1433
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0'", $serveur);
1434
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1435
+            }
1436
+            if (
1437
+                preg_match(',^(datetime),i', $d)
1438
+                and stripos($d, 'NOT NULL') !== false
1439
+                and stripos($d, 'DEFAULT') === false
1440
+                /* pas touche aux cles primaires */
1441
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1442
+            ) {
1443
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0000-00-00 00:00:00'", $serveur);
1444
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1445
+            }
1446
+        }
1447
+
1448
+        return [' OK '];
1449
+    }
1450
+
1451
+    return [' ERROR '];
1452 1452
 }
1453 1453
 
1454 1454
 
@@ -1477,25 +1477,25 @@  discard block
 block discarded – undo
1477 1477
  *     - False en cas d'erreur.
1478 1478
  **/
1479 1479
 function spip_sqlite_replace($table, $couples, $desc = [], $serveur = '', $requeter = true) {
1480
-	if (!$desc) {
1481
-		$desc = description_table($table, $serveur);
1482
-	}
1483
-	if (!$desc) {
1484
-		die("$table insertion sans description");
1485
-	}
1486
-	$fields = isset($desc['field']) ? $desc['field'] : [];
1480
+    if (!$desc) {
1481
+        $desc = description_table($table, $serveur);
1482
+    }
1483
+    if (!$desc) {
1484
+        die("$table insertion sans description");
1485
+    }
1486
+    $fields = isset($desc['field']) ? $desc['field'] : [];
1487 1487
 
1488
-	foreach ($couples as $champ => $val) {
1489
-		$couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1490
-	}
1488
+    foreach ($couples as $champ => $val) {
1489
+        $couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1490
+    }
1491 1491
 
1492
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1493
-	$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1492
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1493
+    $couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1494 1494
 
1495
-	return spip_sqlite_query("REPLACE INTO $table (" . join(',', array_keys($couples)) . ') VALUES (' . join(
1496
-		',',
1497
-		$couples
1498
-	) . ')', $serveur);
1495
+    return spip_sqlite_query("REPLACE INTO $table (" . join(',', array_keys($couples)) . ') VALUES (' . join(
1496
+        ',',
1497
+        $couples
1498
+    ) . ')', $serveur);
1499 1499
 }
1500 1500
 
1501 1501
 
@@ -1525,13 +1525,13 @@  discard block
 block discarded – undo
1525 1525
  **/
1526 1526
 function spip_sqlite_replace_multi($table, $tab_couples, $desc = [], $serveur = '', $requeter = true) {
1527 1527
 
1528
-	// boucler pour trainter chaque requete independemment
1529
-	foreach ($tab_couples as $couples) {
1530
-		$retour = spip_sqlite_replace($table, $couples, $desc, $serveur, $requeter);
1531
-	}
1528
+    // boucler pour trainter chaque requete independemment
1529
+    foreach ($tab_couples as $couples) {
1530
+        $retour = spip_sqlite_replace($table, $couples, $desc, $serveur, $requeter);
1531
+    }
1532 1532
 
1533
-	// renvoie le dernier id
1534
-	return $retour;
1533
+    // renvoie le dernier id
1534
+    return $retour;
1535 1535
 }
1536 1536
 
1537 1537
 
@@ -1558,44 +1558,44 @@  discard block
 block discarded – undo
1558 1558
  *     - array  : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer.
1559 1559
  */
1560 1560
 function spip_sqlite_select(
1561
-	$select,
1562
-	$from,
1563
-	$where = '',
1564
-	$groupby = '',
1565
-	$orderby = '',
1566
-	$limit = '',
1567
-	$having = '',
1568
-	$serveur = '',
1569
-	$requeter = true
1561
+    $select,
1562
+    $from,
1563
+    $where = '',
1564
+    $groupby = '',
1565
+    $orderby = '',
1566
+    $limit = '',
1567
+    $having = '',
1568
+    $serveur = '',
1569
+    $requeter = true
1570 1570
 ) {
1571 1571
 
1572
-	// version() n'est pas connu de sqlite
1573
-	$select = str_replace('version()', 'sqlite_version()', $select);
1572
+    // version() n'est pas connu de sqlite
1573
+    $select = str_replace('version()', 'sqlite_version()', $select);
1574 1574
 
1575
-	// recomposer from
1576
-	$from = (!is_array($from) ? $from : _sqlite_calculer_select_as($from));
1575
+    // recomposer from
1576
+    $from = (!is_array($from) ? $from : _sqlite_calculer_select_as($from));
1577 1577
 
1578
-	$query =
1579
-		_sqlite_calculer_expression('SELECT', $select, ', ')
1580
-		. _sqlite_calculer_expression('FROM', $from, ', ')
1581
-		. _sqlite_calculer_expression('WHERE', $where)
1582
-		. _sqlite_calculer_expression('GROUP BY', $groupby, ',')
1583
-		. _sqlite_calculer_expression('HAVING', $having)
1584
-		. ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) : '')
1585
-		. ($limit ? "\nLIMIT $limit" : '');
1578
+    $query =
1579
+        _sqlite_calculer_expression('SELECT', $select, ', ')
1580
+        . _sqlite_calculer_expression('FROM', $from, ', ')
1581
+        . _sqlite_calculer_expression('WHERE', $where)
1582
+        . _sqlite_calculer_expression('GROUP BY', $groupby, ',')
1583
+        . _sqlite_calculer_expression('HAVING', $having)
1584
+        . ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) : '')
1585
+        . ($limit ? "\nLIMIT $limit" : '');
1586 1586
 
1587
-	// dans un select, on doit renvoyer la requête en cas d'erreur
1588
-	$res = spip_sqlite_query($query, $serveur, $requeter);
1589
-	// texte de la requete demande ?
1590
-	if (!$requeter) {
1591
-		return $res;
1592
-	}
1593
-	// erreur survenue ?
1594
-	if ($res === false) {
1595
-		return spip_sqlite::traduire_requete($query, $serveur);
1596
-	}
1587
+    // dans un select, on doit renvoyer la requête en cas d'erreur
1588
+    $res = spip_sqlite_query($query, $serveur, $requeter);
1589
+    // texte de la requete demande ?
1590
+    if (!$requeter) {
1591
+        return $res;
1592
+    }
1593
+    // erreur survenue ?
1594
+    if ($res === false) {
1595
+        return spip_sqlite::traduire_requete($query, $serveur);
1596
+    }
1597 1597
 
1598
-	return $res;
1598
+    return $res;
1599 1599
 }
1600 1600
 
1601 1601
 
@@ -1614,32 +1614,32 @@  discard block
 block discarded – undo
1614 1614
  *     - False en cas d'erreur.
1615 1615
  **/
1616 1616
 function spip_sqlite_selectdb($db, $serveur = '', $requeter = true) {
1617
-	_sqlite_init();
1617
+    _sqlite_init();
1618 1618
 
1619
-	// interdire la creation d'une nouvelle base,
1620
-	// sauf si on est dans l'installation
1621
-	if (
1622
-		!is_file($f = _DIR_DB . $db . '.sqlite')
1623
-		&& (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)
1624
-	) {
1625
-		spip_log("Il est interdit de creer la base $db", 'sqlite.' . _LOG_HS);
1619
+    // interdire la creation d'une nouvelle base,
1620
+    // sauf si on est dans l'installation
1621
+    if (
1622
+        !is_file($f = _DIR_DB . $db . '.sqlite')
1623
+        && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)
1624
+    ) {
1625
+        spip_log("Il est interdit de creer la base $db", 'sqlite.' . _LOG_HS);
1626 1626
 
1627
-		return false;
1628
-	}
1627
+        return false;
1628
+    }
1629 1629
 
1630
-	// se connecter a la base indiquee
1631
-	// avec les identifiants connus
1632
-	$index = $serveur ? $serveur : 0;
1630
+    // se connecter a la base indiquee
1631
+    // avec les identifiants connus
1632
+    $index = $serveur ? $serveur : 0;
1633 1633
 
1634
-	if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db, $serveur, '', '')) {
1635
-		if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
1636
-			return $db;
1637
-		}
1638
-	} else {
1639
-		spip_log("Impossible de selectionner la base $db", 'sqlite.' . _LOG_HS);
1634
+    if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db, $serveur, '', '')) {
1635
+        if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
1636
+            return $db;
1637
+        }
1638
+    } else {
1639
+        spip_log("Impossible de selectionner la base $db", 'sqlite.' . _LOG_HS);
1640 1640
 
1641
-		return false;
1642
-	}
1641
+        return false;
1642
+    }
1643 1643
 }
1644 1644
 
1645 1645
 
@@ -1654,8 +1654,8 @@  discard block
 block discarded – undo
1654 1654
  * @return void
1655 1655
  */
1656 1656
 function spip_sqlite_set_charset($charset, $serveur = '', $requeter = true) {
1657
-	# spip_log("Gestion charset sql a ecrire : "."SET NAMES "._q($charset), 'sqlite.'._LOG_ERREUR);
1658
-	# return spip_sqlite_query("SET NAMES ". spip_sqlite_quote($charset), $serveur); //<-- Passe pas !
1657
+    # spip_log("Gestion charset sql a ecrire : "."SET NAMES "._q($charset), 'sqlite.'._LOG_ERREUR);
1658
+    # return spip_sqlite_query("SET NAMES ". spip_sqlite_quote($charset), $serveur); //<-- Passe pas !
1659 1659
 }
1660 1660
 
1661 1661
 
@@ -1673,24 +1673,24 @@  discard block
 block discarded – undo
1673 1673
  *     Ressource à utiliser avec sql_fetch()
1674 1674
  **/
1675 1675
 function spip_sqlite_showbase($match, $serveur = '', $requeter = true) {
1676
-	// type est le type d'entrée : table / index / view
1677
-	// on ne retourne que les tables (?) et non les vues...
1678
-	# ESCAPE non supporte par les versions sqlite <3
1679
-	#	return spip_sqlite_query("SELECT name FROM sqlite_master WHERE type='table' AND tbl_name LIKE "._q($match)." ESCAPE '\'", $serveur, $requeter);
1680
-	$match = preg_quote($match);
1681
-	$match = str_replace('\\\_', '[[TIRETBAS]]', $match);
1682
-	$match = str_replace('\\\%', '[[POURCENT]]', $match);
1683
-	$match = str_replace('_', '.', $match);
1684
-	$match = str_replace('%', '.*', $match);
1685
-	$match = str_replace('[[TIRETBAS]]', '_', $match);
1686
-	$match = str_replace('[[POURCENT]]', '%', $match);
1687
-	$match = "^$match$";
1688
-
1689
-	return spip_sqlite_query(
1690
-		"SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP " . _q($match),
1691
-		$serveur,
1692
-		$requeter
1693
-	);
1676
+    // type est le type d'entrée : table / index / view
1677
+    // on ne retourne que les tables (?) et non les vues...
1678
+    # ESCAPE non supporte par les versions sqlite <3
1679
+    #	return spip_sqlite_query("SELECT name FROM sqlite_master WHERE type='table' AND tbl_name LIKE "._q($match)." ESCAPE '\'", $serveur, $requeter);
1680
+    $match = preg_quote($match);
1681
+    $match = str_replace('\\\_', '[[TIRETBAS]]', $match);
1682
+    $match = str_replace('\\\%', '[[POURCENT]]', $match);
1683
+    $match = str_replace('_', '.', $match);
1684
+    $match = str_replace('%', '.*', $match);
1685
+    $match = str_replace('[[TIRETBAS]]', '_', $match);
1686
+    $match = str_replace('[[POURCENT]]', '%', $match);
1687
+    $match = "^$match$";
1688
+
1689
+    return spip_sqlite_query(
1690
+        "SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP " . _q($match),
1691
+        $serveur,
1692
+        $requeter
1693
+    );
1694 1694
 }
1695 1695
 
1696 1696
 define('_SQLITE_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/');
@@ -1713,129 +1713,129 @@  discard block
 block discarded – undo
1713 1713
  *     - array description de la table sinon
1714 1714
  */
1715 1715
 function spip_sqlite_showtable($nom_table, $serveur = '', $requeter = true) {
1716
-	$query =
1717
-		'SELECT sql, type FROM'
1718
-		. ' (SELECT * FROM sqlite_master UNION ALL'
1719
-		. ' SELECT * FROM sqlite_temp_master)'
1720
-		. " WHERE tbl_name LIKE '$nom_table'"
1721
-		. " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'"
1722
-		. ' ORDER BY substr(type,2,1), name';
1723
-
1724
-	$a = spip_sqlite_query($query, $serveur, $requeter);
1725
-	if (!$a) {
1726
-		return '';
1727
-	}
1728
-	if (!$requeter) {
1729
-		return $a;
1730
-	}
1731
-	if (!($a = spip_sqlite_fetch($a, null, $serveur))) {
1732
-		return '';
1733
-	}
1734
-	$vue = ($a['type'] == 'view'); // table | vue
1735
-
1736
-	// c'est une table
1737
-	// il faut parser le create
1738
-	if (!$vue) {
1739
-		if (!preg_match(_SQLITE_RE_SHOW_TABLE, array_shift($a), $r)) {
1740
-			return '';
1741
-		} else {
1742
-			$desc = $r[1];
1743
-			// extraction d'une KEY éventuelle en prenant garde de ne pas
1744
-			// relever un champ dont le nom contient KEY (ex. ID_WHISKEY)
1745
-			if (preg_match('/^(.*?),([^,]*\sKEY[ (].*)$/s', $desc, $r)) {
1746
-				$namedkeys = $r[2];
1747
-				$desc = $r[1];
1748
-			} else {
1749
-				$namedkeys = '';
1750
-			}
1751
-
1752
-			$fields = [];
1753
-			$keys = [];
1754
-
1755
-			// enlever les contenus des valeurs DEFAULT 'xxx' qui pourraient perturber
1756
-			// par exemple s'il contiennent une virgule.
1757
-			// /!\ cela peut aussi echapper le nom des champs si la table a eu des operations avec SQLite Manager !
1758
-			list($desc, $echaps) = query_echappe_textes($desc);
1759
-
1760
-			// separer toutes les descriptions de champs, separes par des virgules
1761
-			# /!\ explode peut exploser aussi DECIMAL(10,2) !
1762
-			$k_precedent = null;
1763
-			foreach (explode(',', $desc) as $v) {
1764
-				preg_match('/^\s*([^\s]+)\s+(.*)/', $v, $r);
1765
-				// Les cles de champs peuvent etre entourees
1766
-				// de guillements doubles " , simples ', graves ` ou de crochets [ ],  ou rien.
1767
-				// http://www.sqlite.org/lang_keywords.html
1768
-				$k = strtolower(query_reinjecte_textes($r[1], $echaps)); // champ, "champ", [champ]...
1769
-				if ($char = strpbrk($k[0], '\'"[`')) {
1770
-					$k = trim($k, $char);
1771
-					if ($char == '[') {
1772
-						$k = rtrim($k, ']');
1773
-					}
1774
-				}
1775
-				$def = query_reinjecte_textes($r[2], $echaps); // valeur du champ
1776
-
1777
-				// rustine pour DECIMAL(10,2)
1778
-				// s'il y a une parenthèse fermante dans la clé
1779
-				// ou dans la définition sans qu'il n'y ait une ouverture avant
1780
-				if (false !== strpos($k, ')') or preg_match('/^[^\(]*\)/', $def)) {
1781
-					$fields[$k_precedent] .= ',' . $k . ' ' . $def;
1782
-					continue;
1783
-				}
1784
-
1785
-				// la primary key peut etre dans une des descriptions de champs
1786
-				// et non en fin de table, cas encore decouvert avec Sqlite Manager
1787
-				if (stripos($r[2], 'PRIMARY KEY') !== false) {
1788
-					$keys['PRIMARY KEY'] = $k;
1789
-				}
1790
-
1791
-				$fields[$k] = $def;
1792
-				$k_precedent = $k;
1793
-			}
1794
-			// key inclues dans la requete
1795
-			foreach (preg_split('/\)\s*(,|$)/', $namedkeys) as $v) {
1796
-				if (preg_match('/^\s*([^(]*)\(([^(]*(\(\d+\))?)$/', $v, $r)) {
1797
-					$k = str_replace('`', '', trim($r[1]));
1798
-					$t = trim(strtolower(str_replace('`', '', $r[2])), '"');
1799
-					if ($k && !isset($keys[$k])) {
1800
-						$keys[$k] = $t;
1801
-					} else {
1802
-						$keys[] = $t;
1803
-					}
1804
-				}
1805
-			}
1806
-			// sinon ajouter les key index
1807
-			$query =
1808
-				'SELECT name,sql FROM'
1809
-				. ' (SELECT * FROM sqlite_master UNION ALL'
1810
-				. ' SELECT * FROM sqlite_temp_master)'
1811
-				. " WHERE tbl_name LIKE '$nom_table'"
1812
-				. " AND type='index' AND name NOT LIKE 'sqlite_%'"
1813
-				. 'ORDER BY substr(type,2,1), name';
1814
-			$a = spip_sqlite_query($query, $serveur, $requeter);
1815
-			while ($r = spip_sqlite_fetch($a, null, $serveur)) {
1816
-				$key = str_replace($nom_table . '_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1817
-				$keytype = 'KEY';
1818
-				if (strpos($r['sql'], 'UNIQUE INDEX') !== false) {
1819
-					$keytype = 'UNIQUE KEY';
1820
-				}
1821
-				$colonnes = preg_replace(',.*\((.*)\).*,', '$1', $r['sql']);
1822
-				$keys[$keytype . ' ' . $key] = $colonnes;
1823
-			}
1824
-		}
1825
-	} // c'est une vue, on liste les champs disponibles simplement
1826
-	else {
1827
-		if ($res = sql_fetsel('*', $nom_table, '', '', '', '1', '', $serveur)) { // limit 1
1828
-			$fields = [];
1829
-			foreach ($res as $c => $v) {
1830
-				$fields[$c] = '';
1831
-			}
1832
-			$keys = [];
1833
-		} else {
1834
-			return '';
1835
-		}
1836
-	}
1837
-
1838
-	return ['field' => $fields, 'key' => $keys];
1716
+    $query =
1717
+        'SELECT sql, type FROM'
1718
+        . ' (SELECT * FROM sqlite_master UNION ALL'
1719
+        . ' SELECT * FROM sqlite_temp_master)'
1720
+        . " WHERE tbl_name LIKE '$nom_table'"
1721
+        . " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'"
1722
+        . ' ORDER BY substr(type,2,1), name';
1723
+
1724
+    $a = spip_sqlite_query($query, $serveur, $requeter);
1725
+    if (!$a) {
1726
+        return '';
1727
+    }
1728
+    if (!$requeter) {
1729
+        return $a;
1730
+    }
1731
+    if (!($a = spip_sqlite_fetch($a, null, $serveur))) {
1732
+        return '';
1733
+    }
1734
+    $vue = ($a['type'] == 'view'); // table | vue
1735
+
1736
+    // c'est une table
1737
+    // il faut parser le create
1738
+    if (!$vue) {
1739
+        if (!preg_match(_SQLITE_RE_SHOW_TABLE, array_shift($a), $r)) {
1740
+            return '';
1741
+        } else {
1742
+            $desc = $r[1];
1743
+            // extraction d'une KEY éventuelle en prenant garde de ne pas
1744
+            // relever un champ dont le nom contient KEY (ex. ID_WHISKEY)
1745
+            if (preg_match('/^(.*?),([^,]*\sKEY[ (].*)$/s', $desc, $r)) {
1746
+                $namedkeys = $r[2];
1747
+                $desc = $r[1];
1748
+            } else {
1749
+                $namedkeys = '';
1750
+            }
1751
+
1752
+            $fields = [];
1753
+            $keys = [];
1754
+
1755
+            // enlever les contenus des valeurs DEFAULT 'xxx' qui pourraient perturber
1756
+            // par exemple s'il contiennent une virgule.
1757
+            // /!\ cela peut aussi echapper le nom des champs si la table a eu des operations avec SQLite Manager !
1758
+            list($desc, $echaps) = query_echappe_textes($desc);
1759
+
1760
+            // separer toutes les descriptions de champs, separes par des virgules
1761
+            # /!\ explode peut exploser aussi DECIMAL(10,2) !
1762
+            $k_precedent = null;
1763
+            foreach (explode(',', $desc) as $v) {
1764
+                preg_match('/^\s*([^\s]+)\s+(.*)/', $v, $r);
1765
+                // Les cles de champs peuvent etre entourees
1766
+                // de guillements doubles " , simples ', graves ` ou de crochets [ ],  ou rien.
1767
+                // http://www.sqlite.org/lang_keywords.html
1768
+                $k = strtolower(query_reinjecte_textes($r[1], $echaps)); // champ, "champ", [champ]...
1769
+                if ($char = strpbrk($k[0], '\'"[`')) {
1770
+                    $k = trim($k, $char);
1771
+                    if ($char == '[') {
1772
+                        $k = rtrim($k, ']');
1773
+                    }
1774
+                }
1775
+                $def = query_reinjecte_textes($r[2], $echaps); // valeur du champ
1776
+
1777
+                // rustine pour DECIMAL(10,2)
1778
+                // s'il y a une parenthèse fermante dans la clé
1779
+                // ou dans la définition sans qu'il n'y ait une ouverture avant
1780
+                if (false !== strpos($k, ')') or preg_match('/^[^\(]*\)/', $def)) {
1781
+                    $fields[$k_precedent] .= ',' . $k . ' ' . $def;
1782
+                    continue;
1783
+                }
1784
+
1785
+                // la primary key peut etre dans une des descriptions de champs
1786
+                // et non en fin de table, cas encore decouvert avec Sqlite Manager
1787
+                if (stripos($r[2], 'PRIMARY KEY') !== false) {
1788
+                    $keys['PRIMARY KEY'] = $k;
1789
+                }
1790
+
1791
+                $fields[$k] = $def;
1792
+                $k_precedent = $k;
1793
+            }
1794
+            // key inclues dans la requete
1795
+            foreach (preg_split('/\)\s*(,|$)/', $namedkeys) as $v) {
1796
+                if (preg_match('/^\s*([^(]*)\(([^(]*(\(\d+\))?)$/', $v, $r)) {
1797
+                    $k = str_replace('`', '', trim($r[1]));
1798
+                    $t = trim(strtolower(str_replace('`', '', $r[2])), '"');
1799
+                    if ($k && !isset($keys[$k])) {
1800
+                        $keys[$k] = $t;
1801
+                    } else {
1802
+                        $keys[] = $t;
1803
+                    }
1804
+                }
1805
+            }
1806
+            // sinon ajouter les key index
1807
+            $query =
1808
+                'SELECT name,sql FROM'
1809
+                . ' (SELECT * FROM sqlite_master UNION ALL'
1810
+                . ' SELECT * FROM sqlite_temp_master)'
1811
+                . " WHERE tbl_name LIKE '$nom_table'"
1812
+                . " AND type='index' AND name NOT LIKE 'sqlite_%'"
1813
+                . 'ORDER BY substr(type,2,1), name';
1814
+            $a = spip_sqlite_query($query, $serveur, $requeter);
1815
+            while ($r = spip_sqlite_fetch($a, null, $serveur)) {
1816
+                $key = str_replace($nom_table . '_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1817
+                $keytype = 'KEY';
1818
+                if (strpos($r['sql'], 'UNIQUE INDEX') !== false) {
1819
+                    $keytype = 'UNIQUE KEY';
1820
+                }
1821
+                $colonnes = preg_replace(',.*\((.*)\).*,', '$1', $r['sql']);
1822
+                $keys[$keytype . ' ' . $key] = $colonnes;
1823
+            }
1824
+        }
1825
+    } // c'est une vue, on liste les champs disponibles simplement
1826
+    else {
1827
+        if ($res = sql_fetsel('*', $nom_table, '', '', '', '1', '', $serveur)) { // limit 1
1828
+            $fields = [];
1829
+            foreach ($res as $c => $v) {
1830
+                $fields[$c] = '';
1831
+            }
1832
+            $keys = [];
1833
+        } else {
1834
+            return '';
1835
+        }
1836
+    }
1837
+
1838
+    return ['field' => $fields, 'key' => $keys];
1839 1839
 }
1840 1840
 
1841 1841
 
@@ -1861,22 +1861,22 @@  discard block
 block discarded – undo
1861 1861
  *     - array Tableau décrivant la requête et son temps d'exécution si var_profile est actif
1862 1862
  */
1863 1863
 function spip_sqlite_update($table, $champs, $where = '', $desc = '', $serveur = '', $requeter = true) {
1864
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1865
-	$champs = _sqlite_ajouter_champs_timestamp($table, $champs, $desc, $serveur);
1864
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1865
+    $champs = _sqlite_ajouter_champs_timestamp($table, $champs, $desc, $serveur);
1866 1866
 
1867
-	$set = [];
1868
-	foreach ($champs as $champ => $val) {
1869
-		$set[] = $champ . "=$val";
1870
-	}
1871
-	if (!empty($set)) {
1872
-		return spip_sqlite_query(
1873
-			_sqlite_calculer_expression('UPDATE', $table, ',')
1874
-			. _sqlite_calculer_expression('SET', $set, ',')
1875
-			. _sqlite_calculer_expression('WHERE', $where),
1876
-			$serveur,
1877
-			$requeter
1878
-		);
1879
-	}
1867
+    $set = [];
1868
+    foreach ($champs as $champ => $val) {
1869
+        $set[] = $champ . "=$val";
1870
+    }
1871
+    if (!empty($set)) {
1872
+        return spip_sqlite_query(
1873
+            _sqlite_calculer_expression('UPDATE', $table, ',')
1874
+            . _sqlite_calculer_expression('SET', $set, ',')
1875
+            . _sqlite_calculer_expression('WHERE', $where),
1876
+            $serveur,
1877
+            $requeter
1878
+        );
1879
+    }
1880 1880
 }
1881 1881
 
1882 1882
 
@@ -1906,38 +1906,38 @@  discard block
 block discarded – undo
1906 1906
  */
1907 1907
 function spip_sqlite_updateq($table, $champs, $where = '', $desc = [], $serveur = '', $requeter = true) {
1908 1908
 
1909
-	if (!$champs) {
1910
-		return;
1911
-	}
1912
-	if (!$desc) {
1913
-		$desc = description_table($table, $serveur);
1914
-	}
1915
-	if (!$desc) {
1916
-		die("$table insertion sans description");
1917
-	}
1918
-	$fields = $desc['field'];
1919
-
1920
-	$set = [];
1921
-	foreach ($champs as $champ => $val) {
1922
-		$set[$champ] = $champ . '=' . _sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
1923
-	}
1924
-
1925
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1926
-	// attention ils sont deja quotes
1927
-	$maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1928
-	foreach ($maj as $champ => $val) {
1929
-		if (!isset($set[$champ])) {
1930
-			$set[$champ] = $champ . '=' . $val;
1931
-		}
1932
-	}
1933
-
1934
-	return spip_sqlite_query(
1935
-		_sqlite_calculer_expression('UPDATE', $table, ',')
1936
-		. _sqlite_calculer_expression('SET', $set, ',')
1937
-		. _sqlite_calculer_expression('WHERE', $where),
1938
-		$serveur,
1939
-		$requeter
1940
-	);
1909
+    if (!$champs) {
1910
+        return;
1911
+    }
1912
+    if (!$desc) {
1913
+        $desc = description_table($table, $serveur);
1914
+    }
1915
+    if (!$desc) {
1916
+        die("$table insertion sans description");
1917
+    }
1918
+    $fields = $desc['field'];
1919
+
1920
+    $set = [];
1921
+    foreach ($champs as $champ => $val) {
1922
+        $set[$champ] = $champ . '=' . _sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
1923
+    }
1924
+
1925
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1926
+    // attention ils sont deja quotes
1927
+    $maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1928
+    foreach ($maj as $champ => $val) {
1929
+        if (!isset($set[$champ])) {
1930
+            $set[$champ] = $champ . '=' . $val;
1931
+        }
1932
+    }
1933
+
1934
+    return spip_sqlite_query(
1935
+        _sqlite_calculer_expression('UPDATE', $table, ',')
1936
+        . _sqlite_calculer_expression('SET', $set, ',')
1937
+        . _sqlite_calculer_expression('WHERE', $where),
1938
+        $serveur,
1939
+        $requeter
1940
+    );
1941 1941
 }
1942 1942
 
1943 1943
 
@@ -1955,17 +1955,17 @@  discard block
 block discarded – undo
1955 1955
  * @return void
1956 1956
  */
1957 1957
 function _sqlite_init() {
1958
-	if (!defined('_DIR_DB')) {
1959
-		define('_DIR_DB', _DIR_ETC . 'bases/');
1960
-	}
1961
-	if (!defined('_SQLITE_CHMOD')) {
1962
-		define('_SQLITE_CHMOD', _SPIP_CHMOD);
1963
-	}
1958
+    if (!defined('_DIR_DB')) {
1959
+        define('_DIR_DB', _DIR_ETC . 'bases/');
1960
+    }
1961
+    if (!defined('_SQLITE_CHMOD')) {
1962
+        define('_SQLITE_CHMOD', _SPIP_CHMOD);
1963
+    }
1964 1964
 
1965
-	if (!is_dir($d = _DIR_DB)) {
1966
-		include_spip('inc/flock');
1967
-		sous_repertoire($d);
1968
-	}
1965
+    if (!is_dir($d = _DIR_DB)) {
1966
+        include_spip('inc/flock');
1967
+        sous_repertoire($d);
1968
+    }
1969 1969
 }
1970 1970
 
1971 1971
 
@@ -1979,20 +1979,20 @@  discard block
 block discarded – undo
1979 1979
  * @return bool|int
1980 1980
  */
1981 1981
 function _sqlite_is_version($version = '', $link = '', $serveur = '', $requeter = true) {
1982
-	if ($link === '') {
1983
-		$link = _sqlite_link($serveur);
1984
-	}
1985
-	if (!$link) {
1986
-		return false;
1987
-	}
1982
+    if ($link === '') {
1983
+        $link = _sqlite_link($serveur);
1984
+    }
1985
+    if (!$link) {
1986
+        return false;
1987
+    }
1988 1988
 
1989
-	$v = 3;
1989
+    $v = 3;
1990 1990
 
1991
-	if (!$version) {
1992
-		return $v;
1993
-	}
1991
+    if (!$version) {
1992
+        return $v;
1993
+    }
1994 1994
 
1995
-	return ($version == $v);
1995
+    return ($version == $v);
1996 1996
 }
1997 1997
 
1998 1998
 
@@ -2003,9 +2003,9 @@  discard block
 block discarded – undo
2003 2003
  * @return Object Information de connexion pour SQLite
2004 2004
  */
2005 2005
 function _sqlite_link($serveur = '') {
2006
-	$link = &$GLOBALS['connexions'][$serveur ? $serveur : 0]['link'];
2006
+    $link = &$GLOBALS['connexions'][$serveur ? $serveur : 0]['link'];
2007 2007
 
2008
-	return $link;
2008
+    return $link;
2009 2009
 }
2010 2010
 
2011 2011
 
@@ -2020,52 +2020,52 @@  discard block
 block discarded – undo
2020 2020
  * @return string|number     Texte ou nombre échappé
2021 2021
  */
2022 2022
 function _sqlite_calculer_cite($v, $type) {
2023
-	if ($type) {
2024
-		if (
2025
-			is_null($v)
2026
-			and stripos($type, 'NOT NULL') === false
2027
-		) {
2028
-			return 'NULL';
2029
-		} // null php se traduit en NULL SQL
2030
-
2031
-		if (sql_test_date($type) and preg_match('/^\w+\(/', $v)) {
2032
-			return $v;
2033
-		}
2034
-		if (sql_test_int($type)) {
2035
-			if (is_numeric($v)) {
2036
-				return $v;
2037
-			} elseif (ctype_xdigit(substr($v, 2)) and strncmp($v, '0x', 2) == 0) {
2038
-				return hexdec(substr($v, 2));
2039
-			} else {
2040
-				return intval($v);
2041
-			}
2042
-		}
2043
-	} else {
2044
-		// si on ne connait pas le type on le deduit de $v autant que possible
2045
-		if (is_bool($v)) {
2046
-			return strval(intval($v));
2047
-		}
2048
-		elseif (is_numeric($v)) {
2049
-			return strval($v);
2050
-		}
2051
-	}
2052
-
2053
-	// trouver un link sqlite pour faire l'echappement
2054
-	foreach ($GLOBALS['connexions'] as $s) {
2055
-		if (
2056
-			$l = $s['link']
2057
-			and is_object($l)
2058
-			and $l instanceof \PDO
2059
-			and $l->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'sqlite'
2060
-		) {
2061
-			return $l->quote($v);
2062
-		}
2063
-	}
2064
-
2065
-	// echapper les ' en ''
2066
-	spip_log('Pas de methode ->quote pour echapper', 'sqlite.' . _LOG_INFO_IMPORTANTE);
2067
-
2068
-	return ("'" . str_replace("'", "''", $v) . "'");
2023
+    if ($type) {
2024
+        if (
2025
+            is_null($v)
2026
+            and stripos($type, 'NOT NULL') === false
2027
+        ) {
2028
+            return 'NULL';
2029
+        } // null php se traduit en NULL SQL
2030
+
2031
+        if (sql_test_date($type) and preg_match('/^\w+\(/', $v)) {
2032
+            return $v;
2033
+        }
2034
+        if (sql_test_int($type)) {
2035
+            if (is_numeric($v)) {
2036
+                return $v;
2037
+            } elseif (ctype_xdigit(substr($v, 2)) and strncmp($v, '0x', 2) == 0) {
2038
+                return hexdec(substr($v, 2));
2039
+            } else {
2040
+                return intval($v);
2041
+            }
2042
+        }
2043
+    } else {
2044
+        // si on ne connait pas le type on le deduit de $v autant que possible
2045
+        if (is_bool($v)) {
2046
+            return strval(intval($v));
2047
+        }
2048
+        elseif (is_numeric($v)) {
2049
+            return strval($v);
2050
+        }
2051
+    }
2052
+
2053
+    // trouver un link sqlite pour faire l'echappement
2054
+    foreach ($GLOBALS['connexions'] as $s) {
2055
+        if (
2056
+            $l = $s['link']
2057
+            and is_object($l)
2058
+            and $l instanceof \PDO
2059
+            and $l->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'sqlite'
2060
+        ) {
2061
+            return $l->quote($v);
2062
+        }
2063
+    }
2064
+
2065
+    // echapper les ' en ''
2066
+    spip_log('Pas de methode ->quote pour echapper', 'sqlite.' . _LOG_INFO_IMPORTANTE);
2067
+
2068
+    return ("'" . str_replace("'", "''", $v) . "'");
2069 2069
 }
2070 2070
 
2071 2071
 
@@ -2081,21 +2081,21 @@  discard block
 block discarded – undo
2081 2081
  * @return string            Texte de l'expression, une partie donc, du texte la requête.
2082 2082
  */
2083 2083
 function _sqlite_calculer_expression($expression, $v, $join = 'AND') {
2084
-	if (empty($v)) {
2085
-		return '';
2086
-	}
2084
+    if (empty($v)) {
2085
+        return '';
2086
+    }
2087 2087
 
2088
-	$exp = "\n$expression ";
2088
+    $exp = "\n$expression ";
2089 2089
 
2090
-	if (!is_array($v)) {
2091
-		return $exp . $v;
2092
-	} else {
2093
-		if (strtoupper($join) === 'AND') {
2094
-			return $exp . join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2095
-		} else {
2096
-			return $exp . join($join, $v);
2097
-		}
2098
-	}
2090
+    if (!is_array($v)) {
2091
+        return $exp . $v;
2092
+    } else {
2093
+        if (strtoupper($join) === 'AND') {
2094
+            return $exp . join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2095
+        } else {
2096
+            return $exp . join($join, $v);
2097
+        }
2098
+    }
2099 2099
 }
2100 2100
 
2101 2101
 
@@ -2111,7 +2111,7 @@  discard block
 block discarded – undo
2111 2111
  * @return string Texte du orderby préparé
2112 2112
  */
2113 2113
 function _sqlite_calculer_order($orderby) {
2114
-	return (is_array($orderby)) ? join(', ', $orderby) : $orderby;
2114
+    return (is_array($orderby)) ? join(', ', $orderby) : $orderby;
2115 2115
 }
2116 2116
 
2117 2117
 
@@ -2122,26 +2122,26 @@  discard block
 block discarded – undo
2122 2122
  * @return string Sélection de colonnes pour une clause SELECT
2123 2123
  */
2124 2124
 function _sqlite_calculer_select_as($args) {
2125
-	$res = '';
2126
-	foreach ($args as $k => $v) {
2127
-		if (substr($k, -1) == '@') {
2128
-			// c'est une jointure qui se refere au from precedent
2129
-			// pas de virgule
2130
-			$res .= '  ' . $v;
2131
-		} else {
2132
-			if (!is_numeric($k)) {
2133
-				$p = strpos($v, ' ');
2134
-				if ($p) {
2135
-					$v = substr($v, 0, $p) . " AS '$k'" . substr($v, $p);
2136
-				} else {
2137
-					$v .= " AS '$k'";
2138
-				}
2139
-			}
2140
-			$res .= ', ' . $v;
2141
-		}
2142
-	}
2143
-
2144
-	return substr($res, 2);
2125
+    $res = '';
2126
+    foreach ($args as $k => $v) {
2127
+        if (substr($k, -1) == '@') {
2128
+            // c'est une jointure qui se refere au from precedent
2129
+            // pas de virgule
2130
+            $res .= '  ' . $v;
2131
+        } else {
2132
+            if (!is_numeric($k)) {
2133
+                $p = strpos($v, ' ');
2134
+                if ($p) {
2135
+                    $v = substr($v, 0, $p) . " AS '$k'" . substr($v, $p);
2136
+                } else {
2137
+                    $v .= " AS '$k'";
2138
+                }
2139
+            }
2140
+            $res .= ', ' . $v;
2141
+        }
2142
+    }
2143
+
2144
+    return substr($res, 2);
2145 2145
 }
2146 2146
 
2147 2147
 
@@ -2164,26 +2164,26 @@  discard block
 block discarded – undo
2164 2164
  *     Contrainte pour clause WHERE
2165 2165
  */
2166 2166
 function _sqlite_calculer_where($v) {
2167
-	if (!is_array($v)) {
2168
-		return $v;
2169
-	}
2170
-
2171
-	$op = array_shift($v);
2172
-	if (!($n = count($v))) {
2173
-		return $op;
2174
-	} else {
2175
-		$arg = _sqlite_calculer_where(array_shift($v));
2176
-		if ($n == 1) {
2177
-			return "$op($arg)";
2178
-		} else {
2179
-			$arg2 = _sqlite_calculer_where(array_shift($v));
2180
-			if ($n == 2) {
2181
-				return "($arg $op $arg2)";
2182
-			} else {
2183
-				return "($arg $op ($arg2) : $v[0])";
2184
-			}
2185
-		}
2186
-	}
2167
+    if (!is_array($v)) {
2168
+        return $v;
2169
+    }
2170
+
2171
+    $op = array_shift($v);
2172
+    if (!($n = count($v))) {
2173
+        return $op;
2174
+    } else {
2175
+        $arg = _sqlite_calculer_where(array_shift($v));
2176
+        if ($n == 1) {
2177
+            return "$op($arg)";
2178
+        } else {
2179
+            $arg2 = _sqlite_calculer_where(array_shift($v));
2180
+            if ($n == 2) {
2181
+                return "($arg $op $arg2)";
2182
+            } else {
2183
+                return "($arg $op ($arg2) : $v[0])";
2184
+            }
2185
+        }
2186
+    }
2187 2187
 }
2188 2188
 
2189 2189
 
@@ -2198,19 +2198,19 @@  discard block
 block discarded – undo
2198 2198
  * @return array|bool
2199 2199
  */
2200 2200
 function _sqlite_charger_version($version = '') {
2201
-	$versions = [];
2201
+    $versions = [];
2202 2202
 
2203
-	// version 3
2204
-	if (!$version || $version == 3) {
2205
-		if (extension_loaded('pdo') && extension_loaded('pdo_sqlite')) {
2206
-			$versions[] = 3;
2207
-		}
2208
-	}
2209
-	if ($version) {
2210
-		return in_array($version, $versions);
2211
-	}
2203
+    // version 3
2204
+    if (!$version || $version == 3) {
2205
+        if (extension_loaded('pdo') && extension_loaded('pdo_sqlite')) {
2206
+            $versions[] = 3;
2207
+        }
2208
+    }
2209
+    if ($version) {
2210
+        return in_array($version, $versions);
2211
+    }
2212 2212
 
2213
-	return $versions;
2213
+    return $versions;
2214 2214
 }
2215 2215
 
2216 2216
 
@@ -2248,147 +2248,147 @@  discard block
 block discarded – undo
2248 2248
  */
2249 2249
 function _sqlite_modifier_table($table, $colonne, $opt = [], $serveur = '') {
2250 2250
 
2251
-	if (is_array($table)) {
2252
-		$table_destination = reset($table);
2253
-		$table_origine = key($table);
2254
-	} else {
2255
-		$table_origine = $table_destination = $table;
2256
-	}
2257
-	// ne prend actuellement qu'un changement
2258
-	// mais pourra etre adapte pour changer plus qu'une colonne a la fois
2259
-	if (is_array($colonne)) {
2260
-		$colonne_destination = reset($colonne);
2261
-		$colonne_origine = key($colonne);
2262
-	} else {
2263
-		$colonne_origine = $colonne_destination = $colonne;
2264
-	}
2265
-	if (!isset($opt['field'])) {
2266
-		$opt['field'] = [];
2267
-	}
2268
-	if (!isset($opt['key'])) {
2269
-		$opt['key'] = [];
2270
-	}
2271
-
2272
-	// si les noms de tables sont differents, pas besoin de table temporaire
2273
-	// on prendra directement le nom de la future table
2274
-	$meme_table = ($table_origine == $table_destination);
2275
-
2276
-	$def_origine = sql_showtable($table_origine, false, $serveur);
2277
-	if (!$def_origine or !isset($def_origine['field'])) {
2278
-		spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite' . _LOG_ERREUR);
2279
-
2280
-		return false;
2281
-	}
2282
-
2283
-
2284
-	$table_tmp = $table_origine . '_tmp';
2285
-
2286
-	// 1) creer une table temporaire avec les modifications
2287
-	// - DROP : suppression de la colonne
2288
-	// - CHANGE : modification de la colonne
2289
-	// (foreach pour conserver l'ordre des champs)
2290
-
2291
-	// field
2292
-	$fields = [];
2293
-	// pour le INSERT INTO plus loin
2294
-	// stocker la correspondance nouvelles->anciennes colonnes
2295
-	$fields_correspondances = [];
2296
-	foreach ($def_origine['field'] as $c => $d) {
2297
-		if ($colonne_origine && ($c == $colonne_origine)) {
2298
-			// si pas DROP
2299
-			if ($colonne_destination) {
2300
-				$fields[$colonne_destination] = $opt['field'][$colonne_destination];
2301
-				$fields_correspondances[$colonne_destination] = $c;
2302
-			}
2303
-		} else {
2304
-			$fields[$c] = $d;
2305
-			$fields_correspondances[$c] = $c;
2306
-		}
2307
-	}
2308
-	// cas de ADD sqlite2 (ajout du champ en fin de table):
2309
-	if (!$colonne_origine && $colonne_destination) {
2310
-		$fields[$colonne_destination] = $opt['field'][$colonne_destination];
2311
-	}
2312
-
2313
-	// key...
2314
-	$keys = [];
2315
-	foreach ($def_origine['key'] as $c => $d) {
2316
-		$c = str_replace($colonne_origine, $colonne_destination, $c);
2317
-		$d = str_replace($colonne_origine, $colonne_destination, $d);
2318
-		// seulement si on ne supprime pas la colonne !
2319
-		if ($d) {
2320
-			$keys[$c] = $d;
2321
-		}
2322
-	}
2323
-
2324
-	// autres keys, on merge
2325
-	$keys = array_merge($keys, $opt['key']);
2326
-	$queries = [];
2327
-
2328
-	// copier dans destination (si differente de origine), sinon tmp
2329
-	$table_copie = ($meme_table) ? $table_tmp : $table_destination;
2330
-	$autoinc = (isset($keys['PRIMARY KEY'])
2331
-		and $keys['PRIMARY KEY']
2332
-		and stripos($keys['PRIMARY KEY'], ',') === false
2333
-		and stripos($fields[$keys['PRIMARY KEY']], 'default') === false);
2334
-
2335
-	if (
2336
-		$q = _sqlite_requete_create(
2337
-			$table_copie,
2338
-			$fields,
2339
-			$keys,
2340
-			$autoinc,
2341
-			$temporary = false,
2342
-			$ifnotexists = true,
2343
-			$serveur
2344
-		)
2345
-	) {
2346
-		$queries[] = $q;
2347
-	}
2348
-
2349
-
2350
-	// 2) y copier les champs qui vont bien
2351
-	$champs_dest = join(', ', array_keys($fields_correspondances));
2352
-	$champs_ori = join(', ', $fields_correspondances);
2353
-	$queries[] = "INSERT INTO $table_copie ($champs_dest) SELECT $champs_ori FROM $table_origine";
2354
-
2355
-	// 3) supprimer la table d'origine
2356
-	$queries[] = "DROP TABLE $table_origine";
2357
-
2358
-	// 4) renommer la table temporaire
2359
-	// avec le nom de la table destination
2360
-	// si necessaire
2361
-	if ($meme_table) {
2362
-		$queries[] = "ALTER TABLE $table_copie RENAME TO $table_destination";
2363
-	}
2364
-
2365
-	// 5) remettre les index !
2366
-	foreach ($keys as $k => $v) {
2367
-		if ($k == 'PRIMARY KEY') {
2368
-		} else {
2369
-			// enlever KEY
2370
-			$k = substr($k, 4);
2371
-			$queries[] = "CREATE INDEX $table_destination" . "_$k ON $table_destination ($v)";
2372
-		}
2373
-	}
2374
-
2375
-
2376
-	if (count($queries)) {
2377
-		spip_sqlite::demarrer_transaction($serveur);
2378
-		// il faut les faire une par une car $query = join('; ', $queries).";"; ne fonctionne pas
2379
-		foreach ($queries as $q) {
2380
-			if (!spip_sqlite::executer_requete($q, $serveur)) {
2381
-				spip_log('SQLite : ALTER TABLE table :'
2382
-					. " Erreur a l'execution de la requete : $q", 'sqlite.' . _LOG_ERREUR);
2383
-				spip_sqlite::annuler_transaction($serveur);
2384
-
2385
-				return false;
2386
-			}
2387
-		}
2388
-		spip_sqlite::finir_transaction($serveur);
2389
-	}
2390
-
2391
-	return true;
2251
+    if (is_array($table)) {
2252
+        $table_destination = reset($table);
2253
+        $table_origine = key($table);
2254
+    } else {
2255
+        $table_origine = $table_destination = $table;
2256
+    }
2257
+    // ne prend actuellement qu'un changement
2258
+    // mais pourra etre adapte pour changer plus qu'une colonne a la fois
2259
+    if (is_array($colonne)) {
2260
+        $colonne_destination = reset($colonne);
2261
+        $colonne_origine = key($colonne);
2262
+    } else {
2263
+        $colonne_origine = $colonne_destination = $colonne;
2264
+    }
2265
+    if (!isset($opt['field'])) {
2266
+        $opt['field'] = [];
2267
+    }
2268
+    if (!isset($opt['key'])) {
2269
+        $opt['key'] = [];
2270
+    }
2271
+
2272
+    // si les noms de tables sont differents, pas besoin de table temporaire
2273
+    // on prendra directement le nom de la future table
2274
+    $meme_table = ($table_origine == $table_destination);
2275
+
2276
+    $def_origine = sql_showtable($table_origine, false, $serveur);
2277
+    if (!$def_origine or !isset($def_origine['field'])) {
2278
+        spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite' . _LOG_ERREUR);
2279
+
2280
+        return false;
2281
+    }
2282
+
2283
+
2284
+    $table_tmp = $table_origine . '_tmp';
2285
+
2286
+    // 1) creer une table temporaire avec les modifications
2287
+    // - DROP : suppression de la colonne
2288
+    // - CHANGE : modification de la colonne
2289
+    // (foreach pour conserver l'ordre des champs)
2290
+
2291
+    // field
2292
+    $fields = [];
2293
+    // pour le INSERT INTO plus loin
2294
+    // stocker la correspondance nouvelles->anciennes colonnes
2295
+    $fields_correspondances = [];
2296
+    foreach ($def_origine['field'] as $c => $d) {
2297
+        if ($colonne_origine && ($c == $colonne_origine)) {
2298
+            // si pas DROP
2299
+            if ($colonne_destination) {
2300
+                $fields[$colonne_destination] = $opt['field'][$colonne_destination];
2301
+                $fields_correspondances[$colonne_destination] = $c;
2302
+            }
2303
+        } else {
2304
+            $fields[$c] = $d;
2305
+            $fields_correspondances[$c] = $c;
2306
+        }
2307
+    }
2308
+    // cas de ADD sqlite2 (ajout du champ en fin de table):
2309
+    if (!$colonne_origine && $colonne_destination) {
2310
+        $fields[$colonne_destination] = $opt['field'][$colonne_destination];
2311
+    }
2312
+
2313
+    // key...
2314
+    $keys = [];
2315
+    foreach ($def_origine['key'] as $c => $d) {
2316
+        $c = str_replace($colonne_origine, $colonne_destination, $c);
2317
+        $d = str_replace($colonne_origine, $colonne_destination, $d);
2318
+        // seulement si on ne supprime pas la colonne !
2319
+        if ($d) {
2320
+            $keys[$c] = $d;
2321
+        }
2322
+    }
2323
+
2324
+    // autres keys, on merge
2325
+    $keys = array_merge($keys, $opt['key']);
2326
+    $queries = [];
2327
+
2328
+    // copier dans destination (si differente de origine), sinon tmp
2329
+    $table_copie = ($meme_table) ? $table_tmp : $table_destination;
2330
+    $autoinc = (isset($keys['PRIMARY KEY'])
2331
+        and $keys['PRIMARY KEY']
2332
+        and stripos($keys['PRIMARY KEY'], ',') === false
2333
+        and stripos($fields[$keys['PRIMARY KEY']], 'default') === false);
2334
+
2335
+    if (
2336
+        $q = _sqlite_requete_create(
2337
+            $table_copie,
2338
+            $fields,
2339
+            $keys,
2340
+            $autoinc,
2341
+            $temporary = false,
2342
+            $ifnotexists = true,
2343
+            $serveur
2344
+        )
2345
+    ) {
2346
+        $queries[] = $q;
2347
+    }
2348
+
2349
+
2350
+    // 2) y copier les champs qui vont bien
2351
+    $champs_dest = join(', ', array_keys($fields_correspondances));
2352
+    $champs_ori = join(', ', $fields_correspondances);
2353
+    $queries[] = "INSERT INTO $table_copie ($champs_dest) SELECT $champs_ori FROM $table_origine";
2354
+
2355
+    // 3) supprimer la table d'origine
2356
+    $queries[] = "DROP TABLE $table_origine";
2357
+
2358
+    // 4) renommer la table temporaire
2359
+    // avec le nom de la table destination
2360
+    // si necessaire
2361
+    if ($meme_table) {
2362
+        $queries[] = "ALTER TABLE $table_copie RENAME TO $table_destination";
2363
+    }
2364
+
2365
+    // 5) remettre les index !
2366
+    foreach ($keys as $k => $v) {
2367
+        if ($k == 'PRIMARY KEY') {
2368
+        } else {
2369
+            // enlever KEY
2370
+            $k = substr($k, 4);
2371
+            $queries[] = "CREATE INDEX $table_destination" . "_$k ON $table_destination ($v)";
2372
+        }
2373
+    }
2374
+
2375
+
2376
+    if (count($queries)) {
2377
+        spip_sqlite::demarrer_transaction($serveur);
2378
+        // il faut les faire une par une car $query = join('; ', $queries).";"; ne fonctionne pas
2379
+        foreach ($queries as $q) {
2380
+            if (!spip_sqlite::executer_requete($q, $serveur)) {
2381
+                spip_log('SQLite : ALTER TABLE table :'
2382
+                    . " Erreur a l'execution de la requete : $q", 'sqlite.' . _LOG_ERREUR);
2383
+                spip_sqlite::annuler_transaction($serveur);
2384
+
2385
+                return false;
2386
+            }
2387
+        }
2388
+        spip_sqlite::finir_transaction($serveur);
2389
+    }
2390
+
2391
+    return true;
2392 2392
 }
2393 2393
 
2394 2394
 
@@ -2398,60 +2398,60 @@  discard block
 block discarded – undo
2398 2398
  * @return array
2399 2399
  */
2400 2400
 function _sqlite_ref_fonctions() {
2401
-	$fonctions = [
2402
-		'alter' => 'spip_sqlite_alter',
2403
-		'count' => 'spip_sqlite_count',
2404
-		'countsel' => 'spip_sqlite_countsel',
2405
-		'create' => 'spip_sqlite_create',
2406
-		'create_base' => 'spip_sqlite_create_base',
2407
-		'create_view' => 'spip_sqlite_create_view',
2408
-		'date_proche' => 'spip_sqlite_date_proche',
2409
-		'delete' => 'spip_sqlite_delete',
2410
-		'drop_table' => 'spip_sqlite_drop_table',
2411
-		'drop_view' => 'spip_sqlite_drop_view',
2412
-		'errno' => 'spip_sqlite_errno',
2413
-		'error' => 'spip_sqlite_error',
2414
-		'explain' => 'spip_sqlite_explain',
2415
-		'fetch' => 'spip_sqlite_fetch',
2416
-		'seek' => 'spip_sqlite_seek',
2417
-		'free' => 'spip_sqlite_free',
2418
-		'hex' => 'spip_sqlite_hex',
2419
-		'in' => 'spip_sqlite_in',
2420
-		'insert' => 'spip_sqlite_insert',
2421
-		'insertq' => 'spip_sqlite_insertq',
2422
-		'insertq_multi' => 'spip_sqlite_insertq_multi',
2423
-		'listdbs' => 'spip_sqlite_listdbs',
2424
-		'multi' => 'spip_sqlite_multi',
2425
-		'optimize' => 'spip_sqlite_optimize',
2426
-		'query' => 'spip_sqlite_query',
2427
-		'quote' => 'spip_sqlite_quote',
2428
-		'repair' => 'spip_sqlite_repair',
2429
-		'replace' => 'spip_sqlite_replace',
2430
-		'replace_multi' => 'spip_sqlite_replace_multi',
2431
-		'select' => 'spip_sqlite_select',
2432
-		'selectdb' => 'spip_sqlite_selectdb',
2433
-		'set_charset' => 'spip_sqlite_set_charset',
2434
-		'get_charset' => 'spip_sqlite_get_charset',
2435
-		'showbase' => 'spip_sqlite_showbase',
2436
-		'showtable' => 'spip_sqlite_showtable',
2437
-		'update' => 'spip_sqlite_update',
2438
-		'updateq' => 'spip_sqlite_updateq',
2439
-		'preferer_transaction' => 'spip_sqlite_preferer_transaction',
2440
-		'demarrer_transaction' => 'spip_sqlite_demarrer_transaction',
2441
-		'terminer_transaction' => 'spip_sqlite_terminer_transaction',
2442
-	];
2443
-
2444
-	// association de chaque nom http d'un charset aux couples sqlite
2445
-	// SQLite supporte utf-8 et utf-16 uniquement.
2446
-	$charsets = [
2447
-		'utf-8' => ['charset' => 'utf8', 'collation' => 'utf8_general_ci'],
2448
-		//'utf-16be'=>array('charset'=>'utf16be','collation'=>'UTF-16BE'),// aucune idee de quoi il faut remplir dans es champs la
2449
-		//'utf-16le'=>array('charset'=>'utf16le','collation'=>'UTF-16LE')
2450
-	];
2451
-
2452
-	$fonctions['charsets'] = $charsets;
2453
-
2454
-	return $fonctions;
2401
+    $fonctions = [
2402
+        'alter' => 'spip_sqlite_alter',
2403
+        'count' => 'spip_sqlite_count',
2404
+        'countsel' => 'spip_sqlite_countsel',
2405
+        'create' => 'spip_sqlite_create',
2406
+        'create_base' => 'spip_sqlite_create_base',
2407
+        'create_view' => 'spip_sqlite_create_view',
2408
+        'date_proche' => 'spip_sqlite_date_proche',
2409
+        'delete' => 'spip_sqlite_delete',
2410
+        'drop_table' => 'spip_sqlite_drop_table',
2411
+        'drop_view' => 'spip_sqlite_drop_view',
2412
+        'errno' => 'spip_sqlite_errno',
2413
+        'error' => 'spip_sqlite_error',
2414
+        'explain' => 'spip_sqlite_explain',
2415
+        'fetch' => 'spip_sqlite_fetch',
2416
+        'seek' => 'spip_sqlite_seek',
2417
+        'free' => 'spip_sqlite_free',
2418
+        'hex' => 'spip_sqlite_hex',
2419
+        'in' => 'spip_sqlite_in',
2420
+        'insert' => 'spip_sqlite_insert',
2421
+        'insertq' => 'spip_sqlite_insertq',
2422
+        'insertq_multi' => 'spip_sqlite_insertq_multi',
2423
+        'listdbs' => 'spip_sqlite_listdbs',
2424
+        'multi' => 'spip_sqlite_multi',
2425
+        'optimize' => 'spip_sqlite_optimize',
2426
+        'query' => 'spip_sqlite_query',
2427
+        'quote' => 'spip_sqlite_quote',
2428
+        'repair' => 'spip_sqlite_repair',
2429
+        'replace' => 'spip_sqlite_replace',
2430
+        'replace_multi' => 'spip_sqlite_replace_multi',
2431
+        'select' => 'spip_sqlite_select',
2432
+        'selectdb' => 'spip_sqlite_selectdb',
2433
+        'set_charset' => 'spip_sqlite_set_charset',
2434
+        'get_charset' => 'spip_sqlite_get_charset',
2435
+        'showbase' => 'spip_sqlite_showbase',
2436
+        'showtable' => 'spip_sqlite_showtable',
2437
+        'update' => 'spip_sqlite_update',
2438
+        'updateq' => 'spip_sqlite_updateq',
2439
+        'preferer_transaction' => 'spip_sqlite_preferer_transaction',
2440
+        'demarrer_transaction' => 'spip_sqlite_demarrer_transaction',
2441
+        'terminer_transaction' => 'spip_sqlite_terminer_transaction',
2442
+    ];
2443
+
2444
+    // association de chaque nom http d'un charset aux couples sqlite
2445
+    // SQLite supporte utf-8 et utf-16 uniquement.
2446
+    $charsets = [
2447
+        'utf-8' => ['charset' => 'utf8', 'collation' => 'utf8_general_ci'],
2448
+        //'utf-16be'=>array('charset'=>'utf16be','collation'=>'UTF-16BE'),// aucune idee de quoi il faut remplir dans es champs la
2449
+        //'utf-16le'=>array('charset'=>'utf16le','collation'=>'UTF-16LE')
2450
+    ];
2451
+
2452
+    $fonctions['charsets'] = $charsets;
2453
+
2454
+    return $fonctions;
2455 2455
 }
2456 2456
 
2457 2457
 
@@ -2463,56 +2463,56 @@  discard block
 block discarded – undo
2463 2463
  * @return mixed
2464 2464
  */
2465 2465
 function _sqlite_remplacements_definitions_table($query, $autoinc = false) {
2466
-	// quelques remplacements
2467
-	$num = '(\s*\([0-9]*\))?';
2468
-	$enum = '(\s*\([^\)]*\))?';
2469
-
2470
-	$remplace = [
2471
-		'/enum' . $enum . '/is' => 'VARCHAR(255)',
2472
-		'/COLLATE \w+_bin/is' => 'COLLATE BINARY',
2473
-		'/COLLATE \w+_ci/is' => 'COLLATE NOCASE',
2474
-		'/auto_increment/is' => '',
2475
-		'/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374
2476
-		'/(timestamp .* )ON .*$/is' => '\\1',
2477
-		'/character set \w+/is' => '',
2478
-		'/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED',
2479
-		'/(text\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2480
-		'/((char|varchar)' . $num . '\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2481
-		'/(datetime\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00 00:00:00'",
2482
-		'/(date\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00'",
2483
-	];
2484
-
2485
-	// pour l'autoincrement, il faut des INTEGER NOT NULL PRIMARY KEY
2486
-	$remplace_autocinc = [
2487
-		'/(big|small|medium|tiny)?int(eger)?' . $num . '/is' => 'INTEGER'
2488
-	];
2489
-	// pour les int non autoincrement, il faut un DEFAULT
2490
-	$remplace_nonautocinc = [
2491
-		'/((big|small|medium|tiny)?int(eger)?' . $num . '\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2492
-	];
2493
-
2494
-	if (is_string($query)) {
2495
-		$query = preg_replace(array_keys($remplace), $remplace, $query);
2496
-		if ($autoinc or preg_match(',AUTO_INCREMENT,is', $query)) {
2497
-			$query = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query);
2498
-		} else {
2499
-			$query = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query);
2500
-			$query = _sqlite_collate_ci($query);
2501
-		}
2502
-	} elseif (is_array($query)) {
2503
-		foreach ($query as $k => $q) {
2504
-			$ai = ($autoinc ? $k == $autoinc : preg_match(',AUTO_INCREMENT,is', $q));
2505
-			$query[$k] = preg_replace(array_keys($remplace), $remplace, $query[$k]);
2506
-			if ($ai) {
2507
-				$query[$k] = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query[$k]);
2508
-			} else {
2509
-				$query[$k] = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query[$k]);
2510
-				$query[$k] = _sqlite_collate_ci($query[$k]);
2511
-			}
2512
-		}
2513
-	}
2514
-
2515
-	return $query;
2466
+    // quelques remplacements
2467
+    $num = '(\s*\([0-9]*\))?';
2468
+    $enum = '(\s*\([^\)]*\))?';
2469
+
2470
+    $remplace = [
2471
+        '/enum' . $enum . '/is' => 'VARCHAR(255)',
2472
+        '/COLLATE \w+_bin/is' => 'COLLATE BINARY',
2473
+        '/COLLATE \w+_ci/is' => 'COLLATE NOCASE',
2474
+        '/auto_increment/is' => '',
2475
+        '/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374
2476
+        '/(timestamp .* )ON .*$/is' => '\\1',
2477
+        '/character set \w+/is' => '',
2478
+        '/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED',
2479
+        '/(text\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2480
+        '/((char|varchar)' . $num . '\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2481
+        '/(datetime\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00 00:00:00'",
2482
+        '/(date\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00'",
2483
+    ];
2484
+
2485
+    // pour l'autoincrement, il faut des INTEGER NOT NULL PRIMARY KEY
2486
+    $remplace_autocinc = [
2487
+        '/(big|small|medium|tiny)?int(eger)?' . $num . '/is' => 'INTEGER'
2488
+    ];
2489
+    // pour les int non autoincrement, il faut un DEFAULT
2490
+    $remplace_nonautocinc = [
2491
+        '/((big|small|medium|tiny)?int(eger)?' . $num . '\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2492
+    ];
2493
+
2494
+    if (is_string($query)) {
2495
+        $query = preg_replace(array_keys($remplace), $remplace, $query);
2496
+        if ($autoinc or preg_match(',AUTO_INCREMENT,is', $query)) {
2497
+            $query = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query);
2498
+        } else {
2499
+            $query = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query);
2500
+            $query = _sqlite_collate_ci($query);
2501
+        }
2502
+    } elseif (is_array($query)) {
2503
+        foreach ($query as $k => $q) {
2504
+            $ai = ($autoinc ? $k == $autoinc : preg_match(',AUTO_INCREMENT,is', $q));
2505
+            $query[$k] = preg_replace(array_keys($remplace), $remplace, $query[$k]);
2506
+            if ($ai) {
2507
+                $query[$k] = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query[$k]);
2508
+            } else {
2509
+                $query[$k] = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query[$k]);
2510
+                $query[$k] = _sqlite_collate_ci($query[$k]);
2511
+            }
2512
+        }
2513
+    }
2514
+
2515
+    return $query;
2516 2516
 }
2517 2517
 
2518 2518
 /**
@@ -2523,17 +2523,17 @@  discard block
 block discarded – undo
2523 2523
  * @return string
2524 2524
  */
2525 2525
 function _sqlite_collate_ci($champ) {
2526
-	if (stripos($champ, 'COLLATE') !== false) {
2527
-		return $champ;
2528
-	}
2529
-	if (stripos($champ, 'BINARY') !== false) {
2530
-		return str_ireplace('BINARY', 'COLLATE BINARY', $champ);
2531
-	}
2532
-	if (preg_match(',^(char|varchar|(long|small|medium|tiny)?text),i', $champ)) {
2533
-		return $champ . ' COLLATE NOCASE';
2534
-	}
2526
+    if (stripos($champ, 'COLLATE') !== false) {
2527
+        return $champ;
2528
+    }
2529
+    if (stripos($champ, 'BINARY') !== false) {
2530
+        return str_ireplace('BINARY', 'COLLATE BINARY', $champ);
2531
+    }
2532
+    if (preg_match(',^(char|varchar|(long|small|medium|tiny)?text),i', $champ)) {
2533
+        return $champ . ' COLLATE NOCASE';
2534
+    }
2535 2535
 
2536
-	return $champ;
2536
+    return $champ;
2537 2537
 }
2538 2538
 
2539 2539
 
@@ -2552,84 +2552,84 @@  discard block
 block discarded – undo
2552 2552
  * @return bool|string
2553 2553
  */
2554 2554
 function _sqlite_requete_create(
2555
-	$nom,
2556
-	$champs,
2557
-	$cles,
2558
-	$autoinc = false,
2559
-	$temporary = false,
2560
-	$_ifnotexists = true,
2561
-	$serveur = '',
2562
-	$requeter = true
2555
+    $nom,
2556
+    $champs,
2557
+    $cles,
2558
+    $autoinc = false,
2559
+    $temporary = false,
2560
+    $_ifnotexists = true,
2561
+    $serveur = '',
2562
+    $requeter = true
2563 2563
 ) {
2564
-	$query = $keys = $s = $p = '';
2565
-
2566
-	// certains plugins declarent les tables  (permet leur inclusion dans le dump)
2567
-	// sans les renseigner (laisse le compilo recuperer la description)
2568
-	if (!is_array($champs) || !is_array($cles)) {
2569
-		return;
2570
-	}
2571
-
2572
-	// sqlite ne gere pas KEY tout court dans une requete CREATE TABLE
2573
-	// il faut passer par des create index
2574
-	// Il gere par contre primary key !
2575
-	// Soit la PK est definie dans les cles, soit dans un champs
2576
-	// soit faussement dans les 2 (et dans ce cas, il faut l’enlever à un des 2 endroits !)
2577
-	$pk = 'PRIMARY KEY';
2578
-	// le champ de cle primaire
2579
-	$champ_pk = !empty($cles[$pk]) ? $cles[$pk] : '';
2580
-
2581
-	foreach ($champs as $k => $v) {
2582
-		if (false !== stripos($v, $pk)) {
2583
-			$champ_pk = $k;
2584
-			// on n'en a plus besoin dans field, vu que defini dans key
2585
-			$champs[$k] = preg_replace("/$pk/is", '', $champs[$k]);
2586
-			break;
2587
-		}
2588
-	}
2589
-
2590
-	if ($champ_pk) {
2591
-		$keys = "\n\t\t$pk ($champ_pk)";
2592
-	}
2593
-	// Pas de DEFAULT 0 sur les cles primaires en auto-increment
2594
-	if (
2595
-		isset($champs[$champ_pk])
2596
-		and stripos($champs[$champ_pk], 'default 0') !== false
2597
-	) {
2598
-		$champs[$champ_pk] = trim(str_ireplace('default 0', '', $champs[$champ_pk]));
2599
-	}
2600
-
2601
-	$champs = _sqlite_remplacements_definitions_table($champs, $autoinc ? $champ_pk : false);
2602
-	foreach ($champs as $k => $v) {
2603
-		$query .= "$s\n\t\t$k $v";
2604
-		$s = ',';
2605
-	}
2606
-
2607
-	$ifnotexists = '';
2608
-	if ($_ifnotexists) {
2609
-		$version = spip_sqlite_fetch(
2610
-			spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur),
2611
-			'',
2612
-			$serveur
2613
-		);
2614
-		if (!function_exists('spip_version_compare')) {
2615
-			include_spip('plugins/installer');
2616
-		}
2617
-
2618
-		if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
2619
-			$ifnotexists = ' IF NOT EXISTS';
2620
-		} else {
2621
-			/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
2622
-			$a = spip_sqlite_showtable($nom, $serveur);
2623
-			if (isset($a['key']['KEY ' . $nom])) {
2624
-				return true;
2625
-			}
2626
-		}
2627
-	}
2628
-
2629
-	$temporary = $temporary ? ' TEMPORARY' : '';
2630
-	$q = "CREATE$temporary TABLE$ifnotexists $nom ($query" . ($keys ? ",$keys" : '') . ")\n";
2631
-
2632
-	return $q;
2564
+    $query = $keys = $s = $p = '';
2565
+
2566
+    // certains plugins declarent les tables  (permet leur inclusion dans le dump)
2567
+    // sans les renseigner (laisse le compilo recuperer la description)
2568
+    if (!is_array($champs) || !is_array($cles)) {
2569
+        return;
2570
+    }
2571
+
2572
+    // sqlite ne gere pas KEY tout court dans une requete CREATE TABLE
2573
+    // il faut passer par des create index
2574
+    // Il gere par contre primary key !
2575
+    // Soit la PK est definie dans les cles, soit dans un champs
2576
+    // soit faussement dans les 2 (et dans ce cas, il faut l’enlever à un des 2 endroits !)
2577
+    $pk = 'PRIMARY KEY';
2578
+    // le champ de cle primaire
2579
+    $champ_pk = !empty($cles[$pk]) ? $cles[$pk] : '';
2580
+
2581
+    foreach ($champs as $k => $v) {
2582
+        if (false !== stripos($v, $pk)) {
2583
+            $champ_pk = $k;
2584
+            // on n'en a plus besoin dans field, vu que defini dans key
2585
+            $champs[$k] = preg_replace("/$pk/is", '', $champs[$k]);
2586
+            break;
2587
+        }
2588
+    }
2589
+
2590
+    if ($champ_pk) {
2591
+        $keys = "\n\t\t$pk ($champ_pk)";
2592
+    }
2593
+    // Pas de DEFAULT 0 sur les cles primaires en auto-increment
2594
+    if (
2595
+        isset($champs[$champ_pk])
2596
+        and stripos($champs[$champ_pk], 'default 0') !== false
2597
+    ) {
2598
+        $champs[$champ_pk] = trim(str_ireplace('default 0', '', $champs[$champ_pk]));
2599
+    }
2600
+
2601
+    $champs = _sqlite_remplacements_definitions_table($champs, $autoinc ? $champ_pk : false);
2602
+    foreach ($champs as $k => $v) {
2603
+        $query .= "$s\n\t\t$k $v";
2604
+        $s = ',';
2605
+    }
2606
+
2607
+    $ifnotexists = '';
2608
+    if ($_ifnotexists) {
2609
+        $version = spip_sqlite_fetch(
2610
+            spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur),
2611
+            '',
2612
+            $serveur
2613
+        );
2614
+        if (!function_exists('spip_version_compare')) {
2615
+            include_spip('plugins/installer');
2616
+        }
2617
+
2618
+        if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
2619
+            $ifnotexists = ' IF NOT EXISTS';
2620
+        } else {
2621
+            /* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
2622
+            $a = spip_sqlite_showtable($nom, $serveur);
2623
+            if (isset($a['key']['KEY ' . $nom])) {
2624
+                return true;
2625
+            }
2626
+        }
2627
+    }
2628
+
2629
+    $temporary = $temporary ? ' TEMPORARY' : '';
2630
+    $q = "CREATE$temporary TABLE$ifnotexists $nom ($query" . ($keys ? ",$keys" : '') . ")\n";
2631
+
2632
+    return $q;
2633 2633
 }
2634 2634
 
2635 2635
 
@@ -2648,41 +2648,41 @@  discard block
 block discarded – undo
2648 2648
  * @return
2649 2649
  */
2650 2650
 function _sqlite_ajouter_champs_timestamp($table, $couples, $desc = '', $serveur = '') {
2651
-	static $tables = [];
2652
-
2653
-	if (!isset($tables[$table])) {
2654
-		if (!$desc) {
2655
-			$trouver_table = charger_fonction('trouver_table', 'base');
2656
-			$desc = $trouver_table($table, $serveur);
2657
-			// si pas de description, on ne fait rien, ou on die() ?
2658
-			if (!$desc) {
2659
-				return $couples;
2660
-			}
2661
-		}
2662
-
2663
-		// recherche des champs avec simplement 'TIMESTAMP'
2664
-		// cependant, il faudra peut etre etendre
2665
-		// avec la gestion de DEFAULT et ON UPDATE
2666
-		// mais ceux-ci ne sont pas utilises dans le core
2667
-		$tables[$table] = ['valeur' => [], 'cite' => [], 'desc' => []];
2668
-
2669
-		$now = _sqlite_func_now(true);
2670
-		foreach ($desc['field'] as $k => $v) {
2671
-			if (strpos(strtolower(ltrim($v)), 'timestamp') === 0) {
2672
-				$tables[$table]['desc'][$k] = $v;
2673
-				$tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2674
-			}
2675
-		}
2676
-	}
2677
-	else {
2678
-		$now = _sqlite_func_now(true);
2679
-		foreach (array_keys($tables[$table]['desc']) as $k) {
2680
-			$tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2681
-		}
2682
-	}
2683
-
2684
-	// ajout des champs type 'timestamp' absents
2685
-	return array_merge($tables[$table]['valeur'], $couples);
2651
+    static $tables = [];
2652
+
2653
+    if (!isset($tables[$table])) {
2654
+        if (!$desc) {
2655
+            $trouver_table = charger_fonction('trouver_table', 'base');
2656
+            $desc = $trouver_table($table, $serveur);
2657
+            // si pas de description, on ne fait rien, ou on die() ?
2658
+            if (!$desc) {
2659
+                return $couples;
2660
+            }
2661
+        }
2662
+
2663
+        // recherche des champs avec simplement 'TIMESTAMP'
2664
+        // cependant, il faudra peut etre etendre
2665
+        // avec la gestion de DEFAULT et ON UPDATE
2666
+        // mais ceux-ci ne sont pas utilises dans le core
2667
+        $tables[$table] = ['valeur' => [], 'cite' => [], 'desc' => []];
2668
+
2669
+        $now = _sqlite_func_now(true);
2670
+        foreach ($desc['field'] as $k => $v) {
2671
+            if (strpos(strtolower(ltrim($v)), 'timestamp') === 0) {
2672
+                $tables[$table]['desc'][$k] = $v;
2673
+                $tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2674
+            }
2675
+        }
2676
+    }
2677
+    else {
2678
+        $now = _sqlite_func_now(true);
2679
+        foreach (array_keys($tables[$table]['desc']) as $k) {
2680
+            $tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2681
+        }
2682
+    }
2683
+
2684
+    // ajout des champs type 'timestamp' absents
2685
+    return array_merge($tables[$table]['valeur'], $couples);
2686 2686
 }
2687 2687
 
2688 2688
 
@@ -2693,7 +2693,7 @@  discard block
 block discarded – undo
2693 2693
  * @return array|bool
2694 2694
  */
2695 2695
 function spip_versions_sqlite() {
2696
-	return _sqlite_charger_version();
2696
+    return _sqlite_charger_version();
2697 2697
 }
2698 2698
 
2699 2699
 /**
@@ -2701,114 +2701,114 @@  discard block
 block discarded – undo
2701 2701
  * encadrées de transactions.
2702 2702
  **/
2703 2703
 class spip_sqlite {
2704
-	/** @var sqlite_requeteur[] Liste des instances de requêteurs créés */
2705
-	public static $requeteurs = [];
2706
-	/** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */
2707
-	public static $transaction_en_cours = [];
2708
-
2709
-
2710
-	/**
2711
-	 * Retourne une unique instance du requêteur
2712
-	 *
2713
-	 * Retourne une instance unique du requêteur pour une connexion SQLite
2714
-	 * donnée
2715
-	 *
2716
-	 * @param string $serveur
2717
-	 *    Nom du connecteur
2718
-	 * @return sqlite_requeteur
2719
-	 *    Instance unique du requêteur
2720
-	 **/
2721
-	public static function requeteur($serveur) {
2722
-		if (!isset(spip_sqlite::$requeteurs[$serveur])) {
2723
-			spip_sqlite::$requeteurs[$serveur] = new sqlite_requeteur($serveur);
2724
-		}
2725
-
2726
-		return spip_sqlite::$requeteurs[$serveur];
2727
-	}
2728
-
2729
-	/**
2730
-	 * Prépare le texte d'une requête avant son exécution
2731
-	 *
2732
-	 * Adapte la requête au format plus ou moins MySQL par un format
2733
-	 * compris de SQLite.
2734
-	 *
2735
-	 * Change les préfixes de tables SPIP par ceux véritables
2736
-	 *
2737
-	 * @param string $query Requête à préparer
2738
-	 * @param string $serveur Nom de la connexion
2739
-	 * @return string           Requête préparée
2740
-	 */
2741
-	public static function traduire_requete($query, $serveur) {
2742
-		$requeteur = spip_sqlite::requeteur($serveur);
2743
-		$traducteur = new sqlite_traducteur($query, $requeteur->prefixe, $requeteur->sqlite_version);
2744
-
2745
-		return $traducteur->traduire_requete();
2746
-	}
2747
-
2748
-	/**
2749
-	 * Démarre une transaction
2750
-	 *
2751
-	 * @param string $serveur Nom de la connexion
2752
-	 **/
2753
-	public static function demarrer_transaction($serveur) {
2754
-		spip_sqlite::executer_requete('BEGIN TRANSACTION', $serveur);
2755
-		spip_sqlite::$transaction_en_cours[$serveur] = true;
2756
-	}
2757
-
2758
-	/**
2759
-	 * Exécute la requête donnée
2760
-	 *
2761
-	 * @param string $query Requête
2762
-	 * @param string $serveur Nom de la connexion
2763
-	 * @param null|bool $tracer Demander des statistiques (temps) ?
2764
-	 **/
2765
-	public static function executer_requete($query, $serveur, $tracer = null) {
2766
-		$requeteur = spip_sqlite::requeteur($serveur);
2767
-
2768
-		return $requeteur->executer_requete($query, $tracer);
2769
-	}
2770
-
2771
-	/**
2772
-	 * Obtient l'identifiant de la dernière ligne insérée ou modifiée
2773
-	 *
2774
-	 * @param string $serveur Nom de la connexion
2775
-	 * return int                Identifiant
2776
-	 **/
2777
-	public static function last_insert_id($serveur) {
2778
-		$requeteur = spip_sqlite::requeteur($serveur);
2779
-
2780
-		return $requeteur->last_insert_id($serveur);
2781
-	}
2782
-
2783
-	/**
2784
-	 * Annule une transaction
2785
-	 *
2786
-	 * @param string $serveur Nom de la connexion
2787
-	 **/
2788
-	public static function annuler_transaction($serveur) {
2789
-		spip_sqlite::executer_requete('ROLLBACK', $serveur);
2790
-		spip_sqlite::$transaction_en_cours[$serveur] = false;
2791
-	}
2792
-
2793
-	/**
2794
-	 * Termine une transaction
2795
-	 *
2796
-	 * @param string $serveur Nom de la connexion
2797
-	 **/
2798
-	public static function finir_transaction($serveur) {
2799
-		// si pas de transaction en cours, ne rien faire et le dire
2800
-		if (
2801
-			!isset(spip_sqlite::$transaction_en_cours[$serveur])
2802
-			or spip_sqlite::$transaction_en_cours[$serveur] == false
2803
-		) {
2804
-			return false;
2805
-		}
2806
-		// sinon fermer la transaction et retourner true
2807
-		spip_sqlite::executer_requete('COMMIT', $serveur);
2808
-		spip_sqlite::$transaction_en_cours[$serveur] = false;
2809
-
2810
-		return true;
2811
-	}
2704
+    /** @var sqlite_requeteur[] Liste des instances de requêteurs créés */
2705
+    public static $requeteurs = [];
2706
+    /** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */
2707
+    public static $transaction_en_cours = [];
2708
+
2709
+
2710
+    /**
2711
+     * Retourne une unique instance du requêteur
2712
+     *
2713
+     * Retourne une instance unique du requêteur pour une connexion SQLite
2714
+     * donnée
2715
+     *
2716
+     * @param string $serveur
2717
+     *    Nom du connecteur
2718
+     * @return sqlite_requeteur
2719
+     *    Instance unique du requêteur
2720
+     **/
2721
+    public static function requeteur($serveur) {
2722
+        if (!isset(spip_sqlite::$requeteurs[$serveur])) {
2723
+            spip_sqlite::$requeteurs[$serveur] = new sqlite_requeteur($serveur);
2724
+        }
2725
+
2726
+        return spip_sqlite::$requeteurs[$serveur];
2727
+    }
2728
+
2729
+    /**
2730
+     * Prépare le texte d'une requête avant son exécution
2731
+     *
2732
+     * Adapte la requête au format plus ou moins MySQL par un format
2733
+     * compris de SQLite.
2734
+     *
2735
+     * Change les préfixes de tables SPIP par ceux véritables
2736
+     *
2737
+     * @param string $query Requête à préparer
2738
+     * @param string $serveur Nom de la connexion
2739
+     * @return string           Requête préparée
2740
+     */
2741
+    public static function traduire_requete($query, $serveur) {
2742
+        $requeteur = spip_sqlite::requeteur($serveur);
2743
+        $traducteur = new sqlite_traducteur($query, $requeteur->prefixe, $requeteur->sqlite_version);
2744
+
2745
+        return $traducteur->traduire_requete();
2746
+    }
2747
+
2748
+    /**
2749
+     * Démarre une transaction
2750
+     *
2751
+     * @param string $serveur Nom de la connexion
2752
+     **/
2753
+    public static function demarrer_transaction($serveur) {
2754
+        spip_sqlite::executer_requete('BEGIN TRANSACTION', $serveur);
2755
+        spip_sqlite::$transaction_en_cours[$serveur] = true;
2756
+    }
2757
+
2758
+    /**
2759
+     * Exécute la requête donnée
2760
+     *
2761
+     * @param string $query Requête
2762
+     * @param string $serveur Nom de la connexion
2763
+     * @param null|bool $tracer Demander des statistiques (temps) ?
2764
+     **/
2765
+    public static function executer_requete($query, $serveur, $tracer = null) {
2766
+        $requeteur = spip_sqlite::requeteur($serveur);
2767
+
2768
+        return $requeteur->executer_requete($query, $tracer);
2769
+    }
2770
+
2771
+    /**
2772
+     * Obtient l'identifiant de la dernière ligne insérée ou modifiée
2773
+     *
2774
+     * @param string $serveur Nom de la connexion
2775
+     * return int                Identifiant
2776
+     **/
2777
+    public static function last_insert_id($serveur) {
2778
+        $requeteur = spip_sqlite::requeteur($serveur);
2779
+
2780
+        return $requeteur->last_insert_id($serveur);
2781
+    }
2782
+
2783
+    /**
2784
+     * Annule une transaction
2785
+     *
2786
+     * @param string $serveur Nom de la connexion
2787
+     **/
2788
+    public static function annuler_transaction($serveur) {
2789
+        spip_sqlite::executer_requete('ROLLBACK', $serveur);
2790
+        spip_sqlite::$transaction_en_cours[$serveur] = false;
2791
+    }
2792
+
2793
+    /**
2794
+     * Termine une transaction
2795
+     *
2796
+     * @param string $serveur Nom de la connexion
2797
+     **/
2798
+    public static function finir_transaction($serveur) {
2799
+        // si pas de transaction en cours, ne rien faire et le dire
2800
+        if (
2801
+            !isset(spip_sqlite::$transaction_en_cours[$serveur])
2802
+            or spip_sqlite::$transaction_en_cours[$serveur] == false
2803
+        ) {
2804
+            return false;
2805
+        }
2806
+        // sinon fermer la transaction et retourner true
2807
+        spip_sqlite::executer_requete('COMMIT', $serveur);
2808
+        spip_sqlite::$transaction_en_cours[$serveur] = false;
2809
+
2810
+        return true;
2811
+    }
2812 2812
 }
2813 2813
 
2814 2814
 /*
@@ -2821,127 +2821,127 @@  discard block
 block discarded – undo
2821 2821
  */
2822 2822
 
2823 2823
 class sqlite_requeteur {
2824
-	/** @var string Texte de la requête */
2825
-	public $query = ''; // la requete
2826
-	/** @var string Nom de la connexion */
2827
-	public $serveur = '';
2828
-	/** @var Ressource Identifiant de la connexion SQLite */
2829
-	public $link = '';
2830
-	/** @var string Prefixe des tables SPIP */
2831
-	public $prefixe = '';
2832
-	/** @var string Nom de la base de donnée */
2833
-	public $db = '';
2834
-	/** @var bool Doit-on tracer les requetes (var_profile) ? */
2835
-	public $tracer = false; // doit-on tracer les requetes (var_profile)
2836
-
2837
-	/** @var string Version de SQLite (2 ou 3) */
2838
-	public $sqlite_version = '';
2839
-
2840
-	/**
2841
-	 * Constructeur
2842
-	 *
2843
-	 * @param string $serveur
2844
-	 * @return bool
2845
-	 */
2846
-	public function __construct($serveur = '') {
2847
-		_sqlite_init();
2848
-		$this->serveur = strtolower($serveur);
2849
-
2850
-		if (!($this->link = _sqlite_link($this->serveur)) && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)) {
2851
-			spip_log('Aucune connexion sqlite (link)', 'sqlite.' . _LOG_ERREUR);
2852
-
2853
-			return false;
2854
-		}
2855
-
2856
-		$this->sqlite_version = _sqlite_is_version('', $this->link);
2857
-
2858
-		$this->prefixe = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['prefixe'];
2859
-		$this->db = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['db'];
2860
-
2861
-		// tracage des requetes ?
2862
-		$this->tracer = (isset($_GET['var_profile']) && $_GET['var_profile']);
2863
-	}
2864
-
2865
-	/**
2866
-	 * Lancer la requête transmise et faire le tracage si demandé
2867
-	 *
2868
-	 * @param string $query
2869
-	 *     Requête à exécuter
2870
-	 * @param bool|null $tracer
2871
-	 *     true pour tracer la requête
2872
-	 * @return bool|SQLiteResult
2873
-	 */
2874
-	public function executer_requete($query, $tracer = null) {
2875
-		if (is_null($tracer)) {
2876
-			$tracer = $this->tracer;
2877
-		}
2878
-		$err = '';
2879
-		$t = 0;
2880
-		if ($tracer or (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES)) {
2881
-			include_spip('public/tracer');
2882
-			$t = trace_query_start();
2883
-		}
2884
-
2885
-		# spip_log("requete: $this->serveur >> $query",'sqlite.'._LOG_DEBUG); // boum ? pourquoi ?
2886
-		if ($this->link) {
2887
-			// memoriser la derniere erreur PHP vue
2888
-			$last_error = (function_exists('error_get_last') ? error_get_last() : '');
2889
-			$e = null;
2890
-			// sauver la derniere requete
2891
-			$GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['last'] = $query;
2892
-			$GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['total_requetes']++;
2893
-
2894
-			try {
2895
-				$r = $this->link->query($query);
2896
-			} catch (\PDOException $e) {
2897
-				spip_log('PDOException: ' . $e->getMessage(), 'sqlite.' . _LOG_DEBUG);
2898
-				$r = false;
2899
-			}
2900
-			// sauvegarde de la requete (elle y est deja dans $r->queryString)
2901
-			# $r->spipQueryString = $query;
2902
-
2903
-			// comptage : oblige de compter le nombre d'entrees retournees
2904
-			// par une requete SELECT
2905
-			// aucune autre solution ne donne le nombre attendu :( !
2906
-			// particulierement s'il y a des LIMIT dans la requete.
2907
-			if (strtoupper(substr(ltrim($query), 0, 6)) == 'SELECT') {
2908
-				if ($r) {
2909
-					// noter le link et la query pour faire le comptage *si* on en a besoin
2910
-					$r->spipSqliteRowCount = [$this->link, $query];
2911
-				} elseif ($r instanceof PDOStatement) {
2912
-					$r->spipSqliteRowCount = 0;
2913
-				}
2914
-			}
2915
-
2916
-			// loger les warnings/erreurs eventuels de sqlite remontant dans PHP
2917
-			if ($e and $e instanceof \PDOException) {
2918
-				$err = strip_tags($e->getMessage()) . ' in ' . $e->getFile() . ' line ' . $e->getLine();
2919
-				spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR);
2920
-			} elseif ($err = (function_exists('error_get_last') ? error_get_last() : '') and $err != $last_error) {
2921
-				$err = strip_tags($err['message']) . ' in ' . $err['file'] . ' line ' . $err['line'];
2922
-				spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR);
2923
-			} else {
2924
-				$err = '';
2925
-			}
2926
-		} else {
2927
-			$r = false;
2928
-		}
2929
-
2930
-		if (spip_sqlite_errno($this->serveur)) {
2931
-			$err .= spip_sqlite_error($query, $this->serveur);
2932
-		}
2933
-
2934
-		return $t ? trace_query_end($query, $t, $r, $err, $this->serveur) : $r;
2935
-	}
2936
-
2937
-	/**
2938
-	 * Obtient l'identifiant de la dernière ligne insérée ou modifiée
2939
-	 *
2940
-	 * @return int
2941
-	 **/
2942
-	public function last_insert_id() {
2943
-		return $this->link->lastInsertId();
2944
-	}
2824
+    /** @var string Texte de la requête */
2825
+    public $query = ''; // la requete
2826
+    /** @var string Nom de la connexion */
2827
+    public $serveur = '';
2828
+    /** @var Ressource Identifiant de la connexion SQLite */
2829
+    public $link = '';
2830
+    /** @var string Prefixe des tables SPIP */
2831
+    public $prefixe = '';
2832
+    /** @var string Nom de la base de donnée */
2833
+    public $db = '';
2834
+    /** @var bool Doit-on tracer les requetes (var_profile) ? */
2835
+    public $tracer = false; // doit-on tracer les requetes (var_profile)
2836
+
2837
+    /** @var string Version de SQLite (2 ou 3) */
2838
+    public $sqlite_version = '';
2839
+
2840
+    /**
2841
+     * Constructeur
2842
+     *
2843
+     * @param string $serveur
2844
+     * @return bool
2845
+     */
2846
+    public function __construct($serveur = '') {
2847
+        _sqlite_init();
2848
+        $this->serveur = strtolower($serveur);
2849
+
2850
+        if (!($this->link = _sqlite_link($this->serveur)) && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)) {
2851
+            spip_log('Aucune connexion sqlite (link)', 'sqlite.' . _LOG_ERREUR);
2852
+
2853
+            return false;
2854
+        }
2855
+
2856
+        $this->sqlite_version = _sqlite_is_version('', $this->link);
2857
+
2858
+        $this->prefixe = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['prefixe'];
2859
+        $this->db = $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['db'];
2860
+
2861
+        // tracage des requetes ?
2862
+        $this->tracer = (isset($_GET['var_profile']) && $_GET['var_profile']);
2863
+    }
2864
+
2865
+    /**
2866
+     * Lancer la requête transmise et faire le tracage si demandé
2867
+     *
2868
+     * @param string $query
2869
+     *     Requête à exécuter
2870
+     * @param bool|null $tracer
2871
+     *     true pour tracer la requête
2872
+     * @return bool|SQLiteResult
2873
+     */
2874
+    public function executer_requete($query, $tracer = null) {
2875
+        if (is_null($tracer)) {
2876
+            $tracer = $this->tracer;
2877
+        }
2878
+        $err = '';
2879
+        $t = 0;
2880
+        if ($tracer or (defined('_DEBUG_TRACE_QUERIES') and _DEBUG_TRACE_QUERIES)) {
2881
+            include_spip('public/tracer');
2882
+            $t = trace_query_start();
2883
+        }
2884
+
2885
+        # spip_log("requete: $this->serveur >> $query",'sqlite.'._LOG_DEBUG); // boum ? pourquoi ?
2886
+        if ($this->link) {
2887
+            // memoriser la derniere erreur PHP vue
2888
+            $last_error = (function_exists('error_get_last') ? error_get_last() : '');
2889
+            $e = null;
2890
+            // sauver la derniere requete
2891
+            $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['last'] = $query;
2892
+            $GLOBALS['connexions'][$this->serveur ? $this->serveur : 0]['total_requetes']++;
2893
+
2894
+            try {
2895
+                $r = $this->link->query($query);
2896
+            } catch (\PDOException $e) {
2897
+                spip_log('PDOException: ' . $e->getMessage(), 'sqlite.' . _LOG_DEBUG);
2898
+                $r = false;
2899
+            }
2900
+            // sauvegarde de la requete (elle y est deja dans $r->queryString)
2901
+            # $r->spipQueryString = $query;
2902
+
2903
+            // comptage : oblige de compter le nombre d'entrees retournees
2904
+            // par une requete SELECT
2905
+            // aucune autre solution ne donne le nombre attendu :( !
2906
+            // particulierement s'il y a des LIMIT dans la requete.
2907
+            if (strtoupper(substr(ltrim($query), 0, 6)) == 'SELECT') {
2908
+                if ($r) {
2909
+                    // noter le link et la query pour faire le comptage *si* on en a besoin
2910
+                    $r->spipSqliteRowCount = [$this->link, $query];
2911
+                } elseif ($r instanceof PDOStatement) {
2912
+                    $r->spipSqliteRowCount = 0;
2913
+                }
2914
+            }
2915
+
2916
+            // loger les warnings/erreurs eventuels de sqlite remontant dans PHP
2917
+            if ($e and $e instanceof \PDOException) {
2918
+                $err = strip_tags($e->getMessage()) . ' in ' . $e->getFile() . ' line ' . $e->getLine();
2919
+                spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR);
2920
+            } elseif ($err = (function_exists('error_get_last') ? error_get_last() : '') and $err != $last_error) {
2921
+                $err = strip_tags($err['message']) . ' in ' . $err['file'] . ' line ' . $err['line'];
2922
+                spip_log("$err - " . $query, 'sqlite.' . _LOG_ERREUR);
2923
+            } else {
2924
+                $err = '';
2925
+            }
2926
+        } else {
2927
+            $r = false;
2928
+        }
2929
+
2930
+        if (spip_sqlite_errno($this->serveur)) {
2931
+            $err .= spip_sqlite_error($query, $this->serveur);
2932
+        }
2933
+
2934
+        return $t ? trace_query_end($query, $t, $r, $err, $this->serveur) : $r;
2935
+    }
2936
+
2937
+    /**
2938
+     * Obtient l'identifiant de la dernière ligne insérée ou modifiée
2939
+     *
2940
+     * @return int
2941
+     **/
2942
+    public function last_insert_id() {
2943
+        return $this->link->lastInsertId();
2944
+    }
2945 2945
 }
2946 2946
 
2947 2947
 
@@ -2951,206 +2951,206 @@  discard block
 block discarded – undo
2951 2951
  * (fonction pour proteger les textes)
2952 2952
  */
2953 2953
 class sqlite_traducteur {
2954
-	/** @var string $query Texte de la requête */
2955
-	public $query = '';
2956
-	/** @var string $prefixe Préfixe des tables */
2957
-	public $prefixe = '';
2958
-	/** @var string $sqlite_version Version de sqlite (2 ou 3) */
2959
-	public $sqlite_version = '';
2960
-
2961
-	/** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé
2962
-	 *
2963
-	 * @var array
2964
-	 */
2965
-	public $textes = [];
2966
-
2967
-	/**
2968
-	 * Constructeur
2969
-	 *
2970
-	 * @param string $query Requête à préparer
2971
-	 * @param string $prefixe Prefixe des tables à utiliser
2972
-	 * @param string $sqlite_version Version SQLite (2 ou 3)
2973
-	 */
2974
-	public function __construct($query, $prefixe, $sqlite_version) {
2975
-		$this->query = $query;
2976
-		$this->prefixe = $prefixe;
2977
-		$this->sqlite_version = $sqlite_version;
2978
-	}
2979
-
2980
-	/**
2981
-	 * Transformer la requete pour SQLite
2982
-	 *
2983
-	 * Enlève les textes, transforme la requête pour quelle soit
2984
-	 * bien interprétée par SQLite, puis remet les textes
2985
-	 * la fonction affecte `$this->query`
2986
-	 */
2987
-	public function traduire_requete() {
2988
-		//
2989
-		// 1) Protection des textes en les remplacant par des codes
2990
-		//
2991
-		// enlever les 'textes' et initialiser avec
2992
-		list($this->query, $textes) = query_echappe_textes($this->query);
2993
-
2994
-		//
2995
-		// 2) Corrections de la requete
2996
-		//
2997
-		// Correction Create Database
2998
-		// Create Database -> requete ignoree
2999
-		if (strpos($this->query, 'CREATE DATABASE') === 0) {
3000
-			spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT);
3001
-			$this->query = 'SELECT 1';
3002
-		}
3003
-
3004
-		// Correction Insert Ignore
3005
-		// INSERT IGNORE -> insert (tout court et pas 'insert or replace')
3006
-		if (strpos($this->query, 'INSERT IGNORE') === 0) {
3007
-			spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG);
3008
-			$this->query = 'INSERT ' . substr($this->query, '13');
3009
-		}
3010
-
3011
-		// Correction des dates avec INTERVAL
3012
-		// utiliser sql_date_proche() de preference
3013
-		if (strpos($this->query, 'INTERVAL') !== false) {
3014
-			$this->query = preg_replace_callback(
3015
-				'/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U',
3016
-				[&$this, '_remplacerDateParTime'],
3017
-				$this->query
3018
-			);
3019
-		}
3020
-
3021
-		if (strpos($this->query, 'LEFT(') !== false) {
3022
-			$this->query = str_replace('LEFT(', '_LEFT(', $this->query);
3023
-		}
3024
-
3025
-		if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) {
3026
-			$this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query);
3027
-		}
3028
-
3029
-
3030
-		// Correction Using
3031
-		// USING (non reconnu en sqlite2)
3032
-		// problematique car la jointure ne se fait pas du coup.
3033
-		if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) {
3034
-			spip_log(
3035
-				"'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'",
3036
-				'sqlite.' . _LOG_ERREUR
3037
-			);
3038
-			$this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query);
3039
-		}
3040
-
3041
-		// Correction Field
3042
-		// remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END
3043
-		if (strpos($this->query, 'FIELD') !== false) {
3044
-			$this->query = preg_replace_callback(
3045
-				'/FIELD\s*\(([^\)]*)\)/',
3046
-				[&$this, '_remplacerFieldParCase'],
3047
-				$this->query
3048
-			);
3049
-		}
3050
-
3051
-		// Correction des noms de tables FROM
3052
-		// mettre les bons noms de table dans from, update, insert, replace...
3053
-		if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) {
3054
-			$suite = strstr($this->query, $regs[0]);
3055
-			$this->query = substr($this->query, 0, -strlen($suite));
3056
-		} else {
3057
-			$suite = '';
3058
-		}
3059
-		$pref = ($this->prefixe) ? $this->prefixe . '_' : '';
3060
-		$this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite;
3061
-
3062
-		// Correction zero AS x
3063
-		// pg n'aime pas 0+x AS alias, sqlite, dans le meme style,
3064
-		// n'apprecie pas du tout SELECT 0 as x ... ORDER BY x
3065
-		// il dit que x ne doit pas être un integer dans le order by !
3066
-		// on remplace du coup x par vide() dans ce cas uniquement
3067
-		//
3068
-		// 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}}
3069
-		// mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28)
3070
-		if ((strpos($this->query, '0 AS') !== false)) {
3071
-			// on ne remplace que dans ORDER BY ou GROUP BY
3072
-			if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) {
3073
-				$suite = strstr($this->query, $regs[0]);
3074
-				$this->query = substr($this->query, 0, -strlen($suite));
3075
-
3076
-				// on cherche les noms des x dans 0 AS x
3077
-				// on remplace dans $suite le nom par vide()
3078
-				preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER);
3079
-				foreach ($matches[1] as $m) {
3080
-					if (strpos($suite, $m) !== false) {
3081
-						$suite = preg_replace(",\b$m\b,", 'VIDE()', $suite);
3082
-					}
3083
-				}
3084
-				$this->query .= $suite;
3085
-			}
3086
-		}
3087
-
3088
-		// Correction possible des divisions entieres
3089
-		// Le standard SQL (lequel? ou?) semble indiquer que
3090
-		// a/b=c doit donner c entier si a et b sont entiers 4/3=1.
3091
-		// C'est ce que retournent effectivement SQL Server et SQLite
3092
-		// Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333...
3093
-		//
3094
-		// On peut forcer la conversion en multipliant par 1.0 avant la division
3095
-		// /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus !
3096
-		// cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228
3097
-		//     http://www.sqlite.org/cvstrac/tktview?tn=3202
3098
-		// (4*1.0/3) n'est pas rendu dans ce cas !
3099
-		# $this->query = str_replace('/','* 1.00 / ',$this->query);
3100
-
3101
-
3102
-		// Correction critere REGEXP, non reconnu en sqlite2
3103
-		if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) {
3104
-			$this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query);
3105
-		}
3106
-
3107
-		//
3108
-		// 3) Remise en place des textes d'origine
3109
-		//
3110
-		// Correction Antiquotes et echappements
3111
-		// ` => rien
3112
-		if (strpos($this->query, '`') !== false) {
3113
-			$this->query = str_replace('`', '', $this->query);
3114
-		}
3115
-
3116
-		$this->query = query_reinjecte_textes($this->query, $textes);
3117
-
3118
-		return $this->query;
3119
-	}
3120
-
3121
-
3122
-	/**
3123
-	 * Callback pour remplacer `DATE_` / `INTERVAL`
3124
-	 * par `DATE ... strtotime`
3125
-	 *
3126
-	 * @param array $matches Captures
3127
-	 * @return string Texte de date compris par SQLite
3128
-	 */
3129
-	public function _remplacerDateParTime($matches) {
3130
-		$op = strtoupper($matches[1] == 'ADD') ? '+' : '-';
3131
-
3132
-		return "datetime$matches[2] '$op$matches[3] $matches[4]')";
3133
-	}
3134
-
3135
-	/**
3136
-	 * Callback pour remplacer `FIELD(table,i,j,k...)`
3137
-	 * par `CASE WHEN table=i THEN n ... ELSE 0 END`
3138
-	 *
3139
-	 * @param array $matches Captures
3140
-	 * @return string Texte de liste ordonnée compris par SQLite
3141
-	 */
3142
-	public function _remplacerFieldParCase($matches) {
3143
-		$fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X)
3144
-		$t = explode(',', $fields);
3145
-		$index = array_shift($t);
3146
-
3147
-		$res = '';
3148
-		$n = 0;
3149
-		foreach ($t as $v) {
3150
-			$n++;
3151
-			$res .= "\nWHEN $index=$v THEN $n";
3152
-		}
3153
-
3154
-		return "CASE $res ELSE 0 END ";
3155
-	}
2954
+    /** @var string $query Texte de la requête */
2955
+    public $query = '';
2956
+    /** @var string $prefixe Préfixe des tables */
2957
+    public $prefixe = '';
2958
+    /** @var string $sqlite_version Version de sqlite (2 ou 3) */
2959
+    public $sqlite_version = '';
2960
+
2961
+    /** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé
2962
+     *
2963
+     * @var array
2964
+     */
2965
+    public $textes = [];
2966
+
2967
+    /**
2968
+     * Constructeur
2969
+     *
2970
+     * @param string $query Requête à préparer
2971
+     * @param string $prefixe Prefixe des tables à utiliser
2972
+     * @param string $sqlite_version Version SQLite (2 ou 3)
2973
+     */
2974
+    public function __construct($query, $prefixe, $sqlite_version) {
2975
+        $this->query = $query;
2976
+        $this->prefixe = $prefixe;
2977
+        $this->sqlite_version = $sqlite_version;
2978
+    }
2979
+
2980
+    /**
2981
+     * Transformer la requete pour SQLite
2982
+     *
2983
+     * Enlève les textes, transforme la requête pour quelle soit
2984
+     * bien interprétée par SQLite, puis remet les textes
2985
+     * la fonction affecte `$this->query`
2986
+     */
2987
+    public function traduire_requete() {
2988
+        //
2989
+        // 1) Protection des textes en les remplacant par des codes
2990
+        //
2991
+        // enlever les 'textes' et initialiser avec
2992
+        list($this->query, $textes) = query_echappe_textes($this->query);
2993
+
2994
+        //
2995
+        // 2) Corrections de la requete
2996
+        //
2997
+        // Correction Create Database
2998
+        // Create Database -> requete ignoree
2999
+        if (strpos($this->query, 'CREATE DATABASE') === 0) {
3000
+            spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT);
3001
+            $this->query = 'SELECT 1';
3002
+        }
3003
+
3004
+        // Correction Insert Ignore
3005
+        // INSERT IGNORE -> insert (tout court et pas 'insert or replace')
3006
+        if (strpos($this->query, 'INSERT IGNORE') === 0) {
3007
+            spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG);
3008
+            $this->query = 'INSERT ' . substr($this->query, '13');
3009
+        }
3010
+
3011
+        // Correction des dates avec INTERVAL
3012
+        // utiliser sql_date_proche() de preference
3013
+        if (strpos($this->query, 'INTERVAL') !== false) {
3014
+            $this->query = preg_replace_callback(
3015
+                '/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U',
3016
+                [&$this, '_remplacerDateParTime'],
3017
+                $this->query
3018
+            );
3019
+        }
3020
+
3021
+        if (strpos($this->query, 'LEFT(') !== false) {
3022
+            $this->query = str_replace('LEFT(', '_LEFT(', $this->query);
3023
+        }
3024
+
3025
+        if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) {
3026
+            $this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query);
3027
+        }
3028
+
3029
+
3030
+        // Correction Using
3031
+        // USING (non reconnu en sqlite2)
3032
+        // problematique car la jointure ne se fait pas du coup.
3033
+        if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) {
3034
+            spip_log(
3035
+                "'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'",
3036
+                'sqlite.' . _LOG_ERREUR
3037
+            );
3038
+            $this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query);
3039
+        }
3040
+
3041
+        // Correction Field
3042
+        // remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END
3043
+        if (strpos($this->query, 'FIELD') !== false) {
3044
+            $this->query = preg_replace_callback(
3045
+                '/FIELD\s*\(([^\)]*)\)/',
3046
+                [&$this, '_remplacerFieldParCase'],
3047
+                $this->query
3048
+            );
3049
+        }
3050
+
3051
+        // Correction des noms de tables FROM
3052
+        // mettre les bons noms de table dans from, update, insert, replace...
3053
+        if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) {
3054
+            $suite = strstr($this->query, $regs[0]);
3055
+            $this->query = substr($this->query, 0, -strlen($suite));
3056
+        } else {
3057
+            $suite = '';
3058
+        }
3059
+        $pref = ($this->prefixe) ? $this->prefixe . '_' : '';
3060
+        $this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite;
3061
+
3062
+        // Correction zero AS x
3063
+        // pg n'aime pas 0+x AS alias, sqlite, dans le meme style,
3064
+        // n'apprecie pas du tout SELECT 0 as x ... ORDER BY x
3065
+        // il dit que x ne doit pas être un integer dans le order by !
3066
+        // on remplace du coup x par vide() dans ce cas uniquement
3067
+        //
3068
+        // 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}}
3069
+        // mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28)
3070
+        if ((strpos($this->query, '0 AS') !== false)) {
3071
+            // on ne remplace que dans ORDER BY ou GROUP BY
3072
+            if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) {
3073
+                $suite = strstr($this->query, $regs[0]);
3074
+                $this->query = substr($this->query, 0, -strlen($suite));
3075
+
3076
+                // on cherche les noms des x dans 0 AS x
3077
+                // on remplace dans $suite le nom par vide()
3078
+                preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER);
3079
+                foreach ($matches[1] as $m) {
3080
+                    if (strpos($suite, $m) !== false) {
3081
+                        $suite = preg_replace(",\b$m\b,", 'VIDE()', $suite);
3082
+                    }
3083
+                }
3084
+                $this->query .= $suite;
3085
+            }
3086
+        }
3087
+
3088
+        // Correction possible des divisions entieres
3089
+        // Le standard SQL (lequel? ou?) semble indiquer que
3090
+        // a/b=c doit donner c entier si a et b sont entiers 4/3=1.
3091
+        // C'est ce que retournent effectivement SQL Server et SQLite
3092
+        // Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333...
3093
+        //
3094
+        // On peut forcer la conversion en multipliant par 1.0 avant la division
3095
+        // /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus !
3096
+        // cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228
3097
+        //     http://www.sqlite.org/cvstrac/tktview?tn=3202
3098
+        // (4*1.0/3) n'est pas rendu dans ce cas !
3099
+        # $this->query = str_replace('/','* 1.00 / ',$this->query);
3100
+
3101
+
3102
+        // Correction critere REGEXP, non reconnu en sqlite2
3103
+        if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) {
3104
+            $this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query);
3105
+        }
3106
+
3107
+        //
3108
+        // 3) Remise en place des textes d'origine
3109
+        //
3110
+        // Correction Antiquotes et echappements
3111
+        // ` => rien
3112
+        if (strpos($this->query, '`') !== false) {
3113
+            $this->query = str_replace('`', '', $this->query);
3114
+        }
3115
+
3116
+        $this->query = query_reinjecte_textes($this->query, $textes);
3117
+
3118
+        return $this->query;
3119
+    }
3120
+
3121
+
3122
+    /**
3123
+     * Callback pour remplacer `DATE_` / `INTERVAL`
3124
+     * par `DATE ... strtotime`
3125
+     *
3126
+     * @param array $matches Captures
3127
+     * @return string Texte de date compris par SQLite
3128
+     */
3129
+    public function _remplacerDateParTime($matches) {
3130
+        $op = strtoupper($matches[1] == 'ADD') ? '+' : '-';
3131
+
3132
+        return "datetime$matches[2] '$op$matches[3] $matches[4]')";
3133
+    }
3134
+
3135
+    /**
3136
+     * Callback pour remplacer `FIELD(table,i,j,k...)`
3137
+     * par `CASE WHEN table=i THEN n ... ELSE 0 END`
3138
+     *
3139
+     * @param array $matches Captures
3140
+     * @return string Texte de liste ordonnée compris par SQLite
3141
+     */
3142
+    public function _remplacerFieldParCase($matches) {
3143
+        $fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X)
3144
+        $t = explode(',', $fields);
3145
+        $index = array_shift($t);
3146
+
3147
+        $res = '';
3148
+        $n = 0;
3149
+        foreach ($t as $v) {
3150
+            $n++;
3151
+            $res .= "\nWHEN $index=$v THEN $n";
3152
+        }
3153
+
3154
+        return "CASE $res ELSE 0 END ";
3155
+    }
3156 3156
 }
Please login to merge, or discard this patch.
ecrire/action/desinstaller_plugin.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 /**
@@ -32,28 +32,28 @@  discard block
 block discarded – undo
32 32
  */
33 33
 function action_desinstaller_plugin_dist() {
34 34
 
35
-	$securiser_action = charger_fonction('securiser_action', 'inc');
36
-	$arg = $securiser_action();
37
-	list($dir_plugins, $plugin) = explode('::', $arg);
38
-	$dir_type = '_DIR_PLUGINS';
39
-	if (defined('_DIR_PLUGINS_SUPPL') and $dir_plugins == _DIR_PLUGINS_SUPPL) {
40
-		$dir_type = '_DIR_PLUGINS_SUPPL';
41
-	}
42
-	$installer_plugins = charger_fonction('installer', 'plugins');
43
-	$infos = $installer_plugins($plugin, 'uninstall', $dir_type);
44
-	if ($infos and !$infos['install_test'][0]) {
45
-		include_spip('inc/plugin');
46
-		ecrire_plugin_actifs([$plugin], false, 'enleve');
47
-		$erreur = '';
48
-	} else {
49
-		$erreur = 'erreur_plugin_desinstalation_echouee';
50
-	}
51
-	if ($redirect = _request('redirect')) {
52
-		include_spip('inc/headers');
53
-		if ($erreur) {
54
-			$redirect = parametre_url($redirect, 'erreur', $erreur);
55
-		}
56
-		$redirect = str_replace('&amp;', '&', $redirect);
57
-		redirige_par_entete($redirect);
58
-	}
35
+    $securiser_action = charger_fonction('securiser_action', 'inc');
36
+    $arg = $securiser_action();
37
+    list($dir_plugins, $plugin) = explode('::', $arg);
38
+    $dir_type = '_DIR_PLUGINS';
39
+    if (defined('_DIR_PLUGINS_SUPPL') and $dir_plugins == _DIR_PLUGINS_SUPPL) {
40
+        $dir_type = '_DIR_PLUGINS_SUPPL';
41
+    }
42
+    $installer_plugins = charger_fonction('installer', 'plugins');
43
+    $infos = $installer_plugins($plugin, 'uninstall', $dir_type);
44
+    if ($infos and !$infos['install_test'][0]) {
45
+        include_spip('inc/plugin');
46
+        ecrire_plugin_actifs([$plugin], false, 'enleve');
47
+        $erreur = '';
48
+    } else {
49
+        $erreur = 'erreur_plugin_desinstalation_echouee';
50
+    }
51
+    if ($redirect = _request('redirect')) {
52
+        include_spip('inc/headers');
53
+        if ($erreur) {
54
+            $redirect = parametre_url($redirect, 'erreur', $erreur);
55
+        }
56
+        $redirect = str_replace('&amp;', '&', $redirect);
57
+        redirige_par_entete($redirect);
58
+    }
59 59
 }
Please login to merge, or discard this patch.
ecrire/action/editer_auteur.php 1 patch
Indentation   +279 added lines, -279 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
  */
18 18
 
19 19
 if (!defined('_ECRIRE_INC_VERSION')) {
20
-	return;
20
+    return;
21 21
 }
22 22
 
23 23
 /**
@@ -37,41 +37,41 @@  discard block
 block discarded – undo
37 37
  */
38 38
 function action_editer_auteur_dist($arg = null) {
39 39
 
40
-	if (is_null($arg)) {
41
-		$securiser_action = charger_fonction('securiser_action', 'inc');
42
-		$arg = $securiser_action();
43
-	}
44
-
45
-
46
-	// si id_auteur n'est pas un nombre, c'est une creation
47
-	if (!$id_auteur = intval($arg)) {
48
-		if (($id_auteur = auteur_inserer()) > 0) {
49
-			# cf. GROS HACK
50
-			# recuperer l'eventuel logo charge avant la creation
51
-			# ils ont un id = 0-id_auteur de la session
52
-			$id_hack = 0 - $GLOBALS['visiteur_session']['id_auteur'];
53
-			$chercher_logo = charger_fonction('chercher_logo', 'inc');
54
-			foreach (['on', 'off'] as $type) {
55
-				if ($logo = $chercher_logo($id_hack, 'id_auteur', $type)) {
56
-					if ($logo = reset($logo)) {
57
-						rename($logo, str_replace($id_hack, $id_auteur, $logo));
58
-					}
59
-				}
60
-			}
61
-		}
62
-	}
63
-
64
-	// Enregistre l'envoi dans la BD
65
-	$err = '';
66
-	if ($id_auteur > 0) {
67
-		$err = auteur_modifier($id_auteur);
68
-	}
69
-
70
-	if ($err) {
71
-		spip_log("echec editeur auteur: $err", _LOG_ERREUR);
72
-	}
73
-
74
-	return [$id_auteur, $err];
40
+    if (is_null($arg)) {
41
+        $securiser_action = charger_fonction('securiser_action', 'inc');
42
+        $arg = $securiser_action();
43
+    }
44
+
45
+
46
+    // si id_auteur n'est pas un nombre, c'est une creation
47
+    if (!$id_auteur = intval($arg)) {
48
+        if (($id_auteur = auteur_inserer()) > 0) {
49
+            # cf. GROS HACK
50
+            # recuperer l'eventuel logo charge avant la creation
51
+            # ils ont un id = 0-id_auteur de la session
52
+            $id_hack = 0 - $GLOBALS['visiteur_session']['id_auteur'];
53
+            $chercher_logo = charger_fonction('chercher_logo', 'inc');
54
+            foreach (['on', 'off'] as $type) {
55
+                if ($logo = $chercher_logo($id_hack, 'id_auteur', $type)) {
56
+                    if ($logo = reset($logo)) {
57
+                        rename($logo, str_replace($id_hack, $id_auteur, $logo));
58
+                    }
59
+                }
60
+            }
61
+        }
62
+    }
63
+
64
+    // Enregistre l'envoi dans la BD
65
+    $err = '';
66
+    if ($id_auteur > 0) {
67
+        $err = auteur_modifier($id_auteur);
68
+    }
69
+
70
+    if ($err) {
71
+        spip_log("echec editeur auteur: $err", _LOG_ERREUR);
72
+    }
73
+
74
+    return [$id_auteur, $err];
75 75
 }
76 76
 
77 77
 /**
@@ -88,44 +88,44 @@  discard block
 block discarded – undo
88 88
  */
89 89
 function auteur_inserer($source = null, $set = null) {
90 90
 
91
-	// Ce qu'on va demander comme modifications
92
-	$champs = [];
93
-	$champs['source'] = $source ? $source : 'spip';
94
-
95
-	$champs['login'] = '';
96
-	$champs['statut'] = '5poubelle';  // inutilisable tant qu'il n'a pas ete renseigne et institue
97
-	$champs['webmestre'] = 'non';
98
-	if (empty($champs['imessage'])) {
99
-		$champs['imessage'] = 'oui';
100
-	}
101
-
102
-	if ($set) {
103
-		$champs = array_merge($champs, $set);
104
-	}
105
-
106
-	// Envoyer aux plugins
107
-	$champs = pipeline(
108
-		'pre_insertion',
109
-		[
110
-			'args' => [
111
-				'table' => 'spip_auteurs',
112
-			],
113
-			'data' => $champs
114
-		]
115
-	);
116
-	$id_auteur = sql_insertq('spip_auteurs', $champs);
117
-	pipeline(
118
-		'post_insertion',
119
-		[
120
-			'args' => [
121
-				'table' => 'spip_auteurs',
122
-				'id_objet' => $id_auteur
123
-			],
124
-			'data' => $champs
125
-		]
126
-	);
127
-
128
-	return $id_auteur;
91
+    // Ce qu'on va demander comme modifications
92
+    $champs = [];
93
+    $champs['source'] = $source ? $source : 'spip';
94
+
95
+    $champs['login'] = '';
96
+    $champs['statut'] = '5poubelle';  // inutilisable tant qu'il n'a pas ete renseigne et institue
97
+    $champs['webmestre'] = 'non';
98
+    if (empty($champs['imessage'])) {
99
+        $champs['imessage'] = 'oui';
100
+    }
101
+
102
+    if ($set) {
103
+        $champs = array_merge($champs, $set);
104
+    }
105
+
106
+    // Envoyer aux plugins
107
+    $champs = pipeline(
108
+        'pre_insertion',
109
+        [
110
+            'args' => [
111
+                'table' => 'spip_auteurs',
112
+            ],
113
+            'data' => $champs
114
+        ]
115
+    );
116
+    $id_auteur = sql_insertq('spip_auteurs', $champs);
117
+    pipeline(
118
+        'post_insertion',
119
+        [
120
+            'args' => [
121
+                'table' => 'spip_auteurs',
122
+                'id_objet' => $id_auteur
123
+            ],
124
+            'data' => $champs
125
+        ]
126
+    );
127
+
128
+    return $id_auteur;
129 129
 }
130 130
 
131 131
 
@@ -150,70 +150,70 @@  discard block
 block discarded – undo
150 150
  */
151 151
 function auteur_modifier($id_auteur, $set = null, $force_update = false) {
152 152
 
153
-	include_spip('inc/modifier');
154
-	include_spip('inc/filtres');
155
-	$c = collecter_requests(
156
-	// white list
157
-		objet_info('auteur', 'champs_editables'),
158
-		// black list
159
-		$force_update ? [] : ['webmestre', 'pass', 'login'],
160
-		// donnees eventuellement fournies
161
-		$set
162
-	);
163
-
164
-	if (
165
-		$err = objet_modifier_champs(
166
-			'auteur',
167
-			$id_auteur,
168
-			[
169
-			'data' => $set,
170
-			'nonvide' => ['nom' => _T('ecrire:item_nouvel_auteur')]
171
-			],
172
-			$c
173
-		)
174
-	) {
175
-		return $err;
176
-	}
177
-	$session = $c;
178
-
179
-	$err = '';
180
-	if (!$force_update) {
181
-		// Modification de statut, changement de rubrique ?
182
-		$c = collecter_requests(
183
-		// white list
184
-			[
185
-				'statut',
186
-				'new_login',
187
-				'new_pass',
188
-				'login',
189
-				'pass',
190
-				'webmestre',
191
-				'restreintes',
192
-				'id_parent'
193
-			],
194
-			// black list
195
-			[],
196
-			// donnees eventuellement fournies
197
-			$set
198
-		);
199
-		if (isset($c['new_login']) and !isset($c['login'])) {
200
-			$c['login'] = $c['new_login'];
201
-		}
202
-		if (isset($c['new_pass']) and !isset($c['pass'])) {
203
-			$c['pass'] = $c['new_pass'];
204
-		}
205
-		$err = auteur_instituer($id_auteur, $c);
206
-		$session = array_merge($session, $c);
207
-	}
208
-
209
-	// .. mettre a jour les sessions de cet auteur
210
-	include_spip('inc/session');
211
-	$session['id_auteur'] = $id_auteur;
212
-	unset($session['new_login']);
213
-	unset($session['new_pass']);
214
-	actualiser_sessions($session);
215
-
216
-	return $err;
153
+    include_spip('inc/modifier');
154
+    include_spip('inc/filtres');
155
+    $c = collecter_requests(
156
+    // white list
157
+        objet_info('auteur', 'champs_editables'),
158
+        // black list
159
+        $force_update ? [] : ['webmestre', 'pass', 'login'],
160
+        // donnees eventuellement fournies
161
+        $set
162
+    );
163
+
164
+    if (
165
+        $err = objet_modifier_champs(
166
+            'auteur',
167
+            $id_auteur,
168
+            [
169
+            'data' => $set,
170
+            'nonvide' => ['nom' => _T('ecrire:item_nouvel_auteur')]
171
+            ],
172
+            $c
173
+        )
174
+    ) {
175
+        return $err;
176
+    }
177
+    $session = $c;
178
+
179
+    $err = '';
180
+    if (!$force_update) {
181
+        // Modification de statut, changement de rubrique ?
182
+        $c = collecter_requests(
183
+        // white list
184
+            [
185
+                'statut',
186
+                'new_login',
187
+                'new_pass',
188
+                'login',
189
+                'pass',
190
+                'webmestre',
191
+                'restreintes',
192
+                'id_parent'
193
+            ],
194
+            // black list
195
+            [],
196
+            // donnees eventuellement fournies
197
+            $set
198
+        );
199
+        if (isset($c['new_login']) and !isset($c['login'])) {
200
+            $c['login'] = $c['new_login'];
201
+        }
202
+        if (isset($c['new_pass']) and !isset($c['pass'])) {
203
+            $c['pass'] = $c['new_pass'];
204
+        }
205
+        $err = auteur_instituer($id_auteur, $c);
206
+        $session = array_merge($session, $c);
207
+    }
208
+
209
+    // .. mettre a jour les sessions de cet auteur
210
+    include_spip('inc/session');
211
+    $session['id_auteur'] = $id_auteur;
212
+    unset($session['new_login']);
213
+    unset($session['new_pass']);
214
+    actualiser_sessions($session);
215
+
216
+    return $err;
217 217
 }
218 218
 
219 219
 /**
@@ -234,9 +234,9 @@  discard block
 block discarded – undo
234 234
  * @return string
235 235
  */
236 236
 function auteur_associer($id_auteur, $objets, $qualif = null) {
237
-	include_spip('action/editer_liens');
237
+    include_spip('action/editer_liens');
238 238
 
239
-	return objet_associer(['auteur' => $id_auteur], $objets, $qualif);
239
+    return objet_associer(['auteur' => $id_auteur], $objets, $qualif);
240 240
 }
241 241
 
242 242
 /**
@@ -255,9 +255,9 @@  discard block
 block discarded – undo
255 255
  * @return string
256 256
  */
257 257
 function auteur_dissocier($id_auteur, $objets) {
258
-	include_spip('action/editer_liens');
258
+    include_spip('action/editer_liens');
259 259
 
260
-	return objet_dissocier(['auteur' => $id_auteur], $objets);
260
+    return objet_dissocier(['auteur' => $id_auteur], $objets);
261 261
 }
262 262
 
263 263
 /**
@@ -278,9 +278,9 @@  discard block
 block discarded – undo
278 278
  * @return bool|int
279 279
  */
280 280
 function auteur_qualifier($id_auteur, $objets, $qualif) {
281
-	include_spip('action/editer_liens');
281
+    include_spip('action/editer_liens');
282 282
 
283
-	return objet_qualifier_liens(['auteur' => $id_auteur], $objets, $qualif);
283
+    return objet_qualifier_liens(['auteur' => $id_auteur], $objets, $qualif);
284 284
 }
285 285
 
286 286
 
@@ -299,139 +299,139 @@  discard block
 block discarded – undo
299 299
  * @return bool|string
300 300
  */
301 301
 function auteur_instituer($id_auteur, $c, $force_webmestre = false) {
302
-	if (!$id_auteur = intval($id_auteur)) {
303
-		return false;
304
-	}
305
-	$erreurs = []; // contiendra les differentes erreurs a traduire par _T()
306
-	$champs = [];
307
-
308
-	// les memoriser pour les faire passer dans le pipeline pre_edition
309
-	if (isset($c['login']) and strlen($c['login'])) {
310
-		$champs['login'] = $c['login'];
311
-	}
312
-	if (isset($c['pass']) and strlen($c['pass'])) {
313
-		$champs['pass'] = $c['pass'];
314
-	}
315
-
316
-	$statut = $statut_ancien = sql_getfetsel('statut', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
317
-
318
-	if (
319
-		isset($c['statut'])
320
-		and (autoriser('modifier', 'auteur', $id_auteur, null, ['statut' => $c['statut']]))
321
-	) {
322
-		$statut = $champs['statut'] = $c['statut'];
323
-	}
324
-
325
-	// Restreindre avant de declarer l'auteur
326
-	// (section critique sur les droits)
327
-	if (isset($c['id_parent']) and $c['id_parent']) {
328
-		if (is_array($c['restreintes'])) {
329
-			$c['restreintes'][] = $c['id_parent'];
330
-		} else {
331
-			$c['restreintes'] = [$c['id_parent']];
332
-		}
333
-	}
334
-
335
-	if (
336
-		isset($c['webmestre'])
337
-		and ($force_webmestre or autoriser('modifier', 'auteur', $id_auteur, null, ['webmestre' => '?']))
338
-	) {
339
-		$champs['webmestre'] = $c['webmestre'] == 'oui' ? 'oui' : 'non';
340
-	}
341
-
342
-	// si statut change et n'est pas 0minirezo, on force webmestre a non
343
-	if (isset($c['statut']) and $c['statut'] !== '0minirezo') {
344
-		$champs['webmestre'] = $c['webmestre'] = 'non';
345
-	}
346
-
347
-	// Envoyer aux plugins
348
-	$champs = pipeline(
349
-		'pre_edition',
350
-		[
351
-			'args' => [
352
-				'table' => 'spip_auteurs',
353
-				'id_objet' => $id_auteur,
354
-				'action' => 'instituer',
355
-				'statut_ancien' => $statut_ancien,
356
-			],
357
-			'data' => $champs
358
-		]
359
-	);
360
-
361
-	if (
362
-		isset($c['restreintes']) and is_array($c['restreintes'])
363
-		and autoriser('modifier', 'auteur', $id_auteur, null, ['restreint' => $c['restreintes']])
364
-	) {
365
-		$rubriques = array_map('intval', $c['restreintes']);
366
-		$rubriques = array_unique($rubriques);
367
-		$rubriques = array_diff($rubriques, [0]);
368
-		auteur_dissocier($id_auteur, ['rubrique' => '*']);
369
-		auteur_associer($id_auteur, ['rubrique' => $rubriques]);
370
-	}
371
-
372
-	$flag_ecrire_acces = false;
373
-	// commencer par traiter les cas particuliers des logins et pass
374
-	// avant les autres ecritures en base
375
-	if (isset($champs['login']) or isset($champs['pass'])) {
376
-		$auth_methode = sql_getfetsel('source', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
377
-		include_spip('inc/auth');
378
-		if (isset($champs['login']) and strlen($champs['login'])) {
379
-			if (!auth_modifier_login($auth_methode, $champs['login'], $id_auteur)) {
380
-				$erreurs[] = 'ecrire:impossible_modifier_login_auteur';
381
-			}
382
-		}
383
-		if (isset($champs['pass']) and strlen($champs['pass'])) {
384
-			$champs['login'] = sql_getfetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
385
-			if (!auth_modifier_pass($auth_methode, $champs['login'], $champs['pass'], $id_auteur)) {
386
-				$erreurs[] = 'ecrire:impossible_modifier_pass_auteur';
387
-			}
388
-		}
389
-		unset($champs['login']);
390
-		unset($champs['pass']);
391
-		$flag_ecrire_acces = true;
392
-	}
393
-
394
-	if (!count($champs)) {
395
-		return implode(' ', array_map('_T', $erreurs));
396
-	}
397
-	sql_updateq('spip_auteurs', $champs, 'id_auteur=' . $id_auteur);
398
-
399
-	// .. mettre a jour les fichiers .htpasswd et .htpasswd-admin
400
-	if (
401
-		$flag_ecrire_acces
402
-		or isset($champs['statut'])
403
-	) {
404
-		include_spip('inc/acces');
405
-		ecrire_acces();
406
-	}
407
-
408
-	// Invalider les caches
409
-	include_spip('inc/invalideur');
410
-	suivre_invalideur("id='auteur/$id_auteur'");
411
-
412
-	// Pipeline
413
-	pipeline(
414
-		'post_edition',
415
-		[
416
-			'args' => [
417
-				'table' => 'spip_auteurs',
418
-				'id_objet' => $id_auteur,
419
-				'action' => 'instituer',
420
-				'statut_ancien' => $statut_ancien,
421
-			],
422
-			'data' => $champs
423
-		]
424
-	);
425
-
426
-
427
-	// Notifications
428
-	if ($notifications = charger_fonction('notifications', 'inc')) {
429
-		$notifications(
430
-			'instituerauteur',
431
-			$id_auteur,
432
-			['statut' => $statut, 'statut_ancien' => $statut_ancien]
433
-		);
434
-	}
435
-
436
-	return implode(' ', array_map('_T', $erreurs));
302
+    if (!$id_auteur = intval($id_auteur)) {
303
+        return false;
304
+    }
305
+    $erreurs = []; // contiendra les differentes erreurs a traduire par _T()
306
+    $champs = [];
307
+
308
+    // les memoriser pour les faire passer dans le pipeline pre_edition
309
+    if (isset($c['login']) and strlen($c['login'])) {
310
+        $champs['login'] = $c['login'];
311
+    }
312
+    if (isset($c['pass']) and strlen($c['pass'])) {
313
+        $champs['pass'] = $c['pass'];
314
+    }
315
+
316
+    $statut = $statut_ancien = sql_getfetsel('statut', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
317
+
318
+    if (
319
+        isset($c['statut'])
320
+        and (autoriser('modifier', 'auteur', $id_auteur, null, ['statut' => $c['statut']]))
321
+    ) {
322
+        $statut = $champs['statut'] = $c['statut'];
323
+    }
324
+
325
+    // Restreindre avant de declarer l'auteur
326
+    // (section critique sur les droits)
327
+    if (isset($c['id_parent']) and $c['id_parent']) {
328
+        if (is_array($c['restreintes'])) {
329
+            $c['restreintes'][] = $c['id_parent'];
330
+        } else {
331
+            $c['restreintes'] = [$c['id_parent']];
332
+        }
333
+    }
334
+
335
+    if (
336
+        isset($c['webmestre'])
337
+        and ($force_webmestre or autoriser('modifier', 'auteur', $id_auteur, null, ['webmestre' => '?']))
338
+    ) {
339
+        $champs['webmestre'] = $c['webmestre'] == 'oui' ? 'oui' : 'non';
340
+    }
341
+
342
+    // si statut change et n'est pas 0minirezo, on force webmestre a non
343
+    if (isset($c['statut']) and $c['statut'] !== '0minirezo') {
344
+        $champs['webmestre'] = $c['webmestre'] = 'non';
345
+    }
346
+
347
+    // Envoyer aux plugins
348
+    $champs = pipeline(
349
+        'pre_edition',
350
+        [
351
+            'args' => [
352
+                'table' => 'spip_auteurs',
353
+                'id_objet' => $id_auteur,
354
+                'action' => 'instituer',
355
+                'statut_ancien' => $statut_ancien,
356
+            ],
357
+            'data' => $champs
358
+        ]
359
+    );
360
+
361
+    if (
362
+        isset($c['restreintes']) and is_array($c['restreintes'])
363
+        and autoriser('modifier', 'auteur', $id_auteur, null, ['restreint' => $c['restreintes']])
364
+    ) {
365
+        $rubriques = array_map('intval', $c['restreintes']);
366
+        $rubriques = array_unique($rubriques);
367
+        $rubriques = array_diff($rubriques, [0]);
368
+        auteur_dissocier($id_auteur, ['rubrique' => '*']);
369
+        auteur_associer($id_auteur, ['rubrique' => $rubriques]);
370
+    }
371
+
372
+    $flag_ecrire_acces = false;
373
+    // commencer par traiter les cas particuliers des logins et pass
374
+    // avant les autres ecritures en base
375
+    if (isset($champs['login']) or isset($champs['pass'])) {
376
+        $auth_methode = sql_getfetsel('source', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
377
+        include_spip('inc/auth');
378
+        if (isset($champs['login']) and strlen($champs['login'])) {
379
+            if (!auth_modifier_login($auth_methode, $champs['login'], $id_auteur)) {
380
+                $erreurs[] = 'ecrire:impossible_modifier_login_auteur';
381
+            }
382
+        }
383
+        if (isset($champs['pass']) and strlen($champs['pass'])) {
384
+            $champs['login'] = sql_getfetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
385
+            if (!auth_modifier_pass($auth_methode, $champs['login'], $champs['pass'], $id_auteur)) {
386
+                $erreurs[] = 'ecrire:impossible_modifier_pass_auteur';
387
+            }
388
+        }
389
+        unset($champs['login']);
390
+        unset($champs['pass']);
391
+        $flag_ecrire_acces = true;
392
+    }
393
+
394
+    if (!count($champs)) {
395
+        return implode(' ', array_map('_T', $erreurs));
396
+    }
397
+    sql_updateq('spip_auteurs', $champs, 'id_auteur=' . $id_auteur);
398
+
399
+    // .. mettre a jour les fichiers .htpasswd et .htpasswd-admin
400
+    if (
401
+        $flag_ecrire_acces
402
+        or isset($champs['statut'])
403
+    ) {
404
+        include_spip('inc/acces');
405
+        ecrire_acces();
406
+    }
407
+
408
+    // Invalider les caches
409
+    include_spip('inc/invalideur');
410
+    suivre_invalideur("id='auteur/$id_auteur'");
411
+
412
+    // Pipeline
413
+    pipeline(
414
+        'post_edition',
415
+        [
416
+            'args' => [
417
+                'table' => 'spip_auteurs',
418
+                'id_objet' => $id_auteur,
419
+                'action' => 'instituer',
420
+                'statut_ancien' => $statut_ancien,
421
+            ],
422
+            'data' => $champs
423
+        ]
424
+    );
425
+
426
+
427
+    // Notifications
428
+    if ($notifications = charger_fonction('notifications', 'inc')) {
429
+        $notifications(
430
+            'instituerauteur',
431
+            $id_auteur,
432
+            ['statut' => $statut, 'statut_ancien' => $statut_ancien]
433
+        );
434
+    }
435
+
436
+    return implode(' ', array_map('_T', $erreurs));
437 437
 }
Please login to merge, or discard this patch.