Overview

Namespaces

  • None
  • Wei
    • Validator

Classes

  • Wei\Validator\All
  • Wei\Validator\AllOf
  • Wei\Validator\Alnum
  • Wei\Validator\Alpha
  • Wei\Validator\BaseValidator
  • Wei\Validator\Between
  • Wei\Validator\Blank
  • Wei\Validator\Callback
  • Wei\Validator\CharLength
  • Wei\Validator\Chinese
  • Wei\Validator\Color
  • Wei\Validator\Contains
  • Wei\Validator\CreditCard
  • Wei\Validator\Date
  • Wei\Validator\DateTime
  • Wei\Validator\Decimal
  • Wei\Validator\Digit
  • Wei\Validator\Dir
  • Wei\Validator\DivisibleBy
  • Wei\Validator\DoubleByte
  • Wei\Validator\Email
  • Wei\Validator\EndsWith
  • Wei\Validator\EqualTo
  • Wei\Validator\Exists
  • Wei\Validator\FieldExists
  • Wei\Validator\File
  • Wei\Validator\GreaterThan
  • Wei\Validator\GreaterThanOrEqual
  • Wei\Validator\IdCardCn
  • Wei\Validator\IdCardHk
  • Wei\Validator\IdCardMo
  • Wei\Validator\IdCardTw
  • Wei\Validator\IdenticalTo
  • Wei\Validator\Image
  • Wei\Validator\In
  • Wei\Validator\Ip
  • Wei\Validator\Length
  • Wei\Validator\LessThan
  • Wei\Validator\LessThanOrEqual
  • Wei\Validator\Lowercase
  • Wei\Validator\Luhn
  • Wei\Validator\MaxLength
  • Wei\Validator\MinLength
  • Wei\Validator\MobileCn
  • Wei\Validator\NaturalNumber
  • Wei\Validator\NoneOf
  • Wei\Validator\Null
  • Wei\Validator\Number
  • Wei\Validator\OneOf
  • Wei\Validator\Password
  • Wei\Validator\Phone
  • Wei\Validator\PhoneCn
  • Wei\Validator\PlateNumberCn
  • Wei\Validator\PositiveInteger
  • Wei\Validator\PostcodeCn
  • Wei\Validator\Present
  • Wei\Validator\QQ
  • Wei\Validator\RecordExists
  • Wei\Validator\Regex
  • Wei\Validator\Required
  • Wei\Validator\SomeOf
  • Wei\Validator\StartsWith
  • Wei\Validator\Time
  • Wei\Validator\Tld
  • Wei\Validator\Type
  • Wei\Validator\Uppercase
  • Wei\Validator\Url
  • Wei\Validator\Uuid
  • Overview
  • Namespace
  • Function
  1: <?php
  2: /**
  3:  * Wei Framework
  4:  *
  5:  * @copyright   Copyright (c) 2008-2015 Twin Huang
  6:  * @license     http://opensource.org/licenses/mit-license.php MIT License
  7:  */
  8: 
  9: namespace Wei;
 10: 
 11: /**
 12:  * A logger service, which is inspired by Monolog
 13:  *
 14:  * @author      Twin Huang <twinhuang@qq.com>
 15:  * @link        https://github.com/Seldaek/monolog
 16:  */
 17: class Logger extends Base
 18: {
 19:     /**
 20:      * The name of channel
 21:      *
 22:      * @var string
 23:      */
 24:     protected $namespace = '';
 25: 
 26:     /**
 27:      * The default level for log record which level is not specified
 28:      *
 29:      * @var string
 30:      */
 31:     protected $level = 'debug';
 32: 
 33:     /**
 34:      * The lowest level to be handled
 35:      *
 36:      * @var string
 37:      */
 38:     protected $handledLevel = 'debug';
 39: 
 40:     /**
 41:      * The log levels and priorities
 42:      *
 43:      * @var array
 44:      */
 45:     protected $levels = array(
 46:         'debug'     => 100,
 47:         'info'      => 200,
 48:         'notice'    => 250,
 49:         'warning'   => 300,
 50:         'error'     => 400,
 51:         'critical'  => 500,
 52:         'alert'     => 550,
 53:         'emergency' => 600
 54:     );
 55: 
 56:     /**
 57:      * The format for log message
 58:      *
 59:      * @var string
 60:      */
 61:     protected $format = "[%datetime%] %level%: %message%\n";
 62: 
 63:     /**
 64:      * The date format for log message
 65:      *
 66:      * @var string
 67:      */
 68:     protected $dateFormat = 'H:i:s';
 69: 
 70:     /**
 71:      * The log file name, if specify this parameter, the "dir" and "fileFormat"
 72:      * parameters would be ignored
 73:      *
 74:      * @var null|string
 75:      */
 76:     protected $file = null;
 77: 
 78:     /**
 79:      * The directory to store log files
 80:      *
 81:      * @var string
 82:      */
 83:     protected $dir = 'log';
 84: 
 85:     /**
 86:      * The log file name, formatted by date
 87:      *
 88:      * @var string
 89:      */
 90:     protected $fileFormat = 'Ymd.\l\o\g';
 91: 
 92:     /**
 93:      * The max file size for log file, default to 128mb, set 0 to ignore this
 94:      * property
 95:      *
 96:      * @var int
 97:      */
 98:     protected $fileSize = 134217728;
 99: 
100:     /**
101:      * Whether log file's exact path has been detected, when set dir, fileFormat
102:      * or fileSize options, log file should be detected again
103:      *
104:      * @var bool
105:      */
106:     protected $fileDetected = false;
107: 
108:     /**
109:      * A key-value array that append to the log message
110:      *
111:      * @var array
112:      */
113:     protected $context = array();
114: 
115:     /**
116:      * The log file handle
117:      *
118:      * @var resource|null
119:      */
120:     private $handle;
121: 
122:     /**
123:      * Logs with an arbitrary level
124:      *
125:      * @param mixed $level
126:      * @param string $message
127:      * @param array $context
128:      * @return bool Whether the log record has been handled
129:      */
130:     public function log($level, $message, array $context = array())
131:     {
132:         $level = isset($this->levels[$level]) ? $level : $this->level;
133: 
134:         // Check if the level would be handled
135:         if (isset($this->levels[$level])) {
136:             if ($this->levels[$level] < $this->levels[$this->handledLevel]) {
137:                 return false;
138:             }
139:         }
140: 
141:         return $this->writeLog($level, $message, $context);
142:     }
143: 
144:     /**
145:      * Write the log message
146:      *
147:      * @param string $level
148:      * @param string $message
149:      * @param array $context
150:      * @return bool
151:      */
152:     protected function writeLog($level, $message, $context)
153:     {
154:         if (!$this->handle) {
155:             $this->handle = fopen($this->getFile(), 'a');
156:         }
157:         $content = $this->formatLog($level, $message, $context);
158:         return (bool)fwrite($this->handle, $content);
159:     }
160: 
161:     /**
162:      * Format the log message
163:      *
164:      * @param string $level
165:      * @param string $message
166:      * @param array $context
167:      * @return string
168:      */
169:     protected function formatLog($level, $message, array $context = array())
170:     {
171:         if ($message instanceof \Exception) {
172:             $context += array(
173:                 'code' => $message->getCode(),
174:                 'file' => $message->getFile(),
175:                 'line' => $message->getLine(),
176:                 'trace' => $message->getTraceAsString(),
177:             );
178:             $message = $message->getMessage();
179:         } elseif (is_array($message)) {
180:             $message = print_r($message, true);
181:         } else {
182:             $message = (string)$message;
183:         }
184: 
185:         // Format log message
186:         $content = str_replace(array(
187:             '%datetime%', '%namespace%', '%level%', '%message%',
188:         ), array(
189:             date($this->dateFormat, microtime(true)),
190:             $this->namespace,
191:             strtoupper($level),
192:             $message,
193:         ), $this->format);
194: 
195:         // Format extra context
196:         if ($this->context || $context) {
197:             $content .= print_r($this->context + $context, true) . "\n";
198:         }
199: 
200:         return $content;
201:     }
202: 
203:     /**
204:      * Logs with an arbitrary level
205:      *
206:      * @param mixed $level
207:      * @param string $message
208:      * @param array $context
209:      * @return bool
210:      */
211:     public function __invoke($level, $message, array $context = array())
212:     {
213:         return $this->log($level, $message, $context);
214:     }
215: 
216:     /**
217:      * System is unusable.
218:      *
219:      * @param string $message
220:      * @param array $context
221:      * @return bool
222:      */
223:     public function emergency($message, array $context = array())
224:     {
225:         return $this('emergency', $message, $context);
226:     }
227: 
228:     /**
229:      * Action must be taken immediately.
230:      *
231:      * Example: Entire website down, database unavailable, etc. This should
232:      * trigger the SMS alerts and wake you up.
233:      *
234:      * @param string $message
235:      * @param array $context
236:      * @return bool
237:      */
238:     public function alert($message, array $context = array())
239:     {
240:         return $this->log('alert', $message, $context);
241:     }
242: 
243:     /**
244:      * Critical conditions.
245:      *
246:      * Example: Application component unavailable, unexpected exception.
247:      *
248:      * @param string $message
249:      * @param array $context
250:      * @return bool
251:      */
252:     public function critical($message, array $context = array())
253:     {
254:         return $this->log('critical', $message, $context);
255:     }
256: 
257:     /**
258:      * Runtime errors that do not require immediate action but should typically
259:      * be logged and monitored.
260:      *
261:      * @param string $message
262:      * @param array $context
263:      * @return bool
264:      */
265:     public function error($message, array $context = array())
266:     {
267:         return $this->log('error', $message, $context);
268:     }
269: 
270:     /**
271:      * Exceptional occurrences that are not errors.
272:      *
273:      * Example: Use of deprecated APIs, poor use of an API, undesirable things
274:      * that are not necessarily wrong.
275:      *
276:      * @param string $message
277:      * @param array $context
278:      * @return bool
279:      */
280:     public function warning($message, array $context = array())
281:     {
282:         return $this->log('warning', $message, $context);
283:     }
284: 
285:     /**
286:      * Normal but significant events.
287:      *
288:      * @param string $message
289:      * @param array $context
290:      * @return bool
291:      */
292:     public function notice($message, array $context = array())
293:     {
294:         return $this->log('notice', $message, $context);
295:     }
296: 
297:     /**
298:      * Interesting events.
299:      *
300:      * Example: User logs in, SQL logs.
301:      *
302:      * @param string $message
303:      * @param array $context
304:      * @return bool
305:      */
306:     public function info($message, array $context = array())
307:     {
308:         return $this->log('info', $message, $context);
309:     }
310: 
311:     /**
312:      * Detailed debug information.
313:      *
314:      * @param string $message
315:      * @param array $context
316:      * @return bool
317:      */
318:     public function debug($message, array $context = array())
319:     {
320:         return $this->log('debug', $message, $context);
321:     }
322: 
323:     /**
324:      * Get log file
325:      *
326:      * @return string
327:      * @throws \RuntimeException When unable to create logging directory
328:      */
329:     public function getFile()
330:     {
331:         if ($this->fileDetected) {
332:             return $this->file;
333:         }
334: 
335:         $this->handle = null;
336:         $file = &$this->file;
337: 
338:         if (!is_dir($this->dir) && !@mkdir($this->dir, 0755, true)) {
339:             $message = sprintf('Fail to create directory "%s"', $this->dir);
340:             ($e = error_get_last()) && $message .= ': ' . $e['message'];
341:             throw new \RuntimeException($message);
342:         }
343: 
344:         $file = realpath($this->dir) . '/' . date($this->fileFormat);
345: 
346:         if ($this->fileSize) {
347:             $firstFile = $file;
348: 
349:             $files = glob($file . '*', GLOB_NOSORT);
350: 
351:             if (1 < count($files)) {
352:                 natsort($files);
353:                 $file = array_pop($files);
354:             }
355: 
356:             if (is_file($file) && $this->fileSize < filesize($file)) {
357:                 $ext = pathinfo($file, PATHINFO_EXTENSION);
358:                 if (is_numeric($ext)) {
359:                     $file = $firstFile . '.' . ($ext + 1);
360:                 } else {
361:                     $file = $firstFile . '.1';
362:                 }
363:             }
364:         }
365: 
366:         $this->fileDetected = true;
367: 
368:         return $file;
369:     }
370: 
371:     /**
372:      * Set default log level
373:      *
374:      * @param string $level
375:      * @return Logger
376:      */
377:     public function setLevel($level)
378:     {
379:         $this->level = $level;
380:         return $this;
381:     }
382: 
383:     /**
384:      * Set handled level
385:      *
386:      * @param int $handledLevel The handled level
387:      * @return Logger
388:      */
389:     public function setHandledLevel($handledLevel)
390:     {
391:         $this->handledLevel = $handledLevel;
392:         return $this;
393:     }
394: 
395:     /**
396:      * Add one or multi item for log message
397:      *
398:      * @param array|string $name
399:      * @param mixed $value
400:      * @return $this
401:      */
402:     public function setContext($name, $value = null)
403:     {
404:         if (is_array($name)) {
405:             $this->context = $name + $this->context;
406:         } else {
407:             $this->context[$name] = $value;
408:         }
409:         return $this;
410:     }
411: 
412:     /**
413:      * Clear up all log file
414:      *
415:      * @return Logger
416:      */
417:     public function clean()
418:     {
419:         // Make sure the handle is close
420:         $this->close();
421: 
422:         $dir = dirname($this->getFile());
423:         if (is_dir($dir)) {
424:             $files = scandir($dir);
425:             foreach ($files as $file) {
426:                 if ('.' != $file && '..' != $file) {
427:                     $file = $dir . DIRECTORY_SEPARATOR .  $file;
428:                     if (is_file($file)) {
429:                         unlink($file);
430:                     }
431:                 }
432:             }
433:         }
434:         return $this;
435:     }
436: 
437:     /**
438:      * Close the file handle and reset to null
439:      */
440:     protected function close()
441:     {
442:         if (is_resource($this->handle)) {
443:             fclose($this->handle);
444:         }
445:         $this->handle = null;
446:     }
447: 
448:     /**
449:      * Destructor
450:      */
451:     public function __destruct()
452:     {
453:         $this->close();
454:     }
455: }
456: 
Wei Framework API documentation generated by ApiGen