Subversion Repositories Applications.framework

Rev

Rev 269 | Rev 290 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 269 Rev 282
1
<?php
1
<?php
2
class CacheSqlite {
2
class CacheSqlite {
3
	/**
3
	/**
4
	 * Available options
4
	 * Options disponibles :
5
	 *
5
	 *
6
	 * =====> (string) cache_db_complete_path :
6
	 * ====> (string) stockage_chemin :
-
 
7
	 * Chemin vers le fichier contenant la base SQLite.
-
 
8
	 * 
-
 
9
	 *
-
 
10
	 * ====> (int) defragmentation_auto :
7
	 * - the complete path (filename included) of the SQLITE database
11
	 * - Désactive / Régler le processus de défragmentation automatique
-
 
12
	 * - Le processus de défragmentation automatiques réduit la taille du fichier contenant la base de données
-
 
13
	 *   quand un ajout ou une suppression de cache est réalisée :
-
 
14
	 *	 0			   => pas de défragmentation automatique
-
 
15
	 *	 1			   => défragmentation automatique systématique
-
 
16
	 *	 x (integer) > 1 => défragmentation automatique toutes les 1 fois (au hasard) sur x ajout ou suppression de cache
8
	 *
17
	 *
9
	 * ====> (int) automatic_vacuum_factor :
-
 
10
	 * - Disable / Tune the automatic vacuum process
-
 
11
	 * - The automatic vacuum process defragment the database file (and make it smaller)
-
 
12
	 *   when a clean() or delete() is called
-
 
13
	 *	 0			   => no automatic vacuum
-
 
14
	 *	 1			   => systematic vacuum (when delete() or clean() methods are called)
-
 
15
	 *	 x (integer) > 1 => automatic vacuum randomly 1 times on x clean() or delete()
-
 
16
	 *
-
 
17
	 * @var array Available options
18
	 * @var array options disponibles
18
	 */
19
	 */
19
	protected $options = array(
20
	protected $options = array(
20
		'stockage_chemin' => null,
21
		'stockage_chemin' => null,
21
		'defragmentation_auto' => 10
22
		'defragmentation_auto' => 10
22
	);
23
	);
23
	
24
	
24
	/**
25
	/**
25
	 * DB ressource
26
	 * DB ressource
26
	 *
27
	 *
27
	 * @var mixed $db
28
	 * @var mixed $db
28
	 */
29
	 */
29
	private $bdd = null;
30
	private $bdd = null;
30
 
31
 
31
	/**
32
	/**
32
	 * Boolean to store if the structure has benn checked or not
33
	 * Boolean to store if the structure has benn checked or not
33
	 *
34
	 *
34
	 * @var boolean $structure_ok
35
	 * @var boolean $structure_ok
35
	 */
36
	 */
36
	private $structure_ok = false;
37
	private $structure_ok = false;
37
 
38
 
38
	private $Cache = null;
39
	private $Cache = null;
39
	
40
	
40
	/**
41
	/**
41
	 * Constructor
42
	 * Constructor
42
	 *
43
	 *
43
	 * @param  array $options Associative array of options
44
	 * @param  array $options Associative array of options
44
	 * @throws Zend_cache_Exception
45
	 * @throws Zend_cache_Exception
45
	 * @return void
46
	 * @return void
46
	 */
47
	 */
47
	public function __construct(array $options = array(), Cache $cache) {
48
	public function __construct(array $options = array(), Cache $cache) {
48
		$this->Cache = $cache;
49
		$this->Cache = $cache;
49
		if (extension_loaded('sqlite')) {
50
		if (extension_loaded('sqlite')) {
-
 
51
			$this->initialiserOptionsParConfig();
50
			$this->setOptions($options);
52
			$this->setOptions($options);
51
		} else {
53
		} else {
52
			$e = "Impossible d'utiliser le cache SQLITE car l'extenssion 'sqlite' n'est pas chargée dans l'environnement PHP courrant.";
54
			$e = "Impossible d'utiliser le cache SQLITE car l'extenssion 'sqlite' n'est pas chargée dans l'environnement PHP courrant.";
53
			trigger_error($e, E_USER_ERROR);
55
			trigger_error($e, E_USER_ERROR);
54
		}
56
		}
-
 
57
	}
-
 
58
	
-
 
59
	private function initialiserOptionsParConfig() {
-
 
60
		while (list($nom, $valeur) = each($this->options)) {
-
 
61
			if (Config::existe($nom)) {
-
 
62
				$this->options[$nom] = Config::get($nom);
-
 
63
			}
-
 
64
		}
55
	}
65
	}
56
	
66
	
57
	/**
67
	/**
58
	 * Destructor
68
	 * Destructor
59
	 *
69
	 *
60
	 * @return void
70
	 * @return void
61
	 */
71
	 */
62
	public function __destruct() {
72
	public function __destruct() {
63
		@sqlite_close($this->getConnexion());
73
		@sqlite_close($this->getConnexion());
64
	}
74
	}
65
	
75
	
66
	private function setOptions($options) {
76
	private function setOptions($options) {
67
		while (list($nom, $valeur) = each($options)) {
77
		while (list($nom, $valeur) = each($options)) {
68
			if (!is_string($nom)) {
78
			if (!is_string($nom)) {
69
				trigger_error("Nom d'option incorecte : $nom", E_USER_WARNING);
79
				trigger_error("Nom d'option incorecte : $nom", E_USER_WARNING);
70
			}
80
			}
71
			$nom = strtolower($nom);
81
			$nom = strtolower($nom);
72
			if (array_key_exists($nom, $this->options)) {
82
			if (array_key_exists($nom, $this->options)) {
73
				$this->options[$nom] = $valeur;
83
				$this->options[$nom] = $valeur;
74
			}
84
			}
75
		}
85
		}
76
	}
86
	}
77
	
87
	
78
	public function setEmplacement($emplacement) {
88
	public function setEmplacement($emplacement) {
79
	 	if (extension_loaded('sqlite')) {
89
	 	if (extension_loaded('sqlite')) {
80
			$this->options['stockage_chemin'] = $emplacement;
90
			$this->options['stockage_chemin'] = $emplacement;
81
		} else {
91
		} else {
82
			trigger_error("Impossible d'utiliser le mode de sotckage SQLite car l'extenssion 'sqlite' n'est pas chargé dans ".
92
			trigger_error("Impossible d'utiliser le mode de sotckage SQLite car l'extenssion 'sqlite' n'est pas chargé dans ".
83
				"l'environnement PHP courrant.", E_USER_ERROR);
93
				"l'environnement PHP courrant.", E_USER_ERROR);
84
		}
94
		}
85
	}
95
	}
86
 
96
 
87
	/**
97
	/**
88
	 * Test if a cache is available for the given id and (if yes) return it (false else)
98
	 * Test if a cache is available for the given id and (if yes) return it (false else)
89
	 *
99
	 *
90
	 * @param  string  $id					 Cache id
100
	 * @param  string  $id					 Cache id
91
	 * @param  boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
101
	 * @param  boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
92
	 * @return string|false Cached datas
102
	 * @return string|false Cached datas
93
	 */
103
	 */
94
	public function charger($id, $ne_pas_tester_validiter_du_cache = false) {
104
	public function charger($id, $ne_pas_tester_validiter_du_cache = false) {
95
		$this->verifierEtCreerStructureBdd();
105
		$this->verifierEtCreerStructureBdd();
96
		$requete = "SELECT content FROM cache WHERE id = '$id'".
106
		$requete = "SELECT content FROM cache WHERE id = '$id'".
97
			(($ne_pas_tester_validiter_du_cache) ? '' : ' AND (expire = 0 OR expire > '.time().')');
107
			(($ne_pas_tester_validiter_du_cache) ? '' : ' AND (expire = 0 OR expire > '.time().')');
98
		$resultat = $this->requeter($requete);
108
		$resultat = $this->requeter($requete);
99
		$ligne = @sqlite_fetch_array($resultat);
109
		$ligne = @sqlite_fetch_array($resultat);
100
		return ($ligne) ? $ligne['content'] : false;
110
		return ($ligne) ? $ligne['content'] : false;
101
	}
111
	}
102
 
112
 
103
	/**
113
	/**
104
	 * Test if a cache is available or not (for the given id)
114
	 * Test if a cache is available or not (for the given id)
105
	 *
115
	 *
106
	 * @param string $id Cache id
116
	 * @param string $id Cache id
107
	 * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record
117
	 * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record
108
	 */
118
	 */
109
	public function tester($id) {
119
	public function tester($id) {
110
		$this->verifierEtCreerStructureBdd();
120
		$this->verifierEtCreerStructureBdd();
111
		$requete = "SELECT lastModified FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
121
		$requete = "SELECT lastModified FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
112
		$resultat = $this->requeter($requete);
122
		$resultat = $this->requeter($requete);
113
		$ligne = @sqlite_fetch_array($resultat);
123
		$ligne = @sqlite_fetch_array($resultat);
114
		return ($ligne) ? ((int) $ligne['lastModified']) : false;
124
		return ($ligne) ? ((int) $ligne['lastModified']) : false;
115
	}
125
	}
116
 
126
 
117
	/**
127
	/**
118
	 * Save some string datas into a cache record
128
	 * Save some string datas into a cache record
119
	 *
129
	 *
120
	 * Note : $data is always "string" (serialization is done by the
130
	 * Note : $data is always "string" (serialization is done by the
121
	 * core not by the backend)
131
	 * core not by the backend)
122
	 *
132
	 *
123
	 * @param  string $data			 Datas to cache
133
	 * @param  string $data			 Datas to cache
124
	 * @param  string $id			   Cache id
134
	 * @param  string $id			   Cache id
125
	 * @param  array  $tags			 Array of strings, the cache record will be tagged by each string entry
135
	 * @param  array  $tags			 Array of strings, the cache record will be tagged by each string entry
126
	 * @param  int	$specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
136
	 * @param  int	$specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
127
	 * @throws Zend_Cache_Exception
137
	 * @throws Zend_Cache_Exception
128
	 * @return boolean True if no problem
138
	 * @return boolean True if no problem
129
	 */
139
	 */
130
	public function sauver($donnees, $id, $tags = array(), $duree_vie_specifique = false) {
140
	public function sauver($donnees, $id, $tags = array(), $duree_vie_specifique = false) {
131
		$this->verifierEtCreerStructureBdd();
141
		$this->verifierEtCreerStructureBdd();
132
		$donnees = @sqlite_escape_string($donnees);
142
		$donnees = @sqlite_escape_string($donnees);
133
		$timestamp_courrant = time();
143
		$timestamp_courrant = time();
134
		$expiration = $this->Cache->getTimestampExpiration($duree_vie_specifique);
144
		$expiration = $this->Cache->getTimestampExpiration($duree_vie_specifique);
135
 
145
 
136
		$this->requeter("DELETE FROM cache WHERE id = '$id'");
146
		$this->requeter("DELETE FROM cache WHERE id = '$id'");
137
		$sql = "INSERT INTO cache (id, content, lastModified, expire) VALUES ('$id', '$donnees', $timestamp_courrant, $expiration)";
147
		$sql = "INSERT INTO cache (id, content, lastModified, expire) VALUES ('$id', '$donnees', $timestamp_courrant, $expiration)";
138
		$resultat = $this->requeter($sql);
148
		$resultat = $this->requeter($sql);
139
		if (!$resultat) {
149
		if (!$resultat) {
140
			// TODO : ajouter un log sauver() : impossible de stocker le cache d'id '$id'
150
			// TODO : ajouter un log sauver() : impossible de stocker le cache d'id '$id'
141
			Debug::printr("sauver() : impossible de stocker le cache d'id '$id'");
151
			Debug::printr("sauver() : impossible de stocker le cache d'id '$id'");
142
			$resultat =  false;
152
			$resultat =  false;
143
		} else {
153
		} else {
144
			$resultat = true;
154
			$resultat = true;
145
			foreach ($tags as $tag) {
155
			foreach ($tags as $tag) {
146
				$resultat = $this->enregisterTag($id, $tag) && $resultat;
156
				$resultat = $this->enregisterTag($id, $tag) && $resultat;
147
			}
157
			}
148
		}
158
		}
149
		return $resultat;
159
		return $resultat;
150
	}
160
	}
151
 
161
 
152
	/**
162
	/**
153
	 * Remove a cache record
163
	 * Remove a cache record
154
	 *
164
	 *
155
	 * @param  string $id Cache id
165
	 * @param  string $id Cache id
156
	 * @return boolean True if no problem
166
	 * @return boolean True if no problem
157
	 */
167
	 */
158
	public function supprimer($id) {
168
	public function supprimer($id) {
159
		$this->verifierEtCreerStructureBdd();
169
		$this->verifierEtCreerStructureBdd();
160
		$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM cache WHERE id = '$id'");
170
		$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM cache WHERE id = '$id'");
161
		$resultat_nbre = @sqlite_fetch_single($resultat);
171
		$resultat_nbre = @sqlite_fetch_single($resultat);
162
		$suppression_cache = $this->requeter("DELETE FROM cache WHERE id = '$id'");
172
		$suppression_cache = $this->requeter("DELETE FROM cache WHERE id = '$id'");
163
		$suppression_tags = $this->requeter("DELETE FROM tag WHERE id = '$id'");
173
		$suppression_tags = $this->requeter("DELETE FROM tag WHERE id = '$id'");
164
		$this->defragmenterAutomatiquement();
174
		$this->defragmenterAutomatiquement();
165
		return ($resultat_nbre && $suppression_cache && $suppression_tags);
175
		return ($resultat_nbre && $suppression_cache && $suppression_tags);
166
	}
176
	}
167
 
177
 
168
	/**
178
	/**
169
	 * Clean some cache records
179
	 * Clean some cache records
170
	 *
180
	 *
171
	 * Available modes are :
181
	 * Available modes are :
172
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
182
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
173
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
183
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
174
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
184
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
175
	 *											   ($tags can be an array of strings or a single string)
185
	 *											   ($tags can be an array of strings or a single string)
176
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
186
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
177
	 *											   ($tags can be an array of strings or a single string)
187
	 *											   ($tags can be an array of strings or a single string)
178
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
188
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
179
	 *											   ($tags can be an array of strings or a single string)
189
	 *											   ($tags can be an array of strings or a single string)
180
	 *
190
	 *
181
	 * @param  string $mode Clean mode
191
	 * @param  string $mode Clean mode
182
	 * @param  array  $tags Array of tags
192
	 * @param  array  $tags Array of tags
183
	 * @return boolean True if no problem
193
	 * @return boolean True if no problem
184
	 */
194
	 */
185
	public function nettoyer($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
195
	public function nettoyer($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
186
		$this->verifierEtCreerStructureBdd();
196
		$this->verifierEtCreerStructureBdd();
187
		$retour = $this->nettoyerSqlite($mode, $tags);
197
		$retour = $this->nettoyerSqlite($mode, $tags);
188
		$this->defragmenterAutomatiquement();
198
		$this->defragmenterAutomatiquement();
189
		return $retour;
199
		return $retour;
190
	}
200
	}
191
 
201
 
192
	/**
202
	/**
193
	 * Return an array of stored cache ids
203
	 * Return an array of stored cache ids
194
	 *
204
	 *
195
	 * @return array array of stored cache ids (string)
205
	 * @return array array of stored cache ids (string)
196
	 */
206
	 */
197
	public function getIds() {
207
	public function getIds() {
198
		$this->verifierEtCreerStructureBdd();
208
		$this->verifierEtCreerStructureBdd();
199
		$resultat = $this->requeter('SELECT id FROM cache WHERE (expire = 0 OR expire > '.time().')');
209
		$resultat = $this->requeter('SELECT id FROM cache WHERE (expire = 0 OR expire > '.time().')');
200
		$retour = array();
210
		$retour = array();
201
		while ($id = @sqlite_fetch_single($resultat)) {
211
		while ($id = @sqlite_fetch_single($resultat)) {
202
			$retour[] = $id;
212
			$retour[] = $id;
203
		}
213
		}
204
		return $retour;
214
		return $retour;
205
	}
215
	}
206
 
216
 
207
	/**
217
	/**
208
	 * Return an array of stored tags
218
	 * Return an array of stored tags
209
	 *
219
	 *
210
	 * @return array array of stored tags (string)
220
	 * @return array array of stored tags (string)
211
	 */
221
	 */
212
	public function getTags() {
222
	public function getTags() {
213
		$this->verifierEtCreerStructureBdd();
223
		$this->verifierEtCreerStructureBdd();
214
		$resultat = $this->requeter('SELECT DISTINCT(name) AS name FROM tag');
224
		$resultat = $this->requeter('SELECT DISTINCT(name) AS name FROM tag');
215
		$retour = array();
225
		$retour = array();
216
		while ($id = @sqlite_fetch_single($resultat)) {
226
		while ($id = @sqlite_fetch_single($resultat)) {
217
			$retour[] = $id;
227
			$retour[] = $id;
218
		}
228
		}
219
		return $retour;
229
		return $retour;
220
	}
230
	}
221
 
231
 
222
	/**
232
	/**
223
	 * Return an array of stored cache ids which match given tags
233
	 * Return an array of stored cache ids which match given tags
224
	 *
234
	 *
225
	 * In case of multiple tags, a logical AND is made between tags
235
	 * In case of multiple tags, a logical AND is made between tags
226
	 *
236
	 *
227
	 * @param array $tags array of tags
237
	 * @param array $tags array of tags
228
	 * @return array array of matching cache ids (string)
238
	 * @return array array of matching cache ids (string)
229
	 */
239
	 */
230
	public function getIdsAvecLesTags($tags = array()) {
240
	public function getIdsAvecLesTags($tags = array()) {
231
		$this->verifierEtCreerStructureBdd();
241
		$this->verifierEtCreerStructureBdd();
232
		$premier = true;
242
		$premier = true;
233
		$ids = array();
243
		$ids = array();
234
		foreach ($tags as $tag) {
244
		foreach ($tags as $tag) {
235
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name='$tag'");
245
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name='$tag'");
236
			if ($resultat) {
246
			if ($resultat) {
237
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
247
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
238
				$ids_tmp = array();
248
				$ids_tmp = array();
239
				foreach ($lignes as $ligne) {
249
				foreach ($lignes as $ligne) {
240
					$ids_tmp[] = $ligne['id'];
250
					$ids_tmp[] = $ligne['id'];
241
				}
251
				}
242
				if ($premier) {
252
				if ($premier) {
243
					$ids = $ids_tmp;
253
					$ids = $ids_tmp;
244
					$premier = false;
254
					$premier = false;
245
				} else {
255
				} else {
246
					$ids = array_intersect($ids, $ids_tmp);
256
					$ids = array_intersect($ids, $ids_tmp);
247
				}
257
				}
248
			}
258
			}
249
		}
259
		}
250
		
260
		
251
		$retour = array();
261
		$retour = array();
252
		if (count($ids) > 0) {
262
		if (count($ids) > 0) {
253
			foreach ($ids as $id) {
263
			foreach ($ids as $id) {
254
				$retour[] = $id;
264
				$retour[] = $id;
255
			}
265
			}
256
		}
266
		}
257
		return $retour;
267
		return $retour;
258
	}
268
	}
259
 
269
 
260
	/**
270
	/**
261
	 * Return an array of stored cache ids which don't match given tags
271
	 * Return an array of stored cache ids which don't match given tags
262
	 *
272
	 *
263
	 * In case of multiple tags, a logical OR is made between tags
273
	 * In case of multiple tags, a logical OR is made between tags
264
	 *
274
	 *
265
	 * @param array $tags array of tags
275
	 * @param array $tags array of tags
266
	 * @return array array of not matching cache ids (string)
276
	 * @return array array of not matching cache ids (string)
267
	 */
277
	 */
268
	public function getIdsSansLesTags($tags = array()) {
278
	public function getIdsSansLesTags($tags = array()) {
269
		$this->verifierEtCreerStructureBdd();
279
		$this->verifierEtCreerStructureBdd();
270
		$resultat = $this->requeter('SELECT id FROM cache');
280
		$resultat = $this->requeter('SELECT id FROM cache');
271
		$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
281
		$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
272
		$retour = array();
282
		$retour = array();
273
		foreach ($lignes as $ligne) {
283
		foreach ($lignes as $ligne) {
274
			$id = $ligne['id'];
284
			$id = $ligne['id'];
275
			$correspondance = false;
285
			$correspondance = false;
276
			foreach ($tags as $tag) {
286
			foreach ($tags as $tag) {
277
				$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM tag WHERE name = '$tag' AND id = '$id'");
287
				$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM tag WHERE name = '$tag' AND id = '$id'");
278
				if ($resultat) {
288
				if ($resultat) {
279
					$nbre = (int) @sqlite_fetch_single($resultat);
289
					$nbre = (int) @sqlite_fetch_single($resultat);
280
					if ($nbre > 0) {
290
					if ($nbre > 0) {
281
						$correspondance = true;
291
						$correspondance = true;
282
					}
292
					}
283
				}
293
				}
284
			}
294
			}
285
			if (!$correspondance) {
295
			if (!$correspondance) {
286
				$retour[] = $id;
296
				$retour[] = $id;
287
			}
297
			}
288
		}
298
		}
289
		return $retour;
299
		return $retour;
290
	}
300
	}
291
 
301
 
292
	/**
302
	/**
293
	 * Return an array of stored cache ids which match any given tags
303
	 * Return an array of stored cache ids which match any given tags
294
	 *
304
	 *
295
	 * In case of multiple tags, a logical AND is made between tags
305
	 * In case of multiple tags, a logical AND is made between tags
296
	 *
306
	 *
297
	 * @param array $tags array of tags
307
	 * @param array $tags array of tags
298
	 * @return array array of any matching cache ids (string)
308
	 * @return array array of any matching cache ids (string)
299
	 */
309
	 */
300
	public function getIdsAvecUnTag($tags = array()) {
310
	public function getIdsAvecUnTag($tags = array()) {
301
		$this->verifierEtCreerStructureBdd();
311
		$this->verifierEtCreerStructureBdd();
302
		$premier = true;
312
		$premier = true;
303
		$ids = array();
313
		$ids = array();
304
		foreach ($tags as $tag) {
314
		foreach ($tags as $tag) {
305
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name = '$tag'");
315
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name = '$tag'");
306
			if ($resultat) {
316
			if ($resultat) {
307
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
317
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
308
				$ids_tmp = array();
318
				$ids_tmp = array();
309
				foreach ($lignes as $ligne) {
319
				foreach ($lignes as $ligne) {
310
					$ids_tmp[] = $ligne['id'];
320
					$ids_tmp[] = $ligne['id'];
311
				}
321
				}
312
				if ($premier) {
322
				if ($premier) {
313
					$ids = $ids_tmp;
323
					$ids = $ids_tmp;
314
					$premier = false;
324
					$premier = false;
315
				} else {
325
				} else {
316
					$ids = array_merge($ids, $ids_tmp);
326
					$ids = array_merge($ids, $ids_tmp);
317
				}
327
				}
318
			}
328
			}
319
		}
329
		}
320
		
330
		
321
		$retour = array();
331
		$retour = array();
322
		if (count($ids) > 0) {
332
		if (count($ids) > 0) {
323
			foreach ($ids as $id) {
333
			foreach ($ids as $id) {
324
				$retour[] = $id;
334
				$retour[] = $id;
325
			}
335
			}
326
		}
336
		}
327
		return $retour;
337
		return $retour;
328
	}
338
	}
329
 
339
 
330
	/**
340
	/**
331
	 * Return the filling percentage of the backend storage
341
	 * Return the filling percentage of the backend storage
332
	 *
342
	 *
333
	 * @throws Zend_Cache_Exception
343
	 * @throws Zend_Cache_Exception
334
	 * @return int integer between 0 and 100
344
	 * @return int integer between 0 and 100
335
	 */
345
	 */
336
	public function getPourcentageRemplissage() {
346
	public function getPourcentageRemplissage() {
337
		$dossier = dirname($this->options['stockage_chemin']);
347
		$dossier = dirname($this->options['stockage_chemin']);
338
		$libre = disk_free_space($dossier);
348
		$libre = disk_free_space($dossier);
339
		$total = disk_total_space($dossier);
349
		$total = disk_total_space($dossier);
340
		
350
		
341
		$pourcentage = 0;
351
		$pourcentage = 0;
342
		if ($total == 0) {
352
		if ($total == 0) {
343
			trigger_error("Impossible d'utiliser la fonction disk_total_space", E_USER_WARNING);
353
			trigger_error("Impossible d'utiliser la fonction disk_total_space", E_USER_WARNING);
344
		} else {
354
		} else {
345
			$pourcentage = ($libre >= $total) ? 100 : ((int) (100. * ($total - $libre) / $total));
355
			$pourcentage = ($libre >= $total) ? 100 : ((int) (100. * ($total - $libre) / $total));
346
		}
356
		}
347
		return $pourcentage;
357
		return $pourcentage;
348
	}
358
	}
349
 
359
 
350
	/**
360
	/**
351
	 * Return an array of metadatas for the given cache id
361
	 * Return an array of metadatas for the given cache id
352
	 *
362
	 *
353
	 * The array must include these keys :
363
	 * The array must include these keys :
354
	 * - expire : the expire timestamp
364
	 * - expire : the expire timestamp
355
	 * - tags : a string array of tags
365
	 * - tags : a string array of tags
356
	 * - mtime : timestamp of last modification time
366
	 * - mtime : timestamp of last modification time
357
	 *
367
	 *
358
	 * @param string $id cache id
368
	 * @param string $id cache id
359
	 * @return array array of metadatas (false if the cache id is not found)
369
	 * @return array array of metadatas (false if the cache id is not found)
360
	 */
370
	 */
361
	public function getMetadonnees($id) {
371
	public function getMetadonnees($id) {
362
		$this->verifierEtCreerStructureBdd();
372
		$this->verifierEtCreerStructureBdd();
363
		$tags = array();
373
		$tags = array();
364
		$resultat = $this->requeter("SELECT name FROM tag WHERE id = '$id'");
374
		$resultat = $this->requeter("SELECT name FROM tag WHERE id = '$id'");
365
		if ($resultat) {
375
		if ($resultat) {
366
			$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
376
			$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
367
			foreach ($lignes as $ligne) {
377
			foreach ($lignes as $ligne) {
368
				$tags[] = $ligne['name'];
378
				$tags[] = $ligne['name'];
369
			}
379
			}
370
		}
380
		}
371
		$resultat = $this->requeter("SELECT lastModified, expire FROM cache WHERE id = '$id'");
381
		$resultat = $this->requeter("SELECT lastModified, expire FROM cache WHERE id = '$id'");
372
		if ($resultat) {
382
		if ($resultat) {
373
			$ligne = @sqlite_fetch_array($resultat, SQLITE_ASSOC);
383
			$ligne = @sqlite_fetch_array($resultat, SQLITE_ASSOC);
374
			$resultat = array(
384
			$resultat = array(
375
				'tags' => $tags,
385
				'tags' => $tags,
376
				'mtime' => $ligne['lastModified'],
386
				'mtime' => $ligne['lastModified'],
377
				'expiration' => $ligne['expire']);
387
				'expiration' => $ligne['expire']);
378
		} else {
388
		} else {
379
			$resultat = false;
389
			$resultat = false;
380
		}
390
		}
381
		return $resultat;
391
		return $resultat;
382
	}
392
	}
383
 
393
 
384
	/**
394
	/**
385
	 * Give (if possible) an extra lifetime to the given cache id
395
	 * Give (if possible) an extra lifetime to the given cache id
386
	 *
396
	 *
387
	 * @param string $id cache id
397
	 * @param string $id cache id
388
	 * @param int $extraLifetime
398
	 * @param int $extraLifetime
389
	 * @return boolean true if ok
399
	 * @return boolean true if ok
390
	 */
400
	 */
391
	public function ajouterSupplementDureeDeVie($id, $supplement_duree_de_vie) {
401
	public function ajouterSupplementDureeDeVie($id, $supplement_duree_de_vie) {
392
		$this->verifierEtCreerStructureBdd();
402
		$this->verifierEtCreerStructureBdd();
393
		$augmentation = false;
403
		$augmentation = false;
394
		$requete = "SELECT expire FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
404
		$requete = "SELECT expire FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
395
		$resultat = $this->requeter($requete);
405
		$resultat = $this->requeter($requete);
396
		if ($resultat) {
406
		if ($resultat) {
397
			$expiration = @sqlite_fetch_single($resultat);
407
			$expiration = @sqlite_fetch_single($resultat);
398
			$nouvelle_expiration = $expiration + $supplement_duree_de_vie;
408
			$nouvelle_expiration = $expiration + $supplement_duree_de_vie;
399
			$resultat = $this->requeter('UPDATE cache SET lastModified = '.time().", expire = $nouvelle_expiration WHERE id = '$id'");
409
			$resultat = $this->requeter('UPDATE cache SET lastModified = '.time().", expire = $nouvelle_expiration WHERE id = '$id'");
400
			$augmentation = ($resultat) ? true : false;
410
			$augmentation = ($resultat) ? true : false;
401
		}
411
		}
402
		return $augmentation;
412
		return $augmentation;
403
	}
413
	}
404
 
414
 
405
	/**
415
	/**
406
	 * Return the connection resource
416
	 * Return the connection resource
407
	 *
417
	 *
408
	 * If we are not connected, the connection is made
418
	 * If we are not connected, the connection is made
409
	 *
419
	 *
410
	 * @throws Zend_Cache_Exception
420
	 * @throws Zend_Cache_Exception
411
	 * @return resource Connection resource
421
	 * @return resource Connection resource
412
	 */
422
	 */
413
	private function getConnexion() {
423
	private function getConnexion() {
414
		if (!is_resource($this->bdd)) {
424
		if (!is_resource($this->bdd)) {
415
			if ($this->options['stockage_chemin'] === null) {
425
			if ($this->options['stockage_chemin'] === null) {
416
				$e = "L'emplacement du chemin vers le fichier de la base de données SQLite n'a pas été défini";
426
				$e = "L'emplacement du chemin vers le fichier de la base de données SQLite n'a pas été défini";
417
				trigger_error($e, E_USER_ERROR);
427
				trigger_error($e, E_USER_ERROR);
418
			} else {
428
			} else {
419
				$this->bdd = sqlite_open($this->options['stockage_chemin']);
429
				$this->bdd = sqlite_open($this->options['stockage_chemin']);
420
				if (!(is_resource($this->bdd))) {
430
				if (!(is_resource($this->bdd))) {
421
					$e = "Impossible d'ouvrir le fichier '".$this->options['stockage_chemin']."' de la base de données SQLite.";
431
					$e = "Impossible d'ouvrir le fichier '".$this->options['stockage_chemin']."' de la base de données SQLite.";
422
					trigger_error($e, E_USER_ERROR);
432
					trigger_error($e, E_USER_ERROR);
423
					$this->bdd = null;
433
					$this->bdd = null;
424
				}
434
				}
425
			}
435
			}
426
		}
436
		}
427
		return $this->bdd;
437
		return $this->bdd;
428
	}
438
	}
429
 
439
 
430
	/**
440
	/**
431
	 * Execute une requête SQL sans afficher de messages d'erreur.
441
	 * Execute une requête SQL sans afficher de messages d'erreur.
432
	 *
442
	 *
433
	 * @param string $requete requête SQL
443
	 * @param string $requete requête SQL
434
	 * @return mixed|false resultats de la requête
444
	 * @return mixed|false resultats de la requête
435
	 */
445
	 */
436
	private function requeter($requete) {
446
	private function requeter($requete) {
437
		$bdd = $this->getConnexion();
447
		$bdd = $this->getConnexion();
438
		//Debug::printr($requete);
448
		//Debug::printr($requete);
439
		$resultat = (is_resource($bdd)) ? @sqlite_query($bdd, $requete, SQLITE_ASSOC, $e_sqlite) : false;
449
		$resultat = (is_resource($bdd)) ? @sqlite_query($bdd, $requete, SQLITE_ASSOC, $e_sqlite) : false;
440
		if (is_resource($bdd) && ! $resultat) {
450
		if (is_resource($bdd) && ! $resultat) {
441
			Debug::printr("Erreur SQLITE :\n$e_sqlite\nPour la requête :\n$requete\nRessource : $bdd");
451
			Debug::printr("Erreur SQLITE :\n$e_sqlite\nPour la requête :\n$requete\nRessource : $bdd");
442
		}
452
		}
443
		return $resultat;
453
		return $resultat;
444
	}
454
	}
445
 
455
 
446
	/**
456
	/**
447
	 * Deal with the automatic vacuum process
457
	 * Deal with the automatic vacuum process
448
	 *
458
	 *
449
	 * @return void
459
	 * @return void
450
	 */
460
	 */
451
	private function defragmenterAutomatiquement() {
461
	private function defragmenterAutomatiquement() {
452
		if ($this->options['defragmentation_auto'] > 0) {
462
		if ($this->options['defragmentation_auto'] > 0) {
453
			$rand = rand(1, $this->options['defragmentation_auto']);
463
			$rand = rand(1, $this->options['defragmentation_auto']);
454
			if ($rand == 1) {
464
			if ($rand == 1) {
455
				$this->requeter('VACUUM');
465
				$this->requeter('VACUUM');
456
				@sqlite_close($this->getConnexion());
466
				@sqlite_close($this->getConnexion());
457
			}
467
			}
458
		}
468
		}
459
	}
469
	}
460
 
470
 
461
	/**
471
	/**
462
	 * Register a cache id with the given tag
472
	 * Register a cache id with the given tag
463
	 *
473
	 *
464
	 * @param  string $id  Cache id
474
	 * @param  string $id  Cache id
465
	 * @param  string $tag Tag
475
	 * @param  string $tag Tag
466
	 * @return boolean True if no problem
476
	 * @return boolean True if no problem
467
	 */
477
	 */
468
	private function enregisterTag($id, $tag) {
478
	private function enregisterTag($id, $tag) {
469
		$requete_suppression = "DELETE FROM tag WHERE name = '$tag' AND id = '$id'";
479
		$requete_suppression = "DELETE FROM tag WHERE name = '$tag' AND id = '$id'";
470
		$resultat = $this->requeter($requete_suppression);
480
		$resultat = $this->requeter($requete_suppression);
471
		$requete_insertion = "INSERT INTO tag(name,id) VALUES ('$tag','$id')";
481
		$requete_insertion = "INSERT INTO tag(name,id) VALUES ('$tag','$id')";
472
		$resultat = $this->requeter($requete_insertion);
482
		$resultat = $this->requeter($requete_insertion);
473
		if (!$resultat) {
483
		if (!$resultat) {
474
			// TODO : ajouter un log -> impossible d'enregistrer le tag=$tag pour le cache id=$id");
484
			// TODO : ajouter un log -> impossible d'enregistrer le tag=$tag pour le cache id=$id");
475
			Debug::printr("Impossible d'enregistrer le tag=$tag pour le cache id=$id");
485
			Debug::printr("Impossible d'enregistrer le tag=$tag pour le cache id=$id");
476
		}
486
		}
477
		return ($resultat) ? true : false;
487
		return ($resultat) ? true : false;
478
	}
488
	}
479
 
489
 
480
	/**
490
	/**
481
	 * Build the database structure
491
	 * Build the database structure
482
	 *
492
	 *
483
	 * @return false
493
	 * @return false
484
	 */
494
	 */
485
	private function creerStructure() {
495
	private function creerStructure() {
486
		Debug::printr("création de la str");
496
		Debug::printr("création de la str");
487
		$this->requeter('DROP INDEX IF EXISTS tag_id_index');
497
		$this->requeter('DROP INDEX IF EXISTS tag_id_index');
488
		$this->requeter('DROP INDEX IF EXISTS tag_name_index');
498
		$this->requeter('DROP INDEX IF EXISTS tag_name_index');
489
		$this->requeter('DROP INDEX IF EXISTS cache_id_expire_index');
499
		$this->requeter('DROP INDEX IF EXISTS cache_id_expire_index');
490
		$this->requeter('DROP TABLE IF EXISTS version');
500
		$this->requeter('DROP TABLE IF EXISTS version');
491
		$this->requeter('DROP TABLE IF EXISTS cache');
501
		$this->requeter('DROP TABLE IF EXISTS cache');
492
		$this->requeter('DROP TABLE IF EXISTS tag');
502
		$this->requeter('DROP TABLE IF EXISTS tag');
493
		$this->requeter('CREATE TABLE version (num INTEGER PRIMARY KEY)');
503
		$this->requeter('CREATE TABLE version (num INTEGER PRIMARY KEY)');
494
		$this->requeter('CREATE TABLE cache(id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)');
504
		$this->requeter('CREATE TABLE cache(id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)');
495
		$this->requeter('CREATE TABLE tag (name TEXT, id TEXT)');
505
		$this->requeter('CREATE TABLE tag (name TEXT, id TEXT)');
496
		$this->requeter('CREATE INDEX tag_id_index ON tag(id)');
506
		$this->requeter('CREATE INDEX tag_id_index ON tag(id)');
497
		$this->requeter('CREATE INDEX tag_name_index ON tag(name)');
507
		$this->requeter('CREATE INDEX tag_name_index ON tag(name)');
498
		$this->requeter('CREATE INDEX cache_id_expire_index ON cache(id, expire)');
508
		$this->requeter('CREATE INDEX cache_id_expire_index ON cache(id, expire)');
499
		$this->requeter('INSERT INTO version (num) VALUES (1)');
509
		$this->requeter('INSERT INTO version (num) VALUES (1)');
500
	}
510
	}
501
 
511
 
502
	/**
512
	/**
503
	 * Check if the database structure is ok (with the good version)
513
	 * Check if the database structure is ok (with the good version)
504
	 *
514
	 *
505
	 * @return boolean True if ok
515
	 * @return boolean True if ok
506
	 */
516
	 */
507
	private function verifierBddStructureVersion() {
517
	private function verifierBddStructureVersion() {
508
		$version_ok = false;
518
		$version_ok = false;
509
		$resultat = $this->requeter('SELECT num FROM version');
519
		$resultat = $this->requeter('SELECT num FROM version');
510
		if ($resultat) {
520
		if ($resultat) {
511
			$ligne = @sqlite_fetch_array($resultat);
521
			$ligne = @sqlite_fetch_array($resultat);
512
			if ($ligne) {
522
			if ($ligne) {
513
				if (((int) $ligne['num']) == 1) {
523
				if (((int) $ligne['num']) == 1) {
514
					$version_ok = true;
524
					$version_ok = true;
515
				} else {
525
				} else {
516
					// TODO : ajouter un log CacheSqlite::verifierBddStructureVersion() : vielle version de la structure de la base de données de cache détectée => le cache est entrain d'être supprimé
526
					// TODO : ajouter un log CacheSqlite::verifierBddStructureVersion() : vielle version de la structure de la base de données de cache détectée => le cache est entrain d'être supprimé
517
				}
527
				}
518
			}
528
			}
519
		}
529
		}
520
		return $version_ok;
530
		return $version_ok;
521
	}
531
	}
522
 
532
 
523
	/**
533
	/**
524
	 * Clean some cache records
534
	 * Clean some cache records
525
	 *
535
	 *
526
	 * Available modes are :
536
	 * Available modes are :
527
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
537
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
528
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
538
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
529
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
539
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
530
	 *											   ($tags can be an array of strings or a single string)
540
	 *											   ($tags can be an array of strings or a single string)
531
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
541
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
532
	 *											   ($tags can be an array of strings or a single string)
542
	 *											   ($tags can be an array of strings or a single string)
533
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
543
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
534
	 *											   ($tags can be an array of strings or a single string)
544
	 *											   ($tags can be an array of strings or a single string)
535
	 *
545
	 *
536
	 * @param  string $mode Clean mode
546
	 * @param  string $mode Clean mode
537
	 * @param  array  $tags Array of tags
547
	 * @param  array  $tags Array of tags
538
	 * @return boolean True if no problem
548
	 * @return boolean True if no problem
539
	 */
549
	 */
540
	private function nettoyerSqlite($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
550
	private function nettoyerSqlite($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
541
		$nettoyage_ok = false;
551
		$nettoyage_ok = false;
542
		switch ($mode) {
552
		switch ($mode) {
543
			case Cache::NETTOYAGE_MODE_TOUS:
553
			case Cache::NETTOYAGE_MODE_TOUS:
544
				$suppression_cache = $this->requeter('DELETE FROM cache');
554
				$suppression_cache = $this->requeter('DELETE FROM cache');
545
				$suppression_tag = $this->requeter('DELETE FROM tag');
555
				$suppression_tag = $this->requeter('DELETE FROM tag');
546
				$nettoyage_ok = $suppression_cache && $suppression_tag;
556
				$nettoyage_ok = $suppression_cache && $suppression_tag;
547
				break;
557
				break;
548
			case Cache::NETTOYAGE_MODE_EXPIRATION:
558
			case Cache::NETTOYAGE_MODE_EXPIRATION:
549
				$mktime = time();
559
				$mktime = time();
550
				$suppression_tag = $this->requeter("DELETE FROM tag WHERE id IN (SELECT id FROM cache WHERE expire > 0 AND expire <= $mktime)");
560
				$suppression_tag = $this->requeter("DELETE FROM tag WHERE id IN (SELECT id FROM cache WHERE expire > 0 AND expire <= $mktime)");
551
				$suppression_cache = $this->requeter("DELETE FROM cache WHERE expire > 0 AND expire <= $mktime");
561
				$suppression_cache = $this->requeter("DELETE FROM cache WHERE expire > 0 AND expire <= $mktime");
552
				return $suppression_tag && $suppression_cache;
562
				return $suppression_tag && $suppression_cache;
553
				break;
563
				break;
554
			case Cache::NETTOYAGE_MODE_AVEC_LES_TAGS:
564
			case Cache::NETTOYAGE_MODE_AVEC_LES_TAGS:
555
				$ids = $this->getIdsAvecLesTags($tags);
565
				$ids = $this->getIdsAvecLesTags($tags);
556
				$resultat = true;
566
				$resultat = true;
557
				foreach ($ids as $id) {
567
				foreach ($ids as $id) {
558
					$resultat = $this->supprimer($id) && $resultat;
568
					$resultat = $this->supprimer($id) && $resultat;
559
				}
569
				}
560
				return $resultat;
570
				return $resultat;
561
				break;
571
				break;
562
			case Cache::NETTOYAGE_MODE_SANS_LES_TAGS:
572
			case Cache::NETTOYAGE_MODE_SANS_LES_TAGS:
563
				$ids = $this->getIdsSansLesTags($tags);
573
				$ids = $this->getIdsSansLesTags($tags);
564
				$resultat = true;
574
				$resultat = true;
565
				foreach ($ids as $id) {
575
				foreach ($ids as $id) {
566
					$resultat = $this->supprimer($id) && $resultat;
576
					$resultat = $this->supprimer($id) && $resultat;
567
				}
577
				}
568
				return $resultat;
578
				return $resultat;
569
				break;
579
				break;
570
			case Cache::NETTOYAGE_MODE_AVEC_UN_TAG:
580
			case Cache::NETTOYAGE_MODE_AVEC_UN_TAG:
571
				$ids = $this->getIdsAvecUnTag($tags);
581
				$ids = $this->getIdsAvecUnTag($tags);
572
				$resultat = true;
582
				$resultat = true;
573
				foreach ($ids as $id) {
583
				foreach ($ids as $id) {
574
					$resultat = $this->supprimer($id) && $resultat;
584
					$resultat = $this->supprimer($id) && $resultat;
575
				}
585
				}
576
				return $resultat;
586
				return $resultat;
577
				break;
587
				break;
578
			default:
588
			default:
579
				break;
589
				break;
580
		}
590
		}
581
		return $nettoyage_ok;
591
		return $nettoyage_ok;
582
	}
592
	}
583
 
593
 
584
	/**
594
	/**
585
	 * Check if the database structure is ok (with the good version), if no : build it
595
	 * Check if the database structure is ok (with the good version), if no : build it
586
	 *
596
	 *
587
	 * @throws Zend_Cache_Exception
597
	 * @throws Zend_Cache_Exception
588
	 * @return boolean True if ok
598
	 * @return boolean True if ok
589
	 */
599
	 */
590
	private function verifierEtCreerStructureBdd() {
600
	private function verifierEtCreerStructureBdd() {
591
		if (! $this->structure_ok) {
601
		if (! $this->structure_ok) {
592
			if (! $this->verifierBddStructureVersion()) {
602
			if (! $this->verifierBddStructureVersion()) {
593
				$this->creerStructure();
603
				$this->creerStructure();
594
				if (! $this->verifierBddStructureVersion()) {
604
				if (! $this->verifierBddStructureVersion()) {
595
					$e = "Impossible de construire la base de données de cache dans ".$this->options['stockage_chemin'];
605
					$e = "Impossible de construire la base de données de cache dans ".$this->options['stockage_chemin'];
596
					trigger_error($e, E_USER_WARNING);
606
					trigger_error($e, E_USER_WARNING);
597
					$this->structure_ok = false;
607
					$this->structure_ok = false;
598
				}
608
				}
599
			}
609
			}
600
			$this->structure_ok = true;
610
			$this->structure_ok = true;
601
		}
611
		}
602
		return $this->structure_ok;
612
		return $this->structure_ok;
603
	}
613
	}
604
 
614
 
605
}
615
}
606
?>
616
?>