Subversion Repositories Applications.framework

Rev

Rev 246 | Rev 269 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 246 Rev 248
Line 80... Line 80...
80
		'serialisation_auto'		  	 => false,
80
		'serialisation_auto'		  	 => false,
81
		'nettoyage_auto'				 => 10,
81
		'nettoyage_auto'				 => 10,
82
		'duree_de_vie'			 		 => 3600,
82
		'duree_de_vie'			 		 => 3600,
83
	);
83
	);
Line 84... Line 84...
84
	
84
	
85
	public function __construct($options) {
-
 
86
		
-
 
Line -... Line 85...
-
 
85
	protected $stockage = null;
87
	}
86
	
-
 
87
	public function __construct($options, $options_stockage) {
-
 
88
		$this->setOptions($options);
-
 
89
		if ($this->options['stockage_mode'] == self::STOCKAGE_MODE_FICHIER) {
88
	
90
			$this->stockage = new CacheFichier($options_stockage);
89
	/**
91
		} else if ($this->options['stockage_mode'] == self::STOCKAGE_MODE_SQLITE) {
90
	 * Fabrique et retourne l'identifiant du cache.
92
			$this->stockage = new CacheSqlite($options_stockage);
91
	 *
93
		}
-
 
94
		$this->stockage->setEmplacement($this->options['stockage_chemin']);
92
	 * Vérifie l'option 'cache_id_prefixe' et retourne le nouvel id avec préfixe ou simplement l'id lui même si elle vaut null.
95
	}
-
 
96
	
-
 
97
	private function setOptions($options) {
93
	 *
98
		while (list($nom, $valeur) = each($options)) {
94
	 * @param  string $id Identifiant du cache.
99
			if (!is_string($nom)) {
95
	 * @return string Identifiant du cache avec ou sans préfixe.
100
				trigger_error("Nom d'option incorecte : $nom", E_USER_WARNING);
96
	 */
-
 
97
	protected function getId($id) {
101
			}
98
		$nouvel_id = $id;
102
			$nom = strtolower($nom);
-
 
103
			if (array_key_exists($nom, $this->options)) {
99
		if (($id !== null) && isset($this->options['cache_id_prefixe'])) {
104
				$this->options[$nom] = $valeur;
100
			$nouvel_id = $this->options['cache_id_prefixe'] . $id;
-
 
101
		}
105
			}
Line 102... Line 106...
102
		return $nouvel_id;
106
		}
103
	}
107
	}
104
	
108
	
Line 112... Line 116...
112
	 */
116
	 */
113
	public function setEmplacement($emplacement) {
117
	public function setEmplacement($emplacement) {
114
		if ($emplacement != null) {
118
		if ($emplacement != null) {
115
			$this->executerMethodeStockage('setEmplacement', array($emplacement));
119
			$this->executerMethodeStockage('setEmplacement', array($emplacement));
116
		} else {
120
		} else {
117
            trigger_error("L'emplacement ne peut pas être null.", E_USER_WARNING);
121
			trigger_error("L'emplacement ne peut pas être null.", E_USER_WARNING);
118
		}
122
		}
119
	}
123
	}
Line 120... Line -...
120
	
-
 
121
	private function setEmplacementFichier($emplacement) {
-
 
122
		if (!is_dir($emplacement)) {
-
 
123
            trigger_error("L'emplacement doit être un dossier.", E_USER_WARNING);
-
 
124
        }
-
 
125
        if (!is_writable($emplacement)) {
-
 
126
            trigger_error("Le dossier de stockage du cache n'est pas accessible en écriture", E_USER_WARNING);
-
 
127
        }
-
 
128
        $emplacement = rtrim(realpath($emplacement), '\\/').DS;
-
 
129
        $this->options['stockage_chemin'] = $emplacement;
-
 
130
	}
-
 
131
	
-
 
132
	private function setEmplacementSqlite($emplacement) {
-
 
133
	 	if (!extension_loaded('sqlite')) {
-
 
134
            trigger_error("Impossible d'utiliser le mode de sotckage SQLite car l'extenssion 'sqlite' n'est pas chargé dans ".
-
 
135
            	"l'environnement PHP courrant.\n Le mode de stockage par fichier sera utilisé à la place.");
-
 
136
            $emplacement = rtrim(realpath($emplacement), '\\/').DS;
-
 
137
            $this->options['stockage_mode'] = self::STOCKAGE_MODE_FICHIER;
-
 
138
        }
-
 
139
        $this->options['stockage_chemin'] = $emplacement;
-
 
140
	}
-
 
141
	
-
 
142
	private function executerMethodeStockage($prefixe, $params) {
-
 
143
		$methode = 'sauver'.$this->options['mode_stockage'];
-
 
144
		if (method_exists($this, $methode)) {
-
 
145
			$resultat = call_user_func_array(array($this, $methode), $params);
-
 
146
		} else {
-
 
147
			$resultat = false;
-
 
148
			trigger_error("La méthode '$methode' n'existe pas dans la classe '".get_class($this)."'.", E_USER_WARNING);
-
 
149
		}
-
 
150
		return $resultat;
-
 
151
	}
-
 
152
	
124
	
153
	/**
125
	/**
154
	 * Teste si un cache est disponible pour l'identifiant donné et (si oui) le retourne (false dans le cas contraire)
126
	 * Teste si un cache est disponible pour l'identifiant donné et (si oui) le retourne (false dans le cas contraire)
155
	 *
127
	 *
156
	 * @param  string  $id Identifiant de cache.
128
	 * @param  string  $id Identifiant de cache.
157
	 * @param  boolean $ne_pas_tester_validiter_du_cache Si mis à true, la validité du cache n'est pas testée
129
	 * @param  boolean $ne_pas_tester_validiter_du_cache Si mis à true, la validité du cache n'est pas testée
158
	 * @return mixed|false Cached datas
130
	 * @return mixed|false Cached datas
159
	 */
131
	 */
160
	public function charger($id, $ne_pas_tester_validiter_du_cache = false) {
132
	public function charger($id, $ne_pas_tester_validiter_du_cache = false) {
161
		$donnees = false;
133
		$donnees = false;
162
		if ($this->options['mise_en_cache'] === true) {
134
		if ($this->options['mise_en_cache'] === true) {
163
			$id = $this->getId($id);
135
			$id = $this->prefixerId($id);
164
			$this->dernier_id = $id;
136
			$this->dernier_id = $id;
165
			self::validerIdOuTag($id);
137
			self::validerIdOuTag($id);
166
			$donnees = $this->executerMethodeStockage('charger', array($id, $ne_pas_tester_validiter_du_cache));
138
			$donnees = $this->executerMethodeStockage('charger', array($id, $ne_pas_tester_validiter_du_cache));
167
			$donnees = $this->deserialiserAutomatiquement($donnees);
139
			$donnees = $this->deserialiserAutomatiquement($donnees);
168
		}
140
		}
169
		return $donnees;
141
		return $donnees;
Line 170... Line 142...
170
	}
142
	}
-
 
143
	
-
 
144
	/**
-
 
145
	 * Test if a cache is available for the given id
-
 
146
	 *
-
 
147
	 * @param  string $id Cache id
-
 
148
	 * @return int|false Last modified time of cache entry if it is available, false otherwise
-
 
149
	 */
-
 
150
	public function tester($id) {
-
 
151
		$resultat = false;
-
 
152
		if ($this->options['mise_en_cache'] === true) {
-
 
153
		  	$id = $this->prefixerId($id);
-
 
154
			self::validerIdOuTag($id);
-
 
155
			$this->dernier_id = $id;
-
 
156
			$resultat = $this->executerMethodeStockage('tester', array($id));
-
 
157
		}
-
 
158
		return $resultat;
-
 
159
	}
171
	
160
	
172
	/**
161
	/**
173
	 * Sauvegarde en cache les données passées en paramètre.
162
	 * Sauvegarde en cache les données passées en paramètre.
174
	 *
163
	 *
175
	 * @param  mixed $donnees Données à mettre en cache (peut être différent d'une chaine si serialisation_auto vaut true).
164
	 * @param  mixed $donnees Données à mettre en cache (peut être différent d'une chaine si serialisation_auto vaut true).
Line 179... Line 168...
179
	 * @return boolean True si aucun problème n'est survenu.
168
	 * @return boolean True si aucun problème n'est survenu.
180
	 */
169
	 */
181
	public function sauver($donnees, $id = null, $tags = array(), $duree_de_vie_specifique = false) {
170
	public function sauver($donnees, $id = null, $tags = array(), $duree_de_vie_specifique = false) {
182
		$resultat = true;
171
		$resultat = true;
183
		if ($this->options['mise_en_cache'] === true) {
172
		if ($this->options['mise_en_cache'] === true) {
184
			$id = ($id === null) ? $this->dernier_id : $this->getId($id);
173
			$id = ($id === null) ? $this->dernier_id : $this->prefixerId($id);
Line 185... Line 174...
185
	
174
	
186
			self::validerIdOuTag($id);
175
			self::validerIdOuTag($id);
187
			self::validerTableauDeTags($tags);
176
			self::validerTableauDeTags($tags);
188
			$donnees = $this->serialiserAutomatiquement($donnees);
177
			$donnees = $this->serialiserAutomatiquement($donnees);
Line 199... Line 188...
199
		}
188
		}
200
		return $resultat;
189
		return $resultat;
201
	}
190
	}
Line 202... Line 191...
202
	
191
	
-
 
192
	/**
-
 
193
	 * Supprime un enregistrement en cache.
-
 
194
	 *
-
 
195
	 * @param  string $id Identificant du cache à supprimer.
-
 
196
	 * @return boolean True si ok
-
 
197
	 */
-
 
198
	public function supprimer($id) {
-
 
199
		$resultat = true;
-
 
200
		if ($this->options['mise_en_cache'] === true) {
-
 
201
			$id = $this->prefixerId($id);
-
 
202
			self::validerIdOuTag($id);
-
 
203
		   $resultat = $this->executerMethodeStockage('supprimer', array($id));
-
 
204
		}
-
 
205
		return $resultat;
-
 
206
	}
-
 
207
	
203
	/**
208
	/**
204
	 * Nettoyage des enregistrements en cache
209
	 * Nettoyage des enregistrements en cache
205
	 * 
210
	 * 
206
	 * Mode de nettoyage disponibles :
211
	 * Mode de nettoyage disponibles :
207
	 * 'tous' (défaut)	=> supprime tous les enregistrements ($tags n'est pas utilisé)
212
	 * 'tous' (défaut)	=> supprime tous les enregistrements ($tags n'est pas utilisé)
Line 228... Line 233...
228
			
233
			
229
			$resultat = $this->executerMethodeStockage('nettoyer', array($mode, $tags));
234
			$resultat = $this->executerMethodeStockage('nettoyer', array($mode, $tags));
230
		}
235
		}
231
		return $resultat;
236
		return $resultat;
-
 
237
	}
-
 
238
 
-
 
239
	/**
-
 
240
	 * Return an array of stored cache ids
-
 
241
	 *
-
 
242
	 * @return array array of stored cache ids (string)
-
 
243
	 */
-
 
244
	public function getIds() {
-
 
245
		$ids = $this->executerMethodeStockage('getIds');
-
 
246
		$ids = $this->supprimerPrefixe($ids);
-
 
247
		return $ids;
-
 
248
	}
-
 
249
 
-
 
250
	/**
-
 
251
	 * Return an array of stored tags
-
 
252
	 *
-
 
253
	 * @return array array of stored tags (string)
-
 
254
	 */
-
 
255
	public function getTags() {
-
 
256
		return $this->executerMethodeStockage('getTags');
Line -... Line 257...
-
 
257
	}
-
 
258
	
-
 
259
	/**
-
 
260
	 * Return an array of stored cache ids which match given tags
-
 
261
	 *
-
 
262
	 * In case of multiple tags, a logical AND is made between tags
-
 
263
	 *
-
 
264
	 * @param array $tags array of tags
-
 
265
	 * @return array array of matching cache ids (string)
-
 
266
	 */
-
 
267
	public function getIdsAvecLesTags($tags = array()) {
-
 
268
		$ids = $this->executerMethodeStockage('getIdsAvecLesTags', array($tags));
-
 
269
		$ids = $this->supprimerPrefixe($ids);
-
 
270
		return $ids;
-
 
271
	}
-
 
272
 
-
 
273
	/**
-
 
274
	 * Return an array of stored cache ids which don't match given tags
-
 
275
	 *
-
 
276
	 * In case of multiple tags, a logical OR is made between tags
-
 
277
	 *
-
 
278
	 * @param array $tags array of tags
-
 
279
	 * @return array array of not matching cache ids (string)
-
 
280
	 */
-
 
281
	public function getIdsSansLesTags($tags = array()) {
-
 
282
	   	$ids = $this->executerMethodeStockage('getIdsSansLesTags', array($tags));
-
 
283
		$ids = $this->supprimerPrefixe($ids);
-
 
284
		return $ids;
-
 
285
	}
-
 
286
 
-
 
287
	/**
-
 
288
	 * Return an array of stored cache ids which match any given tags
-
 
289
	 *
-
 
290
	 * In case of multiple tags, a logical OR is made between tags
-
 
291
	 *
-
 
292
	 * @param array $tags array of tags
-
 
293
	 * @return array array of matching any cache ids (string)
-
 
294
	 */
-
 
295
	public function getIdsAvecUnTag($tags = array()) {
-
 
296
		$ids = $this->executerMethodeStockage('getIdsAvecUnTag', array($tags));
-
 
297
		$ids = $this->supprimerPrefixe($ids);
-
 
298
		return $ids;
-
 
299
	}
-
 
300
 
-
 
301
	/**
-
 
302
	 * Return the filling percentage of the backend storage
-
 
303
	 *
-
 
304
	 * @return int integer between 0 and 100
-
 
305
	 */
-
 
306
	public function getPourcentageRemplissage() {
-
 
307
		return $this->executerMethodeStockage('getPourcentageRemplissage');
-
 
308
	}
-
 
309
 
-
 
310
	/**
-
 
311
	 * Return an array of metadatas for the given cache id
-
 
312
	 *
-
 
313
	 * The array will include these keys :
-
 
314
	 * - expire : the expire timestamp
-
 
315
	 * - tags : a string array of tags
-
 
316
	 * - mtime : timestamp of last modification time
-
 
317
	 *
-
 
318
	 * @param string $id cache id
-
 
319
	 * @return array array of metadatas (false if the cache id is not found)
-
 
320
	 */
-
 
321
	public function getMetadonnees($id) {
-
 
322
		$id = $this->prefixerId($id);
-
 
323
		return $this->executerMethodeStockage('getMetadonnees', array($id));
232
	}
324
	}
233
	
325
 
234
    /**
326
	/**
235
     * Supprime un enregistrement en cache.
327
	 * Give (if possible) an extra lifetime to the given cache id
-
 
328
	 *
236
     *
329
	 * @param string $id cache id
-
 
330
	 * @param int $extraLifetime
-
 
331
	 * @return boolean true if ok
-
 
332
	 */
-
 
333
	public function ajouterSupplementDureeDeVie($id, $supplement_duree_de_vie) {
-
 
334
		$id = $this->prefixerId($id);
-
 
335
		return $this->executerMethodeStockage('ajouterSupplementDureeDeVie', array($id, $supplement_duree_de_vie));
-
 
336
	}
-
 
337
	
-
 
338
 
-
 
339
	/**
-
 
340
	 * Fabrique et retourne l'identifiant du cache avec son préfixe.
-
 
341
	 *
-
 
342
	 * Vérifie l'option 'cache_id_prefixe' et retourne le nouvel id avec préfixe ou simplement l'id lui même si elle vaut null.
-
 
343
	 *
237
     * @param  string $id Identificant du cache à supprimer.
344
	 * @param  string $id Identifiant du cache.
238
     * @return boolean True si ok
345
	 * @return string Identifiant du cache avec ou sans préfixe.
239
     */
346
	 */
240
    public function supprimer($id) {
347
	private function prefixerId($id) {
241
    	$resultat = true;
348
		$nouvel_id = $id;
-
 
349
		if (($id !== null) && isset($this->options['cache_id_prefixe'])) {
242
		if ($this->options['mise_en_cache'] === true) {
350
			$nouvel_id = $this->options['cache_id_prefixe'].$id;
-
 
351
		}
-
 
352
		return $nouvel_id;
243
	        $id = $this->getId($id);
353
	}
-
 
354
	
-
 
355
	private function executerMethodeStockage($methode, $params = null) {
-
 
356
		if (method_exists($this->stockage, $methode)) {
-
 
357
			if ($params == null) {
-
 
358
				$resultat = call_user_func(array($this->stockage, $methode));
-
 
359
			} else {
-
 
360
				$resultat = call_user_func_array(array($this->stockage, $methode), $params);
-
 
361
			}
-
 
362
		} else {
244
	        self::validerIdOuTag($id);
363
			$resultat = false;
245
	       $resultat = $this->executerMethodeStockage('supprimer', array($id));
364
			trigger_error("La méthode '$methode' n'existe pas dans la classe '".get_class($this)."'.", E_USER_WARNING);
-
 
365
		}
-
 
366
		return $resultat;
-
 
367
	}
-
 
368
	
-
 
369
	private function supprimerPrefixe($ids) {
-
 
370
		// Il est nécessaire de retirer les cache_id_prefixe des ids (voir #ZF-6178, #ZF-7600)
-
 
371
		if (isset($this->options['cache_id_prefixe']) && $this->options['cache_id_prefixe'] !== '') {
-
 
372
			$prefixe =& $this->options['cache_id_prefixe'];
-
 
373
			$prefixe_longueur = strlen($prefixe);
-
 
374
			foreach ($ids as &$id) {
246
		}
375
				if (strpos($id, $prefixe) === 0) {
-
 
376
					$id = substr($id, $prefixe_longueur);
-
 
377
				}
-
 
378
			}
-
 
379
		}
Line 247... Line 380...
247
		return $resultat;
380
		return $ids;
248
    }
381
	}
249
	
382
	
250
	private function controlerEcriture($id, $donnees_avant_ecriture) {
383
	private function controlerEcriture($id, $donnees_avant_ecriture) {
Line 281... Line 414...
281
	
414
	
282
	private function nettoyerAutomatiquement() {
415
	private function nettoyerAutomatiquement() {
283
		if ($this->options['nettoyage_auto'] > 0) {
416
		if ($this->options['nettoyage_auto'] > 0) {
284
			$rand = rand(1, $this->options['nettoyage_auto']);
417
			$rand = rand(1, $this->options['nettoyage_auto']);
285
			if ($rand == 1) {
418
			if ($rand == 1) {
286
				$this->clean(self::NETTOYAGE_MODE_EXPIRER);
419
				$this->nettoyer(self::NETTOYAGE_MODE_EXPIRATION);
287
			}
420
			}
288
		}
421
		}
Line 289... Line 422...
289
	}
422
	}
Line 294... Line 427...
294
	 * @param  string $chaine Identificant de cache ou tag
427
	 * @param  string $chaine Identificant de cache ou tag
295
	 * @return void
428
	 * @return void
296
	 */
429
	 */
297
	protected static function validerIdOuTag($chaine) {
430
	protected static function validerIdOuTag($chaine) {
298
		if (!is_string($chaine)) {
431
		if (!is_string($chaine)) {
299
			trigger_error('Id ou tag invalide : doit être une chaîne de caractères', E_USER_WARNING);
432
			trigger_error('Id ou tag invalide : doit être une chaîne de caractères', E_USER_ERROR);
300
		}
433
		}
301
		if (substr($chaine, 0, 9) == 'internal-') {
434
		if (substr($chaine, 0, 9) == 'internal-') {
302
			trigger_error('"internal-*" identifiants ou tags sont réservés', E_USER_WARNING);
435
			trigger_error('"internal-*" identifiants ou tags sont réservés', E_USER_WARNING);
303
		}
436
		}
304
		if (!preg_match('~^[a-zA-Z0-9_]+$~D', $chaine)) {
437
		if (!preg_match('~^[a-zA-Z0-9_]+$~D', $chaine)) {