summaryrefslogtreecommitdiff
path: root/lib/Minz
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2013-12-15 03:30:24 +0100
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2013-12-15 03:30:24 +0100
commit878e96202e8a22e4857b98e29b0a1fce68eccbc9 (patch)
treef9233c3b48a0cd6e0ac2536ddcc1897201595ad4 /lib/Minz
parent4af233e1f736eb2256e5e1696418635165467855 (diff)
Grosse refactorisation pour permettre le chargement automatique des classes
C'est parti de changements pour https://github.com/marienfressinaud/FreshRSS/issues/255 et finalement j'ai continué la refactorisation... Ajout de préfixes FreshRSS_ et Minz_ sur le modèle de SimplePie_. Toutes les classes sont maintenant en chargement automatique (devrait améliorer les performances en évitant de charger plein de classes inutilisées, et faciliter la maintenance). Suppression de set_include_path(). Si souhaité, certaines classes de Minz pourraient être déplacées dans un sous-répertoire, par exemple les exceptions. Tests et relecture nécessaires.
Diffstat (limited to 'lib/Minz')
-rw-r--r--lib/Minz/ActionException.php9
-rw-r--r--lib/Minz/BadConfigurationException.php9
-rw-r--r--lib/Minz/Cache.php116
-rw-r--r--lib/Minz/ControllerNotActionControllerException.php9
-rw-r--r--lib/Minz/ControllerNotExistException.php9
-rw-r--r--lib/Minz/CurrentPagePaginationException.php8
-rw-r--r--lib/Minz/Exception.php16
-rw-r--r--lib/Minz/FileNotExistException.php8
-rw-r--r--lib/Minz/Log.php94
-rw-r--r--lib/Minz/ModelArray.php122
-rw-r--r--lib/Minz/ModelPdo.php111
-rw-r--r--lib/Minz/ModelTxt.php84
-rw-r--r--lib/Minz/PDOConnectionException.php9
-rw-r--r--lib/Minz/PermissionDeniedException.php8
-rw-r--r--lib/Minz/RouteNotFoundException.php16
15 files changed, 628 insertions, 0 deletions
diff --git a/lib/Minz/ActionException.php b/lib/Minz/ActionException.php
new file mode 100644
index 000000000..c566a076f
--- /dev/null
+++ b/lib/Minz/ActionException.php
@@ -0,0 +1,9 @@
+<?php
+class Minz_ActionException extends Minz_Exception {
+ public function __construct ($controller_name, $action_name, $code = self::ERROR) {
+ $message = '`' . $action_name . '` cannot be invoked on `'
+ . $controller_name . '`';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/BadConfigurationException.php b/lib/Minz/BadConfigurationException.php
new file mode 100644
index 000000000..a7b77d687
--- /dev/null
+++ b/lib/Minz/BadConfigurationException.php
@@ -0,0 +1,9 @@
+<?php
+class Minz_BadConfigurationException extends Minz_Exception {
+ public function __construct ($part_missing, $code = self::ERROR) {
+ $message = '`' . $part_missing
+ . '` in the configuration file is missing or is misconfigured';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/Cache.php b/lib/Minz/Cache.php
new file mode 100644
index 000000000..fcb627eb2
--- /dev/null
+++ b/lib/Minz/Cache.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * MINZ - Copyright 2011 Marien Fressinaud
+ * Sous licence AGPL3 <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * La classe Cache permet de gérer facilement les pages en cache
+ */
+class Minz_Cache {
+ /**
+ * $expire timestamp auquel expire le cache de $url
+ */
+ private $expire = 0;
+
+ /**
+ * $file est le nom du fichier de cache
+ */
+ private $file = '';
+
+ /**
+ * $enabled permet de déterminer si le cache est activé
+ */
+ private static $enabled = true;
+
+ /**
+ * Constructeur
+ */
+ public function __construct () {
+ $this->_fileName ();
+ $this->_expire ();
+ }
+
+ /**
+ * Setteurs
+ */
+ public function _fileName () {
+ $file = md5 (Minz_Request::getURI ());
+
+ $this->file = CACHE_PATH . '/'.$file;
+ }
+
+ public function _expire () {
+ if ($this->exist ()) {
+ $this->expire = filemtime ($this->file)
+ + Minz_Configuration::delayCache ();
+ }
+ }
+
+ /**
+ * Permet de savoir si le cache est activé
+ * @return true si activé, false sinon
+ */
+ public static function isEnabled () {
+ return Minz_Configuration::cacheEnabled () && self::$enabled;
+ }
+
+ /**
+ * Active / désactive le cache
+ */
+ public static function switchOn () {
+ self::$enabled = true;
+ }
+ public static function switchOff () {
+ self::$enabled = false;
+ }
+
+ /**
+ * Détermine si le cache de $url a expiré ou non
+ * @return true si il a expiré, false sinon
+ */
+ public function expired () {
+ return time () > $this->expire;
+ }
+
+ /**
+ * Affiche le contenu du cache
+ * @print le code html du cache
+ */
+ public function render () {
+ if ($this->exist ()) {
+ include ($this->file);
+ }
+ }
+
+ /**
+ * Enregistre $html en cache
+ * @param $html le html à mettre en cache
+ */
+ public function cache ($html) {
+ file_put_contents ($this->file, $html);
+ }
+
+ /**
+ * Permet de savoir si le cache existe
+ * @return true si il existe, false sinon
+ */
+ public function exist () {
+ return file_exists ($this->file);
+ }
+
+ /**
+ * Nettoie le cache en supprimant tous les fichiers
+ */
+ public static function clean () {
+ $files = opendir (CACHE_PATH);
+
+ while ($fic = readdir ($files)) {
+ if ($fic != '.' && $fic != '..') {
+ unlink (CACHE_PATH.'/'.$fic);
+ }
+ }
+
+ closedir ($files);
+ }
+}
diff --git a/lib/Minz/ControllerNotActionControllerException.php b/lib/Minz/ControllerNotActionControllerException.php
new file mode 100644
index 000000000..535a1377e
--- /dev/null
+++ b/lib/Minz/ControllerNotActionControllerException.php
@@ -0,0 +1,9 @@
+<?php
+class Minz_ControllerNotActionControllerException extends Minz_Exception {
+ public function __construct ($controller_name, $code = self::ERROR) {
+ $message = 'Controller `' . $controller_name
+ . '` isn\'t instance of ActionController';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/ControllerNotExistException.php b/lib/Minz/ControllerNotExistException.php
new file mode 100644
index 000000000..523867d11
--- /dev/null
+++ b/lib/Minz/ControllerNotExistException.php
@@ -0,0 +1,9 @@
+<?php
+class Minz_ControllerNotExistException extends Minz_Exception {
+ public function __construct ($controller_name, $code = self::ERROR) {
+ $message = 'Controller `' . $controller_name
+ . '` doesn\'t exist';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/CurrentPagePaginationException.php b/lib/Minz/CurrentPagePaginationException.php
new file mode 100644
index 000000000..74214d879
--- /dev/null
+++ b/lib/Minz/CurrentPagePaginationException.php
@@ -0,0 +1,8 @@
+<?php
+class Minz_CurrentPagePaginationException extends Minz_Exception {
+ public function __construct ($page) {
+ $message = 'Page number `' . $page . '` doesn\'t exist';
+
+ parent::__construct ($message, self::ERROR);
+ }
+}
diff --git a/lib/Minz/Exception.php b/lib/Minz/Exception.php
new file mode 100644
index 000000000..b5e71e0d8
--- /dev/null
+++ b/lib/Minz/Exception.php
@@ -0,0 +1,16 @@
+<?php
+class Minz_Exception extends Exception {
+ const ERROR = 0;
+ const WARNING = 10;
+ const NOTICE = 20;
+
+ public function __construct ($message, $code = self::ERROR) {
+ if ($code != Minz_Exception::ERROR
+ && $code != Minz_Exception::WARNING
+ && $code != Minz_Exception::NOTICE) {
+ $code = Minz_Exception::ERROR;
+ }
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/FileNotExistException.php b/lib/Minz/FileNotExistException.php
new file mode 100644
index 000000000..df2b8ff6c
--- /dev/null
+++ b/lib/Minz/FileNotExistException.php
@@ -0,0 +1,8 @@
+<?php
+class Minz_FileNotExistException extends Minz_Exception {
+ public function __construct ($file_name, $code = self::ERROR) {
+ $message = 'File doesn\'t exist : `' . $file_name.'`';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/Log.php b/lib/Minz/Log.php
new file mode 100644
index 000000000..a9b657271
--- /dev/null
+++ b/lib/Minz/Log.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * MINZ - Copyright 2011 Marien Fressinaud
+ * Sous licence AGPL3 <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * La classe Log permet de logger des erreurs
+ */
+class Minz_Log {
+ /**
+ * Les différents niveau de log
+ * ERROR erreurs bloquantes de l'application
+ * WARNING erreurs pouvant géner le bon fonctionnement, mais non bloquantes
+ * NOTICE erreurs mineures ou messages d'informations
+ * DEBUG Informations affichées pour le déboggage
+ */
+ const ERROR = 2;
+ const WARNING = 4;
+ const NOTICE = 8;
+ const DEBUG = 16;
+
+ /**
+ * Enregistre un message dans un fichier de log spécifique
+ * Message non loggué si
+ * - environment = SILENT
+ * - level = WARNING et environment = PRODUCTION
+ * - level = NOTICE et environment = PRODUCTION
+ * @param $information message d'erreur / information à enregistrer
+ * @param $level niveau d'erreur
+ * @param $file_name fichier de log, par défaut LOG_PATH/application.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';
+ break;
+ case Minz_Log::WARNING :
+ $level_label = 'warning';
+ break;
+ case Minz_Log::NOTICE :
+ $level_label = 'notice';
+ break;
+ case Minz_Log::DEBUG :
+ $level_label = 'debug';
+ break;
+ 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
+ );
+ }
+ }
+ }
+
+ /**
+ * Automatise le log des variables globales $_GET et $_POST
+ * Fait appel à la fonction record(...)
+ * Ne fonctionne qu'en environnement "development"
+ * @param $file_name fichier de log, par défaut LOG_PATH/application.log
+ */
+ public static function recordRequest($file_name = null) {
+ $msg_get = str_replace("\n", '', '$_GET content : ' . print_r($_GET, true));
+ $msg_post = str_replace("\n", '', '$_POST content : ' . print_r($_POST, true));
+
+ self::record($msg_get, Minz_Log::DEBUG, $file_name);
+ self::record($msg_post, Minz_Log::DEBUG, $file_name);
+ }
+}
diff --git a/lib/Minz/ModelArray.php b/lib/Minz/ModelArray.php
new file mode 100644
index 000000000..4ba022143
--- /dev/null
+++ b/lib/Minz/ModelArray.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * MINZ - Copyright 2011 Marien Fressinaud
+ * Sous licence AGPL3 <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * 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 {
+ /**
+ * $array Le tableau php contenu dans le fichier $nameFile
+ */
+ protected $array = array ();
+
+ /**
+ * Ouvre le fichier indiqué, charge le tableau dans $array et le $nameFile
+ * @param $nameFile 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);
+ } else {
+ $this->array = include ($this->filename);
+ $this->releaseLock ();
+
+ if (!is_array ($this->array)) {
+ $this->array = array ();
+ }
+
+ $this->array = $this->decodeArray ($this->array);
+ }
+ }
+
+ /**
+ * Écrit un tableau dans le fichier $nameFile
+ * @param $array le tableau php à enregistrer
+ **/
+ 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) . '\',');
+ }
+ }
+ }
+
+ $this->writeLine ($tab . ')', false);
+ }
+
+ private function decodeArray ($array) {
+ $new_array = array ();
+
+ foreach ($array as $key => $value) {
+ if (is_array ($value)) {
+ $new_array[$key] = $this->decodeArray ($value);
+ } else {
+ $new_array[$key] = stripslashes ($value);
+ }
+ }
+
+ return $new_array;
+ }
+
+ private function getLock ($type) {
+ if ($type == 'write') {
+ $lock = LOCK_EX;
+ } else {
+ $lock = LOCK_SH;
+ }
+
+ $count = 1;
+ while (!flock ($this->file, $lock) && $count <= 50) {
+ $count++;
+ }
+
+ if ($count >= 50) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private function releaseLock () {
+ flock ($this->file, LOCK_UN);
+ }
+}
diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php
new file mode 100644
index 000000000..9655539b2
--- /dev/null
+++ b/lib/Minz/ModelPdo.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * MINZ - Copyright 2011 Marien Fressinaud
+ * Sous licence AGPL3 <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * La classe Model_sql représente le modèle interragissant avec les bases de données
+ * Seul la connexion MySQL est prise en charge pour le moment
+ */
+class Minz_ModelPdo {
+
+ /**
+ * Partage la connexion à la base de données entre toutes les instances.
+ */
+ public static $useSharedBd = true;
+ private static $sharedBd = null;
+ private static $sharedPrefix;
+
+ /**
+ * $bd variable représentant la base de données
+ */
+ protected $bd;
+
+ protected $prefix;
+
+ /**
+ * Créé la connexion à la base de données à l'aide des variables
+ * HOST, BASE, USER et PASS définies dans le fichier de configuration
+ */
+ public function __construct () {
+ if (self::$useSharedBd && self::$sharedBd != null) {
+ $this->bd = self::$sharedBd;
+ $this->prefix = self::$sharedPrefix;
+ return;
+ }
+
+ $db = Minz_Configuration::dataBase ();
+ $driver_options = null;
+
+ try {
+ $type = $db['type'];
+ if($type == 'mysql') {
+ $string = $type
+ . ':host=' . $db['host']
+ . ';dbname=' . $db['base']
+ . ';charset=utf8';
+ $driver_options = array(
+ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
+ );
+ } elseif($type == 'sqlite') {
+ $string = $type . ':/' . DATA_PATH . $db['base'] . '.sqlite'; //TODO: DEBUG UTF-8 http://www.siteduzero.com/forum/sujet/sqlite-connexion-utf-8-18797
+ }
+
+ $this->bd = new FreshPDO (
+ $string,
+ $db['user'],
+ $db['password'],
+ $driver_options
+ );
+ self::$sharedBd = $this->bd;
+
+ $userPrefix = Minz_Configuration::currentUser ();
+ $this->prefix = $db['prefix'] . (empty($userPrefix) ? '' : ($userPrefix . '_'));
+ self::$sharedPrefix = $this->prefix;
+ } catch (Exception $e) {
+ throw new Minz_PDOConnectionException (
+ $string,
+ $db['user'], Minz_Exception::ERROR
+ );
+ }
+ }
+
+ public function beginTransaction() {
+ $this->bd->beginTransaction();
+ }
+ public function commit() {
+ $this->bd->commit();
+ }
+ public function rollBack() {
+ $this->bd->rollBack();
+ }
+
+ public function size() {
+ $db = Minz_Configuration::dataBase ();
+ $sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema = ?';
+ $stm = $this->bd->prepare ($sql);
+ $values = array ($db['base']);
+ $stm->execute ($values);
+ $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+ return $res[0];
+ }
+}
+
+class FreshPDO extends PDO {
+ private static function check($statement) {
+ if (preg_match('/^(?:UPDATE|INSERT|DELETE)/i', $statement)) {
+ invalidateHttpCache();
+ }
+ }
+
+ public function prepare ($statement, $driver_options = array()) {
+ FreshPDO::check($statement);
+ return parent::prepare($statement, $driver_options);
+ }
+
+ public function exec ($statement) {
+ FreshPDO::check($statement);
+ return parent::exec($statement);
+ }
+}
diff --git a/lib/Minz/ModelTxt.php b/lib/Minz/ModelTxt.php
new file mode 100644
index 000000000..8c5973f4d
--- /dev/null
+++ b/lib/Minz/ModelTxt.php
@@ -0,0 +1,84 @@
+<?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);
+ }
+ }
+}
diff --git a/lib/Minz/PDOConnectionException.php b/lib/Minz/PDOConnectionException.php
new file mode 100644
index 000000000..faf2e0fe9
--- /dev/null
+++ b/lib/Minz/PDOConnectionException.php
@@ -0,0 +1,9 @@
+<?php
+class Minz_PDOConnectionException extends Minz_Exception {
+ public function __construct ($string_connection, $user, $code = self::ERROR) {
+ $message = 'Access to database is denied for `' . $user . '`'
+ . ' (`' . $string_connection . '`)';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/PermissionDeniedException.php b/lib/Minz/PermissionDeniedException.php
new file mode 100644
index 000000000..61be530d3
--- /dev/null
+++ b/lib/Minz/PermissionDeniedException.php
@@ -0,0 +1,8 @@
+<?php
+class Minz_PermissionDeniedException extends Minz_Exception {
+ public function __construct ($file_name, $code = self::ERROR) {
+ $message = 'Permission is denied for `' . $file_name.'`';
+
+ parent::__construct ($message, $code);
+ }
+}
diff --git a/lib/Minz/RouteNotFoundException.php b/lib/Minz/RouteNotFoundException.php
new file mode 100644
index 000000000..dc4f6fbad
--- /dev/null
+++ b/lib/Minz/RouteNotFoundException.php
@@ -0,0 +1,16 @@
+<?php
+class Minz_RouteNotFoundException extends Minz_Exception {
+ private $route;
+
+ public function __construct ($route, $code = self::ERROR) {
+ $this->route = $route;
+
+ $message = 'Route `' . $route . '` not found';
+
+ parent::__construct ($message, $code);
+ }
+
+ public function route () {
+ return $this->route;
+ }
+}