Completed
Push — master ( 28ee8b...44fd31 )
by cam
01:12
created
ecrire/src/Sql/Sqlite/Sqlite.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -8,119 +8,119 @@
 block discarded – undo
8 8
  **/
9 9
 class Sqlite
10 10
 {
11
-	/** @var Requeteur[] Liste des instances de requêteurs créés */
12
-	public static $requeteurs = [];
13
-	/** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */
14
-	public static $transaction_en_cours = [];
11
+    /** @var Requeteur[] Liste des instances de requêteurs créés */
12
+    public static $requeteurs = [];
13
+    /** @var bool[] Pour chaque connexion, flag pour savoir si une transaction est en cours */
14
+    public static $transaction_en_cours = [];
15 15
 
16 16
 
17
-	/**
18
-	 * Retourne une unique instance du requêteur
19
-	 *
20
-	 * Retourne une instance unique du requêteur pour une connexion SQLite
21
-	 * donnée
22
-	 *
23
-	 * @param string $serveur
24
-	 *    Nom du connecteur
25
-	 * @return SqliteRequeteur
26
-	 *    Instance unique du requêteur
27
-	 **/
28
-	public static function requeteur($serveur)
29
-	{
30
-		if (!isset(static::$requeteurs[$serveur])) {
31
-			static::$requeteurs[$serveur] = new Requeteur($serveur);
32
-		}
17
+    /**
18
+     * Retourne une unique instance du requêteur
19
+     *
20
+     * Retourne une instance unique du requêteur pour une connexion SQLite
21
+     * donnée
22
+     *
23
+     * @param string $serveur
24
+     *    Nom du connecteur
25
+     * @return SqliteRequeteur
26
+     *    Instance unique du requêteur
27
+     **/
28
+    public static function requeteur($serveur)
29
+    {
30
+        if (!isset(static::$requeteurs[$serveur])) {
31
+            static::$requeteurs[$serveur] = new Requeteur($serveur);
32
+        }
33 33
 
34
-		return static::$requeteurs[$serveur];
35
-	}
34
+        return static::$requeteurs[$serveur];
35
+    }
36 36
 
37
-	/**
38
-	 * Prépare le texte d'une requête avant son exécution
39
-	 *
40
-	 * Adapte la requête au format plus ou moins MySQL par un format
41
-	 * compris de SQLite.
42
-	 *
43
-	 * Change les préfixes de tables SPIP par ceux véritables
44
-	 *
45
-	 * @param string $query Requête à préparer
46
-	 * @param string $serveur Nom de la connexion
47
-	 * @return string           Requête préparée
48
-	 */
49
-	public static function traduire_requete($query, $serveur)
50
-	{
51
-		$requeteur = static::requeteur($serveur);
52
-		$traducteur = new Traducteur($query, $requeteur->prefixe, $requeteur->sqlite_version);
37
+    /**
38
+     * Prépare le texte d'une requête avant son exécution
39
+     *
40
+     * Adapte la requête au format plus ou moins MySQL par un format
41
+     * compris de SQLite.
42
+     *
43
+     * Change les préfixes de tables SPIP par ceux véritables
44
+     *
45
+     * @param string $query Requête à préparer
46
+     * @param string $serveur Nom de la connexion
47
+     * @return string           Requête préparée
48
+     */
49
+    public static function traduire_requete($query, $serveur)
50
+    {
51
+        $requeteur = static::requeteur($serveur);
52
+        $traducteur = new Traducteur($query, $requeteur->prefixe, $requeteur->sqlite_version);
53 53
 
54
-		return $traducteur->traduire_requete();
55
-	}
54
+        return $traducteur->traduire_requete();
55
+    }
56 56
 
57
-	/**
58
-	 * Démarre une transaction
59
-	 *
60
-	 * @param string $serveur Nom de la connexion
61
-	 **/
62
-	public static function demarrer_transaction($serveur)
63
-	{
64
-		Sqlite::executer_requete('BEGIN TRANSACTION', $serveur);
65
-		Sqlite::$transaction_en_cours[$serveur] = true;
66
-	}
57
+    /**
58
+     * Démarre une transaction
59
+     *
60
+     * @param string $serveur Nom de la connexion
61
+     **/
62
+    public static function demarrer_transaction($serveur)
63
+    {
64
+        Sqlite::executer_requete('BEGIN TRANSACTION', $serveur);
65
+        Sqlite::$transaction_en_cours[$serveur] = true;
66
+    }
67 67
 
68
-	/**
69
-	 * Exécute la requête donnée
70
-	 *
71
-	 * @param string $query Requête
72
-	 * @param string $serveur Nom de la connexion
73
-	 * @param null|bool $tracer Demander des statistiques (temps) ?
74
-	 **/
75
-	public static function executer_requete($query, $serveur, $tracer = null)
76
-	{
77
-		$requeteur = Sqlite::requeteur($serveur);
68
+    /**
69
+     * Exécute la requête donnée
70
+     *
71
+     * @param string $query Requête
72
+     * @param string $serveur Nom de la connexion
73
+     * @param null|bool $tracer Demander des statistiques (temps) ?
74
+     **/
75
+    public static function executer_requete($query, $serveur, $tracer = null)
76
+    {
77
+        $requeteur = Sqlite::requeteur($serveur);
78 78
 
79
-		return $requeteur->executer_requete($query, $tracer);
80
-	}
79
+        return $requeteur->executer_requete($query, $tracer);
80
+    }
81 81
 
82
-	/**
83
-	 * Obtient l'identifiant de la dernière ligne insérée ou modifiée
84
-	 *
85
-	 * @param string $serveur Nom de la connexion
86
-	 * return int                Identifiant
87
-	 **/
88
-	public static function last_insert_id($serveur)
89
-	{
90
-		$requeteur = Sqlite::requeteur($serveur);
82
+    /**
83
+     * Obtient l'identifiant de la dernière ligne insérée ou modifiée
84
+     *
85
+     * @param string $serveur Nom de la connexion
86
+     * return int                Identifiant
87
+     **/
88
+    public static function last_insert_id($serveur)
89
+    {
90
+        $requeteur = Sqlite::requeteur($serveur);
91 91
 
92
-		return $requeteur->last_insert_id($serveur);
93
-	}
92
+        return $requeteur->last_insert_id($serveur);
93
+    }
94 94
 
95
-	/**
96
-	 * Annule une transaction
97
-	 *
98
-	 * @param string $serveur Nom de la connexion
99
-	 **/
100
-	public static function annuler_transaction($serveur)
101
-	{
102
-		Sqlite::executer_requete('ROLLBACK', $serveur);
103
-		Sqlite::$transaction_en_cours[$serveur] = false;
104
-	}
95
+    /**
96
+     * Annule une transaction
97
+     *
98
+     * @param string $serveur Nom de la connexion
99
+     **/
100
+    public static function annuler_transaction($serveur)
101
+    {
102
+        Sqlite::executer_requete('ROLLBACK', $serveur);
103
+        Sqlite::$transaction_en_cours[$serveur] = false;
104
+    }
105 105
 
106
-	/**
107
-	 * Termine une transaction
108
-	 *
109
-	 * @param string $serveur Nom de la connexion
110
-	 **/
111
-	public static function finir_transaction($serveur)
112
-	{
113
-		// si pas de transaction en cours, ne rien faire et le dire
114
-		if (
115
-			!isset(Sqlite::$transaction_en_cours[$serveur])
116
-			or Sqlite::$transaction_en_cours[$serveur] == false
117
-		) {
118
-			return false;
119
-		}
120
-		// sinon fermer la transaction et retourner true
121
-		Sqlite::executer_requete('COMMIT', $serveur);
122
-		Sqlite::$transaction_en_cours[$serveur] = false;
106
+    /**
107
+     * Termine une transaction
108
+     *
109
+     * @param string $serveur Nom de la connexion
110
+     **/
111
+    public static function finir_transaction($serveur)
112
+    {
113
+        // si pas de transaction en cours, ne rien faire et le dire
114
+        if (
115
+            !isset(Sqlite::$transaction_en_cours[$serveur])
116
+            or Sqlite::$transaction_en_cours[$serveur] == false
117
+        ) {
118
+            return false;
119
+        }
120
+        // sinon fermer la transaction et retourner true
121
+        Sqlite::executer_requete('COMMIT', $serveur);
122
+        Sqlite::$transaction_en_cours[$serveur] = false;
123 123
 
124
-		return true;
125
-	}
124
+        return true;
125
+    }
126 126
 }
Please login to merge, or discard this patch.
ecrire/src/Sql/Sqlite/Traducteur.php 2 patches
Indentation   +207 added lines, -207 removed lines patch added patch discarded remove patch
@@ -9,211 +9,211 @@
 block discarded – undo
9 9
  */
10 10
 class Traducteur
11 11
 {
12
-	/** @var string $query texte de la requête */
13
-	public $query = '';
14
-
15
-	/** @var string $prefixe Préfixe des tables */
16
-	public $prefixe = '';
17
-
18
-	/** @var string $sqlite_version Version de sqlite (2 ou 3) */
19
-	public $sqlite_version = '';
20
-
21
-	/** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé
22
-	 *
23
-	 * @var array
24
-	 */
25
-	public $textes = [];
26
-
27
-	/**
28
-	 * Constructeur
29
-	 *
30
-	 * @param string $query Requête à préparer
31
-	 * @param string $prefixe Prefixe des tables à utiliser
32
-	 * @param string $sqlite_version Version SQLite (2 ou 3)
33
-	 */
34
-	public function __construct($query, $prefixe, $sqlite_version)
35
-	{
36
-		$this->query = $query;
37
-		$this->prefixe = $prefixe;
38
-		$this->sqlite_version = $sqlite_version;
39
-	}
40
-
41
-	/**
42
-	 * Transformer la requete pour SQLite
43
-	 *
44
-	 * Enlève les textes, transforme la requête pour quelle soit
45
-	 * bien interprétée par SQLite, puis remet les textes
46
-	 * la fonction affecte `$this->query`
47
-	 */
48
-	public function traduire_requete()
49
-	{
50
-		//
51
-		// 1) Protection des textes en les remplacant par des codes
52
-		//
53
-		// enlever les 'textes' et initialiser avec
54
-		list($this->query, $textes) = query_echappe_textes($this->query);
55
-
56
-		//
57
-		// 2) Corrections de la requete
58
-		//
59
-		// Correction Create Database
60
-		// Create Database -> requete ignoree
61
-		if (strpos($this->query, 'CREATE DATABASE') === 0) {
62
-			spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT);
63
-			$this->query = 'SELECT 1';
64
-		}
65
-
66
-		// Correction Insert Ignore
67
-		// INSERT IGNORE -> insert (tout court et pas 'insert or replace')
68
-		if (strpos($this->query, 'INSERT IGNORE') === 0) {
69
-			spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG);
70
-			$this->query = 'INSERT ' . substr($this->query, '13');
71
-		}
72
-
73
-		// Correction des dates avec INTERVAL
74
-		// utiliser sql_date_proche() de preference
75
-		if (strpos($this->query, 'INTERVAL') !== false) {
76
-			$this->query = preg_replace_callback(
77
-				'/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U',
78
-				[&$this, '_remplacerDateParTime'],
79
-				$this->query
80
-			);
81
-		}
82
-
83
-		if (strpos($this->query, 'LEFT(') !== false) {
84
-			$this->query = str_replace('LEFT(', '_LEFT(', $this->query);
85
-		}
86
-
87
-		if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) {
88
-			$this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query);
89
-		}
90
-
91
-
92
-		// Correction Using
93
-		// USING (non reconnu en sqlite2)
94
-		// problematique car la jointure ne se fait pas du coup.
95
-		if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) {
96
-			spip_log(
97
-				"'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'",
98
-				'sqlite.' . _LOG_ERREUR
99
-			);
100
-			$this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query);
101
-		}
102
-
103
-		// Correction Field
104
-		// remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END
105
-		if (strpos($this->query, 'FIELD') !== false) {
106
-			$this->query = preg_replace_callback(
107
-				'/FIELD\s*\(([^\)]*)\)/',
108
-				[&$this, '_remplacerFieldParCase'],
109
-				$this->query
110
-			);
111
-		}
112
-
113
-		// Correction des noms de tables FROM
114
-		// mettre les bons noms de table dans from, update, insert, replace...
115
-		if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) {
116
-			$suite = strstr($this->query, $regs[0]);
117
-			$this->query = substr($this->query, 0, -strlen($suite));
118
-		} else {
119
-			$suite = '';
120
-		}
121
-		$pref = ($this->prefixe) ? $this->prefixe . '_' : '';
122
-		$this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite;
123
-
124
-		// Correction zero AS x
125
-		// pg n'aime pas 0+x AS alias, sqlite, dans le meme style,
126
-		// n'apprecie pas du tout SELECT 0 as x ... ORDER BY x
127
-		// il dit que x ne doit pas être un integer dans le order by !
128
-		// on remplace du coup x par vide() dans ce cas uniquement
129
-		//
130
-		// apparait dans public/vertebrer.php et dans le plugin menu aussi qui genere aussi ce genre de requete via un {par num #GET{tri_num}}
131
-		// mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28)
132
-		if ((strpos($this->query, '0 AS') !== false)) {
133
-			// on ne remplace que dans ORDER BY ou GROUP BY
134
-			if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) {
135
-				$suite = strstr($this->query, $regs[0]);
136
-				$this->query = substr($this->query, 0, -strlen($suite));
137
-
138
-				// on cherche les noms des x dans 0 AS x
139
-				// on remplace dans $suite le nom par vide()
140
-				preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER);
141
-				foreach ($matches[1] as $m) {
142
-					if (strpos($suite, $m) !== false) {
143
-						$suite = preg_replace(",\b$m\b,", 'VIDE()', $suite);
144
-					}
145
-				}
146
-				$this->query .= $suite;
147
-			}
148
-		}
149
-
150
-		// Correction possible des divisions entieres
151
-		// Le standard SQL (lequel? ou?) semble indiquer que
152
-		// a/b=c doit donner c entier si a et b sont entiers 4/3=1.
153
-		// C'est ce que retournent effectivement SQL Server et SQLite
154
-		// Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333...
155
-		//
156
-		// On peut forcer la conversion en multipliant par 1.0 avant la division
157
-		// /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus !
158
-		// cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228
159
-		//     http://www.sqlite.org/cvstrac/tktview?tn=3202
160
-		// (4*1.0/3) n'est pas rendu dans ce cas !
161
-		# $this->query = str_replace('/','* 1.00 / ',$this->query);
162
-
163
-
164
-		// Correction critere REGEXP, non reconnu en sqlite2
165
-		if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) {
166
-			$this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query);
167
-		}
168
-
169
-		//
170
-		// 3) Remise en place des textes d'origine
171
-		//
172
-		// Correction Antiquotes et echappements
173
-		// ` => rien
174
-		if (strpos($this->query, '`') !== false) {
175
-			$this->query = str_replace('`', '', $this->query);
176
-		}
177
-
178
-		$this->query = query_reinjecte_textes($this->query, $textes);
179
-
180
-		return $this->query;
181
-	}
182
-
183
-	/**
184
-	 * Callback pour remplacer `DATE_` / `INTERVAL`
185
-	 * par `DATE ... strtotime`
186
-	 *
187
-	 * @param array $matches Captures
188
-	 * @return string texte de date compris par SQLite
189
-	 */
190
-	public function _remplacerDateParTime($matches)
191
-	{
192
-		$op = strtoupper($matches[1] == 'ADD') ? '+' : '-';
193
-
194
-		return "datetime$matches[2] '$op$matches[3] $matches[4]')";
195
-	}
196
-
197
-	/**
198
-	 * Callback pour remplacer `FIELD(table,i,j,k...)`
199
-	 * par `CASE WHEN table=i THEN n ... ELSE 0 END`
200
-	 *
201
-	 * @param array $matches Captures
202
-	 * @return string texte de liste ordonnée compris par SQLite
203
-	 */
204
-	public function _remplacerFieldParCase($matches)
205
-	{
206
-		$fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X)
207
-		$t = explode(',', $fields);
208
-		$index = array_shift($t);
209
-
210
-		$res = '';
211
-		$n = 0;
212
-		foreach ($t as $v) {
213
-			$n++;
214
-			$res .= "\nWHEN $index=$v THEN $n";
215
-		}
216
-
217
-		return "CASE $res ELSE 0 END ";
218
-	}
12
+    /** @var string $query texte de la requête */
13
+    public $query = '';
14
+
15
+    /** @var string $prefixe Préfixe des tables */
16
+    public $prefixe = '';
17
+
18
+    /** @var string $sqlite_version Version de sqlite (2 ou 3) */
19
+    public $sqlite_version = '';
20
+
21
+    /** Pour les corrections à effectuer sur les requêtes : array(code=>'texte') trouvé
22
+     *
23
+     * @var array
24
+     */
25
+    public $textes = [];
26
+
27
+    /**
28
+     * Constructeur
29
+     *
30
+     * @param string $query Requête à préparer
31
+     * @param string $prefixe Prefixe des tables à utiliser
32
+     * @param string $sqlite_version Version SQLite (2 ou 3)
33
+     */
34
+    public function __construct($query, $prefixe, $sqlite_version)
35
+    {
36
+        $this->query = $query;
37
+        $this->prefixe = $prefixe;
38
+        $this->sqlite_version = $sqlite_version;
39
+    }
40
+
41
+    /**
42
+     * Transformer la requete pour SQLite
43
+     *
44
+     * Enlève les textes, transforme la requête pour quelle soit
45
+     * bien interprétée par SQLite, puis remet les textes
46
+     * la fonction affecte `$this->query`
47
+     */
48
+    public function traduire_requete()
49
+    {
50
+        //
51
+        // 1) Protection des textes en les remplacant par des codes
52
+        //
53
+        // enlever les 'textes' et initialiser avec
54
+        list($this->query, $textes) = query_echappe_textes($this->query);
55
+
56
+        //
57
+        // 2) Corrections de la requete
58
+        //
59
+        // Correction Create Database
60
+        // Create Database -> requete ignoree
61
+        if (strpos($this->query, 'CREATE DATABASE') === 0) {
62
+            spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT);
63
+            $this->query = 'SELECT 1';
64
+        }
65
+
66
+        // Correction Insert Ignore
67
+        // INSERT IGNORE -> insert (tout court et pas 'insert or replace')
68
+        if (strpos($this->query, 'INSERT IGNORE') === 0) {
69
+            spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG);
70
+            $this->query = 'INSERT ' . substr($this->query, '13');
71
+        }
72
+
73
+        // Correction des dates avec INTERVAL
74
+        // utiliser sql_date_proche() de preference
75
+        if (strpos($this->query, 'INTERVAL') !== false) {
76
+            $this->query = preg_replace_callback(
77
+                '/DATE_(ADD|SUB)(.*)INTERVAL\s+(\d+)\s+([a-zA-Z]+)\)/U',
78
+                [&$this, '_remplacerDateParTime'],
79
+                $this->query
80
+            );
81
+        }
82
+
83
+        if (strpos($this->query, 'LEFT(') !== false) {
84
+            $this->query = str_replace('LEFT(', '_LEFT(', $this->query);
85
+        }
86
+
87
+        if (strpos($this->query, 'TIMESTAMPDIFF(') !== false) {
88
+            $this->query = preg_replace('/TIMESTAMPDIFF\(\s*([^,]*)\s*,/Uims', "TIMESTAMPDIFF('\\1',", $this->query);
89
+        }
90
+
91
+
92
+        // Correction Using
93
+        // USING (non reconnu en sqlite2)
94
+        // problematique car la jointure ne se fait pas du coup.
95
+        if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) {
96
+            spip_log(
97
+                "'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'",
98
+                'sqlite.' . _LOG_ERREUR
99
+            );
100
+            $this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query);
101
+        }
102
+
103
+        // Correction Field
104
+        // remplace FIELD(table,i,j,k...) par CASE WHEN table=i THEN n ... ELSE 0 END
105
+        if (strpos($this->query, 'FIELD') !== false) {
106
+            $this->query = preg_replace_callback(
107
+                '/FIELD\s*\(([^\)]*)\)/',
108
+                [&$this, '_remplacerFieldParCase'],
109
+                $this->query
110
+            );
111
+        }
112
+
113
+        // Correction des noms de tables FROM
114
+        // mettre les bons noms de table dans from, update, insert, replace...
115
+        if (preg_match('/\s(SET|VALUES|WHERE|DATABASE)\s/iS', $this->query, $regs)) {
116
+            $suite = strstr($this->query, $regs[0]);
117
+            $this->query = substr($this->query, 0, -strlen($suite));
118
+        } else {
119
+            $suite = '';
120
+        }
121
+        $pref = ($this->prefixe) ? $this->prefixe . '_' : '';
122
+        $this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite;
123
+
124
+        // Correction zero AS x
125
+        // pg n'aime pas 0+x AS alias, sqlite, dans le meme style,
126
+        // n'apprecie pas du tout SELECT 0 as x ... ORDER BY x
127
+        // il dit que x ne doit pas être un integer dans le order by !
128
+        // on remplace du coup x par vide() dans ce cas uniquement
129
+        //
130
+        // apparait dans public/vertebrer.php et dans le plugin menu aussi qui genere aussi ce genre de requete via un {par num #GET{tri_num}}
131
+        // mais est-ce encore un soucis pour sqlite en 2021 ? (ie commenter le preg_replace marche très bien en sqlite 3.28)
132
+        if ((strpos($this->query, '0 AS') !== false)) {
133
+            // on ne remplace que dans ORDER BY ou GROUP BY
134
+            if (preg_match('/\s(ORDER|GROUP) BY\s/i', $this->query, $regs)) {
135
+                $suite = strstr($this->query, $regs[0]);
136
+                $this->query = substr($this->query, 0, -strlen($suite));
137
+
138
+                // on cherche les noms des x dans 0 AS x
139
+                // on remplace dans $suite le nom par vide()
140
+                preg_match_all('/\b0 AS\s*([^\s,]+)/', $this->query, $matches, PREG_PATTERN_ORDER);
141
+                foreach ($matches[1] as $m) {
142
+                    if (strpos($suite, $m) !== false) {
143
+                        $suite = preg_replace(",\b$m\b,", 'VIDE()', $suite);
144
+                    }
145
+                }
146
+                $this->query .= $suite;
147
+            }
148
+        }
149
+
150
+        // Correction possible des divisions entieres
151
+        // Le standard SQL (lequel? ou?) semble indiquer que
152
+        // a/b=c doit donner c entier si a et b sont entiers 4/3=1.
153
+        // C'est ce que retournent effectivement SQL Server et SQLite
154
+        // Ce n'est pas ce qu'applique MySQL qui retourne un reel : 4/3=1.333...
155
+        //
156
+        // On peut forcer la conversion en multipliant par 1.0 avant la division
157
+        // /!\ SQLite 3.5.9 Debian/Ubuntu est victime d'un bug en plus !
158
+        // cf. https://bugs.launchpad.net/ubuntu/+source/sqlite3/+bug/254228
159
+        //     http://www.sqlite.org/cvstrac/tktview?tn=3202
160
+        // (4*1.0/3) n'est pas rendu dans ce cas !
161
+        # $this->query = str_replace('/','* 1.00 / ',$this->query);
162
+
163
+
164
+        // Correction critere REGEXP, non reconnu en sqlite2
165
+        if (($this->sqlite_version == 2) && (strpos($this->query, 'REGEXP') !== false)) {
166
+            $this->query = preg_replace('/([^\s\(]*)(\s*)REGEXP(\s*)([^\s\)]*)/', 'REGEXP($4, $1)', $this->query);
167
+        }
168
+
169
+        //
170
+        // 3) Remise en place des textes d'origine
171
+        //
172
+        // Correction Antiquotes et echappements
173
+        // ` => rien
174
+        if (strpos($this->query, '`') !== false) {
175
+            $this->query = str_replace('`', '', $this->query);
176
+        }
177
+
178
+        $this->query = query_reinjecte_textes($this->query, $textes);
179
+
180
+        return $this->query;
181
+    }
182
+
183
+    /**
184
+     * Callback pour remplacer `DATE_` / `INTERVAL`
185
+     * par `DATE ... strtotime`
186
+     *
187
+     * @param array $matches Captures
188
+     * @return string texte de date compris par SQLite
189
+     */
190
+    public function _remplacerDateParTime($matches)
191
+    {
192
+        $op = strtoupper($matches[1] == 'ADD') ? '+' : '-';
193
+
194
+        return "datetime$matches[2] '$op$matches[3] $matches[4]')";
195
+    }
196
+
197
+    /**
198
+     * Callback pour remplacer `FIELD(table,i,j,k...)`
199
+     * par `CASE WHEN table=i THEN n ... ELSE 0 END`
200
+     *
201
+     * @param array $matches Captures
202
+     * @return string texte de liste ordonnée compris par SQLite
203
+     */
204
+    public function _remplacerFieldParCase($matches)
205
+    {
206
+        $fields = substr($matches[0], 6, -1); // ne recuperer que l'interieur X de field(X)
207
+        $t = explode(',', $fields);
208
+        $index = array_shift($t);
209
+
210
+        $res = '';
211
+        $n = 0;
212
+        foreach ($t as $v) {
213
+            $n++;
214
+            $res .= "\nWHEN $index=$v THEN $n";
215
+        }
216
+
217
+        return "CASE $res ELSE 0 END ";
218
+    }
219 219
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -59,15 +59,15 @@  discard block
 block discarded – undo
59 59
 		// Correction Create Database
60 60
 		// Create Database -> requete ignoree
61 61
 		if (strpos($this->query, 'CREATE DATABASE') === 0) {
62
-			spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.' . _LOG_AVERTISSEMENT);
62
+			spip_log("Sqlite : requete non executee -> $this->query", 'sqlite.'._LOG_AVERTISSEMENT);
63 63
 			$this->query = 'SELECT 1';
64 64
 		}
65 65
 
66 66
 		// Correction Insert Ignore
67 67
 		// INSERT IGNORE -> insert (tout court et pas 'insert or replace')
68 68
 		if (strpos($this->query, 'INSERT IGNORE') === 0) {
69
-			spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.' . _LOG_DEBUG);
70
-			$this->query = 'INSERT ' . substr($this->query, '13');
69
+			spip_log("Sqlite : requete transformee -> $this->query", 'sqlite.'._LOG_DEBUG);
70
+			$this->query = 'INSERT '.substr($this->query, '13');
71 71
 		}
72 72
 
73 73
 		// Correction des dates avec INTERVAL
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 		if (($this->sqlite_version == 2) && (strpos($this->query, 'USING') !== false)) {
96 96
 			spip_log(
97 97
 				"'USING (champ)' n'est pas reconnu en SQLite 2. Utilisez 'ON table1.champ = table2.champ'",
98
-				'sqlite.' . _LOG_ERREUR
98
+				'sqlite.'._LOG_ERREUR
99 99
 			);
100 100
 			$this->query = preg_replace('/USING\s*\([^\)]*\)/', '', $this->query);
101 101
 		}
@@ -118,8 +118,8 @@  discard block
 block discarded – undo
118 118
 		} else {
119 119
 			$suite = '';
120 120
 		}
121
-		$pref = ($this->prefixe) ? $this->prefixe . '_' : '';
122
-		$this->query = preg_replace('/([,\s])spip_/S', '\1' . $pref, $this->query) . $suite;
121
+		$pref = ($this->prefixe) ? $this->prefixe.'_' : '';
122
+		$this->query = preg_replace('/([,\s])spip_/S', '\1'.$pref, $this->query).$suite;
123 123
 
124 124
 		// Correction zero AS x
125 125
 		// pg n'aime pas 0+x AS alias, sqlite, dans le meme style,
Please login to merge, or discard this patch.
ecrire/req/sqlite_generique.php 2 patches
Indentation   +1616 added lines, -1616 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
 // TODO: get/set_caracteres ?
@@ -45,88 +45,88 @@  discard block
 block discarded – undo
45 45
  */
46 46
 function req_sqlite_dist($addr, $port, $login, $pass, $db = '', $prefixe = '', $sqlite_version = '')
47 47
 {
48
-	static $last_connect = [];
49
-
50
-	// si provient de selectdb
51
-	// un code pour etre sur que l'on vient de select_db()
52
-	if (strpos($db, $code = '@selectdb@') !== false) {
53
-		foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
54
-			$$a = $last_connect[$a];
55
-		}
56
-		$db = str_replace($code, '', $db);
57
-	}
58
-
59
-	/*
48
+    static $last_connect = [];
49
+
50
+    // si provient de selectdb
51
+    // un code pour etre sur que l'on vient de select_db()
52
+    if (strpos($db, $code = '@selectdb@') !== false) {
53
+        foreach (['addr', 'port', 'login', 'pass', 'prefixe'] as $a) {
54
+            $$a = $last_connect[$a];
55
+        }
56
+        $db = str_replace($code, '', $db);
57
+    }
58
+
59
+    /*
60 60
 	 * En sqlite, seule l'adresse du fichier est importante.
61 61
 	 * Ce sera $db le nom,
62 62
 	 * le path est $addr
63 63
 	 * (_DIR_DB si $addr est vide)
64 64
 	 */
65
-	_sqlite_init();
66
-
67
-	// determiner le dossier de la base : $addr ou _DIR_DB
68
-	$f = _DIR_DB;
69
-	if ($addr and str_contains($addr, '/')) {
70
-		$f = rtrim($addr, '/') . '/';
71
-	}
72
-
73
-	// un nom de base demande et impossible d'obtenir la base, on s'en va :
74
-	// il faut que la base existe ou que le repertoire parent soit writable
75
-	if ($db and !is_file($f .= $db . '.sqlite') and !is_writable(dirname($f))) {
76
-		spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.' . _LOG_HS);
77
-
78
-		return false;
79
-	}
80
-
81
-	// charger les modules sqlite au besoin
82
-	if (!_sqlite_charger_version($sqlite_version)) {
83
-		spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.' . _LOG_HS);
84
-
85
-		return false;
86
-	}
87
-
88
-	// chargement des constantes
89
-	// il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
90
-	$define = 'spip_sqlite' . $sqlite_version . '_constantes';
91
-	$define();
92
-
93
-	if (!$db) {
94
-		// si pas de db ->
95
-		// base temporaire tant qu'on ne connait pas son vrai nom
96
-		// pour tester la connexion
97
-		$db = '_sqlite' . $sqlite_version . '_install';
98
-		$tmp = _DIR_DB . $db . '.sqlite';
99
-		$link = spip_sqlite_open($tmp);
100
-	} else {
101
-		// Ouvrir (eventuellement creer la base)
102
-		$link = spip_sqlite_open($f);
103
-	}
104
-
105
-	if (!$link) {
106
-		spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f", 'sqlite.' . _LOG_HS);
107
-
108
-		return false;
109
-	}
110
-
111
-	$last_connect = [
112
-		'addr' => $addr,
113
-		'port' => $port,
114
-		'login' => $login,
115
-		'pass' => $pass,
116
-		'db' => $db,
117
-		'prefixe' => $prefixe,
118
-	];
119
-
120
-	// etre sur qu'on definit bien les fonctions a chaque nouvelle connexion
121
-	include_spip('req/sqlite_fonctions');
122
-	_sqlite_init_functions($link);
123
-
124
-	return [
125
-		'db' => $db,
126
-		'prefixe' => $prefixe ? $prefixe : $db,
127
-		'link' => $link,
128
-		'total_requetes' => 0,
129
-	];
65
+    _sqlite_init();
66
+
67
+    // determiner le dossier de la base : $addr ou _DIR_DB
68
+    $f = _DIR_DB;
69
+    if ($addr and str_contains($addr, '/')) {
70
+        $f = rtrim($addr, '/') . '/';
71
+    }
72
+
73
+    // un nom de base demande et impossible d'obtenir la base, on s'en va :
74
+    // il faut que la base existe ou que le repertoire parent soit writable
75
+    if ($db and !is_file($f .= $db . '.sqlite') and !is_writable(dirname($f))) {
76
+        spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.' . _LOG_HS);
77
+
78
+        return false;
79
+    }
80
+
81
+    // charger les modules sqlite au besoin
82
+    if (!_sqlite_charger_version($sqlite_version)) {
83
+        spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.' . _LOG_HS);
84
+
85
+        return false;
86
+    }
87
+
88
+    // chargement des constantes
89
+    // il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
90
+    $define = 'spip_sqlite' . $sqlite_version . '_constantes';
91
+    $define();
92
+
93
+    if (!$db) {
94
+        // si pas de db ->
95
+        // base temporaire tant qu'on ne connait pas son vrai nom
96
+        // pour tester la connexion
97
+        $db = '_sqlite' . $sqlite_version . '_install';
98
+        $tmp = _DIR_DB . $db . '.sqlite';
99
+        $link = spip_sqlite_open($tmp);
100
+    } else {
101
+        // Ouvrir (eventuellement creer la base)
102
+        $link = spip_sqlite_open($f);
103
+    }
104
+
105
+    if (!$link) {
106
+        spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f", 'sqlite.' . _LOG_HS);
107
+
108
+        return false;
109
+    }
110
+
111
+    $last_connect = [
112
+        'addr' => $addr,
113
+        'port' => $port,
114
+        'login' => $login,
115
+        'pass' => $pass,
116
+        'db' => $db,
117
+        'prefixe' => $prefixe,
118
+    ];
119
+
120
+    // etre sur qu'on definit bien les fonctions a chaque nouvelle connexion
121
+    include_spip('req/sqlite_fonctions');
122
+    _sqlite_init_functions($link);
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
 /**
@@ -137,9 +137,9 @@  discard block
 block discarded – undo
137 137
  * @return PDO
138 138
  */
139 139
 function spip_sqlite_open(string $file): \PDO {
140
-	$PDO = new \PDO("sqlite:$file");
141
-	$PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS , [\Spip\Sql\Sqlite\PDOStatement::class, [&$PDO]]);
142
-	return $PDO;
140
+    $PDO = new \PDO("sqlite:$file");
141
+    $PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS , [\Spip\Sql\Sqlite\PDOStatement::class, [&$PDO]]);
142
+    return $PDO;
143 143
 }
144 144
 
145 145
 
@@ -159,14 +159,14 @@  discard block
 block discarded – undo
159 159
  */
160 160
 function spip_sqlite_query($query, $serveur = '', $requeter = true)
161 161
 {
162
-	#spip_log("spip_sqlite_query() > $query",'sqlite.'._LOG_DEBUG);
163
-	#_sqlite_init(); // fait la premiere fois dans spip_sqlite
164
-	$query = Sqlite::traduire_requete($query, $serveur);
165
-	if (!$requeter) {
166
-		return $query;
167
-	}
168
-
169
-	return Sqlite::executer_requete($query, $serveur);
162
+    #spip_log("spip_sqlite_query() > $query",'sqlite.'._LOG_DEBUG);
163
+    #_sqlite_init(); // fait la premiere fois dans spip_sqlite
164
+    $query = Sqlite::traduire_requete($query, $serveur);
165
+    if (!$requeter) {
166
+        return $query;
167
+    }
168
+
169
+    return Sqlite::executer_requete($query, $serveur);
170 170
 }
171 171
 
172 172
 
@@ -184,11 +184,11 @@  discard block
 block discarded – undo
184 184
 function spip_sqlite_alter($query, $serveur = '', $requeter = true)
185 185
 {
186 186
 
187
-	$query = spip_sqlite_query("ALTER $query", $serveur, false);
188
-	// traduire la requete pour recuperer les bons noms de table
189
-	$query = Sqlite::traduire_requete($query, $serveur);
187
+    $query = spip_sqlite_query("ALTER $query", $serveur, false);
188
+    // traduire la requete pour recuperer les bons noms de table
189
+    $query = Sqlite::traduire_requete($query, $serveur);
190 190
 
191
-	/*
191
+    /*
192 192
 		 * la il faut faire les transformations
193 193
 		 * si ALTER TABLE x (DROP|CHANGE) y
194 194
 		 *
@@ -197,251 +197,251 @@  discard block
 block discarded – undo
197 197
 		 * 3) faire chaque requete independemment
198 198
 		 */
199 199
 
200
-	// 1
201
-	if (preg_match('/\s*(ALTER(\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
202
-		$debut = $regs[1];
203
-		$table = $regs[3];
204
-		$suite = $regs[4];
205
-	} else {
206
-		spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.' . _LOG_ERREUR);
207
-
208
-		return false;
209
-	}
210
-
211
-	// 2
212
-	// il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
213
-	// tout en cassant "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... en deux
214
-	// ou revoir l'api de sql_alter en creant un
215
-	// sql_alter_table($table,array($actions));
216
-	$todo = explode(',', $suite);
217
-
218
-	// on remet les morceaux dechires ensembles... que c'est laid !
219
-	$todo2 = [];
220
-	$i = 0;
221
-	$ouverte = false;
222
-	while ($do = array_shift($todo)) {
223
-		$todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
224
-		$o = (str_contains($do, '('));
225
-		$f = (str_contains($do, ')'));
226
-		if ($o and !$f) {
227
-			$ouverte = true;
228
-		} elseif ($f) {
229
-			$ouverte = false;
230
-		}
231
-		if (!$ouverte) {
232
-			$i++;
233
-		}
234
-	}
235
-
236
-	// 3
237
-	$resultats = [];
238
-	foreach ($todo2 as $do) {
239
-		$do = trim($do);
240
-		if (
241
-			!preg_match('/(DROP PRIMARY KEY|DROP KEY|DROP INDEX|DROP COLUMN|DROP'
242
-				. '|CHANGE COLUMN|CHANGE|MODIFY|RENAME TO|RENAME'
243
-				. '|ADD PRIMARY KEY|ADD KEY|ADD INDEX|ADD UNIQUE KEY|ADD UNIQUE'
244
-				. '|ADD COLUMN|ADD'
245
-				. ')\s*([^\s]*)\s*(.*)?/i', $do, $matches)
246
-		) {
247
-			spip_log(
248
-				"SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)",
249
-				'sqlite.' . _LOG_ERREUR
250
-			);
251
-
252
-			return false;
253
-		}
254
-
255
-		$cle = strtoupper($matches[1]);
256
-		$colonne_origine = $matches[2];
257
-		$colonne_destination = '';
258
-
259
-		$def = $matches[3];
260
-
261
-		// eluder une eventuelle clause before|after|first inutilisable
262
-		$defr = rtrim(preg_replace('/(BEFORE|AFTER|FIRST)(.*)$/is', '', $def));
263
-		$defo = $defr; // garder la def d'origine pour certains cas
264
-		// remplacer les definitions venant de mysql
265
-		$defr = _sqlite_remplacements_definitions_table($defr);
266
-
267
-		// reinjecter dans le do
268
-		$do = str_replace($def, $defr, $do);
269
-		$def = $defr;
270
-
271
-		switch ($cle) {
272
-				// suppression d'un index
273
-			case 'DROP KEY':
274
-			case 'DROP INDEX':
275
-				$nom_index = $colonne_origine;
276
-				spip_sqlite_drop_index($nom_index, $table, $serveur);
277
-				break;
278
-
279
-				// suppression d'une pk
280
-			case 'DROP PRIMARY KEY':
281
-				if (
282
-					!_sqlite_modifier_table(
283
-						$table,
284
-						$colonne_origine,
285
-						['key' => ['PRIMARY KEY' => '']],
286
-						$serveur
287
-					)
288
-				) {
289
-					return false;
290
-				}
291
-				break;
292
-				// suppression d'une colonne
293
-			case 'DROP COLUMN':
294
-			case 'DROP':
295
-				if (
296
-					!_sqlite_modifier_table(
297
-						$table,
298
-						[$colonne_origine => ''],
299
-						[],
300
-						$serveur
301
-					)
302
-				) {
303
-					return false;
304
-				}
305
-				break;
306
-
307
-			case 'CHANGE COLUMN':
308
-			case 'CHANGE':
309
-				// recuperer le nom de la future colonne
310
-				// on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
311
-				// en tenant compte de la cle primaire (ce qui est mieux)
312
-				$def = trim($defo);
313
-				$colonne_destination = substr($def, 0, strpos($def, ' '));
314
-				$def = substr($def, strlen($colonne_destination) + 1);
315
-
316
-				if (
317
-					!_sqlite_modifier_table(
318
-						$table,
319
-						[$colonne_origine => $colonne_destination],
320
-						['field' => [$colonne_destination => $def]],
321
-						$serveur
322
-					)
323
-				) {
324
-					return false;
325
-				}
326
-				break;
327
-
328
-			case 'MODIFY':
329
-				// on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
330
-				// en tenant compte de la cle primaire (ce qui est mieux)
331
-				if (
332
-					!_sqlite_modifier_table(
333
-						$table,
334
-						$colonne_origine,
335
-						['field' => [$colonne_origine => $defo]],
336
-						$serveur
337
-					)
338
-				) {
339
-					return false;
340
-				}
341
-				break;
342
-
343
-				// pas geres en sqlite2
344
-			case 'RENAME':
345
-				$do = 'RENAME TO' . substr($do, 6);
346
-			case 'RENAME TO':
347
-				if (!Sqlite::executer_requete("$debut $do", $serveur)) {
348
-					spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.' . _LOG_ERREUR);
349
-
350
-					return false;
351
-				}
352
-				break;
353
-
354
-				// ajout d'une pk
355
-			case 'ADD PRIMARY KEY':
356
-				$pk = trim(substr($do, 16));
357
-				$pk = ($pk[0] == '(') ? substr($pk, 1, -1) : $pk;
358
-				if (
359
-					!_sqlite_modifier_table(
360
-						$table,
361
-						$colonne_origine,
362
-						['key' => ['PRIMARY KEY' => $pk]],
363
-						$serveur
364
-					)
365
-				) {
366
-					return false;
367
-				}
368
-				break;
369
-				// ajout d'un index
370
-			case 'ADD UNIQUE KEY':
371
-			case 'ADD UNIQUE':
372
-				$unique = true;
373
-			case 'ADD INDEX':
374
-			case 'ADD KEY':
375
-				if (!isset($unique)) {
376
-					$unique = false;
377
-				}
378
-				// peut etre "(colonne)" ou "nom_index (colonnes)"
379
-				// bug potentiel si qqn met "(colonne, colonne)"
380
-				//
381
-				// nom_index (colonnes)
382
-				if ($def) {
383
-					$colonnes = substr($def, 1, -1);
384
-					$nom_index = $colonne_origine;
385
-				} else {
386
-					// (colonne)
387
-					if ($colonne_origine[0] == '(') {
388
-						$colonnes = substr($colonne_origine, 1, -1);
389
-						if (str_contains(',', $colonnes)) {
390
-							spip_log('SQLite : Erreur, impossible de creer un index sur plusieurs colonnes'
391
-								. " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.' . _LOG_ERREUR);
392
-							break;
393
-						} else {
394
-							$nom_index = $colonnes;
395
-						}
396
-					} // nom_index
397
-					else {
398
-						$nom_index = $colonnes = $colonne_origine;
399
-					}
400
-				}
401
-				spip_sqlite_create_index($nom_index, $table, $colonnes, $unique, $serveur);
402
-				break;
403
-
404
-				// pas geres en sqlite2
405
-			case 'ADD COLUMN':
406
-				$do = 'ADD' . substr($do, 10);
407
-			case 'ADD':
408
-			default:
409
-				if (!preg_match(',primary\s+key,i', $do)) {
410
-					if (!Sqlite::executer_requete("$debut $do", $serveur)) {
411
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
412
-
413
-						return false;
414
-					}
415
-					break;
416
-				}
417
-				// ou si la colonne est aussi primary key
418
-				// cas du add id_truc int primary key
419
-				// ajout d'une colonne qui passe en primary key directe
420
-				else {
421
-					$def = trim(substr($do, 3));
422
-					$colonne_ajoutee = substr($def, 0, strpos($def, ' '));
423
-					$def = substr($def, strlen($colonne_ajoutee) + 1);
424
-					$opts = [];
425
-					if (preg_match(',primary\s+key,i', $def)) {
426
-						$opts['key'] = ['PRIMARY KEY' => $colonne_ajoutee];
427
-						$def = preg_replace(',primary\s+key,i', '', $def);
428
-					}
429
-					$opts['field'] = [$colonne_ajoutee => $def];
430
-					if (!_sqlite_modifier_table($table, [$colonne_ajoutee], $opts, $serveur)) {
431
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
432
-
433
-						return false;
434
-					}
435
-				}
436
-				break;
437
-		}
438
-		// tout est bon, ouf !
439
-		spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.' . _LOG_INFO);
440
-	}
441
-
442
-	spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.' . _LOG_INFO);
443
-
444
-	return true;
200
+    // 1
201
+    if (preg_match('/\s*(ALTER(\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is', $query, $regs)) {
202
+        $debut = $regs[1];
203
+        $table = $regs[3];
204
+        $suite = $regs[4];
205
+    } else {
206
+        spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.' . _LOG_ERREUR);
207
+
208
+        return false;
209
+    }
210
+
211
+    // 2
212
+    // il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
213
+    // tout en cassant "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... en deux
214
+    // ou revoir l'api de sql_alter en creant un
215
+    // sql_alter_table($table,array($actions));
216
+    $todo = explode(',', $suite);
217
+
218
+    // on remet les morceaux dechires ensembles... que c'est laid !
219
+    $todo2 = [];
220
+    $i = 0;
221
+    $ouverte = false;
222
+    while ($do = array_shift($todo)) {
223
+        $todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
224
+        $o = (str_contains($do, '('));
225
+        $f = (str_contains($do, ')'));
226
+        if ($o and !$f) {
227
+            $ouverte = true;
228
+        } elseif ($f) {
229
+            $ouverte = false;
230
+        }
231
+        if (!$ouverte) {
232
+            $i++;
233
+        }
234
+    }
235
+
236
+    // 3
237
+    $resultats = [];
238
+    foreach ($todo2 as $do) {
239
+        $do = trim($do);
240
+        if (
241
+            !preg_match('/(DROP PRIMARY KEY|DROP KEY|DROP INDEX|DROP COLUMN|DROP'
242
+                . '|CHANGE COLUMN|CHANGE|MODIFY|RENAME TO|RENAME'
243
+                . '|ADD PRIMARY KEY|ADD KEY|ADD INDEX|ADD UNIQUE KEY|ADD UNIQUE'
244
+                . '|ADD COLUMN|ADD'
245
+                . ')\s*([^\s]*)\s*(.*)?/i', $do, $matches)
246
+        ) {
247
+            spip_log(
248
+                "SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)",
249
+                'sqlite.' . _LOG_ERREUR
250
+            );
251
+
252
+            return false;
253
+        }
254
+
255
+        $cle = strtoupper($matches[1]);
256
+        $colonne_origine = $matches[2];
257
+        $colonne_destination = '';
258
+
259
+        $def = $matches[3];
260
+
261
+        // eluder une eventuelle clause before|after|first inutilisable
262
+        $defr = rtrim(preg_replace('/(BEFORE|AFTER|FIRST)(.*)$/is', '', $def));
263
+        $defo = $defr; // garder la def d'origine pour certains cas
264
+        // remplacer les definitions venant de mysql
265
+        $defr = _sqlite_remplacements_definitions_table($defr);
266
+
267
+        // reinjecter dans le do
268
+        $do = str_replace($def, $defr, $do);
269
+        $def = $defr;
270
+
271
+        switch ($cle) {
272
+                // suppression d'un index
273
+            case 'DROP KEY':
274
+            case 'DROP INDEX':
275
+                $nom_index = $colonne_origine;
276
+                spip_sqlite_drop_index($nom_index, $table, $serveur);
277
+                break;
278
+
279
+                // suppression d'une pk
280
+            case 'DROP PRIMARY KEY':
281
+                if (
282
+                    !_sqlite_modifier_table(
283
+                        $table,
284
+                        $colonne_origine,
285
+                        ['key' => ['PRIMARY KEY' => '']],
286
+                        $serveur
287
+                    )
288
+                ) {
289
+                    return false;
290
+                }
291
+                break;
292
+                // suppression d'une colonne
293
+            case 'DROP COLUMN':
294
+            case 'DROP':
295
+                if (
296
+                    !_sqlite_modifier_table(
297
+                        $table,
298
+                        [$colonne_origine => ''],
299
+                        [],
300
+                        $serveur
301
+                    )
302
+                ) {
303
+                    return false;
304
+                }
305
+                break;
306
+
307
+            case 'CHANGE COLUMN':
308
+            case 'CHANGE':
309
+                // recuperer le nom de la future colonne
310
+                // on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
311
+                // en tenant compte de la cle primaire (ce qui est mieux)
312
+                $def = trim($defo);
313
+                $colonne_destination = substr($def, 0, strpos($def, ' '));
314
+                $def = substr($def, strlen($colonne_destination) + 1);
315
+
316
+                if (
317
+                    !_sqlite_modifier_table(
318
+                        $table,
319
+                        [$colonne_origine => $colonne_destination],
320
+                        ['field' => [$colonne_destination => $def]],
321
+                        $serveur
322
+                    )
323
+                ) {
324
+                    return false;
325
+                }
326
+                break;
327
+
328
+            case 'MODIFY':
329
+                // on reprend la def d'origine car _sqlite_modifier_table va refaire la translation
330
+                // en tenant compte de la cle primaire (ce qui est mieux)
331
+                if (
332
+                    !_sqlite_modifier_table(
333
+                        $table,
334
+                        $colonne_origine,
335
+                        ['field' => [$colonne_origine => $defo]],
336
+                        $serveur
337
+                    )
338
+                ) {
339
+                    return false;
340
+                }
341
+                break;
342
+
343
+                // pas geres en sqlite2
344
+            case 'RENAME':
345
+                $do = 'RENAME TO' . substr($do, 6);
346
+            case 'RENAME TO':
347
+                if (!Sqlite::executer_requete("$debut $do", $serveur)) {
348
+                    spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.' . _LOG_ERREUR);
349
+
350
+                    return false;
351
+                }
352
+                break;
353
+
354
+                // ajout d'une pk
355
+            case 'ADD PRIMARY KEY':
356
+                $pk = trim(substr($do, 16));
357
+                $pk = ($pk[0] == '(') ? substr($pk, 1, -1) : $pk;
358
+                if (
359
+                    !_sqlite_modifier_table(
360
+                        $table,
361
+                        $colonne_origine,
362
+                        ['key' => ['PRIMARY KEY' => $pk]],
363
+                        $serveur
364
+                    )
365
+                ) {
366
+                    return false;
367
+                }
368
+                break;
369
+                // ajout d'un index
370
+            case 'ADD UNIQUE KEY':
371
+            case 'ADD UNIQUE':
372
+                $unique = true;
373
+            case 'ADD INDEX':
374
+            case 'ADD KEY':
375
+                if (!isset($unique)) {
376
+                    $unique = false;
377
+                }
378
+                // peut etre "(colonne)" ou "nom_index (colonnes)"
379
+                // bug potentiel si qqn met "(colonne, colonne)"
380
+                //
381
+                // nom_index (colonnes)
382
+                if ($def) {
383
+                    $colonnes = substr($def, 1, -1);
384
+                    $nom_index = $colonne_origine;
385
+                } else {
386
+                    // (colonne)
387
+                    if ($colonne_origine[0] == '(') {
388
+                        $colonnes = substr($colonne_origine, 1, -1);
389
+                        if (str_contains(',', $colonnes)) {
390
+                            spip_log('SQLite : Erreur, impossible de creer un index sur plusieurs colonnes'
391
+                                . " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.' . _LOG_ERREUR);
392
+                            break;
393
+                        } else {
394
+                            $nom_index = $colonnes;
395
+                        }
396
+                    } // nom_index
397
+                    else {
398
+                        $nom_index = $colonnes = $colonne_origine;
399
+                    }
400
+                }
401
+                spip_sqlite_create_index($nom_index, $table, $colonnes, $unique, $serveur);
402
+                break;
403
+
404
+                // pas geres en sqlite2
405
+            case 'ADD COLUMN':
406
+                $do = 'ADD' . substr($do, 10);
407
+            case 'ADD':
408
+            default:
409
+                if (!preg_match(',primary\s+key,i', $do)) {
410
+                    if (!Sqlite::executer_requete("$debut $do", $serveur)) {
411
+                        spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
412
+
413
+                        return false;
414
+                    }
415
+                    break;
416
+                }
417
+                // ou si la colonne est aussi primary key
418
+                // cas du add id_truc int primary key
419
+                // ajout d'une colonne qui passe en primary key directe
420
+                else {
421
+                    $def = trim(substr($do, 3));
422
+                    $colonne_ajoutee = substr($def, 0, strpos($def, ' '));
423
+                    $def = substr($def, strlen($colonne_ajoutee) + 1);
424
+                    $opts = [];
425
+                    if (preg_match(',primary\s+key,i', $def)) {
426
+                        $opts['key'] = ['PRIMARY KEY' => $colonne_ajoutee];
427
+                        $def = preg_replace(',primary\s+key,i', '', $def);
428
+                    }
429
+                    $opts['field'] = [$colonne_ajoutee => $def];
430
+                    if (!_sqlite_modifier_table($table, [$colonne_ajoutee], $opts, $serveur)) {
431
+                        spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
432
+
433
+                        return false;
434
+                    }
435
+                }
436
+                break;
437
+        }
438
+        // tout est bon, ouf !
439
+        spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.' . _LOG_INFO);
440
+    }
441
+
442
+    spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.' . _LOG_INFO);
443
+
444
+    return true;
445 445
 }
446 446
 
447 447
 /**
@@ -463,38 +463,38 @@  discard block
 block discarded – undo
463 463
  *     - true si la requête réussie, false sinon.
464 464
  */
465 465
 function spip_sqlite_create(
466
-	$nom,
467
-	$champs,
468
-	$cles,
469
-	$autoinc = false,
470
-	$temporary = false,
471
-	$serveur = '',
472
-	$requeter = true
466
+    $nom,
467
+    $champs,
468
+    $cles,
469
+    $autoinc = false,
470
+    $temporary = false,
471
+    $serveur = '',
472
+    $requeter = true
473 473
 ) {
474
-	$query = _sqlite_requete_create($nom, $champs, $cles, $autoinc, $temporary, $ifnotexists = true, $serveur, $requeter);
475
-	if (!$query) {
476
-		return false;
477
-	}
478
-	$res = spip_sqlite_query($query, $serveur, $requeter);
479
-
480
-	// SQLite ne cree pas les KEY sur les requetes CREATE TABLE
481
-	// il faut donc les faire creer ensuite
482
-	if (!$requeter) {
483
-		return $res;
484
-	}
485
-
486
-	$ok = $res ? true : false;
487
-	if ($ok) {
488
-		foreach ($cles as $k => $v) {
489
-			if (preg_match(',^(UNIQUE KEY|KEY|UNIQUE)\s,i', $k, $m)) {
490
-				$index = trim(substr($k, strlen($m[1])));
491
-				$unique = (strlen($m[1]) > 3);
492
-				$ok &= spip_sqlite_create_index($index, $nom, $v, $unique, $serveur);
493
-			}
494
-		}
495
-	}
496
-
497
-	return $ok ? true : false;
474
+    $query = _sqlite_requete_create($nom, $champs, $cles, $autoinc, $temporary, $ifnotexists = true, $serveur, $requeter);
475
+    if (!$query) {
476
+        return false;
477
+    }
478
+    $res = spip_sqlite_query($query, $serveur, $requeter);
479
+
480
+    // SQLite ne cree pas les KEY sur les requetes CREATE TABLE
481
+    // il faut donc les faire creer ensuite
482
+    if (!$requeter) {
483
+        return $res;
484
+    }
485
+
486
+    $ok = $res ? true : false;
487
+    if ($ok) {
488
+        foreach ($cles as $k => $v) {
489
+            if (preg_match(',^(UNIQUE KEY|KEY|UNIQUE)\s,i', $k, $m)) {
490
+                $index = trim(substr($k, strlen($m[1])));
491
+                $unique = (strlen($m[1]) > 3);
492
+                $ok &= spip_sqlite_create_index($index, $nom, $v, $unique, $serveur);
493
+            }
494
+        }
495
+    }
496
+
497
+    return $ok ? true : false;
498 498
 }
499 499
 
500 500
 /**
@@ -508,21 +508,21 @@  discard block
 block discarded – undo
508 508
  **/
509 509
 function spip_sqlite_create_base($nom, $serveur = '', $option = true)
510 510
 {
511
-	$f = $nom . '.sqlite';
512
-	if (strpos($nom, '/') === false) {
513
-		$f = _DIR_DB . $f;
514
-	}
511
+    $f = $nom . '.sqlite';
512
+    if (strpos($nom, '/') === false) {
513
+        $f = _DIR_DB . $f;
514
+    }
515 515
 
516
-	$ok = new \PDO("sqlite:$f");
516
+    $ok = new \PDO("sqlite:$f");
517 517
 
518
-	if ($ok) {
519
-		unset($ok);
518
+    if ($ok) {
519
+        unset($ok);
520 520
 
521
-		return true;
522
-	}
523
-	unset($ok);
521
+        return true;
522
+    }
523
+    unset($ok);
524 524
 
525
-	return false;
525
+    return false;
526 526
 }
527 527
 
528 528
 
@@ -544,22 +544,22 @@  discard block
 block discarded – undo
544 544
  */
545 545
 function spip_sqlite_create_view($nom, $query_select, $serveur = '', $requeter = true)
546 546
 {
547
-	if (!$query_select) {
548
-		return false;
549
-	}
550
-	// vue deja presente
551
-	if (sql_showtable($nom, false, $serveur)) {
552
-		spip_log(
553
-			"Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)",
554
-			'sqlite.' . _LOG_ERREUR
555
-		);
556
-
557
-		return false;
558
-	}
559
-
560
-	$query = "CREATE VIEW $nom AS " . $query_select;
561
-
562
-	return spip_sqlite_query($query, $serveur, $requeter);
547
+    if (!$query_select) {
548
+        return false;
549
+    }
550
+    // vue deja presente
551
+    if (sql_showtable($nom, false, $serveur)) {
552
+        spip_log(
553
+            "Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)",
554
+            'sqlite.' . _LOG_ERREUR
555
+        );
556
+
557
+        return false;
558
+    }
559
+
560
+    $query = "CREATE VIEW $nom AS " . $query_select;
561
+
562
+    return spip_sqlite_query($query, $serveur, $requeter);
563 563
 }
564 564
 
565 565
 /**
@@ -582,54 +582,54 @@  discard block
 block discarded – undo
582 582
  */
583 583
 function spip_sqlite_create_index($nom, $table, $champs, $unique = '', $serveur = '', $requeter = true)
584 584
 {
585
-	if (!($nom or $table or $champs)) {
586
-		spip_log(
587
-			"Champ manquant pour creer un index sqlite ($nom, $table, (" . join(',', $champs) . '))',
588
-			'sqlite.' . _LOG_ERREUR
589
-		);
590
-
591
-		return false;
592
-	}
593
-
594
-	// SQLite ne differentie pas noms des index en fonction des tables
595
-	// il faut donc creer des noms uniques d'index pour une base sqlite
596
-	$nom = $table . '_' . $nom;
597
-	// enlever d'eventuelles parentheses deja presentes sur champs
598
-	if (!is_array($champs)) {
599
-		if ($champs[0] == '(') {
600
-			$champs = substr($champs, 1, -1);
601
-		}
602
-		$champs = [$champs];
603
-		// supprimer l'info de longueur d'index mysql en fin de champ
604
-		$champs = preg_replace(',\(\d+\)$,', '', $champs);
605
-	}
606
-
607
-	$ifnotexists = '';
608
-	$version = spip_sqlite_fetch(spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur), '', $serveur);
609
-	if (!function_exists('spip_version_compare')) {
610
-		include_spip('plugins/installer');
611
-	}
612
-
613
-	if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
614
-		$ifnotexists = ' IF NOT EXISTS';
615
-	} else {
616
-		/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
617
-		$a = spip_sqlite_showtable($table, $serveur);
618
-		if (isset($a['key']['KEY ' . $nom])) {
619
-			return true;
620
-		}
621
-	}
622
-
623
-	$query = 'CREATE ' . ($unique ? 'UNIQUE ' : '') . "INDEX$ifnotexists $nom ON $table (" . join(',', $champs) . ')';
624
-	$res = spip_sqlite_query($query, $serveur, $requeter);
625
-	if (!$requeter) {
626
-		return $res;
627
-	}
628
-	if ($res) {
629
-		return true;
630
-	} else {
631
-		return false;
632
-	}
585
+    if (!($nom or $table or $champs)) {
586
+        spip_log(
587
+            "Champ manquant pour creer un index sqlite ($nom, $table, (" . join(',', $champs) . '))',
588
+            'sqlite.' . _LOG_ERREUR
589
+        );
590
+
591
+        return false;
592
+    }
593
+
594
+    // SQLite ne differentie pas noms des index en fonction des tables
595
+    // il faut donc creer des noms uniques d'index pour une base sqlite
596
+    $nom = $table . '_' . $nom;
597
+    // enlever d'eventuelles parentheses deja presentes sur champs
598
+    if (!is_array($champs)) {
599
+        if ($champs[0] == '(') {
600
+            $champs = substr($champs, 1, -1);
601
+        }
602
+        $champs = [$champs];
603
+        // supprimer l'info de longueur d'index mysql en fin de champ
604
+        $champs = preg_replace(',\(\d+\)$,', '', $champs);
605
+    }
606
+
607
+    $ifnotexists = '';
608
+    $version = spip_sqlite_fetch(spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur), '', $serveur);
609
+    if (!function_exists('spip_version_compare')) {
610
+        include_spip('plugins/installer');
611
+    }
612
+
613
+    if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
614
+        $ifnotexists = ' IF NOT EXISTS';
615
+    } else {
616
+        /* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
617
+        $a = spip_sqlite_showtable($table, $serveur);
618
+        if (isset($a['key']['KEY ' . $nom])) {
619
+            return true;
620
+        }
621
+    }
622
+
623
+    $query = 'CREATE ' . ($unique ? 'UNIQUE ' : '') . "INDEX$ifnotexists $nom ON $table (" . join(',', $champs) . ')';
624
+    $res = spip_sqlite_query($query, $serveur, $requeter);
625
+    if (!$requeter) {
626
+        return $res;
627
+    }
628
+    if ($res) {
629
+        return true;
630
+    } else {
631
+        return false;
632
+    }
633 633
 }
634 634
 
635 635
 /**
@@ -646,24 +646,24 @@  discard block
 block discarded – undo
646 646
  */
647 647
 function spip_sqlite_count($r, $serveur = '', $requeter = true)
648 648
 {
649
-	if (!$r) {
650
-		return 0;
651
-	}
652
-
653
-	// select ou autre (insert, update,...) ?
654
-	// (link,requete) a compter
655
-	if (strtoupper(substr(ltrim($r->queryString), 0, 6)) === 'SELECT') {
656
-		$link = $r->getPDO();
657
-		$query = "SELECT count(*) as zzzzsqlitecount FROM ({$r->queryString})";
658
-		$l = $link->query($query);
659
-		$i = 0;
660
-		if ($l and $z = $l->fetch()) {
661
-			$i = (int) $z['zzzzsqlitecount'];
662
-		}
663
-		return $i;
664
-	}
665
-
666
-	return $r->rowCount();
649
+    if (!$r) {
650
+        return 0;
651
+    }
652
+
653
+    // select ou autre (insert, update,...) ?
654
+    // (link,requete) a compter
655
+    if (strtoupper(substr(ltrim($r->queryString), 0, 6)) === 'SELECT') {
656
+        $link = $r->getPDO();
657
+        $query = "SELECT count(*) as zzzzsqlitecount FROM ({$r->queryString})";
658
+        $l = $link->query($query);
659
+        $i = 0;
660
+        if ($l and $z = $l->fetch()) {
661
+            $i = (int) $z['zzzzsqlitecount'];
662
+        }
663
+        return $i;
664
+    }
665
+
666
+    return $r->rowCount();
667 667
 }
668 668
 
669 669
 
@@ -682,31 +682,31 @@  discard block
 block discarded – undo
682 682
  *     - false si la requête a échouée
683 683
  **/
684 684
 function spip_sqlite_countsel(
685
-	$from = [],
686
-	$where = [],
687
-	$groupby = '',
688
-	$having = [],
689
-	$serveur = '',
690
-	$requeter = true
685
+    $from = [],
686
+    $where = [],
687
+    $groupby = '',
688
+    $having = [],
689
+    $serveur = '',
690
+    $requeter = true
691 691
 ) {
692
-	$c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
693
-	$r = spip_sqlite_select(
694
-		"COUNT($c)",
695
-		$from,
696
-		$where,
697
-		'',
698
-		'',
699
-		'',
700
-		$having,
701
-		$serveur,
702
-		$requeter
703
-	);
704
-	if ((is_resource($r) or is_object($r)) && $requeter) { // ressource : sqlite2, object : sqlite3
705
-		[$r] = spip_sqlite_fetch($r, SPIP_SQLITE3_NUM, $serveur);
706
-		$r = (int) $r;
707
-	}
708
-
709
-	return $r;
692
+    $c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
693
+    $r = spip_sqlite_select(
694
+        "COUNT($c)",
695
+        $from,
696
+        $where,
697
+        '',
698
+        '',
699
+        '',
700
+        $having,
701
+        $serveur,
702
+        $requeter
703
+    );
704
+    if ((is_resource($r) or is_object($r)) && $requeter) { // ressource : sqlite2, object : sqlite3
705
+        [$r] = spip_sqlite_fetch($r, SPIP_SQLITE3_NUM, $serveur);
706
+        $r = (int) $r;
707
+    }
708
+
709
+    return $r;
710 710
 }
711 711
 
712 712
 
@@ -724,24 +724,24 @@  discard block
 block discarded – undo
724 724
  **/
725 725
 function spip_sqlite_delete($table, $where = '', $serveur = '', $requeter = true)
726 726
 {
727
-	$res = spip_sqlite_query(
728
-		_sqlite_calculer_expression('DELETE FROM', $table, ',')
729
-			. _sqlite_calculer_expression('WHERE', $where),
730
-		$serveur,
731
-		$requeter
732
-	);
733
-
734
-	// renvoyer la requete inerte si demandee
735
-	if (!$requeter) {
736
-		return $res;
737
-	}
738
-
739
-	if ($res) {
740
-		$link = _sqlite_link($serveur);
741
-		return $res->rowCount();
742
-	} else {
743
-		return false;
744
-	}
727
+    $res = spip_sqlite_query(
728
+        _sqlite_calculer_expression('DELETE FROM', $table, ',')
729
+            . _sqlite_calculer_expression('WHERE', $where),
730
+        $serveur,
731
+        $requeter
732
+    );
733
+
734
+    // renvoyer la requete inerte si demandee
735
+    if (!$requeter) {
736
+        return $res;
737
+    }
738
+
739
+    if ($res) {
740
+        $link = _sqlite_link($serveur);
741
+        return $res->rowCount();
742
+    } else {
743
+        return false;
744
+    }
745 745
 }
746 746
 
747 747
 
@@ -758,15 +758,15 @@  discard block
 block discarded – undo
758 758
  */
759 759
 function spip_sqlite_drop_table($table, $exist = '', $serveur = '', $requeter = true)
760 760
 {
761
-	if ($exist) {
762
-		$exist = ' IF EXISTS';
763
-	}
764
-
765
-	if (spip_sqlite_query("DROP TABLE$exist $table", $serveur, $requeter)) {
766
-		return true;
767
-	} else {
768
-		return false;
769
-	}
761
+    if ($exist) {
762
+        $exist = ' IF EXISTS';
763
+    }
764
+
765
+    if (spip_sqlite_query("DROP TABLE$exist $table", $serveur, $requeter)) {
766
+        return true;
767
+    } else {
768
+        return false;
769
+    }
770 770
 }
771 771
 
772 772
 
@@ -783,11 +783,11 @@  discard block
 block discarded – undo
783 783
  */
784 784
 function spip_sqlite_drop_view($view, $exist = '', $serveur = '', $requeter = true)
785 785
 {
786
-	if ($exist) {
787
-		$exist = ' IF EXISTS';
788
-	}
786
+    if ($exist) {
787
+        $exist = ' IF EXISTS';
788
+    }
789 789
 
790
-	return spip_sqlite_query("DROP VIEW$exist $view", $serveur, $requeter);
790
+    return spip_sqlite_query("DROP VIEW$exist $view", $serveur, $requeter);
791 791
 }
792 792
 
793 793
 /**
@@ -802,20 +802,20 @@  discard block
 block discarded – undo
802 802
  */
803 803
 function spip_sqlite_drop_index($nom, $table, $serveur = '', $requeter = true)
804 804
 {
805
-	if (!($nom or $table)) {
806
-		spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.' . _LOG_ERREUR);
805
+    if (!($nom or $table)) {
806
+        spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.' . _LOG_ERREUR);
807 807
 
808
-		return false;
809
-	}
808
+        return false;
809
+    }
810 810
 
811
-	// SQLite ne differentie pas noms des index en fonction des tables
812
-	// il faut donc creer des noms uniques d'index pour une base sqlite
813
-	$index = $table . '_' . $nom;
814
-	$exist = ' IF EXISTS';
811
+    // SQLite ne differentie pas noms des index en fonction des tables
812
+    // il faut donc creer des noms uniques d'index pour une base sqlite
813
+    $index = $table . '_' . $nom;
814
+    $exist = ' IF EXISTS';
815 815
 
816
-	$query = "DROP INDEX$exist $index";
816
+    $query = "DROP INDEX$exist $index";
817 817
 
818
-	return spip_sqlite_query($query, $serveur, $requeter);
818
+    return spip_sqlite_query($query, $serveur, $requeter);
819 819
 }
820 820
 
821 821
 /**
@@ -832,29 +832,29 @@  discard block
 block discarded – undo
832 832
  **/
833 833
 function spip_sqlite_error($query = '', $serveur = '')
834 834
 {
835
-	$link = _sqlite_link($serveur);
836
-
837
-	if ($link) {
838
-		$errs = $link->errorInfo();
839
-		$s = _sqlite_last_error_from_link($link);
840
-	} else {
841
-		$s = ': aucune ressource sqlite (link)';
842
-	}
843
-	if ($s) {
844
-		$trace = debug_backtrace();
845
-		if ($trace[0]['function'] != 'spip_sqlite_error') {
846
-			spip_log("$s - $query - " . sql_error_backtrace(), 'sqlite.' . _LOG_ERREUR);
847
-		}
848
-	}
849
-
850
-	return $s;
835
+    $link = _sqlite_link($serveur);
836
+
837
+    if ($link) {
838
+        $errs = $link->errorInfo();
839
+        $s = _sqlite_last_error_from_link($link);
840
+    } else {
841
+        $s = ': aucune ressource sqlite (link)';
842
+    }
843
+    if ($s) {
844
+        $trace = debug_backtrace();
845
+        if ($trace[0]['function'] != 'spip_sqlite_error') {
846
+            spip_log("$s - $query - " . sql_error_backtrace(), 'sqlite.' . _LOG_ERREUR);
847
+        }
848
+    }
849
+
850
+    return $s;
851 851
 }
852 852
 
853 853
 function _sqlite_last_error_from_link($link)
854 854
 {
855
-	if ($link) {
856
-		$errs = $link->errorInfo();
857
-		/*
855
+    if ($link) {
856
+        $errs = $link->errorInfo();
857
+        /*
858 858
 			$errs[0]
859 859
 				numero SQLState ('HY000' souvent lors d'une erreur)
860 860
 				http://www.easysoft.com/developer/interfaces/odbc/sqlstate_status_return_codes.html
@@ -864,11 +864,11 @@  discard block
 block discarded – undo
864 864
 			$errs[2]
865 865
 				Le texte du message d'erreur
866 866
 		*/
867
-		if (ltrim($errs[0], '0')) { // 00000 si pas d'erreur
868
-			return "$errs[2]";
869
-		}
870
-	}
871
-	return '';
867
+        if (ltrim($errs[0], '0')) { // 00000 si pas d'erreur
868
+            return "$errs[2]";
869
+        }
870
+    }
871
+    return '';
872 872
 }
873 873
 
874 874
 /**
@@ -886,23 +886,23 @@  discard block
 block discarded – undo
886 886
  **/
887 887
 function spip_sqlite_errno($serveur = '')
888 888
 {
889
-	$link = _sqlite_link($serveur);
890
-
891
-	if ($link) {
892
-		$t = $link->errorInfo();
893
-		$s = ltrim($t[0], '0'); // 00000 si pas d'erreur
894
-		if ($s) {
895
-			$s .= ' / ' . $t[1];
896
-		} // ajoute l'erreur du moteur SQLite
897
-	} else {
898
-		$s = ': aucune ressource sqlite (link)';
899
-	}
900
-
901
-	if ($s) {
902
-		spip_log("Erreur sqlite $s", 'sqlite.' . _LOG_ERREUR);
903
-	}
904
-
905
-	return $s ? $s : 0;
889
+    $link = _sqlite_link($serveur);
890
+
891
+    if ($link) {
892
+        $t = $link->errorInfo();
893
+        $s = ltrim($t[0], '0'); // 00000 si pas d'erreur
894
+        if ($s) {
895
+            $s .= ' / ' . $t[1];
896
+        } // ajoute l'erreur du moteur SQLite
897
+    } else {
898
+        $s = ': aucune ressource sqlite (link)';
899
+    }
900
+
901
+    if ($s) {
902
+        spip_log("Erreur sqlite $s", 'sqlite.' . _LOG_ERREUR);
903
+    }
904
+
905
+    return $s ? $s : 0;
906 906
 }
907 907
 
908 908
 
@@ -919,19 +919,19 @@  discard block
 block discarded – undo
919 919
  */
920 920
 function spip_sqlite_explain($query, $serveur = '', $requeter = true)
921 921
 {
922
-	if (strpos(ltrim($query), 'SELECT') !== 0) {
923
-		return [];
924
-	}
925
-
926
-	$query = Sqlite::traduire_requete($query, $serveur);
927
-	$query = 'EXPLAIN ' . $query;
928
-	if (!$requeter) {
929
-		return $query;
930
-	}
931
-	// on ne trace pas ces requetes, sinon on obtient un tracage sans fin...
932
-	$r = Sqlite::executer_requete($query, $serveur, false);
933
-
934
-	return $r ? spip_sqlite_fetch($r, null, $serveur) : false; // hum ? etrange ca... a verifier
922
+    if (strpos(ltrim($query), 'SELECT') !== 0) {
923
+        return [];
924
+    }
925
+
926
+    $query = Sqlite::traduire_requete($query, $serveur);
927
+    $query = 'EXPLAIN ' . $query;
928
+    if (!$requeter) {
929
+        return $query;
930
+    }
931
+    // on ne trace pas ces requetes, sinon on obtient un tracage sans fin...
932
+    $r = Sqlite::executer_requete($query, $serveur, false);
933
+
934
+    return $r ? spip_sqlite_fetch($r, null, $serveur) : false; // hum ? etrange ca... a verifier
935 935
 }
936 936
 
937 937
 
@@ -952,35 +952,35 @@  discard block
 block discarded – undo
952 952
 function spip_sqlite_fetch($r, $t = '', $serveur = '', $requeter = true)
953 953
 {
954 954
 
955
-	$link = _sqlite_link($serveur);
956
-	$t = $t ? $t : SPIP_SQLITE3_ASSOC;
957
-
958
-	if (!$r) {
959
-		return false;
960
-	}
961
-
962
-	$retour = $r->fetch($t);
963
-
964
-	if (!$retour) {
965
-		if ($r->errorCode() === '00000') {
966
-			return null;
967
-		}
968
-		return false;
969
-	}
970
-
971
-	// Renvoie des 'table.titre' au lieu de 'titre' tout court ! pff !
972
-	// suppression de 'table.' pour toutes les cles (c'est un peu violent !)
973
-	// c'est couteux : on ne verifie que la premiere ligne pour voir si on le fait ou non
974
-	if (str_contains(implode('', array_keys($retour)), '.')) {
975
-		foreach ($retour as $cle => $val) {
976
-			if (($pos = strpos($cle, '.')) !== false) {
977
-				$retour[substr($cle, $pos + 1)] = &$retour[$cle];
978
-				unset($retour[$cle]);
979
-			}
980
-		}
981
-	}
982
-
983
-	return $retour;
955
+    $link = _sqlite_link($serveur);
956
+    $t = $t ? $t : SPIP_SQLITE3_ASSOC;
957
+
958
+    if (!$r) {
959
+        return false;
960
+    }
961
+
962
+    $retour = $r->fetch($t);
963
+
964
+    if (!$retour) {
965
+        if ($r->errorCode() === '00000') {
966
+            return null;
967
+        }
968
+        return false;
969
+    }
970
+
971
+    // Renvoie des 'table.titre' au lieu de 'titre' tout court ! pff !
972
+    // suppression de 'table.' pour toutes les cles (c'est un peu violent !)
973
+    // c'est couteux : on ne verifie que la premiere ligne pour voir si on le fait ou non
974
+    if (str_contains(implode('', array_keys($retour)), '.')) {
975
+        foreach ($retour as $cle => $val) {
976
+            if (($pos = strpos($cle, '.')) !== false) {
977
+                $retour[substr($cle, $pos + 1)] = &$retour[$cle];
978
+                unset($retour[$cle]);
979
+            }
980
+        }
981
+    }
982
+
983
+    return $retour;
984 984
 }
985 985
 
986 986
 /**
@@ -994,8 +994,8 @@  discard block
 block discarded – undo
994 994
  **/
995 995
 function spip_sqlite_seek($r, $row_number, $serveur = '', $requeter = true)
996 996
 {
997
-	// encore un truc de bien fichu : PDO ne PEUT PAS faire de seek ou de rewind...
998
-	return false;
997
+    // encore un truc de bien fichu : PDO ne PEUT PAS faire de seek ou de rewind...
998
+    return false;
999 999
 }
1000 1000
 
1001 1001
 
@@ -1012,10 +1012,10 @@  discard block
 block discarded – undo
1012 1012
  */
1013 1013
 function spip_sqlite_free(&$r, $serveur = '', $requeter = true)
1014 1014
 {
1015
-	unset($r);
1015
+    unset($r);
1016 1016
 
1017
-	return true;
1018
-	//return sqlite_free_result($r);
1017
+    return true;
1018
+    //return sqlite_free_result($r);
1019 1019
 }
1020 1020
 
1021 1021
 
@@ -1031,8 +1031,8 @@  discard block
 block discarded – undo
1031 1031
  */
1032 1032
 function spip_sqlite_get_charset($charset = [], $serveur = '', $requeter = true)
1033 1033
 {
1034
-	//$c = !$charset ? '' : (" LIKE "._q($charset['charset']));
1035
-	//return spip_sqlite_fetch(sqlite_query(_sqlite_link($serveur), "SHOW CHARACTER SET$c"), NULL, $serveur);
1034
+    //$c = !$charset ? '' : (" LIKE "._q($charset['charset']));
1035
+    //return spip_sqlite_fetch(sqlite_query(_sqlite_link($serveur), "SHOW CHARACTER SET$c"), NULL, $serveur);
1036 1036
 }
1037 1037
 
1038 1038
 
@@ -1048,7 +1048,7 @@  discard block
 block discarded – undo
1048 1048
  **/
1049 1049
 function spip_sqlite_hex($v)
1050 1050
 {
1051
-	return hexdec($v);
1051
+    return hexdec($v);
1052 1052
 }
1053 1053
 
1054 1054
 
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
  **/
1072 1072
 function spip_sqlite_in($val, $valeurs, $not = '', $serveur = '', $requeter = true)
1073 1073
 {
1074
-	return "($val $not IN ($valeurs))";
1074
+    return "($val $not IN ($valeurs))";
1075 1075
 }
1076 1076
 
1077 1077
 
@@ -1100,20 +1100,20 @@  discard block
 block discarded – undo
1100 1100
 function spip_sqlite_insert($table, $champs, $valeurs, $desc = [], $serveur = '', $requeter = true)
1101 1101
 {
1102 1102
 
1103
-	$query = "INSERT INTO $table " . ($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1104
-	if ($r = spip_sqlite_query($query, $serveur, $requeter)) {
1105
-		if (!$requeter) {
1106
-			return $r;
1107
-		}
1108
-		$nb = Sqlite::last_insert_id($serveur);
1109
-	} else {
1110
-		$nb = false;
1111
-	}
1103
+    $query = "INSERT INTO $table " . ($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1104
+    if ($r = spip_sqlite_query($query, $serveur, $requeter)) {
1105
+        if (!$requeter) {
1106
+            return $r;
1107
+        }
1108
+        $nb = Sqlite::last_insert_id($serveur);
1109
+    } else {
1110
+        $nb = false;
1111
+    }
1112 1112
 
1113
-	$err = spip_sqlite_error($query, $serveur);
1113
+    $err = spip_sqlite_error($query, $serveur);
1114 1114
 
1115
-	// cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1116
-	return isset($_GET['var_profile']) ? $r : $nb;
1115
+    // cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1116
+    return isset($_GET['var_profile']) ? $r : $nb;
1117 1117
 }
1118 1118
 
1119 1119
 
@@ -1139,28 +1139,28 @@  discard block
 block discarded – undo
1139 1139
  **/
1140 1140
 function spip_sqlite_insertq($table, $couples = [], $desc = [], $serveur = '', $requeter = true)
1141 1141
 {
1142
-	if (!$desc) {
1143
-		$desc = description_table($table, $serveur);
1144
-	}
1145
-	if (!$desc) {
1146
-		die("$table insertion sans description");
1147
-	}
1148
-	$fields = isset($desc['field']) ? $desc['field'] : [];
1149
-
1150
-	foreach ($couples as $champ => $val) {
1151
-		$couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1152
-	}
1153
-
1154
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1155
-	$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1156
-
1157
-	$cles = $valeurs = '';
1158
-	if (count($couples)) {
1159
-		$cles = '(' . join(',', array_keys($couples)) . ')';
1160
-		$valeurs = '(' . join(',', $couples) . ')';
1161
-	}
1162
-
1163
-	return spip_sqlite_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1142
+    if (!$desc) {
1143
+        $desc = description_table($table, $serveur);
1144
+    }
1145
+    if (!$desc) {
1146
+        die("$table insertion sans description");
1147
+    }
1148
+    $fields = isset($desc['field']) ? $desc['field'] : [];
1149
+
1150
+    foreach ($couples as $champ => $val) {
1151
+        $couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1152
+    }
1153
+
1154
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1155
+    $couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1156
+
1157
+    $cles = $valeurs = '';
1158
+    if (count($couples)) {
1159
+        $cles = '(' . join(',', array_keys($couples)) . ')';
1160
+        $valeurs = '(' . join(',', $couples) . ')';
1161
+    }
1162
+
1163
+    return spip_sqlite_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
1164 1164
 }
1165 1165
 
1166 1166
 
@@ -1185,70 +1185,70 @@  discard block
 block discarded – undo
1185 1185
  **/
1186 1186
 function spip_sqlite_insertq_multi($table, $tab_couples = [], $desc = [], $serveur = '', $requeter = true)
1187 1187
 {
1188
-	if (!$desc) {
1189
-		$desc = description_table($table, $serveur);
1190
-	}
1191
-	if (!$desc) {
1192
-		die("$table insertion sans description");
1193
-	}
1194
-	if (!isset($desc['field'])) {
1195
-		$desc['field'] = [];
1196
-	}
1197
-
1198
-	// recuperer les champs 'timestamp' pour mise a jour auto de ceux-ci
1199
-	$maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1200
-
1201
-	// seul le nom de la table est a traduire ici :
1202
-	// le faire une seule fois au debut
1203
-	$query_start = "INSERT INTO $table ";
1204
-	$query_start = Sqlite::traduire_requete($query_start, $serveur);
1205
-
1206
-	// ouvrir une transaction
1207
-	if ($requeter) {
1208
-		Sqlite::demarrer_transaction($serveur);
1209
-	}
1210
-
1211
-	while ($couples = array_shift($tab_couples)) {
1212
-		foreach ($couples as $champ => $val) {
1213
-			$couples[$champ] = _sqlite_calculer_cite($val, $desc['field'][$champ]);
1214
-		}
1215
-
1216
-		// inserer les champs timestamp par defaut
1217
-		$couples = array_merge($maj, $couples);
1218
-
1219
-		$champs = $valeurs = '';
1220
-		if (count($couples)) {
1221
-			$champs = '(' . join(',', array_keys($couples)) . ')';
1222
-			$valeurs = '(' . join(',', $couples) . ')';
1223
-			$query = $query_start . "$champs VALUES $valeurs";
1224
-		} else {
1225
-			$query = $query_start . 'DEFAULT VALUES';
1226
-		}
1227
-
1228
-		if ($requeter) {
1229
-			$retour = Sqlite::executer_requete($query, $serveur);
1230
-		}
1231
-
1232
-		// sur le dernier couple uniquement
1233
-		if (!count($tab_couples)) {
1234
-			$nb = 0;
1235
-			if ($requeter) {
1236
-				$nb = Sqlite::last_insert_id($serveur);
1237
-			} else {
1238
-				return $query;
1239
-			}
1240
-		}
1241
-
1242
-		$err = spip_sqlite_error($query, $serveur);
1243
-	}
1244
-
1245
-	if ($requeter) {
1246
-		Sqlite::finir_transaction($serveur);
1247
-	}
1248
-
1249
-	// renvoie le dernier id d'autoincrement ajoute
1250
-	// cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1251
-	return isset($_GET['var_profile']) ? $retour : $nb;
1188
+    if (!$desc) {
1189
+        $desc = description_table($table, $serveur);
1190
+    }
1191
+    if (!$desc) {
1192
+        die("$table insertion sans description");
1193
+    }
1194
+    if (!isset($desc['field'])) {
1195
+        $desc['field'] = [];
1196
+    }
1197
+
1198
+    // recuperer les champs 'timestamp' pour mise a jour auto de ceux-ci
1199
+    $maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
1200
+
1201
+    // seul le nom de la table est a traduire ici :
1202
+    // le faire une seule fois au debut
1203
+    $query_start = "INSERT INTO $table ";
1204
+    $query_start = Sqlite::traduire_requete($query_start, $serveur);
1205
+
1206
+    // ouvrir une transaction
1207
+    if ($requeter) {
1208
+        Sqlite::demarrer_transaction($serveur);
1209
+    }
1210
+
1211
+    while ($couples = array_shift($tab_couples)) {
1212
+        foreach ($couples as $champ => $val) {
1213
+            $couples[$champ] = _sqlite_calculer_cite($val, $desc['field'][$champ]);
1214
+        }
1215
+
1216
+        // inserer les champs timestamp par defaut
1217
+        $couples = array_merge($maj, $couples);
1218
+
1219
+        $champs = $valeurs = '';
1220
+        if (count($couples)) {
1221
+            $champs = '(' . join(',', array_keys($couples)) . ')';
1222
+            $valeurs = '(' . join(',', $couples) . ')';
1223
+            $query = $query_start . "$champs VALUES $valeurs";
1224
+        } else {
1225
+            $query = $query_start . 'DEFAULT VALUES';
1226
+        }
1227
+
1228
+        if ($requeter) {
1229
+            $retour = Sqlite::executer_requete($query, $serveur);
1230
+        }
1231
+
1232
+        // sur le dernier couple uniquement
1233
+        if (!count($tab_couples)) {
1234
+            $nb = 0;
1235
+            if ($requeter) {
1236
+                $nb = Sqlite::last_insert_id($serveur);
1237
+            } else {
1238
+                return $query;
1239
+            }
1240
+        }
1241
+
1242
+        $err = spip_sqlite_error($query, $serveur);
1243
+    }
1244
+
1245
+    if ($requeter) {
1246
+        Sqlite::finir_transaction($serveur);
1247
+    }
1248
+
1249
+    // renvoie le dernier id d'autoincrement ajoute
1250
+    // cas particulier : ne pas substituer la reponse spip_sqlite_query si on est en profilage
1251
+    return isset($_GET['var_profile']) ? $retour : $nb;
1252 1252
 }
1253 1253
 
1254 1254
 
@@ -1264,7 +1264,7 @@  discard block
 block discarded – undo
1264 1264
  **/
1265 1265
 function spip_sqlite_preferer_transaction($serveur = '', $requeter = true)
1266 1266
 {
1267
-	return true;
1267
+    return true;
1268 1268
 }
1269 1269
 
1270 1270
 /**
@@ -1282,12 +1282,12 @@  discard block
 block discarded – undo
1282 1282
  **/
1283 1283
 function spip_sqlite_demarrer_transaction($serveur = '', $requeter = true)
1284 1284
 {
1285
-	if (!$requeter) {
1286
-		return 'BEGIN TRANSACTION';
1287
-	}
1288
-	Sqlite::demarrer_transaction($serveur);
1285
+    if (!$requeter) {
1286
+        return 'BEGIN TRANSACTION';
1287
+    }
1288
+    Sqlite::demarrer_transaction($serveur);
1289 1289
 
1290
-	return true;
1290
+    return true;
1291 1291
 }
1292 1292
 
1293 1293
 /**
@@ -1302,12 +1302,12 @@  discard block
 block discarded – undo
1302 1302
  **/
1303 1303
 function spip_sqlite_terminer_transaction($serveur = '', $requeter = true)
1304 1304
 {
1305
-	if (!$requeter) {
1306
-		return 'COMMIT';
1307
-	}
1308
-	Sqlite::finir_transaction($serveur);
1305
+    if (!$requeter) {
1306
+        return 'COMMIT';
1307
+    }
1308
+    Sqlite::finir_transaction($serveur);
1309 1309
 
1310
-	return true;
1310
+    return true;
1311 1311
 }
1312 1312
 
1313 1313
 
@@ -1323,27 +1323,27 @@  discard block
 block discarded – undo
1323 1323
  **/
1324 1324
 function spip_sqlite_listdbs($serveur = '', $requeter = true)
1325 1325
 {
1326
-	_sqlite_init();
1327
-
1328
-	if (!is_dir($d = substr(_DIR_DB, 0, -1))) {
1329
-		return [];
1330
-	}
1331
-
1332
-	include_spip('inc/flock');
1333
-	$bases = preg_files($d, $pattern = '(.*)\.sqlite$');
1334
-	$bds = [];
1335
-
1336
-	foreach ($bases as $b) {
1337
-		// pas de bases commencant pas sqlite
1338
-		// (on s'en sert pour l'installation pour simuler la presence d'un serveur)
1339
-		// les bases sont de la forme _sqliteX_tmp_spip_install.sqlite
1340
-		if (strpos($b, '_sqlite')) {
1341
-			continue;
1342
-		}
1343
-		$bds[] = preg_replace(";.*/$pattern;iS", '$1', $b);
1344
-	}
1345
-
1346
-	return $bds;
1326
+    _sqlite_init();
1327
+
1328
+    if (!is_dir($d = substr(_DIR_DB, 0, -1))) {
1329
+        return [];
1330
+    }
1331
+
1332
+    include_spip('inc/flock');
1333
+    $bases = preg_files($d, $pattern = '(.*)\.sqlite$');
1334
+    $bds = [];
1335
+
1336
+    foreach ($bases as $b) {
1337
+        // pas de bases commencant pas sqlite
1338
+        // (on s'en sert pour l'installation pour simuler la presence d'un serveur)
1339
+        // les bases sont de la forme _sqliteX_tmp_spip_install.sqlite
1340
+        if (strpos($b, '_sqlite')) {
1341
+            continue;
1342
+        }
1343
+        $bds[] = preg_replace(";.*/$pattern;iS", '$1', $b);
1344
+    }
1345
+
1346
+    return $bds;
1347 1347
 }
1348 1348
 
1349 1349
 
@@ -1359,9 +1359,9 @@  discard block
 block discarded – undo
1359 1359
  */
1360 1360
 function spip_sqlite_multi($objet, $lang)
1361 1361
 {
1362
-	$r = 'EXTRAIRE_MULTI(' . $objet . ", '" . $lang . "') AS multi";
1362
+    $r = 'EXTRAIRE_MULTI(' . $objet . ", '" . $lang . "') AS multi";
1363 1363
 
1364
-	return $r;
1364
+    return $r;
1365 1365
 }
1366 1366
 
1367 1367
 
@@ -1379,15 +1379,15 @@  discard block
 block discarded – undo
1379 1379
  **/
1380 1380
 function spip_sqlite_optimize($table, $serveur = '', $requeter = true)
1381 1381
 {
1382
-	static $do = false;
1383
-	if ($requeter and $do) {
1384
-		return true;
1385
-	}
1386
-	if ($requeter) {
1387
-		$do = true;
1388
-	}
1389
-
1390
-	return spip_sqlite_query('VACUUM', $serveur, $requeter);
1382
+    static $do = false;
1383
+    if ($requeter and $do) {
1384
+        return true;
1385
+    }
1386
+    if ($requeter) {
1387
+        $do = true;
1388
+    }
1389
+
1390
+    return spip_sqlite_query('VACUUM', $serveur, $requeter);
1391 1391
 }
1392 1392
 
1393 1393
 
@@ -1405,15 +1405,15 @@  discard block
 block discarded – undo
1405 1405
  */
1406 1406
 function spip_sqlite_quote($v, $type = '')
1407 1407
 {
1408
-	if (!is_array($v)) {
1409
-		return _sqlite_calculer_cite($v, $type);
1410
-	}
1411
-	// si c'est un tableau, le parcourir en propageant le type
1412
-	foreach ($v as $k => $r) {
1413
-		$v[$k] = spip_sqlite_quote($r, $type);
1414
-	}
1415
-
1416
-	return join(',', $v);
1408
+    if (!is_array($v)) {
1409
+        return _sqlite_calculer_cite($v, $type);
1410
+    }
1411
+    // si c'est un tableau, le parcourir en propageant le type
1412
+    foreach ($v as $k => $r) {
1413
+        $v[$k] = spip_sqlite_quote($r, $type);
1414
+    }
1415
+
1416
+    return join(',', $v);
1417 1417
 }
1418 1418
 
1419 1419
 
@@ -1431,9 +1431,9 @@  discard block
 block discarded – undo
1431 1431
  **/
1432 1432
 function spip_sqlite_date_proche($champ, $interval, $unite)
1433 1433
 {
1434
-	$op = (($interval <= 0) ? '>' : '<');
1434
+    $op = (($interval <= 0) ? '>' : '<');
1435 1435
 
1436
-	return "($champ $op datetime('" . date('Y-m-d H:i:s') . "', '$interval $unite'))";
1436
+    return "($champ $op datetime('" . date('Y-m-d H:i:s') . "', '$interval $unite'))";
1437 1437
 }
1438 1438
 
1439 1439
 
@@ -1452,48 +1452,48 @@  discard block
 block discarded – undo
1452 1452
  */
1453 1453
 function spip_sqlite_repair($table, $serveur = '', $requeter = true)
1454 1454
 {
1455
-	if (
1456
-		$desc = spip_sqlite_showtable($table, $serveur)
1457
-		and isset($desc['field'])
1458
-		and is_array($desc['field'])
1459
-	) {
1460
-		foreach ($desc['field'] as $c => $d) {
1461
-			if (
1462
-				preg_match(',^(tinytext|mediumtext|text|longtext|varchar|char),i', $d)
1463
-				and stripos($d, 'NOT NULL') !== false
1464
-				and stripos($d, 'DEFAULT') === false
1465
-				/* pas touche aux cles primaires */
1466
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1467
-			) {
1468
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT ''", $serveur);
1469
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1470
-			}
1471
-			if (
1472
-				preg_match(',^(INTEGER),i', $d)
1473
-				and stripos($d, 'NOT NULL') !== false
1474
-				and stripos($d, 'DEFAULT') === false
1475
-				/* pas touche aux cles primaires */
1476
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1477
-			) {
1478
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0'", $serveur);
1479
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1480
-			}
1481
-			if (
1482
-				preg_match(',^(datetime),i', $d)
1483
-				and stripos($d, 'NOT NULL') !== false
1484
-				and stripos($d, 'DEFAULT') === false
1485
-				/* pas touche aux cles primaires */
1486
-				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1487
-			) {
1488
-				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0000-00-00 00:00:00'", $serveur);
1489
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1490
-			}
1491
-		}
1492
-
1493
-		return [' OK '];
1494
-	}
1495
-
1496
-	return [' ERROR '];
1455
+    if (
1456
+        $desc = spip_sqlite_showtable($table, $serveur)
1457
+        and isset($desc['field'])
1458
+        and is_array($desc['field'])
1459
+    ) {
1460
+        foreach ($desc['field'] as $c => $d) {
1461
+            if (
1462
+                preg_match(',^(tinytext|mediumtext|text|longtext|varchar|char),i', $d)
1463
+                and stripos($d, 'NOT NULL') !== false
1464
+                and stripos($d, 'DEFAULT') === false
1465
+                /* pas touche aux cles primaires */
1466
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1467
+            ) {
1468
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT ''", $serveur);
1469
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1470
+            }
1471
+            if (
1472
+                preg_match(',^(INTEGER),i', $d)
1473
+                and stripos($d, 'NOT NULL') !== false
1474
+                and stripos($d, 'DEFAULT') === false
1475
+                /* pas touche aux cles primaires */
1476
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1477
+            ) {
1478
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0'", $serveur);
1479
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1480
+            }
1481
+            if (
1482
+                preg_match(',^(datetime),i', $d)
1483
+                and stripos($d, 'NOT NULL') !== false
1484
+                and stripos($d, 'DEFAULT') === false
1485
+                /* pas touche aux cles primaires */
1486
+                and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1487
+            ) {
1488
+                spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0000-00-00 00:00:00'", $serveur);
1489
+                spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1490
+            }
1491
+        }
1492
+
1493
+        return [' OK '];
1494
+    }
1495
+
1496
+    return [' ERROR '];
1497 1497
 }
1498 1498
 
1499 1499
 
@@ -1523,25 +1523,25 @@  discard block
 block discarded – undo
1523 1523
  **/
1524 1524
 function spip_sqlite_replace($table, $couples, $desc = [], $serveur = '', $requeter = true)
1525 1525
 {
1526
-	if (!$desc) {
1527
-		$desc = description_table($table, $serveur);
1528
-	}
1529
-	if (!$desc) {
1530
-		die("$table insertion sans description");
1531
-	}
1532
-	$fields = isset($desc['field']) ? $desc['field'] : [];
1533
-
1534
-	foreach ($couples as $champ => $val) {
1535
-		$couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1536
-	}
1537
-
1538
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1539
-	$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1540
-
1541
-	return spip_sqlite_query("REPLACE INTO $table (" . join(',', array_keys($couples)) . ') VALUES (' . join(
1542
-		',',
1543
-		$couples
1544
-	) . ')', $serveur);
1526
+    if (!$desc) {
1527
+        $desc = description_table($table, $serveur);
1528
+    }
1529
+    if (!$desc) {
1530
+        die("$table insertion sans description");
1531
+    }
1532
+    $fields = isset($desc['field']) ? $desc['field'] : [];
1533
+
1534
+    foreach ($couples as $champ => $val) {
1535
+        $couples[$champ] = _sqlite_calculer_cite($val, $fields[$champ]);
1536
+    }
1537
+
1538
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1539
+    $couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1540
+
1541
+    return spip_sqlite_query("REPLACE INTO $table (" . join(',', array_keys($couples)) . ') VALUES (' . join(
1542
+        ',',
1543
+        $couples
1544
+    ) . ')', $serveur);
1545 1545
 }
1546 1546
 
1547 1547
 
@@ -1572,13 +1572,13 @@  discard block
 block discarded – undo
1572 1572
 function spip_sqlite_replace_multi($table, $tab_couples, $desc = [], $serveur = '', $requeter = true)
1573 1573
 {
1574 1574
 
1575
-	// boucler pour trainter chaque requete independemment
1576
-	foreach ($tab_couples as $couples) {
1577
-		$retour = spip_sqlite_replace($table, $couples, $desc, $serveur, $requeter);
1578
-	}
1575
+    // boucler pour trainter chaque requete independemment
1576
+    foreach ($tab_couples as $couples) {
1577
+        $retour = spip_sqlite_replace($table, $couples, $desc, $serveur, $requeter);
1578
+    }
1579 1579
 
1580
-	// renvoie le dernier id
1581
-	return $retour;
1580
+    // renvoie le dernier id
1581
+    return $retour;
1582 1582
 }
1583 1583
 
1584 1584
 
@@ -1605,44 +1605,44 @@  discard block
 block discarded – undo
1605 1605
  *     - array  : Tableau décrivant requête et temps d'exécution si var_profile actif pour tracer.
1606 1606
  */
1607 1607
 function spip_sqlite_select(
1608
-	$select,
1609
-	$from,
1610
-	$where = '',
1611
-	$groupby = '',
1612
-	$orderby = '',
1613
-	$limit = '',
1614
-	$having = '',
1615
-	$serveur = '',
1616
-	$requeter = true
1608
+    $select,
1609
+    $from,
1610
+    $where = '',
1611
+    $groupby = '',
1612
+    $orderby = '',
1613
+    $limit = '',
1614
+    $having = '',
1615
+    $serveur = '',
1616
+    $requeter = true
1617 1617
 ) {
1618 1618
 
1619
-	// version() n'est pas connu de sqlite
1620
-	$select = str_replace('version()', 'sqlite_version()', $select);
1621
-
1622
-	// recomposer from
1623
-	$from = (!is_array($from) ? $from : _sqlite_calculer_select_as($from));
1624
-
1625
-	$query =
1626
-		_sqlite_calculer_expression('SELECT', $select, ', ')
1627
-		. _sqlite_calculer_expression('FROM', $from, ', ')
1628
-		. _sqlite_calculer_expression('WHERE', $where)
1629
-		. _sqlite_calculer_expression('GROUP BY', $groupby, ',')
1630
-		. _sqlite_calculer_expression('HAVING', $having)
1631
-		. ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) : '')
1632
-		. ($limit ? "\nLIMIT $limit" : '');
1633
-
1634
-	// dans un select, on doit renvoyer la requête en cas d'erreur
1635
-	$res = spip_sqlite_query($query, $serveur, $requeter);
1636
-	// texte de la requete demande ?
1637
-	if (!$requeter) {
1638
-		return $res;
1639
-	}
1640
-	// erreur survenue ?
1641
-	if ($res === false) {
1642
-		return Sqlite::traduire_requete($query, $serveur);
1643
-	}
1644
-
1645
-	return $res;
1619
+    // version() n'est pas connu de sqlite
1620
+    $select = str_replace('version()', 'sqlite_version()', $select);
1621
+
1622
+    // recomposer from
1623
+    $from = (!is_array($from) ? $from : _sqlite_calculer_select_as($from));
1624
+
1625
+    $query =
1626
+        _sqlite_calculer_expression('SELECT', $select, ', ')
1627
+        . _sqlite_calculer_expression('FROM', $from, ', ')
1628
+        . _sqlite_calculer_expression('WHERE', $where)
1629
+        . _sqlite_calculer_expression('GROUP BY', $groupby, ',')
1630
+        . _sqlite_calculer_expression('HAVING', $having)
1631
+        . ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) : '')
1632
+        . ($limit ? "\nLIMIT $limit" : '');
1633
+
1634
+    // dans un select, on doit renvoyer la requête en cas d'erreur
1635
+    $res = spip_sqlite_query($query, $serveur, $requeter);
1636
+    // texte de la requete demande ?
1637
+    if (!$requeter) {
1638
+        return $res;
1639
+    }
1640
+    // erreur survenue ?
1641
+    if ($res === false) {
1642
+        return Sqlite::traduire_requete($query, $serveur);
1643
+    }
1644
+
1645
+    return $res;
1646 1646
 }
1647 1647
 
1648 1648
 
@@ -1662,32 +1662,32 @@  discard block
 block discarded – undo
1662 1662
  **/
1663 1663
 function spip_sqlite_selectdb($db, $serveur = '', $requeter = true)
1664 1664
 {
1665
-	_sqlite_init();
1666
-
1667
-	// interdire la creation d'une nouvelle base,
1668
-	// sauf si on est dans l'installation
1669
-	if (
1670
-		!is_file($f = _DIR_DB . $db . '.sqlite')
1671
-		&& (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)
1672
-	) {
1673
-		spip_log("Il est interdit de creer la base $db", 'sqlite.' . _LOG_HS);
1674
-
1675
-		return false;
1676
-	}
1677
-
1678
-	// se connecter a la base indiquee
1679
-	// avec les identifiants connus
1680
-	$index = $serveur ? $serveur : 0;
1681
-
1682
-	if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db, $serveur, '', '')) {
1683
-		if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
1684
-			return $db;
1685
-		}
1686
-	} else {
1687
-		spip_log("Impossible de selectionner la base $db", 'sqlite.' . _LOG_HS);
1688
-	}
1689
-
1690
-	return false;
1665
+    _sqlite_init();
1666
+
1667
+    // interdire la creation d'une nouvelle base,
1668
+    // sauf si on est dans l'installation
1669
+    if (
1670
+        !is_file($f = _DIR_DB . $db . '.sqlite')
1671
+        && (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)
1672
+    ) {
1673
+        spip_log("Il est interdit de creer la base $db", 'sqlite.' . _LOG_HS);
1674
+
1675
+        return false;
1676
+    }
1677
+
1678
+    // se connecter a la base indiquee
1679
+    // avec les identifiants connus
1680
+    $index = $serveur ? $serveur : 0;
1681
+
1682
+    if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db, $serveur, '', '')) {
1683
+        if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
1684
+            return $db;
1685
+        }
1686
+    } else {
1687
+        spip_log("Impossible de selectionner la base $db", 'sqlite.' . _LOG_HS);
1688
+    }
1689
+
1690
+    return false;
1691 1691
 }
1692 1692
 
1693 1693
 
@@ -1703,8 +1703,8 @@  discard block
 block discarded – undo
1703 1703
  */
1704 1704
 function spip_sqlite_set_charset($charset, $serveur = '', $requeter = true)
1705 1705
 {
1706
-	# spip_log("Gestion charset sql a ecrire : "."SET NAMES "._q($charset), 'sqlite.'._LOG_ERREUR);
1707
-	# return spip_sqlite_query("SET NAMES ". spip_sqlite_quote($charset), $serveur); //<-- Passe pas !
1706
+    # spip_log("Gestion charset sql a ecrire : "."SET NAMES "._q($charset), 'sqlite.'._LOG_ERREUR);
1707
+    # return spip_sqlite_query("SET NAMES ". spip_sqlite_quote($charset), $serveur); //<-- Passe pas !
1708 1708
 }
1709 1709
 
1710 1710
 
@@ -1723,24 +1723,24 @@  discard block
 block discarded – undo
1723 1723
  **/
1724 1724
 function spip_sqlite_showbase($match, $serveur = '', $requeter = true)
1725 1725
 {
1726
-	// type est le type d'entrée : table / index / view
1727
-	// on ne retourne que les tables (?) et non les vues...
1728
-	# ESCAPE non supporte par les versions sqlite <3
1729
-	#	return spip_sqlite_query("SELECT name FROM sqlite_master WHERE type='table' AND tbl_name LIKE "._q($match)." ESCAPE '\'", $serveur, $requeter);
1730
-	$match = preg_quote($match);
1731
-	$match = str_replace('\\\_', '[[TIRETBAS]]', $match);
1732
-	$match = str_replace('\\\%', '[[POURCENT]]', $match);
1733
-	$match = str_replace('_', '.', $match);
1734
-	$match = str_replace('%', '.*', $match);
1735
-	$match = str_replace('[[TIRETBAS]]', '_', $match);
1736
-	$match = str_replace('[[POURCENT]]', '%', $match);
1737
-	$match = "^$match$";
1738
-
1739
-	return spip_sqlite_query(
1740
-		"SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP " . _q($match),
1741
-		$serveur,
1742
-		$requeter
1743
-	);
1726
+    // type est le type d'entrée : table / index / view
1727
+    // on ne retourne que les tables (?) et non les vues...
1728
+    # ESCAPE non supporte par les versions sqlite <3
1729
+    #	return spip_sqlite_query("SELECT name FROM sqlite_master WHERE type='table' AND tbl_name LIKE "._q($match)." ESCAPE '\'", $serveur, $requeter);
1730
+    $match = preg_quote($match);
1731
+    $match = str_replace('\\\_', '[[TIRETBAS]]', $match);
1732
+    $match = str_replace('\\\%', '[[POURCENT]]', $match);
1733
+    $match = str_replace('_', '.', $match);
1734
+    $match = str_replace('%', '.*', $match);
1735
+    $match = str_replace('[[TIRETBAS]]', '_', $match);
1736
+    $match = str_replace('[[POURCENT]]', '%', $match);
1737
+    $match = "^$match$";
1738
+
1739
+    return spip_sqlite_query(
1740
+        "SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP " . _q($match),
1741
+        $serveur,
1742
+        $requeter
1743
+    );
1744 1744
 }
1745 1745
 
1746 1746
 /**
@@ -1759,19 +1759,19 @@  discard block
 block discarded – undo
1759 1759
  **/
1760 1760
 function spip_sqlite_table_exists(string $table, $serveur = '', $requeter = true)
1761 1761
 {
1762
-	$r = spip_sqlite_query(
1763
-		'SELECT name FROM sqlite_master WHERE'
1764
-			. ' type=\'table\''
1765
-			. ' AND name=' . spip_sqlite_quote($table, 'string')
1766
-			. ' AND name NOT LIKE \'sqlite_%\'',
1767
-		$serveur,
1768
-		$requeter
1769
-	);
1770
-	if (!$requeter) {
1771
-		return $r;
1772
-	}
1773
-	$res = spip_sqlite_fetch($r);
1774
-	return (bool) $res;
1762
+    $r = spip_sqlite_query(
1763
+        'SELECT name FROM sqlite_master WHERE'
1764
+            . ' type=\'table\''
1765
+            . ' AND name=' . spip_sqlite_quote($table, 'string')
1766
+            . ' AND name NOT LIKE \'sqlite_%\'',
1767
+        $serveur,
1768
+        $requeter
1769
+    );
1770
+    if (!$requeter) {
1771
+        return $r;
1772
+    }
1773
+    $res = spip_sqlite_fetch($r);
1774
+    return (bool) $res;
1775 1775
 }
1776 1776
 
1777 1777
 define('_SQLITE_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/');
@@ -1795,129 +1795,129 @@  discard block
 block discarded – undo
1795 1795
  */
1796 1796
 function spip_sqlite_showtable($nom_table, $serveur = '', $requeter = true)
1797 1797
 {
1798
-	$query =
1799
-		'SELECT sql, type FROM'
1800
-		. ' (SELECT * FROM sqlite_master UNION ALL'
1801
-		. ' SELECT * FROM sqlite_temp_master)'
1802
-		. " WHERE tbl_name LIKE '$nom_table'"
1803
-		. " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'"
1804
-		. ' ORDER BY substr(type,2,1), name';
1805
-
1806
-	$a = spip_sqlite_query($query, $serveur, $requeter);
1807
-	if (!$a) {
1808
-		return '';
1809
-	}
1810
-	if (!$requeter) {
1811
-		return $a;
1812
-	}
1813
-	if (!($a = spip_sqlite_fetch($a, null, $serveur))) {
1814
-		return '';
1815
-	}
1816
-	$vue = ($a['type'] == 'view'); // table | vue
1817
-
1818
-	// c'est une table
1819
-	// il faut parser le create
1820
-	if (!$vue) {
1821
-		if (!preg_match(_SQLITE_RE_SHOW_TABLE, array_shift($a), $r)) {
1822
-			return '';
1823
-		} else {
1824
-			$desc = $r[1];
1825
-			// extraction d'une KEY éventuelle en prenant garde de ne pas
1826
-			// relever un champ dont le nom contient KEY (ex. ID_WHISKEY)
1827
-			if (preg_match('/^(.*?),([^,]*\sKEY[ (].*)$/s', $desc, $r)) {
1828
-				$namedkeys = $r[2];
1829
-				$desc = $r[1];
1830
-			} else {
1831
-				$namedkeys = '';
1832
-			}
1833
-
1834
-			$fields = [];
1835
-			$keys = [];
1836
-
1837
-			// enlever les contenus des valeurs DEFAULT 'xxx' qui pourraient perturber
1838
-			// par exemple s'il contiennent une virgule.
1839
-			// /!\ cela peut aussi echapper le nom des champs si la table a eu des operations avec SQLite Manager !
1840
-			list($desc, $echaps) = query_echappe_textes($desc);
1841
-
1842
-			// separer toutes les descriptions de champs, separes par des virgules
1843
-			# /!\ explode peut exploser aussi DECIMAL(10,2) !
1844
-			$k_precedent = null;
1845
-			foreach (explode(',', $desc) as $v) {
1846
-				preg_match('/^\s*([^\s]+)\s+(.*)/', $v, $r);
1847
-				// Les cles de champs peuvent etre entourees
1848
-				// de guillements doubles " , simples ', graves ` ou de crochets [ ],  ou rien.
1849
-				// http://www.sqlite.org/lang_keywords.html
1850
-				$k = strtolower(query_reinjecte_textes($r[1], $echaps)); // champ, "champ", [champ]...
1851
-				if ($char = strpbrk($k[0], '\'"[`')) {
1852
-					$k = trim($k, $char);
1853
-					if ($char == '[') {
1854
-						$k = rtrim($k, ']');
1855
-					}
1856
-				}
1857
-				$def = query_reinjecte_textes($r[2], $echaps); // valeur du champ
1858
-
1859
-				// rustine pour DECIMAL(10,2)
1860
-				// s'il y a une parenthèse fermante dans la clé
1861
-				// ou dans la définition sans qu'il n'y ait une ouverture avant
1862
-				if (str_contains($k, ')') or preg_match('/^[^\(]*\)/', $def)) {
1863
-					$fields[$k_precedent] .= ',' . $k . ' ' . $def;
1864
-					continue;
1865
-				}
1866
-
1867
-				// la primary key peut etre dans une des descriptions de champs
1868
-				// et non en fin de table, cas encore decouvert avec Sqlite Manager
1869
-				if (stripos($r[2], 'PRIMARY KEY') !== false) {
1870
-					$keys['PRIMARY KEY'] = $k;
1871
-				}
1872
-
1873
-				$fields[$k] = $def;
1874
-				$k_precedent = $k;
1875
-			}
1876
-			// key inclues dans la requete
1877
-			foreach (preg_split('/\)\s*(,|$)/', $namedkeys) as $v) {
1878
-				if (preg_match('/^\s*([^(]*)\(([^(]*(\(\d+\))?)$/', $v, $r)) {
1879
-					$k = str_replace('`', '', trim($r[1]));
1880
-					$t = trim(strtolower(str_replace('`', '', $r[2])), '"');
1881
-					if ($k && !isset($keys[$k])) {
1882
-						$keys[$k] = $t;
1883
-					} else {
1884
-						$keys[] = $t;
1885
-					}
1886
-				}
1887
-			}
1888
-			// sinon ajouter les key index
1889
-			$query =
1890
-				'SELECT name,sql FROM'
1891
-				. ' (SELECT * FROM sqlite_master UNION ALL'
1892
-				. ' SELECT * FROM sqlite_temp_master)'
1893
-				. " WHERE tbl_name LIKE '$nom_table'"
1894
-				. " AND type='index' AND name NOT LIKE 'sqlite_%'"
1895
-				. 'ORDER BY substr(type,2,1), name';
1896
-			$a = spip_sqlite_query($query, $serveur, $requeter);
1897
-			while ($r = spip_sqlite_fetch($a, null, $serveur)) {
1898
-				$key = str_replace($nom_table . '_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1899
-				$keytype = 'KEY';
1900
-				if (strpos($r['sql'], 'UNIQUE INDEX') !== false) {
1901
-					$keytype = 'UNIQUE KEY';
1902
-				}
1903
-				$colonnes = preg_replace(',.*\((.*)\).*,', '$1', $r['sql']);
1904
-				$keys[$keytype . ' ' . $key] = $colonnes;
1905
-			}
1906
-		}
1907
-	} // c'est une vue, on liste les champs disponibles simplement
1908
-	else {
1909
-		if ($res = sql_fetsel('*', $nom_table, '', '', '', '1', '', $serveur)) { // limit 1
1910
-			$fields = [];
1911
-			foreach ($res as $c => $v) {
1912
-				$fields[$c] = '';
1913
-			}
1914
-			$keys = [];
1915
-		} else {
1916
-			return '';
1917
-		}
1918
-	}
1919
-
1920
-	return ['field' => $fields, 'key' => $keys];
1798
+    $query =
1799
+        'SELECT sql, type FROM'
1800
+        . ' (SELECT * FROM sqlite_master UNION ALL'
1801
+        . ' SELECT * FROM sqlite_temp_master)'
1802
+        . " WHERE tbl_name LIKE '$nom_table'"
1803
+        . " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'"
1804
+        . ' ORDER BY substr(type,2,1), name';
1805
+
1806
+    $a = spip_sqlite_query($query, $serveur, $requeter);
1807
+    if (!$a) {
1808
+        return '';
1809
+    }
1810
+    if (!$requeter) {
1811
+        return $a;
1812
+    }
1813
+    if (!($a = spip_sqlite_fetch($a, null, $serveur))) {
1814
+        return '';
1815
+    }
1816
+    $vue = ($a['type'] == 'view'); // table | vue
1817
+
1818
+    // c'est une table
1819
+    // il faut parser le create
1820
+    if (!$vue) {
1821
+        if (!preg_match(_SQLITE_RE_SHOW_TABLE, array_shift($a), $r)) {
1822
+            return '';
1823
+        } else {
1824
+            $desc = $r[1];
1825
+            // extraction d'une KEY éventuelle en prenant garde de ne pas
1826
+            // relever un champ dont le nom contient KEY (ex. ID_WHISKEY)
1827
+            if (preg_match('/^(.*?),([^,]*\sKEY[ (].*)$/s', $desc, $r)) {
1828
+                $namedkeys = $r[2];
1829
+                $desc = $r[1];
1830
+            } else {
1831
+                $namedkeys = '';
1832
+            }
1833
+
1834
+            $fields = [];
1835
+            $keys = [];
1836
+
1837
+            // enlever les contenus des valeurs DEFAULT 'xxx' qui pourraient perturber
1838
+            // par exemple s'il contiennent une virgule.
1839
+            // /!\ cela peut aussi echapper le nom des champs si la table a eu des operations avec SQLite Manager !
1840
+            list($desc, $echaps) = query_echappe_textes($desc);
1841
+
1842
+            // separer toutes les descriptions de champs, separes par des virgules
1843
+            # /!\ explode peut exploser aussi DECIMAL(10,2) !
1844
+            $k_precedent = null;
1845
+            foreach (explode(',', $desc) as $v) {
1846
+                preg_match('/^\s*([^\s]+)\s+(.*)/', $v, $r);
1847
+                // Les cles de champs peuvent etre entourees
1848
+                // de guillements doubles " , simples ', graves ` ou de crochets [ ],  ou rien.
1849
+                // http://www.sqlite.org/lang_keywords.html
1850
+                $k = strtolower(query_reinjecte_textes($r[1], $echaps)); // champ, "champ", [champ]...
1851
+                if ($char = strpbrk($k[0], '\'"[`')) {
1852
+                    $k = trim($k, $char);
1853
+                    if ($char == '[') {
1854
+                        $k = rtrim($k, ']');
1855
+                    }
1856
+                }
1857
+                $def = query_reinjecte_textes($r[2], $echaps); // valeur du champ
1858
+
1859
+                // rustine pour DECIMAL(10,2)
1860
+                // s'il y a une parenthèse fermante dans la clé
1861
+                // ou dans la définition sans qu'il n'y ait une ouverture avant
1862
+                if (str_contains($k, ')') or preg_match('/^[^\(]*\)/', $def)) {
1863
+                    $fields[$k_precedent] .= ',' . $k . ' ' . $def;
1864
+                    continue;
1865
+                }
1866
+
1867
+                // la primary key peut etre dans une des descriptions de champs
1868
+                // et non en fin de table, cas encore decouvert avec Sqlite Manager
1869
+                if (stripos($r[2], 'PRIMARY KEY') !== false) {
1870
+                    $keys['PRIMARY KEY'] = $k;
1871
+                }
1872
+
1873
+                $fields[$k] = $def;
1874
+                $k_precedent = $k;
1875
+            }
1876
+            // key inclues dans la requete
1877
+            foreach (preg_split('/\)\s*(,|$)/', $namedkeys) as $v) {
1878
+                if (preg_match('/^\s*([^(]*)\(([^(]*(\(\d+\))?)$/', $v, $r)) {
1879
+                    $k = str_replace('`', '', trim($r[1]));
1880
+                    $t = trim(strtolower(str_replace('`', '', $r[2])), '"');
1881
+                    if ($k && !isset($keys[$k])) {
1882
+                        $keys[$k] = $t;
1883
+                    } else {
1884
+                        $keys[] = $t;
1885
+                    }
1886
+                }
1887
+            }
1888
+            // sinon ajouter les key index
1889
+            $query =
1890
+                'SELECT name,sql FROM'
1891
+                . ' (SELECT * FROM sqlite_master UNION ALL'
1892
+                . ' SELECT * FROM sqlite_temp_master)'
1893
+                . " WHERE tbl_name LIKE '$nom_table'"
1894
+                . " AND type='index' AND name NOT LIKE 'sqlite_%'"
1895
+                . 'ORDER BY substr(type,2,1), name';
1896
+            $a = spip_sqlite_query($query, $serveur, $requeter);
1897
+            while ($r = spip_sqlite_fetch($a, null, $serveur)) {
1898
+                $key = str_replace($nom_table . '_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1899
+                $keytype = 'KEY';
1900
+                if (strpos($r['sql'], 'UNIQUE INDEX') !== false) {
1901
+                    $keytype = 'UNIQUE KEY';
1902
+                }
1903
+                $colonnes = preg_replace(',.*\((.*)\).*,', '$1', $r['sql']);
1904
+                $keys[$keytype . ' ' . $key] = $colonnes;
1905
+            }
1906
+        }
1907
+    } // c'est une vue, on liste les champs disponibles simplement
1908
+    else {
1909
+        if ($res = sql_fetsel('*', $nom_table, '', '', '', '1', '', $serveur)) { // limit 1
1910
+            $fields = [];
1911
+            foreach ($res as $c => $v) {
1912
+                $fields[$c] = '';
1913
+            }
1914
+            $keys = [];
1915
+        } else {
1916
+            return '';
1917
+        }
1918
+    }
1919
+
1920
+    return ['field' => $fields, 'key' => $keys];
1921 1921
 }
1922 1922
 
1923 1923
 
@@ -1944,24 +1944,24 @@  discard block
 block discarded – undo
1944 1944
  */
1945 1945
 function spip_sqlite_update($table, $champs, $where = '', $desc = '', $serveur = '', $requeter = true)
1946 1946
 {
1947
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1948
-	$champs = _sqlite_ajouter_champs_timestamp($table, $champs, $desc, $serveur);
1949
-
1950
-	$set = [];
1951
-	foreach ($champs as $champ => $val) {
1952
-		$set[] = $champ . "=$val";
1953
-	}
1954
-	if (!empty($set)) {
1955
-		return spip_sqlite_query(
1956
-			_sqlite_calculer_expression('UPDATE', $table, ',')
1957
-				. _sqlite_calculer_expression('SET', $set, ',')
1958
-				. _sqlite_calculer_expression('WHERE', $where),
1959
-			$serveur,
1960
-			$requeter
1961
-		);
1962
-	}
1963
-
1964
-	return false;
1947
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1948
+    $champs = _sqlite_ajouter_champs_timestamp($table, $champs, $desc, $serveur);
1949
+
1950
+    $set = [];
1951
+    foreach ($champs as $champ => $val) {
1952
+        $set[] = $champ . "=$val";
1953
+    }
1954
+    if (!empty($set)) {
1955
+        return spip_sqlite_query(
1956
+            _sqlite_calculer_expression('UPDATE', $table, ',')
1957
+                . _sqlite_calculer_expression('SET', $set, ',')
1958
+                . _sqlite_calculer_expression('WHERE', $where),
1959
+            $serveur,
1960
+            $requeter
1961
+        );
1962
+    }
1963
+
1964
+    return false;
1965 1965
 }
1966 1966
 
1967 1967
 
@@ -1992,38 +1992,38 @@  discard block
 block discarded – undo
1992 1992
 function spip_sqlite_updateq($table, $champs, $where = '', $desc = [], $serveur = '', $requeter = true)
1993 1993
 {
1994 1994
 
1995
-	if (!$champs) {
1996
-		return;
1997
-	}
1998
-	if (!$desc) {
1999
-		$desc = description_table($table, $serveur);
2000
-	}
2001
-	if (!$desc) {
2002
-		die("$table insertion sans description");
2003
-	}
2004
-	$fields = $desc['field'];
2005
-
2006
-	$set = [];
2007
-	foreach ($champs as $champ => $val) {
2008
-		$set[$champ] = $champ . '=' . _sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
2009
-	}
2010
-
2011
-	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
2012
-	// attention ils sont deja quotes
2013
-	$maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
2014
-	foreach ($maj as $champ => $val) {
2015
-		if (!isset($set[$champ])) {
2016
-			$set[$champ] = $champ . '=' . $val;
2017
-		}
2018
-	}
2019
-
2020
-	return spip_sqlite_query(
2021
-		_sqlite_calculer_expression('UPDATE', $table, ',')
2022
-			. _sqlite_calculer_expression('SET', $set, ',')
2023
-			. _sqlite_calculer_expression('WHERE', $where),
2024
-		$serveur,
2025
-		$requeter
2026
-	);
1995
+    if (!$champs) {
1996
+        return;
1997
+    }
1998
+    if (!$desc) {
1999
+        $desc = description_table($table, $serveur);
2000
+    }
2001
+    if (!$desc) {
2002
+        die("$table insertion sans description");
2003
+    }
2004
+    $fields = $desc['field'];
2005
+
2006
+    $set = [];
2007
+    foreach ($champs as $champ => $val) {
2008
+        $set[$champ] = $champ . '=' . _sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
2009
+    }
2010
+
2011
+    // recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
2012
+    // attention ils sont deja quotes
2013
+    $maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
2014
+    foreach ($maj as $champ => $val) {
2015
+        if (!isset($set[$champ])) {
2016
+            $set[$champ] = $champ . '=' . $val;
2017
+        }
2018
+    }
2019
+
2020
+    return spip_sqlite_query(
2021
+        _sqlite_calculer_expression('UPDATE', $table, ',')
2022
+            . _sqlite_calculer_expression('SET', $set, ',')
2023
+            . _sqlite_calculer_expression('WHERE', $where),
2024
+        $serveur,
2025
+        $requeter
2026
+    );
2027 2027
 }
2028 2028
 
2029 2029
 
@@ -2042,17 +2042,17 @@  discard block
 block discarded – undo
2042 2042
  */
2043 2043
 function _sqlite_init()
2044 2044
 {
2045
-	if (!defined('_DIR_DB')) {
2046
-		define('_DIR_DB', _DIR_ETC . 'bases/');
2047
-	}
2048
-	if (!defined('_SQLITE_CHMOD')) {
2049
-		define('_SQLITE_CHMOD', _SPIP_CHMOD);
2050
-	}
2051
-
2052
-	if (!is_dir($d = _DIR_DB)) {
2053
-		include_spip('inc/flock');
2054
-		sous_repertoire($d);
2055
-	}
2045
+    if (!defined('_DIR_DB')) {
2046
+        define('_DIR_DB', _DIR_ETC . 'bases/');
2047
+    }
2048
+    if (!defined('_SQLITE_CHMOD')) {
2049
+        define('_SQLITE_CHMOD', _SPIP_CHMOD);
2050
+    }
2051
+
2052
+    if (!is_dir($d = _DIR_DB)) {
2053
+        include_spip('inc/flock');
2054
+        sous_repertoire($d);
2055
+    }
2056 2056
 }
2057 2057
 
2058 2058
 
@@ -2067,20 +2067,20 @@  discard block
 block discarded – undo
2067 2067
  */
2068 2068
 function _sqlite_is_version($version = '', $link = '', $serveur = '', $requeter = true)
2069 2069
 {
2070
-	if ($link === '') {
2071
-		$link = _sqlite_link($serveur);
2072
-	}
2073
-	if (!$link) {
2074
-		return false;
2075
-	}
2070
+    if ($link === '') {
2071
+        $link = _sqlite_link($serveur);
2072
+    }
2073
+    if (!$link) {
2074
+        return false;
2075
+    }
2076 2076
 
2077
-	$v = 3;
2077
+    $v = 3;
2078 2078
 
2079
-	if (!$version) {
2080
-		return $v;
2081
-	}
2079
+    if (!$version) {
2080
+        return $v;
2081
+    }
2082 2082
 
2083
-	return ($version == $v);
2083
+    return ($version == $v);
2084 2084
 }
2085 2085
 
2086 2086
 
@@ -2092,9 +2092,9 @@  discard block
 block discarded – undo
2092 2092
  */
2093 2093
 function _sqlite_link($serveur = ''): ?\PDO
2094 2094
 {
2095
-	$link = &$GLOBALS['connexions'][$serveur ? $serveur : 0]['link'];
2095
+    $link = &$GLOBALS['connexions'][$serveur ? $serveur : 0]['link'];
2096 2096
 
2097
-	return $link;
2097
+    return $link;
2098 2098
 }
2099 2099
 
2100 2100
 
@@ -2110,54 +2110,54 @@  discard block
 block discarded – undo
2110 2110
  */
2111 2111
 function _sqlite_calculer_cite($v, $type)
2112 2112
 {
2113
-	if ($type) {
2114
-		if (
2115
-			is_null($v)
2116
-			and stripos($type, 'NOT NULL') === false
2117
-		) {
2118
-			// null php se traduit en NULL SQL
2119
-			return 'NULL';
2120
-		}
2121
-
2122
-		if (sql_test_date($type) and preg_match('/^\w+\(/', $v)) {
2123
-			return $v;
2124
-		}
2125
-		if (sql_test_int($type)) {
2126
-			if (is_numeric($v)) {
2127
-				return $v;
2128
-			} elseif ($v === null) {
2129
-				return 0;
2130
-			} elseif (ctype_xdigit(substr($v, 2)) and strncmp($v, '0x', 2) === 0) {
2131
-				return hexdec(substr($v, 2));
2132
-			} else {
2133
-				return intval($v);
2134
-			}
2135
-		}
2136
-	} else {
2137
-		// si on ne connait pas le type on le deduit de $v autant que possible
2138
-		if (is_bool($v)) {
2139
-			return strval(intval($v));
2140
-		} elseif (is_numeric($v)) {
2141
-			return strval($v);
2142
-		}
2143
-	}
2144
-
2145
-	// trouver un link sqlite pour faire l'echappement
2146
-	foreach ($GLOBALS['connexions'] as $s) {
2147
-		if (
2148
-			$l = $s['link']
2149
-			and is_object($l)
2150
-			and $l instanceof \PDO
2151
-			and $l->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'sqlite'
2152
-		) {
2153
-			return $l->quote($v ?? '');
2154
-		}
2155
-	}
2156
-
2157
-	// echapper les ' en ''
2158
-	spip_log('Pas de methode ->quote pour echapper', 'sqlite.' . _LOG_INFO_IMPORTANTE);
2159
-
2160
-	return ("'" . str_replace("'", "''", $v) . "'");
2113
+    if ($type) {
2114
+        if (
2115
+            is_null($v)
2116
+            and stripos($type, 'NOT NULL') === false
2117
+        ) {
2118
+            // null php se traduit en NULL SQL
2119
+            return 'NULL';
2120
+        }
2121
+
2122
+        if (sql_test_date($type) and preg_match('/^\w+\(/', $v)) {
2123
+            return $v;
2124
+        }
2125
+        if (sql_test_int($type)) {
2126
+            if (is_numeric($v)) {
2127
+                return $v;
2128
+            } elseif ($v === null) {
2129
+                return 0;
2130
+            } elseif (ctype_xdigit(substr($v, 2)) and strncmp($v, '0x', 2) === 0) {
2131
+                return hexdec(substr($v, 2));
2132
+            } else {
2133
+                return intval($v);
2134
+            }
2135
+        }
2136
+    } else {
2137
+        // si on ne connait pas le type on le deduit de $v autant que possible
2138
+        if (is_bool($v)) {
2139
+            return strval(intval($v));
2140
+        } elseif (is_numeric($v)) {
2141
+            return strval($v);
2142
+        }
2143
+    }
2144
+
2145
+    // trouver un link sqlite pour faire l'echappement
2146
+    foreach ($GLOBALS['connexions'] as $s) {
2147
+        if (
2148
+            $l = $s['link']
2149
+            and is_object($l)
2150
+            and $l instanceof \PDO
2151
+            and $l->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'sqlite'
2152
+        ) {
2153
+            return $l->quote($v ?? '');
2154
+        }
2155
+    }
2156
+
2157
+    // echapper les ' en ''
2158
+    spip_log('Pas de methode ->quote pour echapper', 'sqlite.' . _LOG_INFO_IMPORTANTE);
2159
+
2160
+    return ("'" . str_replace("'", "''", $v) . "'");
2161 2161
 }
2162 2162
 
2163 2163
 
@@ -2174,21 +2174,21 @@  discard block
 block discarded – undo
2174 2174
  */
2175 2175
 function _sqlite_calculer_expression($expression, $v, $join = 'AND')
2176 2176
 {
2177
-	if (empty($v)) {
2178
-		return '';
2179
-	}
2180
-
2181
-	$exp = "\n$expression ";
2182
-
2183
-	if (!is_array($v)) {
2184
-		return $exp . $v;
2185
-	} else {
2186
-		if (strtoupper($join) === 'AND') {
2187
-			return $exp . join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2188
-		} else {
2189
-			return $exp . join($join, $v);
2190
-		}
2191
-	}
2177
+    if (empty($v)) {
2178
+        return '';
2179
+    }
2180
+
2181
+    $exp = "\n$expression ";
2182
+
2183
+    if (!is_array($v)) {
2184
+        return $exp . $v;
2185
+    } else {
2186
+        if (strtoupper($join) === 'AND') {
2187
+            return $exp . join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2188
+        } else {
2189
+            return $exp . join($join, $v);
2190
+        }
2191
+    }
2192 2192
 }
2193 2193
 
2194 2194
 
@@ -2205,7 +2205,7 @@  discard block
 block discarded – undo
2205 2205
  */
2206 2206
 function _sqlite_calculer_order($orderby)
2207 2207
 {
2208
-	return (is_array($orderby)) ? join(', ', $orderby) : $orderby;
2208
+    return (is_array($orderby)) ? join(', ', $orderby) : $orderby;
2209 2209
 }
2210 2210
 
2211 2211
 
@@ -2217,26 +2217,26 @@  discard block
 block discarded – undo
2217 2217
  */
2218 2218
 function _sqlite_calculer_select_as($args)
2219 2219
 {
2220
-	$res = '';
2221
-	foreach ($args as $k => $v) {
2222
-		if (substr($k, -1) == '@') {
2223
-			// c'est une jointure qui se refere au from precedent
2224
-			// pas de virgule
2225
-			$res .= '  ' . $v;
2226
-		} else {
2227
-			if (!is_numeric($k)) {
2228
-				$p = strpos($v, ' ');
2229
-				if ($p) {
2230
-					$v = substr($v, 0, $p) . " AS '$k'" . substr($v, $p);
2231
-				} else {
2232
-					$v .= " AS '$k'";
2233
-				}
2234
-			}
2235
-			$res .= ', ' . $v;
2236
-		}
2237
-	}
2238
-
2239
-	return substr($res, 2);
2220
+    $res = '';
2221
+    foreach ($args as $k => $v) {
2222
+        if (substr($k, -1) == '@') {
2223
+            // c'est une jointure qui se refere au from precedent
2224
+            // pas de virgule
2225
+            $res .= '  ' . $v;
2226
+        } else {
2227
+            if (!is_numeric($k)) {
2228
+                $p = strpos($v, ' ');
2229
+                if ($p) {
2230
+                    $v = substr($v, 0, $p) . " AS '$k'" . substr($v, $p);
2231
+                } else {
2232
+                    $v .= " AS '$k'";
2233
+                }
2234
+            }
2235
+            $res .= ', ' . $v;
2236
+        }
2237
+    }
2238
+
2239
+    return substr($res, 2);
2240 2240
 }
2241 2241
 
2242 2242
 
@@ -2260,26 +2260,26 @@  discard block
 block discarded – undo
2260 2260
  */
2261 2261
 function _sqlite_calculer_where($v)
2262 2262
 {
2263
-	if (!is_array($v)) {
2264
-		return $v;
2265
-	}
2266
-
2267
-	$op = array_shift($v);
2268
-	if (!($n = count($v))) {
2269
-		return $op;
2270
-	} else {
2271
-		$arg = _sqlite_calculer_where(array_shift($v));
2272
-		if ($n == 1) {
2273
-			return "$op($arg)";
2274
-		} else {
2275
-			$arg2 = _sqlite_calculer_where(array_shift($v));
2276
-			if ($n == 2) {
2277
-				return "($arg $op $arg2)";
2278
-			} else {
2279
-				return "($arg $op ($arg2) : $v[0])";
2280
-			}
2281
-		}
2282
-	}
2263
+    if (!is_array($v)) {
2264
+        return $v;
2265
+    }
2266
+
2267
+    $op = array_shift($v);
2268
+    if (!($n = count($v))) {
2269
+        return $op;
2270
+    } else {
2271
+        $arg = _sqlite_calculer_where(array_shift($v));
2272
+        if ($n == 1) {
2273
+            return "$op($arg)";
2274
+        } else {
2275
+            $arg2 = _sqlite_calculer_where(array_shift($v));
2276
+            if ($n == 2) {
2277
+                return "($arg $op $arg2)";
2278
+            } else {
2279
+                return "($arg $op ($arg2) : $v[0])";
2280
+            }
2281
+        }
2282
+    }
2283 2283
 }
2284 2284
 
2285 2285
 
@@ -2295,19 +2295,19 @@  discard block
 block discarded – undo
2295 2295
  */
2296 2296
 function _sqlite_charger_version($version = '')
2297 2297
 {
2298
-	$versions = [];
2299
-
2300
-	// version 3
2301
-	if (!$version || $version == 3) {
2302
-		if (extension_loaded('pdo') && extension_loaded('pdo_sqlite')) {
2303
-			$versions[] = 3;
2304
-		}
2305
-	}
2306
-	if ($version) {
2307
-		return in_array($version, $versions);
2308
-	}
2309
-
2310
-	return $versions;
2298
+    $versions = [];
2299
+
2300
+    // version 3
2301
+    if (!$version || $version == 3) {
2302
+        if (extension_loaded('pdo') && extension_loaded('pdo_sqlite')) {
2303
+            $versions[] = 3;
2304
+        }
2305
+    }
2306
+    if ($version) {
2307
+        return in_array($version, $versions);
2308
+    }
2309
+
2310
+    return $versions;
2311 2311
 }
2312 2312
 
2313 2313
 
@@ -2346,147 +2346,147 @@  discard block
 block discarded – undo
2346 2346
 function _sqlite_modifier_table($table, $colonne, $opt = [], $serveur = '')
2347 2347
 {
2348 2348
 
2349
-	if (is_array($table)) {
2350
-		$table_destination = reset($table);
2351
-		$table_origine = key($table);
2352
-	} else {
2353
-		$table_origine = $table_destination = $table;
2354
-	}
2355
-	// ne prend actuellement qu'un changement
2356
-	// mais pourra etre adapte pour changer plus qu'une colonne a la fois
2357
-	if (is_array($colonne)) {
2358
-		$colonne_destination = reset($colonne);
2359
-		$colonne_origine = key($colonne);
2360
-	} else {
2361
-		$colonne_origine = $colonne_destination = $colonne;
2362
-	}
2363
-	if (!isset($opt['field'])) {
2364
-		$opt['field'] = [];
2365
-	}
2366
-	if (!isset($opt['key'])) {
2367
-		$opt['key'] = [];
2368
-	}
2369
-
2370
-	// si les noms de tables sont differents, pas besoin de table temporaire
2371
-	// on prendra directement le nom de la future table
2372
-	$meme_table = ($table_origine == $table_destination);
2373
-
2374
-	$def_origine = sql_showtable($table_origine, false, $serveur);
2375
-	if (!$def_origine or !isset($def_origine['field'])) {
2376
-		spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite' . _LOG_ERREUR);
2377
-
2378
-		return false;
2379
-	}
2380
-
2381
-
2382
-	$table_tmp = $table_origine . '_tmp';
2383
-
2384
-	// 1) creer une table temporaire avec les modifications
2385
-	// - DROP : suppression de la colonne
2386
-	// - CHANGE : modification de la colonne
2387
-	// (foreach pour conserver l'ordre des champs)
2388
-
2389
-	// field
2390
-	$fields = [];
2391
-	// pour le INSERT INTO plus loin
2392
-	// stocker la correspondance nouvelles->anciennes colonnes
2393
-	$fields_correspondances = [];
2394
-	foreach ($def_origine['field'] as $c => $d) {
2395
-		if ($colonne_origine && ($c == $colonne_origine)) {
2396
-			// si pas DROP
2397
-			if ($colonne_destination) {
2398
-				$fields[$colonne_destination] = $opt['field'][$colonne_destination];
2399
-				$fields_correspondances[$colonne_destination] = $c;
2400
-			}
2401
-		} else {
2402
-			$fields[$c] = $d;
2403
-			$fields_correspondances[$c] = $c;
2404
-		}
2405
-	}
2406
-	// cas de ADD sqlite2 (ajout du champ en fin de table):
2407
-	if (!$colonne_origine && $colonne_destination) {
2408
-		$fields[$colonne_destination] = $opt['field'][$colonne_destination];
2409
-	}
2410
-
2411
-	// key...
2412
-	$keys = [];
2413
-	foreach ($def_origine['key'] as $c => $d) {
2414
-		$c = str_replace($colonne_origine, $colonne_destination, $c);
2415
-		$d = str_replace($colonne_origine, $colonne_destination, $d);
2416
-		// seulement si on ne supprime pas la colonne !
2417
-		if ($d) {
2418
-			$keys[$c] = $d;
2419
-		}
2420
-	}
2421
-
2422
-	// autres keys, on merge
2423
-	$keys = array_merge($keys, $opt['key']);
2424
-	$queries = [];
2425
-
2426
-	// copier dans destination (si differente de origine), sinon tmp
2427
-	$table_copie = ($meme_table) ? $table_tmp : $table_destination;
2428
-	$autoinc = (isset($keys['PRIMARY KEY'])
2429
-		and $keys['PRIMARY KEY']
2430
-		and stripos($keys['PRIMARY KEY'], ',') === false
2431
-		and stripos($fields[$keys['PRIMARY KEY']], 'default') === false);
2432
-
2433
-	if (
2434
-		$q = _sqlite_requete_create(
2435
-			$table_copie,
2436
-			$fields,
2437
-			$keys,
2438
-			$autoinc,
2439
-			$temporary = false,
2440
-			$ifnotexists = true,
2441
-			$serveur
2442
-		)
2443
-	) {
2444
-		$queries[] = $q;
2445
-	}
2446
-
2447
-
2448
-	// 2) y copier les champs qui vont bien
2449
-	$champs_dest = join(', ', array_keys($fields_correspondances));
2450
-	$champs_ori = join(', ', $fields_correspondances);
2451
-	$queries[] = "INSERT INTO $table_copie ($champs_dest) SELECT $champs_ori FROM $table_origine";
2452
-
2453
-	// 3) supprimer la table d'origine
2454
-	$queries[] = "DROP TABLE $table_origine";
2455
-
2456
-	// 4) renommer la table temporaire
2457
-	// avec le nom de la table destination
2458
-	// si necessaire
2459
-	if ($meme_table) {
2460
-		$queries[] = "ALTER TABLE $table_copie RENAME TO $table_destination";
2461
-	}
2462
-
2463
-	// 5) remettre les index !
2464
-	foreach ($keys as $k => $v) {
2465
-		if ($k == 'PRIMARY KEY') {
2466
-		} else {
2467
-			// enlever KEY
2468
-			$k = substr($k, 4);
2469
-			$queries[] = "CREATE INDEX $table_destination" . "_$k ON $table_destination ($v)";
2470
-		}
2471
-	}
2472
-
2473
-
2474
-	if (count($queries)) {
2475
-		Sqlite::demarrer_transaction($serveur);
2476
-		// il faut les faire une par une car $query = join('; ', $queries).";"; ne fonctionne pas
2477
-		foreach ($queries as $q) {
2478
-			if (!Sqlite::executer_requete($q, $serveur)) {
2479
-				spip_log('SQLite : ALTER TABLE table :'
2480
-					. " Erreur a l'execution de la requete : $q", 'sqlite.' . _LOG_ERREUR);
2481
-				Sqlite::annuler_transaction($serveur);
2482
-
2483
-				return false;
2484
-			}
2485
-		}
2486
-		Sqlite::finir_transaction($serveur);
2487
-	}
2488
-
2489
-	return true;
2349
+    if (is_array($table)) {
2350
+        $table_destination = reset($table);
2351
+        $table_origine = key($table);
2352
+    } else {
2353
+        $table_origine = $table_destination = $table;
2354
+    }
2355
+    // ne prend actuellement qu'un changement
2356
+    // mais pourra etre adapte pour changer plus qu'une colonne a la fois
2357
+    if (is_array($colonne)) {
2358
+        $colonne_destination = reset($colonne);
2359
+        $colonne_origine = key($colonne);
2360
+    } else {
2361
+        $colonne_origine = $colonne_destination = $colonne;
2362
+    }
2363
+    if (!isset($opt['field'])) {
2364
+        $opt['field'] = [];
2365
+    }
2366
+    if (!isset($opt['key'])) {
2367
+        $opt['key'] = [];
2368
+    }
2369
+
2370
+    // si les noms de tables sont differents, pas besoin de table temporaire
2371
+    // on prendra directement le nom de la future table
2372
+    $meme_table = ($table_origine == $table_destination);
2373
+
2374
+    $def_origine = sql_showtable($table_origine, false, $serveur);
2375
+    if (!$def_origine or !isset($def_origine['field'])) {
2376
+        spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite' . _LOG_ERREUR);
2377
+
2378
+        return false;
2379
+    }
2380
+
2381
+
2382
+    $table_tmp = $table_origine . '_tmp';
2383
+
2384
+    // 1) creer une table temporaire avec les modifications
2385
+    // - DROP : suppression de la colonne
2386
+    // - CHANGE : modification de la colonne
2387
+    // (foreach pour conserver l'ordre des champs)
2388
+
2389
+    // field
2390
+    $fields = [];
2391
+    // pour le INSERT INTO plus loin
2392
+    // stocker la correspondance nouvelles->anciennes colonnes
2393
+    $fields_correspondances = [];
2394
+    foreach ($def_origine['field'] as $c => $d) {
2395
+        if ($colonne_origine && ($c == $colonne_origine)) {
2396
+            // si pas DROP
2397
+            if ($colonne_destination) {
2398
+                $fields[$colonne_destination] = $opt['field'][$colonne_destination];
2399
+                $fields_correspondances[$colonne_destination] = $c;
2400
+            }
2401
+        } else {
2402
+            $fields[$c] = $d;
2403
+            $fields_correspondances[$c] = $c;
2404
+        }
2405
+    }
2406
+    // cas de ADD sqlite2 (ajout du champ en fin de table):
2407
+    if (!$colonne_origine && $colonne_destination) {
2408
+        $fields[$colonne_destination] = $opt['field'][$colonne_destination];
2409
+    }
2410
+
2411
+    // key...
2412
+    $keys = [];
2413
+    foreach ($def_origine['key'] as $c => $d) {
2414
+        $c = str_replace($colonne_origine, $colonne_destination, $c);
2415
+        $d = str_replace($colonne_origine, $colonne_destination, $d);
2416
+        // seulement si on ne supprime pas la colonne !
2417
+        if ($d) {
2418
+            $keys[$c] = $d;
2419
+        }
2420
+    }
2421
+
2422
+    // autres keys, on merge
2423
+    $keys = array_merge($keys, $opt['key']);
2424
+    $queries = [];
2425
+
2426
+    // copier dans destination (si differente de origine), sinon tmp
2427
+    $table_copie = ($meme_table) ? $table_tmp : $table_destination;
2428
+    $autoinc = (isset($keys['PRIMARY KEY'])
2429
+        and $keys['PRIMARY KEY']
2430
+        and stripos($keys['PRIMARY KEY'], ',') === false
2431
+        and stripos($fields[$keys['PRIMARY KEY']], 'default') === false);
2432
+
2433
+    if (
2434
+        $q = _sqlite_requete_create(
2435
+            $table_copie,
2436
+            $fields,
2437
+            $keys,
2438
+            $autoinc,
2439
+            $temporary = false,
2440
+            $ifnotexists = true,
2441
+            $serveur
2442
+        )
2443
+    ) {
2444
+        $queries[] = $q;
2445
+    }
2446
+
2447
+
2448
+    // 2) y copier les champs qui vont bien
2449
+    $champs_dest = join(', ', array_keys($fields_correspondances));
2450
+    $champs_ori = join(', ', $fields_correspondances);
2451
+    $queries[] = "INSERT INTO $table_copie ($champs_dest) SELECT $champs_ori FROM $table_origine";
2452
+
2453
+    // 3) supprimer la table d'origine
2454
+    $queries[] = "DROP TABLE $table_origine";
2455
+
2456
+    // 4) renommer la table temporaire
2457
+    // avec le nom de la table destination
2458
+    // si necessaire
2459
+    if ($meme_table) {
2460
+        $queries[] = "ALTER TABLE $table_copie RENAME TO $table_destination";
2461
+    }
2462
+
2463
+    // 5) remettre les index !
2464
+    foreach ($keys as $k => $v) {
2465
+        if ($k == 'PRIMARY KEY') {
2466
+        } else {
2467
+            // enlever KEY
2468
+            $k = substr($k, 4);
2469
+            $queries[] = "CREATE INDEX $table_destination" . "_$k ON $table_destination ($v)";
2470
+        }
2471
+    }
2472
+
2473
+
2474
+    if (count($queries)) {
2475
+        Sqlite::demarrer_transaction($serveur);
2476
+        // il faut les faire une par une car $query = join('; ', $queries).";"; ne fonctionne pas
2477
+        foreach ($queries as $q) {
2478
+            if (!Sqlite::executer_requete($q, $serveur)) {
2479
+                spip_log('SQLite : ALTER TABLE table :'
2480
+                    . " Erreur a l'execution de la requete : $q", 'sqlite.' . _LOG_ERREUR);
2481
+                Sqlite::annuler_transaction($serveur);
2482
+
2483
+                return false;
2484
+            }
2485
+        }
2486
+        Sqlite::finir_transaction($serveur);
2487
+    }
2488
+
2489
+    return true;
2490 2490
 }
2491 2491
 
2492 2492
 
@@ -2497,61 +2497,61 @@  discard block
 block discarded – undo
2497 2497
  */
2498 2498
 function _sqlite_ref_fonctions()
2499 2499
 {
2500
-	$fonctions = [
2501
-		'alter' => 'spip_sqlite_alter',
2502
-		'count' => 'spip_sqlite_count',
2503
-		'countsel' => 'spip_sqlite_countsel',
2504
-		'create' => 'spip_sqlite_create',
2505
-		'create_base' => 'spip_sqlite_create_base',
2506
-		'create_view' => 'spip_sqlite_create_view',
2507
-		'date_proche' => 'spip_sqlite_date_proche',
2508
-		'delete' => 'spip_sqlite_delete',
2509
-		'drop_table' => 'spip_sqlite_drop_table',
2510
-		'drop_view' => 'spip_sqlite_drop_view',
2511
-		'errno' => 'spip_sqlite_errno',
2512
-		'error' => 'spip_sqlite_error',
2513
-		'explain' => 'spip_sqlite_explain',
2514
-		'fetch' => 'spip_sqlite_fetch',
2515
-		'seek' => 'spip_sqlite_seek',
2516
-		'free' => 'spip_sqlite_free',
2517
-		'hex' => 'spip_sqlite_hex',
2518
-		'in' => 'spip_sqlite_in',
2519
-		'insert' => 'spip_sqlite_insert',
2520
-		'insertq' => 'spip_sqlite_insertq',
2521
-		'insertq_multi' => 'spip_sqlite_insertq_multi',
2522
-		'listdbs' => 'spip_sqlite_listdbs',
2523
-		'multi' => 'spip_sqlite_multi',
2524
-		'optimize' => 'spip_sqlite_optimize',
2525
-		'query' => 'spip_sqlite_query',
2526
-		'quote' => 'spip_sqlite_quote',
2527
-		'repair' => 'spip_sqlite_repair',
2528
-		'replace' => 'spip_sqlite_replace',
2529
-		'replace_multi' => 'spip_sqlite_replace_multi',
2530
-		'select' => 'spip_sqlite_select',
2531
-		'selectdb' => 'spip_sqlite_selectdb',
2532
-		'set_charset' => 'spip_sqlite_set_charset',
2533
-		'get_charset' => 'spip_sqlite_get_charset',
2534
-		'showbase' => 'spip_sqlite_showbase',
2535
-		'showtable' => 'spip_sqlite_showtable',
2536
-		'table_exists' => 'spip_sqlite_table_exists',
2537
-		'update' => 'spip_sqlite_update',
2538
-		'updateq' => 'spip_sqlite_updateq',
2539
-		'preferer_transaction' => 'spip_sqlite_preferer_transaction',
2540
-		'demarrer_transaction' => 'spip_sqlite_demarrer_transaction',
2541
-		'terminer_transaction' => 'spip_sqlite_terminer_transaction',
2542
-	];
2543
-
2544
-	// association de chaque nom http d'un charset aux couples sqlite
2545
-	// SQLite supporte utf-8 et utf-16 uniquement.
2546
-	$charsets = [
2547
-		'utf-8' => ['charset' => 'utf8', 'collation' => 'utf8_general_ci'],
2548
-		//'utf-16be'=>array('charset'=>'utf16be','collation'=>'UTF-16BE'),// aucune idee de quoi il faut remplir dans es champs la
2549
-		//'utf-16le'=>array('charset'=>'utf16le','collation'=>'UTF-16LE')
2550
-	];
2551
-
2552
-	$fonctions['charsets'] = $charsets;
2553
-
2554
-	return $fonctions;
2500
+    $fonctions = [
2501
+        'alter' => 'spip_sqlite_alter',
2502
+        'count' => 'spip_sqlite_count',
2503
+        'countsel' => 'spip_sqlite_countsel',
2504
+        'create' => 'spip_sqlite_create',
2505
+        'create_base' => 'spip_sqlite_create_base',
2506
+        'create_view' => 'spip_sqlite_create_view',
2507
+        'date_proche' => 'spip_sqlite_date_proche',
2508
+        'delete' => 'spip_sqlite_delete',
2509
+        'drop_table' => 'spip_sqlite_drop_table',
2510
+        'drop_view' => 'spip_sqlite_drop_view',
2511
+        'errno' => 'spip_sqlite_errno',
2512
+        'error' => 'spip_sqlite_error',
2513
+        'explain' => 'spip_sqlite_explain',
2514
+        'fetch' => 'spip_sqlite_fetch',
2515
+        'seek' => 'spip_sqlite_seek',
2516
+        'free' => 'spip_sqlite_free',
2517
+        'hex' => 'spip_sqlite_hex',
2518
+        'in' => 'spip_sqlite_in',
2519
+        'insert' => 'spip_sqlite_insert',
2520
+        'insertq' => 'spip_sqlite_insertq',
2521
+        'insertq_multi' => 'spip_sqlite_insertq_multi',
2522
+        'listdbs' => 'spip_sqlite_listdbs',
2523
+        'multi' => 'spip_sqlite_multi',
2524
+        'optimize' => 'spip_sqlite_optimize',
2525
+        'query' => 'spip_sqlite_query',
2526
+        'quote' => 'spip_sqlite_quote',
2527
+        'repair' => 'spip_sqlite_repair',
2528
+        'replace' => 'spip_sqlite_replace',
2529
+        'replace_multi' => 'spip_sqlite_replace_multi',
2530
+        'select' => 'spip_sqlite_select',
2531
+        'selectdb' => 'spip_sqlite_selectdb',
2532
+        'set_charset' => 'spip_sqlite_set_charset',
2533
+        'get_charset' => 'spip_sqlite_get_charset',
2534
+        'showbase' => 'spip_sqlite_showbase',
2535
+        'showtable' => 'spip_sqlite_showtable',
2536
+        'table_exists' => 'spip_sqlite_table_exists',
2537
+        'update' => 'spip_sqlite_update',
2538
+        'updateq' => 'spip_sqlite_updateq',
2539
+        'preferer_transaction' => 'spip_sqlite_preferer_transaction',
2540
+        'demarrer_transaction' => 'spip_sqlite_demarrer_transaction',
2541
+        'terminer_transaction' => 'spip_sqlite_terminer_transaction',
2542
+    ];
2543
+
2544
+    // association de chaque nom http d'un charset aux couples sqlite
2545
+    // SQLite supporte utf-8 et utf-16 uniquement.
2546
+    $charsets = [
2547
+        'utf-8' => ['charset' => 'utf8', 'collation' => 'utf8_general_ci'],
2548
+        //'utf-16be'=>array('charset'=>'utf16be','collation'=>'UTF-16BE'),// aucune idee de quoi il faut remplir dans es champs la
2549
+        //'utf-16le'=>array('charset'=>'utf16le','collation'=>'UTF-16LE')
2550
+    ];
2551
+
2552
+    $fonctions['charsets'] = $charsets;
2553
+
2554
+    return $fonctions;
2555 2555
 }
2556 2556
 
2557 2557
 
@@ -2564,56 +2564,56 @@  discard block
 block discarded – undo
2564 2564
  */
2565 2565
 function _sqlite_remplacements_definitions_table($query, $autoinc = false)
2566 2566
 {
2567
-	// quelques remplacements
2568
-	$num = '(\s*\([0-9]*\))?';
2569
-	$enum = '(\s*\([^\)]*\))?';
2570
-
2571
-	$remplace = [
2572
-		'/enum' . $enum . '/is' => 'VARCHAR(255)',
2573
-		'/COLLATE \w+_bin/is' => 'COLLATE BINARY',
2574
-		'/COLLATE \w+_ci/is' => 'COLLATE NOCASE',
2575
-		'/auto_increment/is' => '',
2576
-		'/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374
2577
-		'/(timestamp .* )ON .*$/is' => '\\1',
2578
-		'/character set \w+/is' => '',
2579
-		'/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED',
2580
-		'/(text\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2581
-		'/((char|varchar)' . $num . '\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2582
-		'/(datetime\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00 00:00:00'",
2583
-		'/(date\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00'",
2584
-	];
2585
-
2586
-	// pour l'autoincrement, il faut des INTEGER NOT NULL PRIMARY KEY
2587
-	$remplace_autocinc = [
2588
-		'/(big|small|medium|tiny)?int(eger)?' . $num . '/is' => 'INTEGER'
2589
-	];
2590
-	// pour les int non autoincrement, il faut un DEFAULT
2591
-	$remplace_nonautocinc = [
2592
-		'/((big|small|medium|tiny)?int(eger)?' . $num . '\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2593
-	];
2594
-
2595
-	if (is_string($query)) {
2596
-		$query = preg_replace(array_keys($remplace), $remplace, $query);
2597
-		if ($autoinc or preg_match(',AUTO_INCREMENT,is', $query)) {
2598
-			$query = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query);
2599
-		} else {
2600
-			$query = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query);
2601
-			$query = _sqlite_collate_ci($query);
2602
-		}
2603
-	} elseif (is_array($query)) {
2604
-		foreach ($query as $k => $q) {
2605
-			$ai = ($autoinc ? $k == $autoinc : preg_match(',AUTO_INCREMENT,is', $q));
2606
-			$query[$k] = preg_replace(array_keys($remplace), $remplace, $query[$k]);
2607
-			if ($ai) {
2608
-				$query[$k] = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query[$k]);
2609
-			} else {
2610
-				$query[$k] = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query[$k]);
2611
-				$query[$k] = _sqlite_collate_ci($query[$k]);
2612
-			}
2613
-		}
2614
-	}
2615
-
2616
-	return $query;
2567
+    // quelques remplacements
2568
+    $num = '(\s*\([0-9]*\))?';
2569
+    $enum = '(\s*\([^\)]*\))?';
2570
+
2571
+    $remplace = [
2572
+        '/enum' . $enum . '/is' => 'VARCHAR(255)',
2573
+        '/COLLATE \w+_bin/is' => 'COLLATE BINARY',
2574
+        '/COLLATE \w+_ci/is' => 'COLLATE NOCASE',
2575
+        '/auto_increment/is' => '',
2576
+        '/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374
2577
+        '/(timestamp .* )ON .*$/is' => '\\1',
2578
+        '/character set \w+/is' => '',
2579
+        '/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED',
2580
+        '/(text\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2581
+        '/((char|varchar)' . $num . '\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2582
+        '/(datetime\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00 00:00:00'",
2583
+        '/(date\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00'",
2584
+    ];
2585
+
2586
+    // pour l'autoincrement, il faut des INTEGER NOT NULL PRIMARY KEY
2587
+    $remplace_autocinc = [
2588
+        '/(big|small|medium|tiny)?int(eger)?' . $num . '/is' => 'INTEGER'
2589
+    ];
2590
+    // pour les int non autoincrement, il faut un DEFAULT
2591
+    $remplace_nonautocinc = [
2592
+        '/((big|small|medium|tiny)?int(eger)?' . $num . '\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2593
+    ];
2594
+
2595
+    if (is_string($query)) {
2596
+        $query = preg_replace(array_keys($remplace), $remplace, $query);
2597
+        if ($autoinc or preg_match(',AUTO_INCREMENT,is', $query)) {
2598
+            $query = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query);
2599
+        } else {
2600
+            $query = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query);
2601
+            $query = _sqlite_collate_ci($query);
2602
+        }
2603
+    } elseif (is_array($query)) {
2604
+        foreach ($query as $k => $q) {
2605
+            $ai = ($autoinc ? $k == $autoinc : preg_match(',AUTO_INCREMENT,is', $q));
2606
+            $query[$k] = preg_replace(array_keys($remplace), $remplace, $query[$k]);
2607
+            if ($ai) {
2608
+                $query[$k] = preg_replace(array_keys($remplace_autocinc), $remplace_autocinc, $query[$k]);
2609
+            } else {
2610
+                $query[$k] = preg_replace(array_keys($remplace_nonautocinc), $remplace_nonautocinc, $query[$k]);
2611
+                $query[$k] = _sqlite_collate_ci($query[$k]);
2612
+            }
2613
+        }
2614
+    }
2615
+
2616
+    return $query;
2617 2617
 }
2618 2618
 
2619 2619
 /**
@@ -2625,17 +2625,17 @@  discard block
 block discarded – undo
2625 2625
  */
2626 2626
 function _sqlite_collate_ci($champ)
2627 2627
 {
2628
-	if (stripos($champ, 'COLLATE') !== false) {
2629
-		return $champ;
2630
-	}
2631
-	if (stripos($champ, 'BINARY') !== false) {
2632
-		return str_ireplace('BINARY', 'COLLATE BINARY', $champ);
2633
-	}
2634
-	if (preg_match(',^(char|varchar|(long|small|medium|tiny)?text),i', $champ)) {
2635
-		return $champ . ' COLLATE NOCASE';
2636
-	}
2637
-
2638
-	return $champ;
2628
+    if (stripos($champ, 'COLLATE') !== false) {
2629
+        return $champ;
2630
+    }
2631
+    if (stripos($champ, 'BINARY') !== false) {
2632
+        return str_ireplace('BINARY', 'COLLATE BINARY', $champ);
2633
+    }
2634
+    if (preg_match(',^(char|varchar|(long|small|medium|tiny)?text),i', $champ)) {
2635
+        return $champ . ' COLLATE NOCASE';
2636
+    }
2637
+
2638
+    return $champ;
2639 2639
 }
2640 2640
 
2641 2641
 
@@ -2654,84 +2654,84 @@  discard block
 block discarded – undo
2654 2654
  * @return bool|string
2655 2655
  */
2656 2656
 function _sqlite_requete_create(
2657
-	$nom,
2658
-	$champs,
2659
-	$cles,
2660
-	$autoinc = false,
2661
-	$temporary = false,
2662
-	$_ifnotexists = true,
2663
-	$serveur = '',
2664
-	$requeter = true
2657
+    $nom,
2658
+    $champs,
2659
+    $cles,
2660
+    $autoinc = false,
2661
+    $temporary = false,
2662
+    $_ifnotexists = true,
2663
+    $serveur = '',
2664
+    $requeter = true
2665 2665
 ) {
2666
-	$query = $keys = $s = $p = '';
2667
-
2668
-	// certains plugins declarent les tables  (permet leur inclusion dans le dump)
2669
-	// sans les renseigner (laisse le compilo recuperer la description)
2670
-	if (!is_array($champs) || !is_array($cles)) {
2671
-		return;
2672
-	}
2673
-
2674
-	// sqlite ne gere pas KEY tout court dans une requete CREATE TABLE
2675
-	// il faut passer par des create index
2676
-	// Il gere par contre primary key !
2677
-	// Soit la PK est definie dans les cles, soit dans un champs
2678
-	// soit faussement dans les 2 (et dans ce cas, il faut l’enlever à un des 2 endroits !)
2679
-	$pk = 'PRIMARY KEY';
2680
-	// le champ de cle primaire
2681
-	$champ_pk = !empty($cles[$pk]) ? $cles[$pk] : '';
2682
-
2683
-	foreach ($champs as $k => $v) {
2684
-		if (false !== stripos($v, $pk)) {
2685
-			$champ_pk = $k;
2686
-			// on n'en a plus besoin dans field, vu que defini dans key
2687
-			$champs[$k] = preg_replace("/$pk/is", '', $champs[$k]);
2688
-			break;
2689
-		}
2690
-	}
2691
-
2692
-	if ($champ_pk) {
2693
-		$keys = "\n\t\t$pk ($champ_pk)";
2694
-	}
2695
-	// Pas de DEFAULT 0 sur les cles primaires en auto-increment
2696
-	if (
2697
-		isset($champs[$champ_pk])
2698
-		and stripos($champs[$champ_pk], 'default 0') !== false
2699
-	) {
2700
-		$champs[$champ_pk] = trim(str_ireplace('default 0', '', $champs[$champ_pk]));
2701
-	}
2702
-
2703
-	$champs = _sqlite_remplacements_definitions_table($champs, $autoinc ? $champ_pk : false);
2704
-	foreach ($champs as $k => $v) {
2705
-		$query .= "$s\n\t\t$k $v";
2706
-		$s = ',';
2707
-	}
2708
-
2709
-	$ifnotexists = '';
2710
-	if ($_ifnotexists) {
2711
-		$version = spip_sqlite_fetch(
2712
-			spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur),
2713
-			'',
2714
-			$serveur
2715
-		);
2716
-		if (!function_exists('spip_version_compare')) {
2717
-			include_spip('plugins/installer');
2718
-		}
2719
-
2720
-		if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
2721
-			$ifnotexists = ' IF NOT EXISTS';
2722
-		} else {
2723
-			/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
2724
-			$a = spip_sqlite_showtable($nom, $serveur);
2725
-			if (isset($a['key']['KEY ' . $nom])) {
2726
-				return true;
2727
-			}
2728
-		}
2729
-	}
2730
-
2731
-	$temporary = $temporary ? ' TEMPORARY' : '';
2732
-	$q = "CREATE$temporary TABLE$ifnotexists $nom ($query" . ($keys ? ",$keys" : '') . ")\n";
2733
-
2734
-	return $q;
2666
+    $query = $keys = $s = $p = '';
2667
+
2668
+    // certains plugins declarent les tables  (permet leur inclusion dans le dump)
2669
+    // sans les renseigner (laisse le compilo recuperer la description)
2670
+    if (!is_array($champs) || !is_array($cles)) {
2671
+        return;
2672
+    }
2673
+
2674
+    // sqlite ne gere pas KEY tout court dans une requete CREATE TABLE
2675
+    // il faut passer par des create index
2676
+    // Il gere par contre primary key !
2677
+    // Soit la PK est definie dans les cles, soit dans un champs
2678
+    // soit faussement dans les 2 (et dans ce cas, il faut l’enlever à un des 2 endroits !)
2679
+    $pk = 'PRIMARY KEY';
2680
+    // le champ de cle primaire
2681
+    $champ_pk = !empty($cles[$pk]) ? $cles[$pk] : '';
2682
+
2683
+    foreach ($champs as $k => $v) {
2684
+        if (false !== stripos($v, $pk)) {
2685
+            $champ_pk = $k;
2686
+            // on n'en a plus besoin dans field, vu que defini dans key
2687
+            $champs[$k] = preg_replace("/$pk/is", '', $champs[$k]);
2688
+            break;
2689
+        }
2690
+    }
2691
+
2692
+    if ($champ_pk) {
2693
+        $keys = "\n\t\t$pk ($champ_pk)";
2694
+    }
2695
+    // Pas de DEFAULT 0 sur les cles primaires en auto-increment
2696
+    if (
2697
+        isset($champs[$champ_pk])
2698
+        and stripos($champs[$champ_pk], 'default 0') !== false
2699
+    ) {
2700
+        $champs[$champ_pk] = trim(str_ireplace('default 0', '', $champs[$champ_pk]));
2701
+    }
2702
+
2703
+    $champs = _sqlite_remplacements_definitions_table($champs, $autoinc ? $champ_pk : false);
2704
+    foreach ($champs as $k => $v) {
2705
+        $query .= "$s\n\t\t$k $v";
2706
+        $s = ',';
2707
+    }
2708
+
2709
+    $ifnotexists = '';
2710
+    if ($_ifnotexists) {
2711
+        $version = spip_sqlite_fetch(
2712
+            spip_sqlite_query('select sqlite_version() AS sqlite_version', $serveur),
2713
+            '',
2714
+            $serveur
2715
+        );
2716
+        if (!function_exists('spip_version_compare')) {
2717
+            include_spip('plugins/installer');
2718
+        }
2719
+
2720
+        if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) {
2721
+            $ifnotexists = ' IF NOT EXISTS';
2722
+        } else {
2723
+            /* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
2724
+            $a = spip_sqlite_showtable($nom, $serveur);
2725
+            if (isset($a['key']['KEY ' . $nom])) {
2726
+                return true;
2727
+            }
2728
+        }
2729
+    }
2730
+
2731
+    $temporary = $temporary ? ' TEMPORARY' : '';
2732
+    $q = "CREATE$temporary TABLE$ifnotexists $nom ($query" . ($keys ? ",$keys" : '') . ")\n";
2733
+
2734
+    return $q;
2735 2735
 }
2736 2736
 
2737 2737
 
@@ -2751,40 +2751,40 @@  discard block
 block discarded – undo
2751 2751
  */
2752 2752
 function _sqlite_ajouter_champs_timestamp($table, $couples, $desc = '', $serveur = '')
2753 2753
 {
2754
-	static $tables = [];
2755
-
2756
-	if (!isset($tables[$table])) {
2757
-		if (!$desc) {
2758
-			$trouver_table = charger_fonction('trouver_table', 'base');
2759
-			$desc = $trouver_table($table, $serveur);
2760
-			// si pas de description, on ne fait rien, ou on die() ?
2761
-			if (!$desc) {
2762
-				return $couples;
2763
-			}
2764
-		}
2765
-
2766
-		// recherche des champs avec simplement 'TIMESTAMP'
2767
-		// cependant, il faudra peut etre etendre
2768
-		// avec la gestion de DEFAULT et ON UPDATE
2769
-		// mais ceux-ci ne sont pas utilises dans le core
2770
-		$tables[$table] = ['valeur' => [], 'cite' => [], 'desc' => []];
2771
-
2772
-		$now = _sqlite_func_now(true);
2773
-		foreach ($desc['field'] as $k => $v) {
2774
-			if (strpos(strtolower(ltrim($v)), 'timestamp') === 0) {
2775
-				$tables[$table]['desc'][$k] = $v;
2776
-				$tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2777
-			}
2778
-		}
2779
-	} else {
2780
-		$now = _sqlite_func_now(true);
2781
-		foreach (array_keys($tables[$table]['desc']) as $k) {
2782
-			$tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2783
-		}
2784
-	}
2785
-
2786
-	// ajout des champs type 'timestamp' absents
2787
-	return array_merge($tables[$table]['valeur'], $couples);
2754
+    static $tables = [];
2755
+
2756
+    if (!isset($tables[$table])) {
2757
+        if (!$desc) {
2758
+            $trouver_table = charger_fonction('trouver_table', 'base');
2759
+            $desc = $trouver_table($table, $serveur);
2760
+            // si pas de description, on ne fait rien, ou on die() ?
2761
+            if (!$desc) {
2762
+                return $couples;
2763
+            }
2764
+        }
2765
+
2766
+        // recherche des champs avec simplement 'TIMESTAMP'
2767
+        // cependant, il faudra peut etre etendre
2768
+        // avec la gestion de DEFAULT et ON UPDATE
2769
+        // mais ceux-ci ne sont pas utilises dans le core
2770
+        $tables[$table] = ['valeur' => [], 'cite' => [], 'desc' => []];
2771
+
2772
+        $now = _sqlite_func_now(true);
2773
+        foreach ($desc['field'] as $k => $v) {
2774
+            if (strpos(strtolower(ltrim($v)), 'timestamp') === 0) {
2775
+                $tables[$table]['desc'][$k] = $v;
2776
+                $tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2777
+            }
2778
+        }
2779
+    } else {
2780
+        $now = _sqlite_func_now(true);
2781
+        foreach (array_keys($tables[$table]['desc']) as $k) {
2782
+            $tables[$table]['valeur'][$k] = _sqlite_calculer_cite($now, $tables[$table]['desc'][$k]);
2783
+        }
2784
+    }
2785
+
2786
+    // ajout des champs type 'timestamp' absents
2787
+    return array_merge($tables[$table]['valeur'], $couples);
2788 2788
 }
2789 2789
 
2790 2790
 
@@ -2796,5 +2796,5 @@  discard block
 block discarded – undo
2796 2796
  */
2797 2797
 function spip_versions_sqlite()
2798 2798
 {
2799
-	return _sqlite_charger_version();
2799
+    return _sqlite_charger_version();
2800 2800
 }
Please login to merge, or discard this patch.
Spacing   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -67,35 +67,35 @@  discard block
 block discarded – undo
67 67
 	// determiner le dossier de la base : $addr ou _DIR_DB
68 68
 	$f = _DIR_DB;
69 69
 	if ($addr and str_contains($addr, '/')) {
70
-		$f = rtrim($addr, '/') . '/';
70
+		$f = rtrim($addr, '/').'/';
71 71
 	}
72 72
 
73 73
 	// un nom de base demande et impossible d'obtenir la base, on s'en va :
74 74
 	// il faut que la base existe ou que le repertoire parent soit writable
75
-	if ($db and !is_file($f .= $db . '.sqlite') and !is_writable(dirname($f))) {
76
-		spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.' . _LOG_HS);
75
+	if ($db and !is_file($f .= $db.'.sqlite') and !is_writable(dirname($f))) {
76
+		spip_log("base $f non trouvee ou droits en ecriture manquants", 'sqlite.'._LOG_HS);
77 77
 
78 78
 		return false;
79 79
 	}
80 80
 
81 81
 	// charger les modules sqlite au besoin
82 82
 	if (!_sqlite_charger_version($sqlite_version)) {
83
-		spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.' . _LOG_HS);
83
+		spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!", 'sqlite.'._LOG_HS);
84 84
 
85 85
 		return false;
86 86
 	}
87 87
 
88 88
 	// chargement des constantes
89 89
 	// il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
90
-	$define = 'spip_sqlite' . $sqlite_version . '_constantes';
90
+	$define = 'spip_sqlite'.$sqlite_version.'_constantes';
91 91
 	$define();
92 92
 
93 93
 	if (!$db) {
94 94
 		// si pas de db ->
95 95
 		// base temporaire tant qu'on ne connait pas son vrai nom
96 96
 		// pour tester la connexion
97
-		$db = '_sqlite' . $sqlite_version . '_install';
98
-		$tmp = _DIR_DB . $db . '.sqlite';
97
+		$db = '_sqlite'.$sqlite_version.'_install';
98
+		$tmp = _DIR_DB.$db.'.sqlite';
99 99
 		$link = spip_sqlite_open($tmp);
100 100
 	} else {
101 101
 		// Ouvrir (eventuellement creer la base)
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 	}
104 104
 
105 105
 	if (!$link) {
106
-		spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f", 'sqlite.' . _LOG_HS);
106
+		spip_log("Impossible d'ouvrir la base SQLite($sqlite_version) $f", 'sqlite.'._LOG_HS);
107 107
 
108 108
 		return false;
109 109
 	}
@@ -138,7 +138,7 @@  discard block
 block discarded – undo
138 138
  */
139 139
 function spip_sqlite_open(string $file): \PDO {
140 140
 	$PDO = new \PDO("sqlite:$file");
141
-	$PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS , [\Spip\Sql\Sqlite\PDOStatement::class, [&$PDO]]);
141
+	$PDO->setAttribute(\PDO::ATTR_STATEMENT_CLASS, [\Spip\Sql\Sqlite\PDOStatement::class, [&$PDO]]);
142 142
 	return $PDO;
143 143
 }
144 144
 
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
 		$table = $regs[3];
204 204
 		$suite = $regs[4];
205 205
 	} else {
206
-		spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.' . _LOG_ERREUR);
206
+		spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite.'._LOG_ERREUR);
207 207
 
208 208
 		return false;
209 209
 	}
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
 	$i = 0;
221 221
 	$ouverte = false;
222 222
 	while ($do = array_shift($todo)) {
223
-		$todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . ',' . $do : $do;
223
+		$todo2[$i] = isset($todo2[$i]) ? $todo2[$i].','.$do : $do;
224 224
 		$o = (str_contains($do, '('));
225 225
 		$f = (str_contains($do, ')'));
226 226
 		if ($o and !$f) {
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 		) {
247 247
 			spip_log(
248 248
 				"SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)",
249
-				'sqlite.' . _LOG_ERREUR
249
+				'sqlite.'._LOG_ERREUR
250 250
 			);
251 251
 
252 252
 			return false;
@@ -342,10 +342,10 @@  discard block
 block discarded – undo
342 342
 
343 343
 				// pas geres en sqlite2
344 344
 			case 'RENAME':
345
-				$do = 'RENAME TO' . substr($do, 6);
345
+				$do = 'RENAME TO'.substr($do, 6);
346 346
 			case 'RENAME TO':
347 347
 				if (!Sqlite::executer_requete("$debut $do", $serveur)) {
348
-					spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.' . _LOG_ERREUR);
348
+					spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite.'._LOG_ERREUR);
349 349
 
350 350
 					return false;
351 351
 				}
@@ -388,7 +388,7 @@  discard block
 block discarded – undo
388 388
 						$colonnes = substr($colonne_origine, 1, -1);
389 389
 						if (str_contains(',', $colonnes)) {
390 390
 							spip_log('SQLite : Erreur, impossible de creer un index sur plusieurs colonnes'
391
-								. " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.' . _LOG_ERREUR);
391
+								. " sans qu'il ait de nom ($table, ($colonnes))", 'sqlite.'._LOG_ERREUR);
392 392
 							break;
393 393
 						} else {
394 394
 							$nom_index = $colonnes;
@@ -403,12 +403,12 @@  discard block
 block discarded – undo
403 403
 
404 404
 				// pas geres en sqlite2
405 405
 			case 'ADD COLUMN':
406
-				$do = 'ADD' . substr($do, 10);
406
+				$do = 'ADD'.substr($do, 10);
407 407
 			case 'ADD':
408 408
 			default:
409 409
 				if (!preg_match(',primary\s+key,i', $do)) {
410 410
 					if (!Sqlite::executer_requete("$debut $do", $serveur)) {
411
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
411
+						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.'._LOG_ERREUR);
412 412
 
413 413
 						return false;
414 414
 					}
@@ -428,7 +428,7 @@  discard block
 block discarded – undo
428 428
 					}
429 429
 					$opts['field'] = [$colonne_ajoutee => $def];
430 430
 					if (!_sqlite_modifier_table($table, [$colonne_ajoutee], $opts, $serveur)) {
431
-						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.' . _LOG_ERREUR);
431
+						spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite.'._LOG_ERREUR);
432 432
 
433 433
 						return false;
434 434
 					}
@@ -436,10 +436,10 @@  discard block
 block discarded – undo
436 436
 				break;
437 437
 		}
438 438
 		// tout est bon, ouf !
439
-		spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.' . _LOG_INFO);
439
+		spip_log("SQLite ($serveur) : Changements OK : $debut $do", 'sqlite.'._LOG_INFO);
440 440
 	}
441 441
 
442
-	spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.' . _LOG_INFO);
442
+	spip_log("SQLite ($serveur) : fin ALTER TABLE OK !", 'sqlite.'._LOG_INFO);
443 443
 
444 444
 	return true;
445 445
 }
@@ -508,9 +508,9 @@  discard block
 block discarded – undo
508 508
  **/
509 509
 function spip_sqlite_create_base($nom, $serveur = '', $option = true)
510 510
 {
511
-	$f = $nom . '.sqlite';
511
+	$f = $nom.'.sqlite';
512 512
 	if (strpos($nom, '/') === false) {
513
-		$f = _DIR_DB . $f;
513
+		$f = _DIR_DB.$f;
514 514
 	}
515 515
 
516 516
 	$ok = new \PDO("sqlite:$f");
@@ -551,13 +551,13 @@  discard block
 block discarded – undo
551 551
 	if (sql_showtable($nom, false, $serveur)) {
552 552
 		spip_log(
553 553
 			"Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)",
554
-			'sqlite.' . _LOG_ERREUR
554
+			'sqlite.'._LOG_ERREUR
555 555
 		);
556 556
 
557 557
 		return false;
558 558
 	}
559 559
 
560
-	$query = "CREATE VIEW $nom AS " . $query_select;
560
+	$query = "CREATE VIEW $nom AS ".$query_select;
561 561
 
562 562
 	return spip_sqlite_query($query, $serveur, $requeter);
563 563
 }
@@ -584,8 +584,8 @@  discard block
 block discarded – undo
584 584
 {
585 585
 	if (!($nom or $table or $champs)) {
586 586
 		spip_log(
587
-			"Champ manquant pour creer un index sqlite ($nom, $table, (" . join(',', $champs) . '))',
588
-			'sqlite.' . _LOG_ERREUR
587
+			"Champ manquant pour creer un index sqlite ($nom, $table, (".join(',', $champs).'))',
588
+			'sqlite.'._LOG_ERREUR
589 589
 		);
590 590
 
591 591
 		return false;
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
 
594 594
 	// SQLite ne differentie pas noms des index en fonction des tables
595 595
 	// il faut donc creer des noms uniques d'index pour une base sqlite
596
-	$nom = $table . '_' . $nom;
596
+	$nom = $table.'_'.$nom;
597 597
 	// enlever d'eventuelles parentheses deja presentes sur champs
598 598
 	if (!is_array($champs)) {
599 599
 		if ($champs[0] == '(') {
@@ -615,12 +615,12 @@  discard block
 block discarded – undo
615 615
 	} else {
616 616
 		/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
617 617
 		$a = spip_sqlite_showtable($table, $serveur);
618
-		if (isset($a['key']['KEY ' . $nom])) {
618
+		if (isset($a['key']['KEY '.$nom])) {
619 619
 			return true;
620 620
 		}
621 621
 	}
622 622
 
623
-	$query = 'CREATE ' . ($unique ? 'UNIQUE ' : '') . "INDEX$ifnotexists $nom ON $table (" . join(',', $champs) . ')';
623
+	$query = 'CREATE '.($unique ? 'UNIQUE ' : '')."INDEX$ifnotexists $nom ON $table (".join(',', $champs).')';
624 624
 	$res = spip_sqlite_query($query, $serveur, $requeter);
625 625
 	if (!$requeter) {
626 626
 		return $res;
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
 	$serveur = '',
690 690
 	$requeter = true
691 691
 ) {
692
-	$c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
692
+	$c = !$groupby ? '*' : ('DISTINCT '.(is_string($groupby) ? $groupby : join(',', $groupby)));
693 693
 	$r = spip_sqlite_select(
694 694
 		"COUNT($c)",
695 695
 		$from,
@@ -803,14 +803,14 @@  discard block
 block discarded – undo
803 803
 function spip_sqlite_drop_index($nom, $table, $serveur = '', $requeter = true)
804 804
 {
805 805
 	if (!($nom or $table)) {
806
-		spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.' . _LOG_ERREUR);
806
+		spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)", 'sqlite.'._LOG_ERREUR);
807 807
 
808 808
 		return false;
809 809
 	}
810 810
 
811 811
 	// SQLite ne differentie pas noms des index en fonction des tables
812 812
 	// il faut donc creer des noms uniques d'index pour une base sqlite
813
-	$index = $table . '_' . $nom;
813
+	$index = $table.'_'.$nom;
814 814
 	$exist = ' IF EXISTS';
815 815
 
816 816
 	$query = "DROP INDEX$exist $index";
@@ -843,7 +843,7 @@  discard block
 block discarded – undo
843 843
 	if ($s) {
844 844
 		$trace = debug_backtrace();
845 845
 		if ($trace[0]['function'] != 'spip_sqlite_error') {
846
-			spip_log("$s - $query - " . sql_error_backtrace(), 'sqlite.' . _LOG_ERREUR);
846
+			spip_log("$s - $query - ".sql_error_backtrace(), 'sqlite.'._LOG_ERREUR);
847 847
 		}
848 848
 	}
849 849
 
@@ -892,14 +892,14 @@  discard block
 block discarded – undo
892 892
 		$t = $link->errorInfo();
893 893
 		$s = ltrim($t[0], '0'); // 00000 si pas d'erreur
894 894
 		if ($s) {
895
-			$s .= ' / ' . $t[1];
895
+			$s .= ' / '.$t[1];
896 896
 		} // ajoute l'erreur du moteur SQLite
897 897
 	} else {
898 898
 		$s = ': aucune ressource sqlite (link)';
899 899
 	}
900 900
 
901 901
 	if ($s) {
902
-		spip_log("Erreur sqlite $s", 'sqlite.' . _LOG_ERREUR);
902
+		spip_log("Erreur sqlite $s", 'sqlite.'._LOG_ERREUR);
903 903
 	}
904 904
 
905 905
 	return $s ? $s : 0;
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
 	}
925 925
 
926 926
 	$query = Sqlite::traduire_requete($query, $serveur);
927
-	$query = 'EXPLAIN ' . $query;
927
+	$query = 'EXPLAIN '.$query;
928 928
 	if (!$requeter) {
929 929
 		return $query;
930 930
 	}
@@ -1100,7 +1100,7 @@  discard block
 block discarded – undo
1100 1100
 function spip_sqlite_insert($table, $champs, $valeurs, $desc = [], $serveur = '', $requeter = true)
1101 1101
 {
1102 1102
 
1103
-	$query = "INSERT INTO $table " . ($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1103
+	$query = "INSERT INTO $table ".($champs ? "$champs VALUES $valeurs" : 'DEFAULT VALUES');
1104 1104
 	if ($r = spip_sqlite_query($query, $serveur, $requeter)) {
1105 1105
 		if (!$requeter) {
1106 1106
 			return $r;
@@ -1156,8 +1156,8 @@  discard block
 block discarded – undo
1156 1156
 
1157 1157
 	$cles = $valeurs = '';
1158 1158
 	if (count($couples)) {
1159
-		$cles = '(' . join(',', array_keys($couples)) . ')';
1160
-		$valeurs = '(' . join(',', $couples) . ')';
1159
+		$cles = '('.join(',', array_keys($couples)).')';
1160
+		$valeurs = '('.join(',', $couples).')';
1161 1161
 	}
1162 1162
 
1163 1163
 	return spip_sqlite_insert($table, $cles, $valeurs, $desc, $serveur, $requeter);
@@ -1218,11 +1218,11 @@  discard block
 block discarded – undo
1218 1218
 
1219 1219
 		$champs = $valeurs = '';
1220 1220
 		if (count($couples)) {
1221
-			$champs = '(' . join(',', array_keys($couples)) . ')';
1222
-			$valeurs = '(' . join(',', $couples) . ')';
1223
-			$query = $query_start . "$champs VALUES $valeurs";
1221
+			$champs = '('.join(',', array_keys($couples)).')';
1222
+			$valeurs = '('.join(',', $couples).')';
1223
+			$query = $query_start."$champs VALUES $valeurs";
1224 1224
 		} else {
1225
-			$query = $query_start . 'DEFAULT VALUES';
1225
+			$query = $query_start.'DEFAULT VALUES';
1226 1226
 		}
1227 1227
 
1228 1228
 		if ($requeter) {
@@ -1359,7 +1359,7 @@  discard block
 block discarded – undo
1359 1359
  */
1360 1360
 function spip_sqlite_multi($objet, $lang)
1361 1361
 {
1362
-	$r = 'EXTRAIRE_MULTI(' . $objet . ", '" . $lang . "') AS multi";
1362
+	$r = 'EXTRAIRE_MULTI('.$objet.", '".$lang."') AS multi";
1363 1363
 
1364 1364
 	return $r;
1365 1365
 }
@@ -1433,7 +1433,7 @@  discard block
 block discarded – undo
1433 1433
 {
1434 1434
 	$op = (($interval <= 0) ? '>' : '<');
1435 1435
 
1436
-	return "($champ $op datetime('" . date('Y-m-d H:i:s') . "', '$interval $unite'))";
1436
+	return "($champ $op datetime('".date('Y-m-d H:i:s')."', '$interval $unite'))";
1437 1437
 }
1438 1438
 
1439 1439
 
@@ -1466,7 +1466,7 @@  discard block
 block discarded – undo
1466 1466
 				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1467 1467
 			) {
1468 1468
 				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT ''", $serveur);
1469
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1469
+				spip_log("ALTER $q", 'repair'._LOG_INFO_IMPORTANTE);
1470 1470
 			}
1471 1471
 			if (
1472 1472
 				preg_match(',^(INTEGER),i', $d)
@@ -1476,7 +1476,7 @@  discard block
 block discarded – undo
1476 1476
 				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1477 1477
 			) {
1478 1478
 				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0'", $serveur);
1479
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1479
+				spip_log("ALTER $q", 'repair'._LOG_INFO_IMPORTANTE);
1480 1480
 			}
1481 1481
 			if (
1482 1482
 				preg_match(',^(datetime),i', $d)
@@ -1486,7 +1486,7 @@  discard block
 block discarded – undo
1486 1486
 				and (!isset($desc['key']['PRIMARY KEY']) or $desc['key']['PRIMARY KEY'] !== $c)
1487 1487
 			) {
1488 1488
 				spip_sqlite_alter($q = "TABLE $table CHANGE $c $c $d DEFAULT '0000-00-00 00:00:00'", $serveur);
1489
-				spip_log("ALTER $q", 'repair' . _LOG_INFO_IMPORTANTE);
1489
+				spip_log("ALTER $q", 'repair'._LOG_INFO_IMPORTANTE);
1490 1490
 			}
1491 1491
 		}
1492 1492
 
@@ -1538,10 +1538,10 @@  discard block
 block discarded – undo
1538 1538
 	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
1539 1539
 	$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
1540 1540
 
1541
-	return spip_sqlite_query("REPLACE INTO $table (" . join(',', array_keys($couples)) . ') VALUES (' . join(
1541
+	return spip_sqlite_query("REPLACE INTO $table (".join(',', array_keys($couples)).') VALUES ('.join(
1542 1542
 		',',
1543 1543
 		$couples
1544
-	) . ')', $serveur);
1544
+	).')', $serveur);
1545 1545
 }
1546 1546
 
1547 1547
 
@@ -1628,7 +1628,7 @@  discard block
 block discarded – undo
1628 1628
 		. _sqlite_calculer_expression('WHERE', $where)
1629 1629
 		. _sqlite_calculer_expression('GROUP BY', $groupby, ',')
1630 1630
 		. _sqlite_calculer_expression('HAVING', $having)
1631
-		. ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) : '')
1631
+		. ($orderby ? ("\nORDER BY "._sqlite_calculer_order($orderby)) : '')
1632 1632
 		. ($limit ? "\nLIMIT $limit" : '');
1633 1633
 
1634 1634
 	// dans un select, on doit renvoyer la requête en cas d'erreur
@@ -1667,10 +1667,10 @@  discard block
 block discarded – undo
1667 1667
 	// interdire la creation d'une nouvelle base,
1668 1668
 	// sauf si on est dans l'installation
1669 1669
 	if (
1670
-		!is_file($f = _DIR_DB . $db . '.sqlite')
1670
+		!is_file($f = _DIR_DB.$db.'.sqlite')
1671 1671
 		&& (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL)
1672 1672
 	) {
1673
-		spip_log("Il est interdit de creer la base $db", 'sqlite.' . _LOG_HS);
1673
+		spip_log("Il est interdit de creer la base $db", 'sqlite.'._LOG_HS);
1674 1674
 
1675 1675
 		return false;
1676 1676
 	}
@@ -1679,12 +1679,12 @@  discard block
 block discarded – undo
1679 1679
 	// avec les identifiants connus
1680 1680
 	$index = $serveur ? $serveur : 0;
1681 1681
 
1682
-	if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db, $serveur, '', '')) {
1682
+	if ($link = spip_connect_db('', '', '', '', '@selectdb@'.$db, $serveur, '', '')) {
1683 1683
 		if (($db == $link['db']) && $GLOBALS['connexions'][$index] = $link) {
1684 1684
 			return $db;
1685 1685
 		}
1686 1686
 	} else {
1687
-		spip_log("Impossible de selectionner la base $db", 'sqlite.' . _LOG_HS);
1687
+		spip_log("Impossible de selectionner la base $db", 'sqlite.'._LOG_HS);
1688 1688
 	}
1689 1689
 
1690 1690
 	return false;
@@ -1737,7 +1737,7 @@  discard block
 block discarded – undo
1737 1737
 	$match = "^$match$";
1738 1738
 
1739 1739
 	return spip_sqlite_query(
1740
-		"SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP " . _q($match),
1740
+		"SELECT name FROM sqlite_master WHERE type='table' AND tbl_name REGEXP "._q($match),
1741 1741
 		$serveur,
1742 1742
 		$requeter
1743 1743
 	);
@@ -1762,7 +1762,7 @@  discard block
 block discarded – undo
1762 1762
 	$r = spip_sqlite_query(
1763 1763
 		'SELECT name FROM sqlite_master WHERE'
1764 1764
 			. ' type=\'table\''
1765
-			. ' AND name=' . spip_sqlite_quote($table, 'string')
1765
+			. ' AND name='.spip_sqlite_quote($table, 'string')
1766 1766
 			. ' AND name NOT LIKE \'sqlite_%\'',
1767 1767
 		$serveur,
1768 1768
 		$requeter
@@ -1860,7 +1860,7 @@  discard block
 block discarded – undo
1860 1860
 				// s'il y a une parenthèse fermante dans la clé
1861 1861
 				// ou dans la définition sans qu'il n'y ait une ouverture avant
1862 1862
 				if (str_contains($k, ')') or preg_match('/^[^\(]*\)/', $def)) {
1863
-					$fields[$k_precedent] .= ',' . $k . ' ' . $def;
1863
+					$fields[$k_precedent] .= ','.$k.' '.$def;
1864 1864
 					continue;
1865 1865
 				}
1866 1866
 
@@ -1895,13 +1895,13 @@  discard block
 block discarded – undo
1895 1895
 				. 'ORDER BY substr(type,2,1), name';
1896 1896
 			$a = spip_sqlite_query($query, $serveur, $requeter);
1897 1897
 			while ($r = spip_sqlite_fetch($a, null, $serveur)) {
1898
-				$key = str_replace($nom_table . '_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1898
+				$key = str_replace($nom_table.'_', '', $r['name']); // enlever le nom de la table ajoute a l'index
1899 1899
 				$keytype = 'KEY';
1900 1900
 				if (strpos($r['sql'], 'UNIQUE INDEX') !== false) {
1901 1901
 					$keytype = 'UNIQUE KEY';
1902 1902
 				}
1903 1903
 				$colonnes = preg_replace(',.*\((.*)\).*,', '$1', $r['sql']);
1904
-				$keys[$keytype . ' ' . $key] = $colonnes;
1904
+				$keys[$keytype.' '.$key] = $colonnes;
1905 1905
 			}
1906 1906
 		}
1907 1907
 	} // c'est une vue, on liste les champs disponibles simplement
@@ -1949,7 +1949,7 @@  discard block
 block discarded – undo
1949 1949
 
1950 1950
 	$set = [];
1951 1951
 	foreach ($champs as $champ => $val) {
1952
-		$set[] = $champ . "=$val";
1952
+		$set[] = $champ."=$val";
1953 1953
 	}
1954 1954
 	if (!empty($set)) {
1955 1955
 		return spip_sqlite_query(
@@ -2005,7 +2005,7 @@  discard block
 block discarded – undo
2005 2005
 
2006 2006
 	$set = [];
2007 2007
 	foreach ($champs as $champ => $val) {
2008
-		$set[$champ] = $champ . '=' . _sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
2008
+		$set[$champ] = $champ.'='._sqlite_calculer_cite($val, isset($fields[$champ]) ? $fields[$champ] : '');
2009 2009
 	}
2010 2010
 
2011 2011
 	// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
@@ -2013,7 +2013,7 @@  discard block
 block discarded – undo
2013 2013
 	$maj = _sqlite_ajouter_champs_timestamp($table, [], $desc, $serveur);
2014 2014
 	foreach ($maj as $champ => $val) {
2015 2015
 		if (!isset($set[$champ])) {
2016
-			$set[$champ] = $champ . '=' . $val;
2016
+			$set[$champ] = $champ.'='.$val;
2017 2017
 		}
2018 2018
 	}
2019 2019
 
@@ -2043,7 +2043,7 @@  discard block
 block discarded – undo
2043 2043
 function _sqlite_init()
2044 2044
 {
2045 2045
 	if (!defined('_DIR_DB')) {
2046
-		define('_DIR_DB', _DIR_ETC . 'bases/');
2046
+		define('_DIR_DB', _DIR_ETC.'bases/');
2047 2047
 	}
2048 2048
 	if (!defined('_SQLITE_CHMOD')) {
2049 2049
 		define('_SQLITE_CHMOD', _SPIP_CHMOD);
@@ -2155,9 +2155,9 @@  discard block
 block discarded – undo
2155 2155
 	}
2156 2156
 
2157 2157
 	// echapper les ' en ''
2158
-	spip_log('Pas de methode ->quote pour echapper', 'sqlite.' . _LOG_INFO_IMPORTANTE);
2158
+	spip_log('Pas de methode ->quote pour echapper', 'sqlite.'._LOG_INFO_IMPORTANTE);
2159 2159
 
2160
-	return ("'" . str_replace("'", "''", $v) . "'");
2160
+	return ("'".str_replace("'", "''", $v)."'");
2161 2161
 }
2162 2162
 
2163 2163
 
@@ -2181,12 +2181,12 @@  discard block
 block discarded – undo
2181 2181
 	$exp = "\n$expression ";
2182 2182
 
2183 2183
 	if (!is_array($v)) {
2184
-		return $exp . $v;
2184
+		return $exp.$v;
2185 2185
 	} else {
2186 2186
 		if (strtoupper($join) === 'AND') {
2187
-			return $exp . join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2187
+			return $exp.join("\n\t$join ", array_map('_sqlite_calculer_where', $v));
2188 2188
 		} else {
2189
-			return $exp . join($join, $v);
2189
+			return $exp.join($join, $v);
2190 2190
 		}
2191 2191
 	}
2192 2192
 }
@@ -2222,17 +2222,17 @@  discard block
 block discarded – undo
2222 2222
 		if (substr($k, -1) == '@') {
2223 2223
 			// c'est une jointure qui se refere au from precedent
2224 2224
 			// pas de virgule
2225
-			$res .= '  ' . $v;
2225
+			$res .= '  '.$v;
2226 2226
 		} else {
2227 2227
 			if (!is_numeric($k)) {
2228 2228
 				$p = strpos($v, ' ');
2229 2229
 				if ($p) {
2230
-					$v = substr($v, 0, $p) . " AS '$k'" . substr($v, $p);
2230
+					$v = substr($v, 0, $p)." AS '$k'".substr($v, $p);
2231 2231
 				} else {
2232 2232
 					$v .= " AS '$k'";
2233 2233
 				}
2234 2234
 			}
2235
-			$res .= ', ' . $v;
2235
+			$res .= ', '.$v;
2236 2236
 		}
2237 2237
 	}
2238 2238
 
@@ -2373,13 +2373,13 @@  discard block
 block discarded – undo
2373 2373
 
2374 2374
 	$def_origine = sql_showtable($table_origine, false, $serveur);
2375 2375
 	if (!$def_origine or !isset($def_origine['field'])) {
2376
-		spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite' . _LOG_ERREUR);
2376
+		spip_log("Alter table impossible sur $table_origine : table non trouvee", 'sqlite'._LOG_ERREUR);
2377 2377
 
2378 2378
 		return false;
2379 2379
 	}
2380 2380
 
2381 2381
 
2382
-	$table_tmp = $table_origine . '_tmp';
2382
+	$table_tmp = $table_origine.'_tmp';
2383 2383
 
2384 2384
 	// 1) creer une table temporaire avec les modifications
2385 2385
 	// - DROP : suppression de la colonne
@@ -2466,7 +2466,7 @@  discard block
 block discarded – undo
2466 2466
 		} else {
2467 2467
 			// enlever KEY
2468 2468
 			$k = substr($k, 4);
2469
-			$queries[] = "CREATE INDEX $table_destination" . "_$k ON $table_destination ($v)";
2469
+			$queries[] = "CREATE INDEX $table_destination"."_$k ON $table_destination ($v)";
2470 2470
 		}
2471 2471
 	}
2472 2472
 
@@ -2477,7 +2477,7 @@  discard block
 block discarded – undo
2477 2477
 		foreach ($queries as $q) {
2478 2478
 			if (!Sqlite::executer_requete($q, $serveur)) {
2479 2479
 				spip_log('SQLite : ALTER TABLE table :'
2480
-					. " Erreur a l'execution de la requete : $q", 'sqlite.' . _LOG_ERREUR);
2480
+					. " Erreur a l'execution de la requete : $q", 'sqlite.'._LOG_ERREUR);
2481 2481
 				Sqlite::annuler_transaction($serveur);
2482 2482
 
2483 2483
 				return false;
@@ -2569,27 +2569,27 @@  discard block
 block discarded – undo
2569 2569
 	$enum = '(\s*\([^\)]*\))?';
2570 2570
 
2571 2571
 	$remplace = [
2572
-		'/enum' . $enum . '/is' => 'VARCHAR(255)',
2572
+		'/enum'.$enum.'/is' => 'VARCHAR(255)',
2573 2573
 		'/COLLATE \w+_bin/is' => 'COLLATE BINARY',
2574 2574
 		'/COLLATE \w+_ci/is' => 'COLLATE NOCASE',
2575 2575
 		'/auto_increment/is' => '',
2576 2576
 		'/current_timestamp\(\)/is' => 'CURRENT_TIMESTAMP', // Fix export depuis mariaDB #4374
2577 2577
 		'/(timestamp .* )ON .*$/is' => '\\1',
2578 2578
 		'/character set \w+/is' => '',
2579
-		'/((big|small|medium|tiny)?int(eger)?)' . $num . '\s*unsigned/is' => '\\1 UNSIGNED',
2579
+		'/((big|small|medium|tiny)?int(eger)?)'.$num.'\s*unsigned/is' => '\\1 UNSIGNED',
2580 2580
 		'/(text\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2581
-		'/((char|varchar)' . $num . '\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2581
+		'/((char|varchar)'.$num.'\s+not\s+null(\s+collate\s+\w+)?)\s*$/is' => "\\1 DEFAULT ''",
2582 2582
 		'/(datetime\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00 00:00:00'",
2583 2583
 		'/(date\s+not\s+null)\s*$/is' => "\\1 DEFAULT '0000-00-00'",
2584 2584
 	];
2585 2585
 
2586 2586
 	// pour l'autoincrement, il faut des INTEGER NOT NULL PRIMARY KEY
2587 2587
 	$remplace_autocinc = [
2588
-		'/(big|small|medium|tiny)?int(eger)?' . $num . '/is' => 'INTEGER'
2588
+		'/(big|small|medium|tiny)?int(eger)?'.$num.'/is' => 'INTEGER'
2589 2589
 	];
2590 2590
 	// pour les int non autoincrement, il faut un DEFAULT
2591 2591
 	$remplace_nonautocinc = [
2592
-		'/((big|small|medium|tiny)?int(eger)?' . $num . '\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2592
+		'/((big|small|medium|tiny)?int(eger)?'.$num.'\s+not\s+null)\s*$/is' => "\\1 DEFAULT 0",
2593 2593
 	];
2594 2594
 
2595 2595
 	if (is_string($query)) {
@@ -2632,7 +2632,7 @@  discard block
 block discarded – undo
2632 2632
 		return str_ireplace('BINARY', 'COLLATE BINARY', $champ);
2633 2633
 	}
2634 2634
 	if (preg_match(',^(char|varchar|(long|small|medium|tiny)?text),i', $champ)) {
2635
-		return $champ . ' COLLATE NOCASE';
2635
+		return $champ.' COLLATE NOCASE';
2636 2636
 	}
2637 2637
 
2638 2638
 	return $champ;
@@ -2722,14 +2722,14 @@  discard block
 block discarded – undo
2722 2722
 		} else {
2723 2723
 			/* simuler le IF EXISTS - version 2 et sqlite < 3.3a */
2724 2724
 			$a = spip_sqlite_showtable($nom, $serveur);
2725
-			if (isset($a['key']['KEY ' . $nom])) {
2725
+			if (isset($a['key']['KEY '.$nom])) {
2726 2726
 				return true;
2727 2727
 			}
2728 2728
 		}
2729 2729
 	}
2730 2730
 
2731 2731
 	$temporary = $temporary ? ' TEMPORARY' : '';
2732
-	$q = "CREATE$temporary TABLE$ifnotexists $nom ($query" . ($keys ? ",$keys" : '') . ")\n";
2732
+	$q = "CREATE$temporary TABLE$ifnotexists $nom ($query".($keys ? ",$keys" : '').")\n";
2733 2733
 
2734 2734
 	return $q;
2735 2735
 }
Please login to merge, or discard this patch.
ecrire/src/Compilateur/Iterateur/Data.php 2 patches
Indentation   +490 added lines, -490 removed lines patch added patch discarded remove patch
@@ -12,498 +12,498 @@
 block discarded – undo
12 12
  */
13 13
 class Data extends AbstractIterateur implements Iterator
14 14
 {
15
-	/** Tableau de données */
16
-	protected array $tableau = [];
17
-
18
-	/**
19
-	 * Conditions de filtrage
20
-	 * ie criteres de selection
21
-	 */
22
-	protected array $filtre = [];
23
-
24
-	/**
25
-	 * Cle courante
26
-	 *
27
-	 * @var scalar
28
-	 */
29
-	protected $cle = null;
30
-
31
-	/**
32
-	 * Valeur courante
33
-	 *
34
-	 * @var mixed
35
-	 */
36
-	protected $valeur = null;
37
-
38
-	/**
39
-	 * Constructeur
40
-	 *
41
-	 * @param  $command
42
-	 * @param array $info
43
-	 */
44
-	public function __construct(array $command, array $info = []) {
45
-		include_spip('iterateur/data');
46
-		$this->type = 'DATA';
47
-		$this->command = $command;
48
-		$this->info = $info;
49
-		$this->select($command);
50
-	}
51
-
52
-	/**
53
-	 * Revenir au depart
54
-	 *
55
-	 * @return void
56
-	 */
57
-	public function rewind(): void {
58
-		reset($this->tableau);
59
-		$this->cle = array_key_first($this->tableau);
60
-		$this->valeur = current($this->tableau);
61
-		next($this->tableau);
62
-	}
63
-
64
-	/**
65
-	 * Déclarer les critères exceptions
66
-	 *
67
-	 * @return array
68
-	 */
69
-	public function exception_des_criteres() {
70
-		return ['tableau'];
71
-	}
72
-
73
-	/**
74
-	 * Récupérer depuis le cache si possible
75
-	 *
76
-	 * @param string $cle
77
-	 * @return mixed
78
-	 */
79
-	protected function cache_get($cle) {
80
-		if (!$cle) {
81
-			return;
82
-		}
83
-		# utiliser memoization si dispo
84
-		if (!function_exists('cache_get')) {
85
-			return;
86
-		}
87
-
88
-		return cache_get($cle);
89
-	}
90
-
91
-	/**
92
-	 * Stocker en cache si possible
93
-	 *
94
-	 * @param string $cle
95
-	 * @param int $ttl
96
-	 * @param null|mixed $valeur
97
-	 * @return bool
98
-	 */
99
-	protected function cache_set($cle, $ttl, $valeur = null) {
100
-		if (!$cle) {
101
-			return;
102
-		}
103
-		if (is_null($valeur)) {
104
-			$valeur = $this->tableau;
105
-		}
106
-		# utiliser memoization si dispo
107
-		if (!function_exists('cache_set')) {
108
-			return;
109
-		}
110
-
111
-		return cache_set(
112
-			$cle,
113
-			[
114
-				'data' => $valeur,
115
-				'time' => time(),
116
-				'ttl' => $ttl
117
-			],
118
-			3600 + $ttl
119
-		);
120
-		# conserver le cache 1h de plus que la validite demandee,
121
-		# pour le cas ou le serveur distant ne reponde plus
122
-	}
123
-
124
-	/**
125
-	 * Aller chercher les données de la boucle DATA
126
-	 *
127
-	 * @throws Exception
128
-	 * @param array $command
129
-	 * @return void
130
-	 */
131
-	protected function select($command) {
132
-
133
-		// l'iterateur DATA peut etre appele en passant (data:type)
134
-		// le type se retrouve dans la commande 'from'
135
-		// dans ce cas la le critere {source}, si present, n'a pas besoin du 1er argument
136
-		if (isset($this->command['from'][0])) {
137
-			if (isset($this->command['source']) and is_array($this->command['source'])) {
138
-				array_unshift($this->command['source'], $this->command['sourcemode']);
139
-			}
140
-			$this->command['sourcemode'] = $this->command['from'][0];
141
-		}
142
-
143
-		// cherchons differents moyens de creer le tableau de donnees
144
-		// les commandes connues pour l'iterateur DATA
145
-		// sont : {tableau #ARRAY} ; {cle=...} ; {valeur=...}
146
-
147
-		// {source format, [URL], [arg2]...}
148
-		if (
149
-			isset($this->command['source'])
150
-			and isset($this->command['sourcemode'])
151
-		) {
152
-			$this->select_source();
153
-		}
154
-
155
-		// Critere {liste X1, X2, X3}
156
-		if (isset($this->command['liste'])) {
157
-			$this->select_liste();
158
-		}
159
-		if (isset($this->command['enum'])) {
160
-			$this->select_enum();
161
-		}
162
-
163
-		// Si a ce stade on n'a pas de table, il y a un bug
164
-		if (!is_array($this->tableau)) {
165
-			$this->err = true;
166
-			spip_log('erreur datasource ' . var_export($command, true));
167
-		}
168
-
169
-		// {datapath query.results}
170
-		// extraire le chemin "query.results" du tableau de donnees
171
-		if (
172
-			!$this->err
173
-			and isset($this->command['datapath'])
174
-			and is_array($this->command['datapath'])
175
-		) {
176
-			$this->select_datapath();
177
-		}
178
-
179
-		// tri {par x}
180
-		if ($this->command['orderby']) {
181
-			$this->select_orderby();
182
-		}
183
-
184
-		// grouper les resultats {fusion /x/y/z} ;
185
-		if ($this->command['groupby']) {
186
-			$this->select_groupby();
187
-		}
188
-
189
-		$this->rewind();
190
-		#var_dump($this->tableau);
191
-	}
192
-
193
-
194
-	/**
195
-	 * Aller chercher les donnees de la boucle DATA
196
-	 * depuis une source
197
-	 * {source format, [URL], [arg2]...}
198
-	 */
199
-	protected function select_source() {
200
-		# un peu crado : avant de charger le cache il faut charger
201
-		# les class indispensables, sinon PHP ne saura pas gerer
202
-		# l'objet en cache ; cf plugins/icalendar
203
-		# perf : pas de fonction table_to_array ! (table est deja un array)
204
-		if (
205
-			isset($this->command['sourcemode'])
206
-			and !in_array($this->command['sourcemode'], ['table', 'array', 'tableau'])
207
-		) {
208
-			charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true);
209
-		}
210
-
211
-		# le premier argument peut etre un array, une URL etc.
212
-		$src = $this->command['source'][0];
213
-
214
-		# avons-nous un cache dispo ?
215
-		$cle = null;
216
-		if (is_string($src)) {
217
-			$cle = 'datasource_' . md5($this->command['sourcemode'] . ':' . var_export($this->command['source'], true));
218
-		}
219
-
220
-		$cache = $this->cache_get($cle);
221
-		if (isset($this->command['datacache'])) {
222
-			$ttl = intval($this->command['datacache']);
223
-		}
224
-		if (
225
-			$cache
226
-			and ($cache['time'] + ($ttl ?? $cache['ttl'])
227
-				> time())
228
-			and !(_request('var_mode') === 'recalcul'
229
-				and include_spip('inc/autoriser')
230
-				and autoriser('recalcul')
231
-			)
232
-		) {
233
-			$this->tableau = $cache['data'];
234
-		} else {
235
-			try {
236
-				if (
237
-					isset($this->command['sourcemode'])
238
-					and in_array(
239
-						$this->command['sourcemode'],
240
-						['table', 'array', 'tableau']
241
-					)
242
-				) {
243
-					if (
244
-						is_array($a = $src)
245
-						or (is_string($a)
246
-							and $a = str_replace('&quot;', '"', $a) # fragile!
247
-							and is_array($a = @unserialize($a)))
248
-					) {
249
-						$this->tableau = $a;
250
-					}
251
-				} else {
252
-					$data = $src;
253
-					if (is_string($src)) {
254
-						if (tester_url_absolue($src)) {
255
-							include_spip('inc/distant');
256
-							$data = recuperer_url($src, ['taille_max' => _DATA_SOURCE_MAX_SIZE]);
257
-							$data = $data['page'] ?? '';
258
-							if (!$data) {
259
-								throw new Exception('404');
260
-							}
261
-							if (!isset($ttl)) {
262
-								$ttl = 24 * 3600;
263
-							}
264
-						} elseif (@is_dir($src)) {
265
-							$data = $src;
266
-						} elseif (@is_readable($src) && @is_file($src)) {
267
-							$data = spip_file_get_contents($src);
268
-						}
269
-						if (!isset($ttl)) {
270
-							$ttl = 10;
271
-						}
272
-					}
273
-					if (
274
-						!$this->err
275
-						and $data_to_array = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)
276
-					) {
277
-						$args = $this->command['source'];
278
-						$args[0] = $data;
279
-						if (is_array($a = $data_to_array(...$args))) {
280
-							$this->tableau = $a;
281
-						}
282
-					}
283
-				}
284
-
285
-				if (!is_array($this->tableau)) {
286
-					$this->err = true;
287
-				}
288
-
289
-				if (!$this->err and isset($ttl) and $ttl > 0) {
290
-					$this->cache_set($cle, $ttl);
291
-				}
292
-			} catch (Exception $e) {
293
-				$e = $e->getMessage();
294
-				$err = sprintf(
295
-					"[%s, %s] $e",
296
-					$src,
297
-					$this->command['sourcemode']
298
-				);
299
-				erreur_squelette([$err, []]);
300
-				$this->err = true;
301
-			}
302
-		}
303
-
304
-		# en cas d'erreur, utiliser le cache si encore dispo
305
-		if (
306
-			$this->err
307
-			and $cache
308
-		) {
309
-			$this->tableau = $cache['data'];
310
-			$this->err = false;
311
-		}
312
-	}
313
-
314
-
315
-	/**
316
-	 * Retourne un tableau donne depuis un critère liste
317
-	 *
318
-	 * Critère `{liste X1, X2, X3}`
319
-	 *
320
-	 * @see critere_DATA_liste_dist()
321
-	 *
322
-	 **/
323
-	protected function select_liste() {
324
-		# s'il n'y a qu'une valeur dans la liste, sans doute une #BALISE
325
-		if (!isset($this->command['liste'][1])) {
326
-			if (!is_array($this->command['liste'][0])) {
327
-				$this->command['liste'] = explode(',', $this->command['liste'][0]);
328
-			} else {
329
-				$this->command['liste'] = $this->command['liste'][0];
330
-			}
331
-		}
332
-		$this->tableau = $this->command['liste'];
333
-	}
334
-
335
-	/**
336
-	 * Retourne un tableau donne depuis un critere liste
337
-	 * Critere {enum Xmin, Xmax}
338
-	 *
339
-	 **/
340
-	protected function select_enum() {
341
-		# s'il n'y a qu'une valeur dans la liste, sans doute une #BALISE
342
-		if (!isset($this->command['enum'][1])) {
343
-			if (!is_array($this->command['enum'][0])) {
344
-				$this->command['enum'] = explode(',', $this->command['enum'][0]);
345
-			} else {
346
-				$this->command['enum'] = $this->command['enum'][0];
347
-			}
348
-		}
349
-		if ((is_countable($this->command['enum']) ? count($this->command['enum']) : 0) >= 3) {
350
-			$enum = range(
351
-				array_shift($this->command['enum']),
352
-				array_shift($this->command['enum']),
353
-				array_shift($this->command['enum'])
354
-			);
355
-		} else {
356
-			$enum = range(array_shift($this->command['enum']), array_shift($this->command['enum']));
357
-		}
358
-		$this->tableau = $enum;
359
-	}
360
-
361
-
362
-	/**
363
-	 * extraire le chemin "query.results" du tableau de donnees
364
-	 * {datapath query.results}
365
-	 *
366
-	 **/
367
-	protected function select_datapath() {
368
-		$base = reset($this->command['datapath']);
369
-		if (strlen($base = ltrim(trim($base), '/'))) {
370
-			$this->tableau = table_valeur($this->tableau, $base);
371
-			if (!is_array($this->tableau)) {
372
-				$this->tableau = [];
373
-				$this->err = true;
374
-				spip_log("datapath '$base' absent");
375
-			}
376
-		}
377
-	}
378
-
379
-	/**
380
-	 * Ordonner les resultats
381
-	 * {par x}
382
-	 *
383
-	 **/
384
-	protected function select_orderby() {
385
-		$sortfunc = '';
386
-		$aleas = 0;
387
-		foreach ($this->command['orderby'] as $tri) {
388
-			// virer le / initial pour les criteres de la forme {par /xx}
389
-			if (preg_match(',^\.?([/\w:_-]+)( DESC)?$,iS', ltrim($tri, '/'), $r)) {
390
-				$r = array_pad($r, 3, null);
391
-
392
-				// tri par cle
393
-				if ($r[1] == 'cle') {
394
-					if (isset($r[2]) and $r[2]) {
395
-						krsort($this->tableau);
396
-					} else {
397
-						ksort($this->tableau);
398
-					}
399
-				} # {par hasard}
400
-				else {
401
-					if ($r[1] == 'hasard') {
402
-						$k = array_keys($this->tableau);
403
-						shuffle($k);
404
-						$v = [];
405
-						foreach ($k as $cle) {
406
-							$v[$cle] = $this->tableau[$cle];
407
-						}
408
-						$this->tableau = $v;
409
-					} else {
410
-						# {par valeur}
411
-						if ($r[1] == 'valeur') {
412
-							$tv = '%s';
413
-						} # {par valeur/xx/yy} ??
414
-						else {
415
-							$tv = 'table_valeur(%s, ' . var_export($r[1], true) . ')';
416
-						}
417
-						$sortfunc .= '
15
+    /** Tableau de données */
16
+    protected array $tableau = [];
17
+
18
+    /**
19
+     * Conditions de filtrage
20
+     * ie criteres de selection
21
+     */
22
+    protected array $filtre = [];
23
+
24
+    /**
25
+     * Cle courante
26
+     *
27
+     * @var scalar
28
+     */
29
+    protected $cle = null;
30
+
31
+    /**
32
+     * Valeur courante
33
+     *
34
+     * @var mixed
35
+     */
36
+    protected $valeur = null;
37
+
38
+    /**
39
+     * Constructeur
40
+     *
41
+     * @param  $command
42
+     * @param array $info
43
+     */
44
+    public function __construct(array $command, array $info = []) {
45
+        include_spip('iterateur/data');
46
+        $this->type = 'DATA';
47
+        $this->command = $command;
48
+        $this->info = $info;
49
+        $this->select($command);
50
+    }
51
+
52
+    /**
53
+     * Revenir au depart
54
+     *
55
+     * @return void
56
+     */
57
+    public function rewind(): void {
58
+        reset($this->tableau);
59
+        $this->cle = array_key_first($this->tableau);
60
+        $this->valeur = current($this->tableau);
61
+        next($this->tableau);
62
+    }
63
+
64
+    /**
65
+     * Déclarer les critères exceptions
66
+     *
67
+     * @return array
68
+     */
69
+    public function exception_des_criteres() {
70
+        return ['tableau'];
71
+    }
72
+
73
+    /**
74
+     * Récupérer depuis le cache si possible
75
+     *
76
+     * @param string $cle
77
+     * @return mixed
78
+     */
79
+    protected function cache_get($cle) {
80
+        if (!$cle) {
81
+            return;
82
+        }
83
+        # utiliser memoization si dispo
84
+        if (!function_exists('cache_get')) {
85
+            return;
86
+        }
87
+
88
+        return cache_get($cle);
89
+    }
90
+
91
+    /**
92
+     * Stocker en cache si possible
93
+     *
94
+     * @param string $cle
95
+     * @param int $ttl
96
+     * @param null|mixed $valeur
97
+     * @return bool
98
+     */
99
+    protected function cache_set($cle, $ttl, $valeur = null) {
100
+        if (!$cle) {
101
+            return;
102
+        }
103
+        if (is_null($valeur)) {
104
+            $valeur = $this->tableau;
105
+        }
106
+        # utiliser memoization si dispo
107
+        if (!function_exists('cache_set')) {
108
+            return;
109
+        }
110
+
111
+        return cache_set(
112
+            $cle,
113
+            [
114
+                'data' => $valeur,
115
+                'time' => time(),
116
+                'ttl' => $ttl
117
+            ],
118
+            3600 + $ttl
119
+        );
120
+        # conserver le cache 1h de plus que la validite demandee,
121
+        # pour le cas ou le serveur distant ne reponde plus
122
+    }
123
+
124
+    /**
125
+     * Aller chercher les données de la boucle DATA
126
+     *
127
+     * @throws Exception
128
+     * @param array $command
129
+     * @return void
130
+     */
131
+    protected function select($command) {
132
+
133
+        // l'iterateur DATA peut etre appele en passant (data:type)
134
+        // le type se retrouve dans la commande 'from'
135
+        // dans ce cas la le critere {source}, si present, n'a pas besoin du 1er argument
136
+        if (isset($this->command['from'][0])) {
137
+            if (isset($this->command['source']) and is_array($this->command['source'])) {
138
+                array_unshift($this->command['source'], $this->command['sourcemode']);
139
+            }
140
+            $this->command['sourcemode'] = $this->command['from'][0];
141
+        }
142
+
143
+        // cherchons differents moyens de creer le tableau de donnees
144
+        // les commandes connues pour l'iterateur DATA
145
+        // sont : {tableau #ARRAY} ; {cle=...} ; {valeur=...}
146
+
147
+        // {source format, [URL], [arg2]...}
148
+        if (
149
+            isset($this->command['source'])
150
+            and isset($this->command['sourcemode'])
151
+        ) {
152
+            $this->select_source();
153
+        }
154
+
155
+        // Critere {liste X1, X2, X3}
156
+        if (isset($this->command['liste'])) {
157
+            $this->select_liste();
158
+        }
159
+        if (isset($this->command['enum'])) {
160
+            $this->select_enum();
161
+        }
162
+
163
+        // Si a ce stade on n'a pas de table, il y a un bug
164
+        if (!is_array($this->tableau)) {
165
+            $this->err = true;
166
+            spip_log('erreur datasource ' . var_export($command, true));
167
+        }
168
+
169
+        // {datapath query.results}
170
+        // extraire le chemin "query.results" du tableau de donnees
171
+        if (
172
+            !$this->err
173
+            and isset($this->command['datapath'])
174
+            and is_array($this->command['datapath'])
175
+        ) {
176
+            $this->select_datapath();
177
+        }
178
+
179
+        // tri {par x}
180
+        if ($this->command['orderby']) {
181
+            $this->select_orderby();
182
+        }
183
+
184
+        // grouper les resultats {fusion /x/y/z} ;
185
+        if ($this->command['groupby']) {
186
+            $this->select_groupby();
187
+        }
188
+
189
+        $this->rewind();
190
+        #var_dump($this->tableau);
191
+    }
192
+
193
+
194
+    /**
195
+     * Aller chercher les donnees de la boucle DATA
196
+     * depuis une source
197
+     * {source format, [URL], [arg2]...}
198
+     */
199
+    protected function select_source() {
200
+        # un peu crado : avant de charger le cache il faut charger
201
+        # les class indispensables, sinon PHP ne saura pas gerer
202
+        # l'objet en cache ; cf plugins/icalendar
203
+        # perf : pas de fonction table_to_array ! (table est deja un array)
204
+        if (
205
+            isset($this->command['sourcemode'])
206
+            and !in_array($this->command['sourcemode'], ['table', 'array', 'tableau'])
207
+        ) {
208
+            charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true);
209
+        }
210
+
211
+        # le premier argument peut etre un array, une URL etc.
212
+        $src = $this->command['source'][0];
213
+
214
+        # avons-nous un cache dispo ?
215
+        $cle = null;
216
+        if (is_string($src)) {
217
+            $cle = 'datasource_' . md5($this->command['sourcemode'] . ':' . var_export($this->command['source'], true));
218
+        }
219
+
220
+        $cache = $this->cache_get($cle);
221
+        if (isset($this->command['datacache'])) {
222
+            $ttl = intval($this->command['datacache']);
223
+        }
224
+        if (
225
+            $cache
226
+            and ($cache['time'] + ($ttl ?? $cache['ttl'])
227
+                > time())
228
+            and !(_request('var_mode') === 'recalcul'
229
+                and include_spip('inc/autoriser')
230
+                and autoriser('recalcul')
231
+            )
232
+        ) {
233
+            $this->tableau = $cache['data'];
234
+        } else {
235
+            try {
236
+                if (
237
+                    isset($this->command['sourcemode'])
238
+                    and in_array(
239
+                        $this->command['sourcemode'],
240
+                        ['table', 'array', 'tableau']
241
+                    )
242
+                ) {
243
+                    if (
244
+                        is_array($a = $src)
245
+                        or (is_string($a)
246
+                            and $a = str_replace('&quot;', '"', $a) # fragile!
247
+                            and is_array($a = @unserialize($a)))
248
+                    ) {
249
+                        $this->tableau = $a;
250
+                    }
251
+                } else {
252
+                    $data = $src;
253
+                    if (is_string($src)) {
254
+                        if (tester_url_absolue($src)) {
255
+                            include_spip('inc/distant');
256
+                            $data = recuperer_url($src, ['taille_max' => _DATA_SOURCE_MAX_SIZE]);
257
+                            $data = $data['page'] ?? '';
258
+                            if (!$data) {
259
+                                throw new Exception('404');
260
+                            }
261
+                            if (!isset($ttl)) {
262
+                                $ttl = 24 * 3600;
263
+                            }
264
+                        } elseif (@is_dir($src)) {
265
+                            $data = $src;
266
+                        } elseif (@is_readable($src) && @is_file($src)) {
267
+                            $data = spip_file_get_contents($src);
268
+                        }
269
+                        if (!isset($ttl)) {
270
+                            $ttl = 10;
271
+                        }
272
+                    }
273
+                    if (
274
+                        !$this->err
275
+                        and $data_to_array = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)
276
+                    ) {
277
+                        $args = $this->command['source'];
278
+                        $args[0] = $data;
279
+                        if (is_array($a = $data_to_array(...$args))) {
280
+                            $this->tableau = $a;
281
+                        }
282
+                    }
283
+                }
284
+
285
+                if (!is_array($this->tableau)) {
286
+                    $this->err = true;
287
+                }
288
+
289
+                if (!$this->err and isset($ttl) and $ttl > 0) {
290
+                    $this->cache_set($cle, $ttl);
291
+                }
292
+            } catch (Exception $e) {
293
+                $e = $e->getMessage();
294
+                $err = sprintf(
295
+                    "[%s, %s] $e",
296
+                    $src,
297
+                    $this->command['sourcemode']
298
+                );
299
+                erreur_squelette([$err, []]);
300
+                $this->err = true;
301
+            }
302
+        }
303
+
304
+        # en cas d'erreur, utiliser le cache si encore dispo
305
+        if (
306
+            $this->err
307
+            and $cache
308
+        ) {
309
+            $this->tableau = $cache['data'];
310
+            $this->err = false;
311
+        }
312
+    }
313
+
314
+
315
+    /**
316
+     * Retourne un tableau donne depuis un critère liste
317
+     *
318
+     * Critère `{liste X1, X2, X3}`
319
+     *
320
+     * @see critere_DATA_liste_dist()
321
+     *
322
+     **/
323
+    protected function select_liste() {
324
+        # s'il n'y a qu'une valeur dans la liste, sans doute une #BALISE
325
+        if (!isset($this->command['liste'][1])) {
326
+            if (!is_array($this->command['liste'][0])) {
327
+                $this->command['liste'] = explode(',', $this->command['liste'][0]);
328
+            } else {
329
+                $this->command['liste'] = $this->command['liste'][0];
330
+            }
331
+        }
332
+        $this->tableau = $this->command['liste'];
333
+    }
334
+
335
+    /**
336
+     * Retourne un tableau donne depuis un critere liste
337
+     * Critere {enum Xmin, Xmax}
338
+     *
339
+     **/
340
+    protected function select_enum() {
341
+        # s'il n'y a qu'une valeur dans la liste, sans doute une #BALISE
342
+        if (!isset($this->command['enum'][1])) {
343
+            if (!is_array($this->command['enum'][0])) {
344
+                $this->command['enum'] = explode(',', $this->command['enum'][0]);
345
+            } else {
346
+                $this->command['enum'] = $this->command['enum'][0];
347
+            }
348
+        }
349
+        if ((is_countable($this->command['enum']) ? count($this->command['enum']) : 0) >= 3) {
350
+            $enum = range(
351
+                array_shift($this->command['enum']),
352
+                array_shift($this->command['enum']),
353
+                array_shift($this->command['enum'])
354
+            );
355
+        } else {
356
+            $enum = range(array_shift($this->command['enum']), array_shift($this->command['enum']));
357
+        }
358
+        $this->tableau = $enum;
359
+    }
360
+
361
+
362
+    /**
363
+     * extraire le chemin "query.results" du tableau de donnees
364
+     * {datapath query.results}
365
+     *
366
+     **/
367
+    protected function select_datapath() {
368
+        $base = reset($this->command['datapath']);
369
+        if (strlen($base = ltrim(trim($base), '/'))) {
370
+            $this->tableau = table_valeur($this->tableau, $base);
371
+            if (!is_array($this->tableau)) {
372
+                $this->tableau = [];
373
+                $this->err = true;
374
+                spip_log("datapath '$base' absent");
375
+            }
376
+        }
377
+    }
378
+
379
+    /**
380
+     * Ordonner les resultats
381
+     * {par x}
382
+     *
383
+     **/
384
+    protected function select_orderby() {
385
+        $sortfunc = '';
386
+        $aleas = 0;
387
+        foreach ($this->command['orderby'] as $tri) {
388
+            // virer le / initial pour les criteres de la forme {par /xx}
389
+            if (preg_match(',^\.?([/\w:_-]+)( DESC)?$,iS', ltrim($tri, '/'), $r)) {
390
+                $r = array_pad($r, 3, null);
391
+
392
+                // tri par cle
393
+                if ($r[1] == 'cle') {
394
+                    if (isset($r[2]) and $r[2]) {
395
+                        krsort($this->tableau);
396
+                    } else {
397
+                        ksort($this->tableau);
398
+                    }
399
+                } # {par hasard}
400
+                else {
401
+                    if ($r[1] == 'hasard') {
402
+                        $k = array_keys($this->tableau);
403
+                        shuffle($k);
404
+                        $v = [];
405
+                        foreach ($k as $cle) {
406
+                            $v[$cle] = $this->tableau[$cle];
407
+                        }
408
+                        $this->tableau = $v;
409
+                    } else {
410
+                        # {par valeur}
411
+                        if ($r[1] == 'valeur') {
412
+                            $tv = '%s';
413
+                        } # {par valeur/xx/yy} ??
414
+                        else {
415
+                            $tv = 'table_valeur(%s, ' . var_export($r[1], true) . ')';
416
+                        }
417
+                        $sortfunc .= '
418 418
 					$a = ' . sprintf($tv, '$aa') . ';
419 419
 					$b = ' . sprintf($tv, '$bb') . ';
420 420
 					if ($a <> $b)
421 421
 						return ($a ' . (!empty($r[2]) ? '>' : '<') . ' $b) ? -1 : 1;';
422
-					}
423
-				}
424
-			}
425
-		}
426
-
427
-		if ($sortfunc) {
428
-			$sortfunc .= "\n return 0;";
429
-			uasort($this->tableau, fn($aa, $bb) => eval($sortfunc));
430
-		}
431
-	}
432
-
433
-
434
-	/**
435
-	 * Grouper les resultats
436
-	 * {fusion /x/y/z}
437
-	 *
438
-	 **/
439
-	protected function select_groupby() {
440
-		// virer le / initial pour les criteres de la forme {fusion /xx}
441
-		if (strlen($fusion = ltrim($this->command['groupby'][0], '/'))) {
442
-			$vu = [];
443
-			foreach ($this->tableau as $k => $v) {
444
-				$val = table_valeur($v, $fusion);
445
-				if (isset($vu[$val])) {
446
-					unset($this->tableau[$k]);
447
-				} else {
448
-					$vu[$val] = true;
449
-				}
450
-			}
451
-		}
452
-	}
453
-
454
-
455
-	/**
456
-	 * L'iterateur est-il encore valide ?
457
-	 *
458
-	 * @return bool
459
-	 */
460
-	public function valid(): bool {
461
-		return !is_null($this->cle);
462
-	}
463
-
464
-	/**
465
-	 * Retourner la valeur
466
-	 *
467
-	 * @return mixed
468
-	 */
469
-	#[\ReturnTypeWillChange]
470
-	public function current() {
471
-		return $this->valeur;
472
-	}
473
-
474
-	/**
475
-	 * Retourner la cle
476
-	 *
477
-	 * @return mixed
478
-	 */
479
-	#[\ReturnTypeWillChange]
480
-	public function key() {
481
-		return $this->cle;
482
-	}
483
-
484
-	/**
485
-	 * Passer a la valeur suivante
486
-	 *
487
-	 * @return void
488
-	 */
489
-	public function next(): void {
490
-		if ($this->valid()) {
491
-			$this->cle = key($this->tableau);
492
-			$this->valeur = current($this->tableau);
493
-			next($this->tableau);
494
-		}
495
-	}
496
-
497
-	/**
498
-	 * Compter le nombre total de resultats
499
-	 *
500
-	 * @return int
501
-	 */
502
-	public function count() {
503
-		if (is_null($this->total)) {
504
-			$this->total = count($this->tableau);
505
-		}
506
-
507
-		return $this->total;
508
-	}
422
+                    }
423
+                }
424
+            }
425
+        }
426
+
427
+        if ($sortfunc) {
428
+            $sortfunc .= "\n return 0;";
429
+            uasort($this->tableau, fn($aa, $bb) => eval($sortfunc));
430
+        }
431
+    }
432
+
433
+
434
+    /**
435
+     * Grouper les resultats
436
+     * {fusion /x/y/z}
437
+     *
438
+     **/
439
+    protected function select_groupby() {
440
+        // virer le / initial pour les criteres de la forme {fusion /xx}
441
+        if (strlen($fusion = ltrim($this->command['groupby'][0], '/'))) {
442
+            $vu = [];
443
+            foreach ($this->tableau as $k => $v) {
444
+                $val = table_valeur($v, $fusion);
445
+                if (isset($vu[$val])) {
446
+                    unset($this->tableau[$k]);
447
+                } else {
448
+                    $vu[$val] = true;
449
+                }
450
+            }
451
+        }
452
+    }
453
+
454
+
455
+    /**
456
+     * L'iterateur est-il encore valide ?
457
+     *
458
+     * @return bool
459
+     */
460
+    public function valid(): bool {
461
+        return !is_null($this->cle);
462
+    }
463
+
464
+    /**
465
+     * Retourner la valeur
466
+     *
467
+     * @return mixed
468
+     */
469
+    #[\ReturnTypeWillChange]
470
+    public function current() {
471
+        return $this->valeur;
472
+    }
473
+
474
+    /**
475
+     * Retourner la cle
476
+     *
477
+     * @return mixed
478
+     */
479
+    #[\ReturnTypeWillChange]
480
+    public function key() {
481
+        return $this->cle;
482
+    }
483
+
484
+    /**
485
+     * Passer a la valeur suivante
486
+     *
487
+     * @return void
488
+     */
489
+    public function next(): void {
490
+        if ($this->valid()) {
491
+            $this->cle = key($this->tableau);
492
+            $this->valeur = current($this->tableau);
493
+            next($this->tableau);
494
+        }
495
+    }
496
+
497
+    /**
498
+     * Compter le nombre total de resultats
499
+     *
500
+     * @return int
501
+     */
502
+    public function count() {
503
+        if (is_null($this->total)) {
504
+            $this->total = count($this->tableau);
505
+        }
506
+
507
+        return $this->total;
508
+    }
509 509
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
 		// Si a ce stade on n'a pas de table, il y a un bug
164 164
 		if (!is_array($this->tableau)) {
165 165
 			$this->err = true;
166
-			spip_log('erreur datasource ' . var_export($command, true));
166
+			spip_log('erreur datasource '.var_export($command, true));
167 167
 		}
168 168
 
169 169
 		// {datapath query.results}
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
 			isset($this->command['sourcemode'])
206 206
 			and !in_array($this->command['sourcemode'], ['table', 'array', 'tableau'])
207 207
 		) {
208
-			charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true);
208
+			charger_fonction($this->command['sourcemode'].'_to_array', 'inc', true);
209 209
 		}
210 210
 
211 211
 		# le premier argument peut etre un array, une URL etc.
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
 		# avons-nous un cache dispo ?
215 215
 		$cle = null;
216 216
 		if (is_string($src)) {
217
-			$cle = 'datasource_' . md5($this->command['sourcemode'] . ':' . var_export($this->command['source'], true));
217
+			$cle = 'datasource_'.md5($this->command['sourcemode'].':'.var_export($this->command['source'], true));
218 218
 		}
219 219
 
220 220
 		$cache = $this->cache_get($cle);
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 					}
273 273
 					if (
274 274
 						!$this->err
275
-						and $data_to_array = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)
275
+						and $data_to_array = charger_fonction($this->command['sourcemode'].'_to_array', 'inc', true)
276 276
 					) {
277 277
 						$args = $this->command['source'];
278 278
 						$args[0] = $data;
@@ -412,13 +412,13 @@  discard block
 block discarded – undo
412 412
 							$tv = '%s';
413 413
 						} # {par valeur/xx/yy} ??
414 414
 						else {
415
-							$tv = 'table_valeur(%s, ' . var_export($r[1], true) . ')';
415
+							$tv = 'table_valeur(%s, '.var_export($r[1], true).')';
416 416
 						}
417 417
 						$sortfunc .= '
418
-					$a = ' . sprintf($tv, '$aa') . ';
419
-					$b = ' . sprintf($tv, '$bb') . ';
418
+					$a = ' . sprintf($tv, '$aa').';
419
+					$b = ' . sprintf($tv, '$bb').';
420 420
 					if ($a <> $b)
421
-						return ($a ' . (!empty($r[2]) ? '>' : '<') . ' $b) ? -1 : 1;';
421
+						return ($a ' . (!empty($r[2]) ? '>' : '<').' $b) ? -1 : 1;';
422 422
 					}
423 423
 				}
424 424
 			}
Please login to merge, or discard this patch.