1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14: 
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40: 
 41: class cLog {
 42: 
 43:      44:  45: 
 46:     const EMERG   = 0;
 47: 
 48:      49:  50: 
 51:     const ALERT   = 1;
 52: 
 53:      54:  55: 
 56:     const CRIT    = 2;
 57: 
 58:      59:  60: 
 61:     const ERR     = 3;
 62: 
 63:      64:  65: 
 66:     const WARN    = 4;
 67: 
 68:      69:  70: 
 71:     const NOTICE  = 5;
 72: 
 73:      74:  75: 
 76:     const INFO    = 6;
 77: 
 78:      79:  80: 
 81:     const DEBUG   = 7;
 82: 
 83:      84:  85: 
 86:     protected $_writer;
 87: 
 88:      89:  90: 
 91:     protected $_shortcutHandlers = array();
 92: 
 93:      94:  95: 
 96:     protected $_priorities = array();
 97: 
 98:      99: 100: 
101:     protected $_defaultPriorities = array();
102: 
103:     104: 105: 
106:     protected $_buffer = array();
107: 
108:     109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 
123:     public function __construct($writer = false) {
124:         global $cfg;
125: 
126:         $createWriter = false;
127: 
128:         if ($writer == false) {
129:             $createWriter = true;
130:         } else if (!is_object($writer) || ($writer instanceof cLogWriter) == false) {
131:             cWarning(__FILE__, __LINE__, "The passed class is not a subclass of cLogWriter. Creating new one.");
132:             $createWriter = true;
133:         }
134: 
135:         if ($createWriter == true) {
136:             $options = array('destination' => $cfg['path']['contenido_logs'] . 'data/contenido.log');
137:             $writer = cLogWriter::factory("File", $options);
138:         }
139: 
140:         $this->setWriter($writer);
141:         $this->setShortcutHandler("%date", array($this, "shDate"));
142:         $this->setShortcutHandler("%level", array($this, "shLevel"));
143:         $this->setShortcutHandler("%message", array($this, "shMessage"));
144: 
145:         $this->getWriter()->setOption('log_format', '[%date] [%level] %message', false);
146: 
147:         $reflection = new ReflectionClass($this);
148:         $this->_priorities = $this->_defaultPriorities = array_flip($reflection->getConstants());
149:     }
150: 
151:     152: 153: 154: 
155:     public function getWriter() {
156:         return $this->_writer;
157:     }
158: 
159:     160: 161: 162: 163: 
164:     public function setWriter(cLogWriter $writer) {
165:         $this->_writer = $writer;
166:     }
167: 
168:     169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 
180:     public function setShortcutHandler($shortcut, $handler) {
181:         if ($shortcut == '') {
182:             throw new cInvalidArgumentException('The shortcut name must not be empty.');
183:         }
184: 
185:         if (substr($shortcut, 0, 1) == "%") {
186:             $shortcut = substr($shortcut, 1);
187:         }
188: 
189:         if (is_callable($handler) == false) {
190:             throw new cInvalidArgumentException('The specified shortcut handler does not exist.');
191:         }
192: 
193:         if (array_key_exists($shortcut, $this->_shortcutHandlers)) {
194:             throw new cInvalidArgumentException('The shortcut ' . $shortcut . ' is already in use!');
195:         }
196: 
197:         $this->_shortcutHandlers[$shortcut] = $handler;
198: 
199:         return true;
200:     }
201: 
202:     203: 204: 205: 206: 207: 208: 209: 
210:     public function unsetShortcutHandler($shortcut) {
211:         if (!in_array($shortcut, $this->_shortcutHandlers)) {
212:             throw new cInvalidArgumentException('The specified shortcut handler does not exist.');
213:         }
214: 
215:         unset($this->_shortcutHandlers[$shortcut]);
216:         return true;
217:     }
218: 
219:     220: 221: 222: 223: 224: 
225:     public function buffer($message, $priority = NULL) {
226:         $this->_buffer[] = array($message, $priority);
227:     }
228: 
229:     230: 231: 232: 233: 
234:     public function commit($revoke = true) {
235:         if (count($this->_buffer) == 0) {
236:             cWarning(__FILE__, __LINE__, "There are no buffered messages to commit.");
237:             return false;
238:         }
239: 
240:         foreach ($this->_buffer as $bufferInfo) {
241:             $this->log($bufferInfo[0], $bufferInfo[1]);
242:         }
243: 
244:         if ($revoke == true) {
245:             $this->revoke();
246:         }
247:     }
248: 
249:     250: 251: 
252:     public function revoke() {
253:         $this->_buffer = array();
254:     }
255: 
256:     257: 258: 259: 260: 261: 
262:     public function log($message, $priority = NULL) {
263:         if ($priority && is_int($priority) == false && in_array($priority, $this->_priorities)) {
264:             $priority = array_search($priority, $this->_priorities);
265:         }
266: 
267:         if ($priority === NULL || array_key_exists($priority, $this->_priorities) == false) {
268:             $priority = $this->getWriter()->getOption('default_priority');
269:         }
270: 
271:         $logMessage = $this->getWriter()->getOption('log_format');
272:         $lineEnding = $this->getWriter()->getOption('line_ending');
273: 
274:         foreach ($this->_shortcutHandlers as $shortcut => $handler) {
275:             if (substr($shortcut, 0, 1) != "%") {
276:                 $shortcut = "%" . $shortcut;
277:             }
278: 
279:             $info = array(
280:                 'message' => $message,
281:                 'priority' => $priority
282:             );
283: 
284:             $value = call_user_func($handler, $info);
285: 
286:             $logMessage = str_replace($shortcut, $value, $logMessage);
287:         }
288: 
289:         $this->getWriter()->write($logMessage . $lineEnding, $priority);
290:     }
291: 
292:     293: 294: 295: 296: 297: 298: 299: 
300:     public function addPriority($name, $value) {
301:         if ($name == '') {
302:             throw new cInvalidArgumentException('Priority name must not be empty.');
303:         }
304: 
305:         if (in_array($name, $this->_priorities)) {
306:             throw new cInvalidArgumentException('The given priority name already exists.');
307:         }
308: 
309:         if (array_key_exists($value, $this->_priorities)) {
310:             throw new cInvalidArgumentException('The priority value already exists.');
311:         }
312: 
313:         $this->_priorities[$value] = $name;
314:     }
315: 
316:     317: 318: 319: 320: 321: 322: 323: 
324:     public function removePriority($name) {
325:         if ($name == '') {
326:             throw new cInvalidArgumentException('Priority name must not be empty.');
327:         }
328: 
329:         if (in_array($name, $this->_priorities) == false) {
330:             throw new cInvalidArgumentException('Priority name does not exist.');
331:         }
332: 
333:         if (in_array($name, $this->_defaultPriorities) == true) {
334:             throw new cInvalidArgumentException('Removing default priorities is not allowed.');
335:         }
336: 
337:         $priorityIndex = array_search($name, $this->_priorities);
338: 
339:         unset($this->_priorities[$priorityIndex]);
340:     }
341: 
342:     343: 344: 345: 346: 347: 348: 
349:     public function __call($method, $arguments) {
350:         $priorityName = strtoupper($method);
351: 
352:         if (in_array($priorityName, $this->_priorities) == false) {
353:             throw new cInvalidArgumentException('The given priority ' . $priorityName . ' is not supported.');
354:         }
355: 
356:         $priorityIndex = array_search($priorityName, $this->_priorities);
357: 
358:         return $this->log($arguments[0], $priorityIndex);
359:     }
360: 
361:     362: 363: 364: 365: 
366:     public function shDate() {
367:         return date("Y-m-d H:i:s");
368:     }
369: 
370:     371: 372: 373: 374: 375: 
376:     public function shLevel($info) {
377:         $logLevel = $info['priority'];
378:         return str_pad($this->_priorities[$logLevel], 10, " ", STR_PAD_BOTH);
379:     }
380: 
381:     382: 383: 384: 385: 
386:     public function shMessage($info) {
387:         return $info['message'];
388:     }
389: }
390: 
391: ?>