Преглед изворни кода

Minz : refactorisation ModelArray et Log

Utilisation de fonctions natives de PHP comme file_put_contents et
var_export
Évite de garder un descripteur de fichier ouvert tout le temps
Et ModelTxt n'est plus utilisé
Alexandre Alapetite пре 12 година
родитељ
комит
01a1dd09a8

+ 1 - 8
app/Controllers/indexController.php

@@ -225,14 +225,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
 			file_put_contents(LOG_PATH . '/application.log', '');
 		}
 
-		$logs = array();
-		try {
-			$logDAO = new FreshRSS_LogDAO ();
-			$logs = $logDAO->lister ();
-			$logs = array_reverse ($logs);
-		} catch (Minz_FileNotExistException $e) {
-
-		}
+		$logs = FreshRSS_LogDAO::lines();	//TODO: ask only the necessary lines
 
 		//gestion pagination
 		$page = Minz_Request::param ('page', 1);

+ 3 - 6
app/Models/ConfigurationDAO.php

@@ -146,12 +146,9 @@ class FreshRSS_ConfigurationDAO extends Minz_ModelArray {
 		}
 	}
 
-	public function update ($values) {
-		foreach ($values as $key => $value) {
-			$this->array[$key] = $value;
-		}
-
-		$this->writeFile($this->array);
+	public function update($values) {
+		$this->array = array_merge($this->array, $values);
 		invalidateHttpCache();
+		return parent::writeFile();
 	}
 }

+ 15 - 13
app/Models/LogDAO.php

@@ -1,21 +1,23 @@
 <?php
 
-class FreshRSS_LogDAO extends Minz_ModelTxt {
-	public function __construct () {
-		parent::__construct (LOG_PATH . '/application.log', 'r+');
-	}
+class FreshRSS_LogDAO {
+	private static $filename = '/application.log';
 
-	public function lister () {
+	public static function lines() {
 		$logs = array ();
-		while (($line = $this->readLine ()) !== false) {
-			if (preg_match ('/^\[([^\[]+)\] \[([^\[]+)\] --- (.*)$/', $line, $matches)) {
-				$myLog = new FreshRSS_Log ();
-				$myLog->_date ($matches[1]);
-				$myLog->_level ($matches[2]);
-				$myLog->_info ($matches[3]);
-				$logs[] = $myLog;
+		$handle = @fopen(LOG_PATH . self::$filename, 'r');
+		if ($handle) {
+			while (($line = fgets($handle)) !== false) {
+				if (preg_match ('/^\[([^\[]+)\] \[([^\[]+)\] --- (.*)$/', $line, $matches)) {
+					$myLog = new FreshRSS_Log ();
+					$myLog->_date ($matches[1]);
+					$myLog->_level ($matches[2]);
+					$myLog->_info ($matches[3]);
+					$logs[] = $myLog;
+				}
 			}
+			fclose($handle);
 		}
-		return $logs;
+		return array_reverse($logs);
 	}
 }

+ 11 - 22
lib/Minz/Log.php

@@ -1,5 +1,5 @@
 <?php
-/** 
+/**
  * MINZ - Copyright 2011 Marien Fressinaud
  * Sous licence AGPL3 <http://www.gnu.org/licenses/>
 */
@@ -19,7 +19,7 @@ class Minz_Log {
 	const WARNING = 4;
 	const NOTICE = 8;
 	const DEBUG = 16;
-	
+
 	/**
 	 * Enregistre un message dans un fichier de log spécifique
 	 * Message non loggué si
@@ -32,14 +32,14 @@ class Minz_Log {
 	 */
 	public static function record ($information, $level, $file_name = null) {
 		$env = Minz_Configuration::environment ();
-		
+
 		if (! ($env === Minz_Configuration::SILENT
 		       || ($env === Minz_Configuration::PRODUCTION
 		       && ($level >= Minz_Log::NOTICE)))) {
 			if (is_null ($file_name)) {
 				$file_name = LOG_PATH . '/application.log';
 			}
-			
+
 			switch ($level) {
 			case Minz_Log::ERROR :
 				$level_label = 'error';
@@ -56,24 +56,13 @@ class Minz_Log {
 			default :
 				$level_label = 'unknown';
 			}
-			
-			if ($env == Minz_Configuration::PRODUCTION) {
-				$file = @fopen ($file_name, 'a');
-			} else {
-				$file = fopen ($file_name, 'a');
-			}
-			
-			if ($file !== false) {
-				$log = '[' . date('r') . ']';
-				$log .= ' [' . $level_label . ']';
-				$log .= ' --- ' . $information . "\n";
-				fwrite ($file, $log); 
-				fclose ($file);
-			} else {
-				throw new Minz_PermissionDeniedException (
-					$file_name,
-					Minz_Exception::ERROR
-				);
+
+			$log = '[' . date('r') . ']'
+			     . ' [' . $level_label . ']'
+			     . ' --- ' . $information . "\n";
+
+			if (file_put_contents($file_name, $log, FILE_APPEND | LOCK_EX) === false) {
+				throw new Minz_PermissionDeniedException($file_name, Minz_Exception::ERROR);
 			}
 		}
 	}

+ 57 - 82
lib/Minz/ModelArray.php

@@ -1,5 +1,5 @@
 <?php
-/** 
+/**
  * MINZ - Copyright 2011 Marien Fressinaud
  * Sous licence AGPL3 <http://www.gnu.org/licenses/>
 */
@@ -7,85 +7,58 @@
 /**
  * La classe Model_array représente le modèle interragissant avec les fichiers de type texte gérant des tableaux php
  */
-class Minz_ModelArray extends Minz_ModelTxt {
+class Minz_ModelArray {
 	/**
-	 * $array Le tableau php contenu dans le fichier $nameFile
+	 * $array Le tableau php contenu dans le fichier $filename
 	 */
 	protected $array = array ();
-	
+
+	/**
+	 * $filename est le nom du fichier
+	 */
+	protected $filename;
+
 	/**
-	 * Ouvre le fichier indiqué, charge le tableau dans $array et le $nameFile
-	 * @param $nameFile le nom du fichier à ouvrir contenant un tableau
+	 * Ouvre le fichier indiqué, charge le tableau dans $array et le $filename
+	 * @param $filename le nom du fichier à ouvrir contenant un tableau
 	 * Remarque : $array sera obligatoirement un tableau
 	 */
-	public function __construct ($nameFile) {
-		parent::__construct ($nameFile);
-		
-		if (!$this->getLock ('read')) {
-			throw new Minz_PermissionDeniedException ($this->filename);
+	public function __construct ($filename) {
+		$this->filename = $filename;
+
+		if (!file_exists($this->filename)) {
+			throw new Minz_FileNotExistException($this->filename, Minz_Exception::WARNING);
+		}
+		elseif (($handle = $this->getLock()) === false) {
+			throw new Minz_PermissionDeniedException($this->filename);
 		} else {
-			$this->array = include ($this->filename);
-			$this->releaseLock ();
-		
-			if (!is_array ($this->array)) {
+			$this->array = include($this->filename);
+			$this->releaseLock($handle);
+
+			if ($this->array === false) {
+				throw new Minz_PermissionDeniedException($this->filename);
+			} elseif (is_array($this->array)) {
+				$this->array = $this->decodeArray($this->array);
+			} else {
 				$this->array = array ();
 			}
-		
-			$this->array = $this->decodeArray ($this->array);
 		}
-	}	
-	
+	}
+
 	/**
-	 * Écrit un tableau dans le fichier $nameFile
-	 * @param $array le tableau php à enregistrer
+	 * Sauve le tableau $array dans le fichier $filename
 	 **/
-	public function writeFile ($array) {
-		if (!$this->getLock ('write')) {
-			throw new Minz_PermissionDeniedException ($this->namefile);
-		} else {
-			$this->erase ();
-		
-			$this->writeLine ('<?php');
-			$this->writeLine ('return ', false);
-			$this->writeArray ($array);
-			$this->writeLine (';');
-		
-			$this->releaseLock ();
-		}
-	}
-	
-	private function writeArray ($array, $profondeur = 0) {
-		$tab = '';
-		for ($i = 0; $i < $profondeur; $i++) {
-			$tab .= "\t";
-		}
-		$this->writeLine ('array (');
-		
-		foreach ($array as $key => $value) {
-			if (is_int ($key)) {
-				$this->writeLine ($tab . "\t" . $key . ' => ', false);
-			} else {
-				$this->writeLine ($tab . "\t" . '\'' . $key . '\'' . ' => ', false);
-			}
-			
-			if (is_array ($value)) {
-				$this->writeArray ($value, $profondeur + 1);
-				$this->writeLine (',');
-			} else {
-				if (is_numeric ($value)) {
-					$this->writeLine ($value . ',');
-				} else {
-					$this->writeLine ('\'' . addslashes ($value) . '\',');
-				}
-			}
+	protected function writeFile() {
+		if (!file_put_contents($this->filename, "<?php\n return " . var_export($this->array, true) . ';', LOCK_EX)) {
+			throw new Minz_PermissionDeniedException($this->filename);
 		}
-		
-		$this->writeLine ($tab . ')', false);
+		return true;
 	}
-	
+
+	//TODO: check if still useful, and if yes, use a native function such as array_map
 	private function decodeArray ($array) {
 		$new_array = array ();
-		
+
 		foreach ($array as $key => $value) {
 			if (is_array ($value)) {
 				$new_array[$key] = $this->decodeArray ($value);
@@ -93,30 +66,32 @@ class Minz_ModelArray extends Minz_ModelTxt {
 				$new_array[$key] = stripslashes ($value);
 			}
 		}
-		
+
 		return $new_array;
 	}
-	
-	private function getLock ($type) {
-		if ($type == 'write') {
-			$lock = LOCK_EX;
-		} else {
-			$lock = LOCK_SH;
+
+	private function getLock() {
+		$handle = fopen($this->filename, 'r');
+		if ($handle === false) {
+			return false;
 		}
-	
-		$count = 1;
-		while (!flock ($this->file, $lock) && $count <= 50) {
-			$count++;
+
+		$count = 50;
+		while (!flock($handle, LOCK_SH) && $count > 0) {
+			$count--;
+			usleep(1000);
 		}
-		
-		if ($count >= 50) {
-			return false;
+
+		if ($count > 0) {
+			return $handle;
 		} else {
-			return true;
+			fclose($handle);
+			return false;
 		}
 	}
-	
-	private function releaseLock () {
-		flock ($this->file, LOCK_UN);
+
+	private function releaseLock($handle) {
+		flock($handle, LOCK_UN);
+		fclose($handle);
 	}
 }

+ 0 - 84
lib/Minz/ModelTxt.php

@@ -1,84 +0,0 @@
-<?php
-/** 
- * MINZ - Copyright 2011 Marien Fressinaud
- * Sous licence AGPL3 <http://www.gnu.org/licenses/>
-*/
-
-/**
- * La classe Model_txt représente le modèle interragissant avec les fichiers de type texte
- */
-class Minz_ModelTxt {
-	/**
-	 * $file représente le fichier à ouvrir
-	 */
-	protected $file;
-	
-	/**
-	 * $filename est le nom du fichier
-	 */
-	protected $filename;
-	
-	/**
-	 * Ouvre un fichier dans $file
-	 * @param $nameFile nom du fichier à ouvrir
-	 * @param $mode mode d'ouverture du fichier ('a+' par défaut)
-	 * @exception FileNotExistException si le fichier n'existe pas
-	 *          > ou ne peux pas être ouvert
-	 */
-	public function __construct ($nameFile, $mode = 'a+') {
-		$this->filename = $nameFile;
-		if (!file_exists($this->filename)) {
-			throw new Minz_FileNotExistException (
-				$this->filename,
-				Minz_Exception::WARNING
-			);
-		}
-
-		$this->file = @fopen ($this->filename, $mode);
-		
-		if (!$this->file) {
-			throw new Minz_PermissionDeniedException (
-				$this->filename,
-				Minz_Exception::WARNING
-			);
-		}
-	}
-	
-	/**
-	 * Lit une ligne de $file
-	 * @return une ligne du fichier
-	 */
-	public function readLine () {
-		return fgets ($this->file);
-	}
-	
-	/**
-	 * Écrit une ligne dans $file
-	 * @param $line la ligne à écrire
-	 */
-	public function writeLine ($line, $newLine = true) {
-		$char = '';
-		if ($newLine) {
-			$char = "\n";
-		}
-		
-		fwrite ($this->file, $line . $char);
-	}
-	
-	/**
-	 * Efface le fichier $file
-	 * @return true en cas de succès, false sinon
-	 */
-	public function erase () {
-		return ftruncate ($this->file, 0);
-	}
-	
-	/**
-	 * Ferme $file
-	 */
-	public function __destruct () {
-		if (isset ($this->file)) {
-			fclose ($this->file);
-		}
-	}
-}