50,8 → 50,8 |
*/ |
protected $options = array( |
'stockage_chemin' => null, |
'fichier_verrou' => true,// file_locking |
'controle_lecture' => true,// controle de lecture |
'fichier_verrou' => true, |
'controle_lecture' => true, |
'controle_lecture_type' => 'crc32', |
'dossier_niveau' => 0, |
'dossier_umask' => 0700, |
65,7 → 65,7 |
* |
* @var array |
*/ |
protected $metadonnees = array(); // metadatasArray |
protected $metadonnees = array(); |
|
|
/** |
76,12 → 76,14 |
* @return void |
*/ |
public function __construct(array $options = array()) { |
$this->setOptions($options); |
|
if (isset($this->options['prefixe_fichier'])) { |
if (!preg_match('~^[a-zA-Z0-9_]+$~D', $this->options['prefixe_fichier'])) { |
trigger_error("Préfixe de nom de fichier invalide : doit contenir seulement [a-zA-Z0-9_]", E_USER_WARNING); |
} |
} |
if ($this->_options['metadonnees_max_taille'] < 10) { |
if ($this->options['metadonnees_max_taille'] < 10) { |
trigger_error("Taille du tableau des méta-données invalide, elle doit être > 10", E_USER_WARNING); |
} |
if (isset($options['dossier_umask']) && is_string($options['dossier_umask'])) { |
94,7 → 96,19 |
} |
} |
|
private function setEmplacement($emplacement) { |
private function setOptions($options) { |
while (list($nom, $valeur) = each($options)) { |
if (!is_string($nom)) { |
trigger_error("Nom d'option incorecte : $nom", E_USER_WARNING); |
} |
$nom = strtolower($nom); |
if (array_key_exists($nom, $this->options)) { |
$this->options[$nom] = $valeur; |
} |
} |
} |
|
public function setEmplacement($emplacement) { |
if (!is_dir($emplacement)) { |
trigger_error("L'emplacement doit être un dossier.", E_USER_WARNING); |
} |
155,38 → 169,44 |
* @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) |
* @return boolean true if no problem |
*/ |
public function save($data, $id, $tags = array(), $specificLifetime = false) { |
public function sauver($donnees, $id, $tags = array(), $duree_vie_specifique = false) { |
clearstatcache(); |
$file = $this->getFichierNom($id); |
$path = $this->getChemin($id); |
if ($this->_options['hashed_directory_level'] > 0) { |
if (!is_writable($path)) { |
$fichier = $this->getFichierNom($id); |
$chemin = $this->getChemin($id); |
|
$resultat = true; |
if ($this->options['dossier_niveau'] > 0) { |
if (!is_writable($chemin)) { |
// maybe, we just have to build the directory structure |
$this->lancerMkdirEtChmodRecursif($id); |
} |
if (!is_writable($path)) { |
return false; |
if (!is_writable($chemin)) { |
$resultat = false; |
} |
} |
if ($this->_options['read_control']) { |
$hash = $this->genererCleSecu($data, $this->_options['read_control_type']); |
|
if ($resultat === true) { |
if ($this->options['controle_lecture']) { |
$cle_secu = $this->genererCleSecu($donnees, $this->options['controle_lecture_type']); |
} else { |
$hash = ''; |
$cle_secu = ''; |
} |
$metadatas = array( |
'hash' => $hash, |
|
$metadonnees = array( |
'hash' => $cle_secu, |
'mtime' => time(), |
'expire' => $this->_expireTime($this->getLifetime($specificLifetime)), |
'expiration' => $this->getTimestampExpiration($duree_vie_specifique), |
'tags' => $tags |
); |
$res = $this->_setMetadatas($id, $metadatas); |
if (!$res) { |
$this->_log('Zend_Cache_Backend_File::save() / error on saving metadata'); |
return false; |
|
if (! $resultat = $this->setMetadonnees($id, $metadonnees)) { |
// TODO : ajouter un log |
} else { |
$resultat = $this->setContenuFichier($fichier, $donnees); |
} |
$res = $this->setContenuFichier($file, $data); |
return $res; |
} |
return $resultat; |
} |
|
/** |
* Remove a cache record |
221,7 → 241,7 |
public function nettoyer($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) { |
// We use this protected method to hide the recursive stuff |
clearstatcache(); |
return $this->nettoyerFichiers($this->options['stockage_dossier'], $mode, $tags); |
return $this->nettoyerFichiers($this->options['stockage_chemin'], $mode, $tags); |
} |
|
/** |
229,9 → 249,8 |
* |
* @return array array of stored cache ids (string) |
*/ |
public function getIds() |
{ |
return $this->_get($this->_options['cache_dir'], 'ids', array()); |
public function getIds() { |
return $this->analyserCache($this->options['stockage_chemin'], 'ids', array()); |
} |
|
/** |
239,9 → 258,8 |
* |
* @return array array of stored tags (string) |
*/ |
public function getTags() |
{ |
return $this->_get($this->_options['cache_dir'], 'tags', array()); |
public function getTags() { |
return $this->analyserCache($this->options['stockage_chemin'], 'tags', array()); |
} |
|
/** |
252,9 → 270,8 |
* @param array $tags array of tags |
* @return array array of matching cache ids (string) |
*/ |
public function getIdsMatchingTags($tags = array()) |
{ |
return $this->_get($this->_options['cache_dir'], 'matching', $tags); |
public function getIdsAvecLesTags($tags = array()) { |
return $this->analyserCache($this->options['stockage_chemin'], 'matching', $tags); |
} |
|
/** |
265,9 → 282,8 |
* @param array $tags array of tags |
* @return array array of not matching cache ids (string) |
*/ |
public function getIdsNotMatchingTags($tags = array()) |
{ |
return $this->_get($this->_options['cache_dir'], 'notMatching', $tags); |
public function getIdsSansLesTags($tags = array()) { |
return $this->analyserCache($this->options['stockage_chemin'], 'notMatching', $tags); |
} |
|
/** |
278,9 → 294,8 |
* @param array $tags array of tags |
* @return array array of any matching cache ids (string) |
*/ |
public function getIdsMatchingAnyTags($tags = array()) |
{ |
return $this->_get($this->_options['cache_dir'], 'matchingAny', $tags); |
public function getIdsAvecUnTag($tags = array()) { |
return $this->analyserCache($this->options['stockage_chemin'], 'matchingAny', $tags); |
} |
|
/** |
289,19 → 304,18 |
* @throws Zend_Cache_Exception |
* @return int integer between 0 and 100 |
*/ |
public function getFillingPercentage() |
{ |
$free = disk_free_space($this->_options['cache_dir']); |
$total = disk_total_space($this->_options['cache_dir']); |
public function getPourcentageRemplissage() { |
$libre = disk_free_space($this->options['sotckage_chemin']); |
$total = disk_total_space($this->options['sotckage_chemin']); |
|
$pourcentage = 0; |
if ($total == 0) { |
Zend_Cache::throwException('can\'t get disk_total_space'); |
trigger_error("Impossible d'utiliser la fonction disk_total_space", E_USER_WARNING); |
} else { |
if ($free >= $total) { |
return 100; |
$pourcentage = ($libre >= $total) ? 100 : ((int) (100. * ($total - $libre) / $total)); |
} |
return ((int) (100. * ($total - $free) / $total)); |
return $pourcentage; |
} |
} |
|
/** |
* Return an array of metadatas for the given cache id |
314,20 → 328,20 |
* @param string $id cache id |
* @return array array of metadatas (false if the cache id is not found) |
*/ |
public function getMetadatas($id) |
{ |
$metadatas = $this->getMetadonneesFichier($id); |
if (!$metadatas) { |
return false; |
public function getMetadonnees($id) { |
if ($metadonnees = $this->getMetadonneesFichier($id)) { |
if (time() > $metadonnees['expiration']) { |
$metadonnees = false; |
} else { |
$metadonnees = array( |
'expiration' => $metadonnees['expiration'], |
'tags' => $metadonnees['tags'], |
'mtime' => $metadonnees['mtime'] |
); |
} |
if (time() > $metadatas['expire']) { |
return false; |
} |
return array( |
'expire' => $metadatas['expire'], |
'tags' => $metadatas['tags'], |
'mtime' => $metadatas['mtime'] |
); |
|
return $metadonnees; |
} |
|
/** |
337,27 → 351,23 |
* @param int $extraLifetime |
* @return boolean true if ok |
*/ |
public function touch($id, $extraLifetime) |
{ |
$metadatas = $this->getMetadonneesFichier($id); |
if (!$metadatas) { |
return false; |
} |
if (time() > $metadatas['expire']) { |
return false; |
} |
$newMetadatas = array( |
'hash' => $metadatas['hash'], |
public function ajouterSupplementDureeDeVie($id, $supplement_duree_de_vie) { |
$augmentation = true; |
if ($metadonnees = $this->getMetadonneesFichier($id)) { |
if (time() > $metadonnees['expiration']) { |
$augmentation = false; |
} else { |
$metadonnees_nouvelle = array( |
'hash' => $metadonnees['hash'], |
'mtime' => time(), |
'expire' => $metadatas['expire'] + $extraLifetime, |
'tags' => $metadatas['tags'] |
'expiration' => $metadonnees['expiration'] + $supplement_duree_de_vie, |
'tags' => $metadonnees['tags'] |
); |
$res = $this->_setMetadatas($id, $newMetadatas); |
if (!$res) { |
return false; |
$augmentation = $this->setMetadonnees($id, $metadonnees_nouvelle); |
} |
return true; |
} |
return $augmentation; |
} |
|
/** |
* Get a metadatas record |
527,77 → 537,76 |
if (is_file($fichier)) { |
$fichier_nom = basename($fichier); |
if ($this->etreFichierMeta($fichier_nom)) { |
// in CLEANING_MODE_ALL, we drop anything, even remainings old metadatas files |
// Pour le mode Cache::NETTOYAGE_MODE_TOUS, nous essayons de tous supprimer même les vieux fichiers méta |
if ($mode != Cache::NETTOYAGE_MODE_TOUS) { |
continue; |
} |
} |
$id = $this->transformerNomFichierEnId($fichier_nom); |
$metadatas = $this->getMetadonneesFichier($id); |
if ($metadatas === FALSE) { |
$metadatas = array('expire' => 1, 'tags' => array()); |
$metadonnees = $this->getMetadonneesFichier($id); |
if ($metadonnees === FALSE) { |
$metadonnees = array('expiration' => 1, 'tags' => array()); |
} |
switch ($mode) { |
case Zend_Cache::CLEANING_MODE_ALL: |
$res = $this->remove($id); |
if (!$res) { |
// in this case only, we accept a problem with the metadatas file drop |
$res = $this->supprimerFichier($file); |
case Cache::NETTOYAGE_MODE_TOUS : |
if ($resultat_suppression = $this->supprimer($id)) { |
// Dans ce cas seulement, nous acception qu'il y ait un problème avec la suppresssion du fichier meta |
$resultat_suppression = $this->supprimerFichier($fichier); |
} |
$resultat = $resultat && $res; |
$resultat = $resultat && $resultat_suppression; |
break; |
case Zend_Cache::CLEANING_MODE_OLD: |
if (time() > $metadatas['expire']) { |
$resultat = $this->remove($id) && $resultat; |
case Cache::NETTOYAGE_MODE_EXPIRATION : |
if (time() > $metadonnees['expiration']) { |
$resultat = $this->supprimer($id) && $resultat; |
} |
break; |
case Zend_Cache::CLEANING_MODE_MATCHING_TAG: |
$matching = true; |
case Cache::NETTOYAGE_MODE_AVEC_LES_TAGS : |
$correspondance = true; |
foreach ($tags as $tag) { |
if (!in_array($tag, $metadatas['tags'])) { |
$matching = false; |
if (!in_array($tag, $metadonnees['tags'])) { |
$correspondance = false; |
break; |
} |
} |
if ($matching) { |
$resultat = $this->remove($id) && $resultat; |
if ($correspondance) { |
$resultat = $this->supprimer($id) && $resultat; |
} |
break; |
case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG: |
$matching = false; |
case Cache::NETTOYAGE_MODE_SANS_LES_TAGS : |
$correspondance = false; |
foreach ($tags as $tag) { |
if (in_array($tag, $metadatas['tags'])) { |
$matching = true; |
if (in_array($tag, $metadonnees['tags'])) { |
$correspondance = true; |
break; |
} |
} |
if (!$matching) { |
$resultat = $this->remove($id) && $resultat; |
if (!$correspondance) { |
$resultat = $this->supprimer($id) && $resultat; |
} |
break; |
case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG: |
$matching = false; |
case Cache::NETTOYAGE_MODE_AVEC_UN_TAG : |
$correspondance = false; |
foreach ($tags as $tag) { |
if (in_array($tag, $metadatas['tags'])) { |
$matching = true; |
if (in_array($tag, $metadonnees['tags'])) { |
$correspondance = true; |
break; |
} |
} |
if ($matching) { |
$resultat = $this->remove($id) && $resultat; |
if ($correspondance) { |
$resultat = $this->supprimer($id) && $resultat; |
} |
break; |
default: |
Zend_Cache::throwException('Invalid mode for clean() method'); |
trigger_error("Mode de nettoyage invalide pour la méthode nettoyer()", E_USER_WARNING); |
break; |
} |
} |
if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { |
// Recursive call |
$resultat = $this->nettoyerFichiers($file . DIRECTORY_SEPARATOR, $mode, $tags) && $resultat; |
if ($mode=='all') { |
// if mode=='all', we try to drop the structure too |
@rmdir($file); |
if ((is_dir($fichier)) and ($this->options['dossier_niveau'] > 0)) { |
// Appel récursif |
$resultat = $this->nettoyerFichiers($fichier.DS, $mode, $tags) && $resultat; |
if ($mode == Cache::NETTOYAGE_MODE_TOUS) { |
// Si mode == Cache::NETTOYAGE_MODE_TOUS, nous essayons de supprimer la structure aussi |
@rmdir($fichier); |
} |
} |
} |
604,87 → 613,87 |
return $resultat; |
} |
|
protected function _get($dir, $mode, $tags = array()) { |
if (!is_dir($dir)) { |
protected function analyserCache($dossier, $mode, $tags = array()) { |
if (!is_dir($dossier)) { |
return false; |
} |
$result = array(); |
$prefix = $this->_options['file_name_prefix']; |
$glob = @glob($dir . $prefix . '--*'); |
$resultat = array(); |
$prefixe = $this->options['fichier_prefixe']; |
$glob = @glob($dossier.$prefixe.'--*'); |
if ($glob === false) { |
// On some systems it is impossible to distinguish between empty match and an error. |
return array(); |
} |
foreach ($glob as $file) { |
if (is_file($file)) { |
$fileName = basename($file); |
$id = $this->transformerNomFichierEnId($fileName); |
$metadatas = $this->getMetadonneesFichier($id); |
if ($metadatas === FALSE) { |
foreach ($glob as $fichier) { |
if (is_file($fichier)) { |
$nom_fichier = basename($fichier); |
$id = $this->transformerNomFichierEnId($nom_fichier); |
$metadonnees = $this->getMetadonneesFichier($id); |
if ($metadonnees === FALSE) { |
continue; |
} |
if (time() > $metadatas['expire']) { |
if (time() > $metadonnees['expiration']) { |
continue; |
} |
switch ($mode) { |
case 'ids': |
$result[] = $id; |
$resultat[] = $id; |
break; |
case 'tags': |
$result = array_unique(array_merge($result, $metadatas['tags'])); |
$resultat = array_unique(array_merge($resultat, $metadonnees['tags'])); |
break; |
case 'matching': |
$matching = true; |
$correspondance = true; |
foreach ($tags as $tag) { |
if (!in_array($tag, $metadatas['tags'])) { |
$matching = false; |
if (!in_array($tag, $metadonnees['tags'])) { |
$correspondance = false; |
break; |
} |
} |
if ($matching) { |
$result[] = $id; |
if ($correspondance) { |
$resultat[] = $id; |
} |
break; |
case 'notMatching': |
$matching = false; |
$correspondance = false; |
foreach ($tags as $tag) { |
if (in_array($tag, $metadatas['tags'])) { |
$matching = true; |
if (in_array($tag, $metadonnees['tags'])) { |
$correspondance = true; |
break; |
} |
} |
if (!$matching) { |
$result[] = $id; |
if (!$correspondance) { |
$resultat[] = $id; |
} |
break; |
case 'matchingAny': |
$matching = false; |
$correspondance = false; |
foreach ($tags as $tag) { |
if (in_array($tag, $metadatas['tags'])) { |
$matching = true; |
if (in_array($tag, $metadonnees['tags'])) { |
$correspondance = true; |
break; |
} |
} |
if ($matching) { |
$result[] = $id; |
if ($correspondance) { |
$resultat[] = $id; |
} |
break; |
default: |
Zend_Cache::throwException('Invalid mode for _get() method'); |
trigger_error("Mode invalide pour la méthode analyserCache()", E_USER_WARNING); |
break; |
} |
} |
if ((is_dir($file)) and ($this->_options['hashed_directory_level']>0)) { |
// Recursive call |
$recursiveRs = $this->_get($file . DIRECTORY_SEPARATOR, $mode, $tags); |
if ($recursiveRs === false) { |
$this->_log('Zend_Cache_Backend_File::_get() / recursive call : can\'t list entries of "'.$file.'"'); |
if ((is_dir($fichier)) and ($this->options['dossier_niveau'] > 0)) { |
// Appel récursif |
$resultat_analyse_recursive = $this->analyserCache($fichier.DS, $mode, $tags); |
if ($resultat_analyse_recursive === false) { |
// TODO : ajoute un log |
} else { |
$result = array_unique(array_merge($result, $recursiveRs)); |
$resultat = array_unique(array_merge($resultat, $resultat_analyse_recursive)); |
} |
} |
} |
return array_unique($result); |
return array_unique($resultat); |
} |
|
/** |
692,11 → 701,12 |
* |
* @return int expire time (unix timestamp) |
*/ |
protected function _expireTime($lifetime) { |
if ($lifetime === null) { |
return 9999999999; |
protected function getTimestampExpiration($duree_de_vie) { |
if ($duree_de_vie === false) { |
$duree_de_vie = 3600; |
} |
return time() + $lifetime; |
$timestamp = ($duree_de_vie === null) ? 9999999999 : (time() + $duree_de_vie); |
return $timestamp; |
} |
|
/** |
730,7 → 740,7 |
*/ |
protected function transformaterIdEnNomFichier($id) { |
$prefixe = $this->options['fichier_prefixe']; |
$resulta = $prefixe.'---'.$id; |
$resultat = $prefixe.'---'.$id; |
return $resultat; |
} |
|
760,7 → 770,7 |
if ($this->options['dossier_niveau'] > 0) { |
$hash = hash('adler32', $id); |
for ($i = 0 ; $i < $this->options['dossier_niveau'] ; $i++) { |
$chemin .= $prefix.'--'.substr($hash, 0, $i + 1).DS; |
$chemin .= $prefixe.'--'.substr($hash, 0, $i + 1).DS; |
$morceaux[] = $chemin; |
} |
} |