PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/trasweb/common/helpers/Notice.class.php

https://bitbucket.org/trasweb/trasweb-framework
PHP | 283 lines | 173 code | 38 blank | 72 comment | 23 complexity | eefda624f531f688d41328d7879b1c01 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. New Licence bsd:
  4. Copyright (c) <2012>, Manuel Jesus Canga Muñoz
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without
  7. modification, are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright
  9. notice, this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright
  11. notice, this list of conditions and the following disclaimer in the
  12. documentation and/or other materials provided with the distribution.
  13. * Neither the name of the Trasweb.net nor the
  14. names of its contributors may be used to endorse or promote products
  15. derived from this software without specific prior written permission.
  16. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. DISCLAIMED. IN NO EVENT SHALL Manuel Jesus Canga Muñoz BE LIABLE FOR ANY
  20. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /** **************************************************************************************
  28. Sistema de notificaciones/Avisos/Alertas. Muy útil para devolver mensajes fácilmente al usuario
  29. de la web después de que este haya realizado alguna operación.
  30. Se basa en proceso, un proceso puede tener éxito o pudo tener un error crítico.
  31. A su vez, los pasos del proceso, pudieron tener avisos informátivos o avisos de errores(normales).
  32. También, pudo haber otro tipo de errores, ocasionados por el sistema(fallo de acceso a la bd, un archivo que no se encuentra, ...
  33. *************************************************************************************** */
  34. class Notice
  35. {
  36. /** Errores posibles en php. Si tiene asociado un 1 es que puede continuar a pesar del error. 0 es que no es posible continuar */
  37. static public $php_errors = array(
  38. E_ERROR => 0, E_WARNING => 0, E_PARSE => 0, E_NOTICE => 1, E_CORE_ERROR => 0,E_CORE_WARNING => 1, E_COMPILE_ERROR => 0,
  39. E_COMPILE_WARNING => 1, E_USER_ERROR => 0, E_USER_WARNING => 1, E_USER_NOTICE => 1, E_STRICT => 1, E_RECOVERABLE_ERROR => 0,
  40. E_DEPRECATED => 1, E_USER_DEPRECATED => 1
  41. );
  42. static public $php_errors_code = array(
  43. E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE", E_CORE_ERROR => "E_CORE_ERROR",
  44. E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING",
  45. E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT",
  46. E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_DEPRECATED => "E_DEPRECATED", E_USER_DEPRECATED => "E_USER_DEPRECATED"
  47. );
  48. /** Tipos de avisos: */
  49. const INFO = 1; //Información de lo que está ocurriendo(suele terminar en un SUCCESS ).
  50. const SUCCESS = 0; //El proceso entero, del módulo, ha tenido éxito
  51. const WARNING = 2; //Es un error que se da, en una de las operaciones del proceso.(warning)
  52. const ERROR = 3; //Error en el proceso, del módulo, que se esperaba realizar..
  53. const SYSTEM = 4; //Error producido de manera externa al framework(bbdd, clase, ...
  54. static private $types = array( self::SUCCESS => "SUCCESS", self::INFO => "INFO", self::WARNING => "WARNING", self::ERROR => "ERROR");
  55. /** indice de la cola de mensajes. */
  56. static private $index = 0;
  57. /** listado de avisos ( notices[$index][$tipo][] = msg */
  58. static public $notices = array();
  59. /** avisos del nivel superior que ya no existen */
  60. static public $last = array();
  61. /** Carga de comienzo de la clase */
  62. public static function load() { }
  63. /** Inicializador de la clase */
  64. public static function __initialize() {
  65. ini_set('display_errors', 0);
  66. // Report all PHP errors
  67. error_reporting(E_ALL );
  68. set_error_handler( array( '\Notice', 'errorEnviroment' ),E_ALL );
  69. register_shutdown_function(array( '\Notice', 'fatalError' ));
  70. if(!function_exists("Notice") ) {
  71. function Notice($_msg = NULL ) { Notice::send($_msg); }
  72. }
  73. self::$notices[0] = array( "SUCCESS" => NULL, "INFO" => array(), "WARNING" => array(), "ERROR" => NULL);
  74. }
  75. public static function type($_type) { return self::$types[$_type]; }
  76. /** Empezamos la captura de avisos, dentro del bloque. */
  77. public static function up() {
  78. self::$index++;
  79. self::$notices[self::$index] = array( "SUCCESS" => NULL, "INFO" => array(), "WARNING" => array(), "ERROR" => NULL);
  80. }
  81. /** Terminamos la captura de avisos, dentro del bloque en el que estamos */
  82. public static function down()
  83. {
  84. //Guardamos el listado de avisos del nivel actual.
  85. \State::setNotices(self::$notices[self::$index]);
  86. //Hacemos una copia del nivel antes de bajarlo
  87. self::$last = self::$notices[self::$index];
  88. //Borramos los avisos del nivel actual
  89. //ya que hemos hecho una copia
  90. unset(self::$notices[self::$index]);
  91. self::$index = ( ( self::$index -1 ) < 0 ) ? 0 : self::$index - 1; //Bajamos la cola
  92. }
  93. /**
  94. Mandamos un aviso a la cola, con un mensaje($_msg) y especificando el self::type($_type)
  95. @param @_msg es el mensage del aviso
  96. @param $_type el tipo de aviso ocurrido
  97. */
  98. public static function send($_msg = "", $_type = self::WARNING, $_code = NULL )
  99. {
  100. if(empty($_msg) ) return ;
  101. if($_type != self::SYSTEM ) {
  102. //Sino es un mensaje del sistema.
  103. $_name_type = self::type($_type);
  104. if( $_type == self::WARNING || $_type == self::INFO ) {
  105. if(is_array($_msg) ){
  106. //si es un array de mensajes lo mezclamos con los que hay
  107. self::$notices[self::$index][$_name_type] = array_merge(self::$notices[self::$index][$_name_type], $_msg);
  108. }else {
  109. self::$notices[self::$index][$_name_type][] = $_msg;
  110. }
  111. }else {//Se supone que si es exito o critico, sólo habrá un mensaje
  112. self::$notices[self::$index][$_name_type] = $_msg;
  113. }
  114. }else {
  115. \Debug::getFileLine($_file, $_line);
  116. //En caso de ser un error del sistema, lo tratamos directamente.
  117. self::errorSystem($_msg, $_code, $_file, $_line);
  118. }
  119. }
  120. public static function system($_msg, $_code = NULL) {
  121. \Debug::getFileLine($_file, $_line);
  122. self::errorSystem($_msg, $_code, $_file, $_line);
  123. return false;
  124. }
  125. public static function success($_msg) { self::send($_msg, self::SUCCESS); return true; }
  126. public static function info($_msg) { self::send($_msg, self::INFO); }
  127. public static function warning($_msg) { self::send($_msg, self::WARNING); }
  128. public static function error($_msg) { self::send($_msg, self::ERROR); return false; }
  129. public static function ok($_msg) { self::send($_msg, self::SUCCESS); return true; }
  130. public static function nok($_msg) { self::send($_msg, self::ERROR); return false; }
  131. /**
  132. Devuelve un listado con todos los Avisos del nivel actual o del nivel $_index
  133. @param $_index el nivel del que se quiere los vaisos.
  134. @param $_type por si queremos filtrar los avisos por un determinado tipo.
  135. */
  136. public static function get($_type = NULL, $_index = NULL)
  137. {
  138. if ($_index == NULL ) $_index = self::$index;
  139. if ($_type != NULL ) {
  140. $_name_type = self::type($_type);
  141. if(array_key_exists($_name_type,self::$notices[$_index]) ) {
  142. return self::$notices[$_index][$_name_type];
  143. } else {
  144. return array();
  145. }
  146. }else
  147. return self::$notices[$_index];
  148. }
  149. public static function getSuccess() { return self::get(self::SUCCESS); }
  150. public static function getInfos() { return self::get(self::INFO); }
  151. public static function getWarnings(){ return self::get(self::WARNING); }
  152. public static function getError() { return self::get(self::ERROR); }
  153. public static function getAll() { return self::all(); }
  154. public static function getLast() { return self::$last; }
  155. /** Devuelve todos los avisos, independientemente del nivel */
  156. public static function all() { return self::$notices; }
  157. /**
  158. Comprueba si hubo algun aviso del tipo especificado, en el nivel actual
  159. @param $_type es el tipo del que se quiere comprobar si hay o no, aviso.
  160. @return true|false, true si lo hubo, false sino.
  161. */
  162. public static function check($_type = self::ERROR )
  163. {
  164. $_type = self::type($_type);
  165. return array_key_exists($_type,self::$notices[self::$index]) && !empty(self::$notices[self::$index][$_type]);
  166. }
  167. public static function checkSuccess() { return self::check(self::SUCCESS); }
  168. public static function checkInfos() { return self::check(self::INFO); }
  169. public static function checkWarnings() { return self::check(self::WARNING); }
  170. public static function checkError() { return self::check(self::ERROR); }
  171. /** Se añade aquí la vista, porque puede que haya sido error a cargar la vista, y sería una tontería intentar cargar otra vista Daría un error recursivo
  172. @param $_error es el texto de error que se quiere presentar */
  173. public static function errorSystem($_msg, $_code, $_file = NULL, $_line = NULL)
  174. {
  175. if(null == $_file && null == $_line) {
  176. \Debug::getFileLine($_file, $_line);
  177. }
  178. //@error_log($_error, 0);
  179. $e = new System_Error($_msg, $_code);
  180. $e->setFile($_file);
  181. $e->setLine($_line);
  182. throw $e;
  183. }
  184. private static function showError($_errno, $_errstr, $_errfile, $_errline, $_context = array()) {
  185. $namespace = \State::getNamespace();
  186. $file = $_errfile;
  187. $line = $_errline;
  188. if(array_key_exists("_smarty_tpl", $_context) ) {
  189. $context = "| Smarty template ";
  190. $title = " Error in template";
  191. $file = PATH.$_context["_smarty_tpl"]->template_resource;
  192. $line = "..";
  193. $_errfile = $file;
  194. }else if(!empty($_context) ) {
  195. $context = "| context: ".print_r($_context, true);
  196. $title = " Error in System";
  197. }else {
  198. $context = "";
  199. $title = "";
  200. }
  201. Debug::info("[{$namespace}][".self::$php_errors_code[$_errno]."]: {$_errstr} . file {$_errfile} {$context} ", $title, $file, $line);
  202. }
  203. public static function errorEnviroment($_errno, $_errstr, $_errfile, $_errline, $_context = array()) {
  204. self::showError($_errno, $_errstr, $_errfile, $_errline, $_context);
  205. if(!self::$php_errors[$_errno] ) {
  206. //Es un error grave y necesita tratamiento.
  207. $SE = new System_Error($_errstr, '\\php\\', $_errno);
  208. $SE->setFile($_errfile);
  209. $SE->setLine($_errline);
  210. $SE->setNamespace(\State::getNamespace());
  211. throw $SE;
  212. }
  213. return true;
  214. }
  215. public static function fatalError() {
  216. $error = error_get_last();
  217. if (!empty($error) && array_key_exists("type", $error) && $error['type'] >= 0) {
  218. // fatal error
  219. self::showError($error['type'], $error['message'], $error['file'], $error['line']);
  220. $data = new Data($error);
  221. $data->state = \State::get();
  222. \Event("Critical", '\trasweb')->ocurred($data);
  223. }else {
  224. \State::down();
  225. }
  226. }
  227. public static function debug() {
  228. $backtrace = debug_backtrace();
  229. $file = $backtrace[0]["file"];
  230. $line = $backtrace[0]["line"];
  231. \Debug(self::$notices, "Notice Log", $file, $line);
  232. }
  233. }