|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00035 abstract class base_logger implements checksumable { 00036 00037 protected $level; // minimum level of logging this logger must handle (valid level from @backup class) 00038 protected $showdate; // flag to decide if the logger must output the date (true) or no (false) 00039 protected $showlevel; // flag to decide if the logger must output the level (true) or no (false) 00040 protected $next; // next logger in the chain 00041 00042 public function __construct($level, $showdate = false, $showlevel = false) { 00043 // TODO: check level is correct 00044 $this->level = $level; 00045 $this->showdate = $showdate; 00046 $this->showlevel = $showlevel; 00047 $this->next = null; 00048 } 00049 00050 public final function set_next($next) { 00051 // TODO: Check is a base logger 00052 00053 // TODO: Check next hasn't been set already 00054 00055 // TODO: Avoid circular dependencies 00056 if ($this->is_circular_reference($next)) { 00057 $a = new stdclass(); 00058 $a->alreadyinchain = get_class($this); 00059 $a->main = get_class($next); 00060 throw new base_logger_exception('logger_circular_reference', $a); 00061 } 00062 00063 $this->next = $next; 00064 } 00065 00066 public function get_next() { 00067 return $this->next; 00068 } 00069 00070 public function get_level() { 00071 return $this->level; 00072 } 00073 00074 // checksumable interface methods 00075 00076 public function calculate_checksum() { 00077 // Checksum is a simple md5 hash of classname, level and 00078 // on each specialised logger, its own atrributes 00079 // Not following the chain at all. 00080 return md5(get_class($this) . '-' . $this->level); 00081 } 00082 00083 public function is_checksum_correct($checksum) { 00084 return $this->calculate_checksum() === $checksum; 00085 } 00086 00087 // Protected API starts here 00088 00089 abstract protected function action($message, $level, $options = null); // To implement 00090 00091 public final function process($message, $level, $options = null) { 00092 $result = true; 00093 if ($this->level != backup::LOG_NONE && $this->level >= $level) { // Perform action conditionally 00094 $result = $this->action($message, $level, $options); 00095 } 00096 if ($result === false) { // Something was wrong, stop the chain 00097 return $result; 00098 } 00099 if ($this->next !== null) { // The chain continues being processed 00100 $result = $this->next->process($message, $level, $options); 00101 } 00102 return $result; 00103 } 00104 00105 protected function is_circular_reference($obj) { 00106 // Get object all nexts recursively and check if $this is already there 00107 $nexts = $obj->get_nexts(); 00108 if (array_key_exists($this->calculate_checksum(), $nexts) || $obj == $this) { 00109 return true; 00110 } 00111 return false; 00112 } 00113 00114 protected function get_nexts() { 00115 $nexts = array(); 00116 if ($this->next !== null) { 00117 $nexts[$this->next->calculate_checksum()] = $this->next->calculate_checksum(); 00118 $nexts = array_merge($nexts, $this->next->get_nexts()); 00119 } 00120 return $nexts; 00121 } 00122 00123 protected function get_datestr() { 00124 return userdate(time(), '%c'); 00125 } 00126 00127 protected function get_levelstr($level) { 00128 $result = 'undefined'; 00129 switch ($level) { 00130 case backup::LOG_ERROR: 00131 $result = 'error'; 00132 break; 00133 case backup::LOG_WARNING: 00134 $result = 'warn'; 00135 break; 00136 case backup::LOG_INFO: 00137 $result = 'info'; 00138 break; 00139 case backup::LOG_DEBUG: 00140 $result = 'debug'; 00141 break; 00142 } 00143 return $result; 00144 } 00145 00146 protected function get_prefix($level, $options) { 00147 $prefix = ''; 00148 if ($this->showdate) { 00149 $prefix .= '[' . $this->get_datestr() . '] '; 00150 } 00151 if ($this->showlevel) { 00152 $prefix .= '[' . $this->get_levelstr($level) . '] '; 00153 } 00154 return $prefix; 00155 } 00156 } 00157 00158 /* 00159 * Exception class used by all the @base_logger stuff 00160 */ 00161 class base_logger_exception extends backup_exception { 00162 00163 public function __construct($errorcode, $a=NULL, $debuginfo=null) { 00164 parent::__construct($errorcode, $a, $debuginfo); 00165 } 00166 }