PHP Classes

File: docs/files/Stream/StreamLoggerTrait.php.txt

Recommend this page to a friend!
  Classes of Kiril Savchev   ITE Logger   docs/files/Stream/StreamLoggerTrait.php.txt   Download  
File: docs/files/Stream/StreamLoggerTrait.php.txt
Role: Documentation
Content type: text/plain
Description: Documentation
Class: ITE Logger
Log messages to different storage PSR-3 compliant
Author: By
Last change: Change stream logger and strategy loading and leave their init to the concrete stream class
Date: 7 years ago
Size: 7,487 bytes
 

Contents

Class file image Download
<?php /** * StreamLoggerTrait file * * Copyright (c) 2016, Kiril Savchev * All rights reserved. * * @category Libs * @package Logger * * @author Kiril Savchev <k.savchev@gmail.com> * * @license https://opensource.org/licenses/BSD-3-Clause BSD 3 License * @link http://ifthenelse.info */ namespace Ite\Logger\Stream; use Ite\Logger\AbstractDatabaseLogger; use Ite\Logger\AbstractEmailLogger; use Ite\Logger\Exception\InvalidArgumentException; use Ite\Logger\FileLogger as FLogger; use Ite\Logger\Stream\Strategy\FileLoggerStrategy; use Psr\Log\LoggerInterface; /** * Trait with common stream loggers functionalities * * @version 1.1 * * @author Kiril Savchev <k.savchev@gmail.com> */ trait StreamLoggerTrait { /** * The logger * * @var LoggerInterface */ protected $logger; /** * The log level * * @var string */ protected $level; /** * Map with pre-preparation strategies for logger classes * * @var array */ protected $loggerStrategies = [ FLogger::class => FileLoggerStrategy::class, AbstractEmailLogger::class => Strategy\AbstractEmailLoggerStrategy::class, AbstractDatabaseLogger::class => Strategy\AbstractDatabaseLoggerStrategy::class ]; /** * The method that is called when the stream is open * * This method will receive all parameters send to opening stream function, * e.g. fopen($path, $mode). If the mode includes reading modes (r, r+, w+, a+, x+) * it will trigger an error and will return false. If the searched logger * (the 'path' file of the $path var) type is not registered in $loggersMap * this method will trigger an error and will return false. * Otherwise will instanciate an object and will check for registered * strategy that will pre-prepare the object before its use for writing. * * @param string $path * @param string $mode * @param int $options * @param string $opened_path * @return boolean */ public function stream_open($path, $mode, $options, &$opened_path) { if ($path != 'w' && $path != 'a' && $path != 'x' && ($options & STREAM_REPORT_ERRORS)) { trigger_error("This wrapper is write-only"); return false; } return $this->openStream(parse_url($path), $options); } /** * The actual logger preparing * * This method checks whether the logger is instance of Psr\Log\LoggerInterface * and invokes its pre-prepare strategy if there is any registered * * @param array $url * @param int $options * @return boolean */ protected function openStream(array $url, $options) { if (!($this->logger instanceof LoggerInterface) && ($options & STREAM_REPORT_ERRORS)) { trigger_error("Invalid logger type"); return false; } if (empty($url['path'])) { if ($options & STREAM_REPORT_ERRORS) { trigger_error("Invalid log level"); } return false; } $this->level = substr($url['path'], 1); try { $this->prepareLoggerStrategy($url); } catch (InvalidArgumentException $e) { if ($options & STREAM_REPORT_ERRORS) { trigger_error($e->getMessage()); } return false; } return true; } /** * Instantiate and invoke the logger pre-prepare strategy * * If a strategy is registered for logger's class, parent classes or * its interfaces, it will be instantiated and its prepareLogger() * method will be invoked. * If no strategy is registered for the logger's class, BUT IS registered * for its parent classes and/or interfaces, ONLY the first one will be used. * The parend classes are prior the interfaces. * * @param array $url * @return void */ protected function prepareLoggerStrategy(array $url) { if (!empty($url['query'])) { $query = urldecode($url['query']); parse_str($query, $url['query']); } else { $url['query'] = []; } if (empty($this->strategy)) { $this->loadStrategy(); } if ($this->strategy instanceof Strategy\StreamLoggerStrategyInterface) { $this->strategy->prepareLogger($this->logger, $url); } } /** * Load strategy object based on $loggerStrategies * * @return null|void Null if there is no strategy. Otherwise is void */ protected function loadStrategy() { $class = get_class($this->logger); if (array_key_exists($class, $this->loggerStrategies)) { $strategyClass = $this->loggerStrategies[$class]; } else { $parents = class_parents($class); $interfaces = class_implements($class); $searched = array_merge($parents, $interfaces); $intersects = array_intersect(array_keys($this->loggerStrategies), $searched); if ($intersects) { $strategyClass = $this->loggerStrategies[array_shift($intersects)]; } else { return null; } } $this->strategy = new $strategyClass(); } /** * Writes the log * * Do the actual logging, it call the log() method of the logger. The * data can be string with the message, or serialized array with first * element - the message, and second element - the context of the log. * If there are more elements, they will be ignored * * @param string $data The log message - string or serialized array with message and context * @return int The $data string length */ public function stream_write($data) { $regex = '/^a\:\d+\:\{(.*)(\;\}\})$/i'; if (preg_match($regex, $data)) { $message = unserialize($data); if (count($message) == 1) { $message[1] = []; } else if (!is_array($message[1])) { $message[1] = [$message[1]]; } } else { $message = [$data, []]; } $this->logger->log($this->level, $message[0], $message[1]); return strlen($data); } }