PK APK8%
LICENSE.mdnu W+A Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Laminas Foundation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PK APF[ [ COPYRIGHT.mdnu W+A Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)
PK AP@ÅI I .travis.ymlnu W+A language: php
cache:
directories:
- $HOME/.composer/cache
env:
global:
- COMPOSER_ARGS="--no-interaction"
- COVERAGE_DEPS="php-coveralls/php-coveralls"
services:
- mongodb
matrix:
fast_finish: true
include:
- php: 5.6
env:
- DEPS=lowest
- php: 5.6
env:
- DEPS=latest
- php: 7
env:
- DEPS=lowest
- php: 7
env:
- DEPS=latest
- php: 7.1
env:
- DEPS=lowest
- php: 7.1
env:
- DEPS=latest
- CS_CHECK=true
- TEST_COVERAGE=true
- php: 7.2
env:
- DEPS=lowest
- php: 7.2
env:
- DEPS=latest
- php: 7.3
env:
- DEPS=lowest
- php: 7.3
env:
- DEPS=latest
before_install:
- if [[ $TEST_COVERAGE != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
- if [[ $TRAVIS_PHP_VERSION =~ ^5.6 ]]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini ; fi
install:
- travis_retry composer install $COMPOSER_ARGS --ignore-platform-reqs
- if [[ $LEGACY_DEPS != '' ]]; then travis_retry composer update $COMPOSER_ARGS --with-dependencies $LEGACY_DEPS ; fi
- if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi
- if [[ $DEPS == 'lowest' ]]; then travis_retry composer update --prefer-lowest --prefer-stable $COMPOSER_ARGS ; fi
- if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi
- stty cols 120 && composer show
script:
- if [[ $TEST_COVERAGE == 'true' ]]; then composer test-coverage ; else composer test ; fi
- if [[ $CS_CHECK == 'true' ]]; then composer cs-check ; fi
after_script:
- if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry php vendor/bin/php-coveralls -v ; fi
notifications:
email: false
PK APx= = .coveralls.ymlnu W+A coverage_clover: clover.xml
json_path: coveralls-upload.json
PK AP}CC phpcs.xmlnu W+A
src
test
PK APPT< < README.mdnu W+A # laminas-log
[![Build Status](https://travis-ci.com/laminas/laminas-log.svg?branch=master)](https://travis-ci.com/laminas/laminas-log)
[![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-log/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-log?branch=master)
`Laminas\Log` is a component for general purpose logging. It supports multiple log
backends, formatting messages sent to the log, and filtering messages from being
logged.
## Installation
Run the following to install this library:
```bash
$ composer require laminas/laminas-log
```
## Documentation
Browse the documentation online at https://docs.laminas.dev/laminas-log/
## Support
* [Issues](https://github.com/laminas/laminas-log/issues/)
* [Chat](https://laminas.dev/chat/)
* [Forum](https://discourse.laminas.dev/)
PK AP@ݫ
.gitignorenu W+A /clover.xml
/composer.lock
/coveralls-upload.json
/docs/html/
/laminas-mkdoc-theme.tgz
/laminas-mkdoc-theme/
/phpunit.xml
/vendor/
PK APL " src/FilterPluginManagerFactory.phpnu W+A has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have log_filters configuration, nothing more to do
if (! isset($config['log_filters']) || ! is_array($config['log_filters'])) {
return $pluginManager;
}
// Wire service configuration for log_filters
(new Config($config['log_filters']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return FilterPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this($container, $requestedName ?: FilterPluginManager::class, $this->creationOptions);
}
/**
* laminas-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
PK AP
" src/WriterPluginManagerFactory.phpnu W+A has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have log_writers configuration, nothing more to do
if (! isset($config['log_writers']) || ! is_array($config['log_writers'])) {
return $pluginManager;
}
// Wire service configuration for log_writers
(new Config($config['log_writers']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return WriterPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this($container, $requestedName ?: WriterPluginManager::class, $this->creationOptions);
}
/**
* laminas-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
PK APfq " src/Exception/RuntimeException.phpnu W+A format($this->getDateTimeFormat());
}
$output = $event['timestamp'] . ' ' . $event['priorityName'] . ' ('
. $event['priority'] . ') ' . $event['message'] .' in '
. $event['extra']['file'] . ' on line ' . $event['extra']['line'];
if (! empty($event['extra']['trace'])) {
$outputTrace = '';
foreach ($event['extra']['trace'] as $trace) {
$outputTrace .= "File : {$trace['file']}\n"
. "Line : {$trace['line']}\n"
. "Func : {$trace['function']}\n"
. "Class : {$trace['class']}\n"
. "Type : " . $this->getType($trace['type']) . "\n"
. "Args : " . print_r($trace['args'], true) . "\n";
}
$output .= "\n[Trace]\n" . $outputTrace;
}
return $output;
}
/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}
/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
/**
* Get the type of a function
*
* @param string $type
* @return string
*/
protected function getType($type)
{
switch ($type) {
case "::":
return "static";
case "->":
return "method";
default:
return $type;
}
}
}
PK APrv9 9 src/Formatter/ChromePhp.phpnu W+A dateTimeFormat = $dateTimeFormat;
}
}
/**
* Formats data to be written by the writer.
*
* @param array $event event data
* @return array
*/
public function format($event)
{
foreach ($event as $key => $value) {
// Keep extra as an array
if ('extra' === $key && is_array($value)) {
$event[$key] = self::format($value);
} else {
$event[$key] = $this->normalize($value);
}
}
return $event;
}
/**
* Normalize all non-scalar data types (except null) in a string value
*
* @param mixed $value
* @return mixed
*/
protected function normalize($value)
{
if (is_scalar($value) || null === $value) {
return $value;
}
// better readable JSON
static $jsonFlags;
if ($jsonFlags === null) {
$jsonFlags = 0;
$jsonFlags |= defined('JSON_UNESCAPED_SLASHES') ? JSON_UNESCAPED_SLASHES : 0;
$jsonFlags |= defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0;
}
// Error suppression is used in several of these cases as a fix for each of
// #5383 and #4616. Without it, #4616 fails whenever recursion occurs during
// json_encode() operations; usage of a dedicated error handler callback
// causes #5383 to fail when the Logger is being used as an error handler.
// The only viable solution here is error suppression, ugly as it may be.
if ($value instanceof DateTime) {
$value = $value->format($this->getDateTimeFormat());
} elseif ($value instanceof Traversable) {
$value = @json_encode(iterator_to_array($value), $jsonFlags);
} elseif (is_array($value)) {
$value = @json_encode($value, $jsonFlags);
} elseif (is_object($value) && ! method_exists($value, '__toString')) {
$value = sprintf('object(%s) %s', get_class($value), @json_encode($value));
} elseif (is_resource($value)) {
$value = sprintf('resource(%s)', get_resource_type($value));
} elseif (! is_object($value)) {
$value = gettype($value);
}
return (string) $value;
}
/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}
/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
}
PK AP<L L src/Formatter/FirePhp.phpnu W+A format = isset($format) ? $format : static::DEFAULT_FORMAT;
parent::__construct($dateTimeFormat);
}
/**
* Formats data into a single line to be written by the writer.
*
* @param array $event event data
* @return string formatted line to write to the log
*/
public function format($event)
{
$output = $this->format;
$event = parent::format($event);
foreach ($event as $name => $value) {
if ('extra' == $name && count($value)) {
$value = $this->normalize($value);
} elseif ('extra' == $name) {
// Don't print an empty array
$value = '';
}
$output = str_replace("%$name%", $value, $output);
}
if (isset($event['extra']) && empty($event['extra'])
&& false !== strpos($this->format, '%extra%')
) {
$output = rtrim($output, ' ');
}
return $output;
}
}
PK AP-c4: / src/Formatter/LogFormatterProviderInterface.phpnu W+A array_shift($args)
];
if (! empty($args)) {
$options['elementMap'] = array_shift($args);
}
if (! empty($args)) {
$options['encoding'] = array_shift($args);
}
if (! empty($args)) {
$options['dateTimeFormat'] = array_shift($args);
}
}
if (! array_key_exists('rootElement', $options)) {
$options['rootElement'] = 'logEntry';
}
if (! array_key_exists('encoding', $options)) {
$options['encoding'] = 'UTF-8';
}
$this->rootElement = $options['rootElement'];
$this->setEncoding($options['encoding']);
if (array_key_exists('elementMap', $options)) {
$this->elementMap = $options['elementMap'];
}
if (array_key_exists('dateTimeFormat', $options)) {
$this->setDateTimeFormat($options['dateTimeFormat']);
}
}
/**
* Get encoding
*
* @return string
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* Set encoding
*
* @param string $value
* @return Xml
*/
public function setEncoding($value)
{
$this->encoding = (string) $value;
return $this;
}
/**
* Set Escaper instance
*
* @param Escaper $escaper
* @return Xml
*/
public function setEscaper(Escaper $escaper)
{
$this->escaper = $escaper;
return $this;
}
/**
* Get Escaper instance
*
* Lazy-loads an instance with the current encoding if none registered.
*
* @return Escaper
*/
public function getEscaper()
{
if (null === $this->escaper) {
$this->setEscaper(new Escaper($this->getEncoding()));
}
return $this->escaper;
}
/**
* Formats data into a single line to be written by the writer.
*
* @param array $event event data
* @return string formatted line to write to the log
*/
public function format($event)
{
if (isset($event['timestamp']) && $event['timestamp'] instanceof DateTime) {
$event['timestamp'] = $event['timestamp']->format($this->getDateTimeFormat());
}
$dataToInsert = $event;
if (null !== $this->elementMap) {
$dataToInsert = [];
foreach ($this->elementMap as $elementName => $fieldKey) {
$dataToInsert[$elementName] = $event[$fieldKey];
}
}
$enc = $this->getEncoding();
$escaper = $this->getEscaper();
$dom = new DOMDocument('1.0', $enc);
$elt = $dom->appendChild(new DOMElement($this->rootElement));
foreach ($dataToInsert as $key => $value) {
if (empty($value)
|| is_scalar($value)
|| ((is_array($value) || $value instanceof Traversable) && $key == "extra")
|| (is_object($value) && method_exists($value, '__toString'))
) {
if ($key == "message") {
$value = $escaper->escapeHtml($value);
}
if ($key == "extra" && empty($value)) {
continue;
}
if ($key == "extra" && (is_array($value) || $value instanceof Traversable)) {
$elt->appendChild($this->buildElementTree($dom, $dom->createElement('extra'), $value));
continue;
}
$elt->appendChild(new DOMElement($key, (string) $value));
}
}
return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $dom->saveXML()) . PHP_EOL;
}
/**
* Recursion function to create an xml tree structure out of array structure
* @param DomDocument $doc - DomDocument where the current nodes will be generated
* @param DomElement $rootElement - root element the tree will be attached to
* @param $mixedData array|Traversable - mixedData
* @return DomElement $domElement - DOM Element with appended child nodes
*/
protected function buildElementTree(DOMDocument $doc, DOMElement $rootElement, $mixedData)
{
if (! (is_array($mixedData) || $mixedData instanceof Traversable)) {
return $rootElement;
}
foreach ($mixedData as $key => $value) {
// key is numeric and switch is not possible, numeric values are not valid node names
if ((empty($value) || is_numeric($value)) && is_numeric($key)) {
continue;
}
if ($value instanceof Traversable || is_array($value)) {
// current value is an array, start recursion
$rootElement->appendChild($this->buildElementTree($doc, $doc->createElement($key), $value));
continue;
}
if (is_object($value) && ! method_exists($value, '__toString')) {
// object does not support __toString() method, manually convert the value
$value = $this->getEscaper()->escapeHtml(
'"Object" of type ' . get_class($value) . " does not support __toString() method"
);
} else {
$value = $this->getEscaper()->escapeHtml($value);
}
if (is_numeric($key)) {
// xml does not allow numeric values, try to switch the value and the key
$key = (string) $value;
$value = null;
}
try {
$rootElement->appendChild(new DOMElement($key, empty($value) ? null : (string) $value));
} catch (\DOMException $e) {
// the input name is not valid, go one.
continue;
}
}
return $rootElement;
}
/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}
/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
}
PK APo|0 src/Formatter/Db.phpnu W+A setDateTimeFormat($dateTimeFormat);
}
}
/**
* Formats data to be written by the writer.
*
* @param array $event event data
* @return array
*/
public function format($event)
{
$format = $this->getDateTimeFormat();
array_walk_recursive($event, function (&$value) use ($format) {
if ($value instanceof DateTime) {
$value = $value->format($format);
}
});
return $event;
}
/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}
/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string) $dateTimeFormat;
return $this;
}
}
PK AP K src/Formatter/Json.phpnu W+A format($this->getDateTimeFormat());
}
return @json_encode(
$event,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION
);
}
/**
* {@inheritDoc}
*/
public function getDateTimeFormat()
{
return $this->dateTimeFormat;
}
/**
* {@inheritDoc}
*/
public function setDateTimeFormat($dateTimeFormat)
{
$this->dateTimeFormat = (string)$dateTimeFormat;
return $this;
}
}
PK AP, $ src/Formatter/FormatterInterface.phpnu W+A format;
if (isset($event['timestamp']) && $event['timestamp'] instanceof DateTime) {
$event['timestamp'] = $event['timestamp']->format($this->getDateTimeFormat());
}
foreach ($this->buildReplacementsFromArray($event) as $name => $value) {
$output = str_replace("%$name%", $value, $output);
}
return $output;
}
/**
* Flatten the multi-dimensional $event array into a single dimensional
* array
*
* @param array $event
* @param string $key
* @return array
*/
protected function buildReplacementsFromArray($event, $key = null)
{
$result = [];
foreach ($event as $index => $value) {
$nextIndex = $key === null ? $index : $key . '[' . $index . ']';
if ($value === null) {
continue;
}
if (! is_array($value)) {
if ($key === null) {
$result[$nextIndex] = $value;
} else {
if (! is_object($value) || method_exists($value, "__toString")) {
$result[$nextIndex] = $value;
}
}
} else {
$result = array_merge($result, $this->buildReplacementsFromArray($value, $nextIndex));
}
}
return $result;
}
}
PK AP src/PsrLoggerAdapter.phpnu W+A Logger::EMERG,
LogLevel::ALERT => Logger::ALERT,
LogLevel::CRITICAL => Logger::CRIT,
LogLevel::ERROR => Logger::ERR,
LogLevel::WARNING => Logger::WARN,
LogLevel::NOTICE => Logger::NOTICE,
LogLevel::INFO => Logger::INFO,
LogLevel::DEBUG => Logger::DEBUG,
];
/**
* Constructor
*
* @param LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Returns composed LoggerInterface instance.
*
* @return LoggerInterface
*/
public function getLogger()
{
return $this->logger;
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
* @throws InvalidArgumentException if log level is not recognized
*/
public function log($level, $message, array $context = [])
{
if (! array_key_exists($level, $this->psrPriorityMap)) {
throw new InvalidArgumentException(sprintf(
'$level must be one of PSR-3 log levels; received %s',
var_export($level, 1)
));
}
$priority = $this->psrPriorityMap[$level];
$this->logger->log($priority, $message, $context);
}
}
PK APA A src/LoggerServiceFactory.phpnu W+A get('config');
$logConfig = isset($config['log']) ? $config['log'] : [];
return new Logger($logConfig);
}
/**
* Factory for laminas-servicemanager v2.
*
* Proxies to `__invoke()`.
*
* @param ServiceLocatorInterface $serviceLocator
* @return Logger
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
return $this($serviceLocator, Logger::class);
}
}
PK APZyo o src/WriterPluginManager.phpnu W+A Writer\ChromePhp::class,
'db' => Writer\Db::class,
'fingerscrossed' => Writer\FingersCrossed::class,
'firephp' => Writer\FirePhp::class,
'mail' => Writer\Mail::class,
'mock' => Writer\Mock::class,
'mongo' => Writer\Mongo::class,
'mongodb' => Writer\MongoDB::class,
'noop' => Writer\Noop::class,
'psr' => Writer\Psr::class,
'stream' => Writer\Stream::class,
'syslog' => Writer\Syslog::class,
'zendmonitor' => Writer\ZendMonitor::class,
// The following are for backwards compatibility only; users
// should update their code to use the noop writer instead.
'null' => Writer\Noop::class,
Writer\Null::class => Writer\Noop::class,
'laminaslogwriternull' => Writer\Noop::class,
// Legacy Zend Framework aliases
\Zend\Log\Writer\ChromePhp::class => Writer\ChromePhp::class,
\Zend\Log\Writer\Db::class => Writer\Db::class,
\Zend\Log\Writer\FirePhp::class => Writer\FirePhp::class,
\Zend\Log\Writer\Mail::class => Writer\Mail::class,
\Zend\Log\Writer\Mock::class => Writer\Mock::class,
\Zend\Log\Writer\Mongo::class => Writer\Mongo::class,
\Zend\Log\Writer\MongoDB::class => Writer\MongoDB::class,
\Zend\Log\Writer\Noop::class => Writer\Noop::class,
\Zend\Log\Writer\Psr::class => Writer\Psr::class,
\Zend\Log\Writer\Stream::class => Writer\Stream::class,
\Zend\Log\Writer\Syslog::class => Writer\Syslog::class,
\Zend\Log\Writer\FingersCrossed::class => Writer\FingersCrossed::class,
\Zend\Log\Writer\ZendMonitor::class => Writer\ZendMonitor::class,
\Zend\Log\Writer\Null::class => Writer\Noop::class,
'zendlogwriternull' => Writer\Noop::class,
// v2 normalized FQCNs
'zendlogwriterchromephp' => Writer\ChromePhp::class,
'zendlogwriterdb' => Writer\Db::class,
'zendlogwriterfirephp' => Writer\FirePhp::class,
'zendlogwritermail' => Writer\Mail::class,
'zendlogwritermock' => Writer\Mock::class,
'zendlogwritermongo' => Writer\Mongo::class,
'zendlogwritermongodb' => Writer\MongoDB::class,
'zendlogwriternoop' => Writer\Noop::class,
'zendlogwriterpsr' => Writer\Psr::class,
'zendlogwriterstream' => Writer\Stream::class,
'zendlogwritersyslog' => Writer\Syslog::class,
'zendlogwriterfingerscrossed' => Writer\FingersCrossed::class,
'zendlogwriterzendmonitor' => Writer\ZendMonitor::class,
];
protected $factories = [
Writer\ChromePhp::class => WriterFactory::class,
Writer\Db::class => WriterFactory::class,
Writer\FirePhp::class => WriterFactory::class,
Writer\Mail::class => WriterFactory::class,
Writer\Mock::class => WriterFactory::class,
Writer\Mongo::class => WriterFactory::class,
Writer\MongoDB::class => WriterFactory::class,
Writer\Noop::class => WriterFactory::class,
Writer\Psr::class => WriterFactory::class,
Writer\Stream::class => WriterFactory::class,
Writer\Syslog::class => WriterFactory::class,
Writer\FingersCrossed::class => WriterFactory::class,
Writer\ZendMonitor::class => WriterFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'laminaslogwriterchromephp' => WriterFactory::class,
'laminaslogwriterdb' => WriterFactory::class,
'laminaslogwriterfirephp' => WriterFactory::class,
'laminaslogwritermail' => WriterFactory::class,
'laminaslogwritermock' => WriterFactory::class,
'laminaslogwritermongo' => WriterFactory::class,
'laminaslogwritermongodb' => WriterFactory::class,
'laminaslogwriternoop' => WriterFactory::class,
'laminaslogwriterpsr' => WriterFactory::class,
'laminaslogwriterstream' => WriterFactory::class,
'laminaslogwritersyslog' => WriterFactory::class,
'laminaslogwriterfingerscrossed' => WriterFactory::class,
'laminaslogwriterzendmonitor' => WriterFactory::class,
];
protected $instanceOf = Writer\WriterInterface::class;
/**
* Allow many writers of the same type (v2)
* @param bool
*/
protected $shareByDefault = false;
/**
* Allow many writers of the same type (v3)
* @param bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $plugin
* @throws InvalidServiceException
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Writer\WriterInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
}
}
PK AP̂ߟ % src/ProcessorPluginManagerFactory.phpnu W+A has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have log_processors configuration, nothing more to do
if (! isset($config['log_processors']) || ! is_array($config['log_processors'])) {
return $pluginManager;
}
// Wire service configuration for log_processors
(new Config($config['log_processors']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return ProcessorPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this($container, $requestedName ?: ProcessorPluginManager::class, $this->creationOptions);
}
/**
* laminas-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
PK APWo src/Filter/FilterInterface.phpnu W+A events[] = $event;
return true;
}
}
PK APEH src/Filter/Validator.phpnu W+A validator = $validator;
}
/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool
*/
public function filter(array $event)
{
return $this->validator->isValid($event['message']);
}
}
PK AP#- ) src/Filter/LogFilterProviderInterface.phpnu W+A regex = $regex;
}
/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool accepted?
*/
public function filter(array $event)
{
$message = $event['message'];
if (is_array($event['message'])) {
$message = var_export($message, true);
}
return preg_match($this->regex, $message) > 0;
}
}
PK AP4} src/Filter/Timestamp.phpnu W+A
*/
class Timestamp implements FilterInterface
{
/**
* DateTime instance or desired value based on $dateFormatChar.
*
* @var int|DateTime
*/
protected $value;
/**
* PHP idate()-compliant format character.
*
* @var string|null
*/
protected $dateFormatChar;
/**
* @var string
*/
protected $operator;
/**
* @param int|DateTime|array|Traversable $value DateTime instance or desired value based on $dateFormatChar
* @param string $dateFormatChar PHP idate()-compliant format character
* @param string $operator Comparison operator
* @return Timestamp
* @throws Exception\InvalidArgumentException
*/
public function __construct($value, $dateFormatChar = null, $operator = '<=')
{
if ($value instanceof Traversable) {
$value = ArrayUtils::iteratorToArray($value);
}
if (is_array($value)) {
$dateFormatChar = isset($value['dateFormatChar']) ? $value['dateFormatChar'] : null;
$operator = isset($value['operator']) ? $value['operator'] : null;
$value = isset($value['value']) ? $value['value'] : null;
}
if ($value instanceof DateTime) {
$this->value = $value;
} else {
if (! is_int($value)) {
throw new Exception\InvalidArgumentException(sprintf(
'Value must be either DateTime instance or integer; received "%s"',
gettype($value)
));
}
if (! is_string($dateFormatChar)) {
throw new Exception\InvalidArgumentException(sprintf(
'Date format character must be supplied as string; received "%s"',
gettype($dateFormatChar)
));
}
$this->value = $value;
$this->dateFormatChar = $dateFormatChar;
}
if ($operator === null) {
$operator = '<=';
} elseif (! in_array(
$operator,
['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>']
)) {
throw new Exception\InvalidArgumentException(
"Unsupported comparison operator: '$operator'"
);
}
$this->operator = $operator;
}
/**
* Returns TRUE if timestamp is accepted, otherwise FALSE is returned.
*
* @param array $event event data
* @return bool
*/
public function filter(array $event)
{
if (! isset($event['timestamp'])) {
return false;
}
$datetime = $event['timestamp'];
if (! ($datetime instanceof DateTime || is_int($datetime) || is_string($datetime))) {
return false;
}
$timestamp = $datetime instanceof DateTime ? $datetime->getTimestamp() : (int) $datetime;
if ($this->value instanceof DateTime) {
return version_compare($timestamp, $this->value->getTimestamp(), $this->operator);
}
return version_compare(
idate($this->dateFormatChar, $timestamp),
$this->value,
$this->operator
);
}
}
PK AP ǻ src/Filter/Sample.phpnu W+A sampleRate = (float) $sampleRate;
}
/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool Accepted ?
*/
public function filter(array $event)
{
return (mt_rand() / mt_getrandmax()) <= $this->sampleRate;
}
}
PK AP src/Filter/SuppressFilter.phpnu W+A suppress($suppress);
}
/**
* This is a simple boolean filter.
*
* Call suppress(true) to suppress all log events.
* Call suppress(false) to accept all log events.
*
* @param bool $suppress Should all log events be suppressed?
* @return void
*/
public function suppress($suppress)
{
$this->accept = ! (bool) $suppress;
}
/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool accepted?
*/
public function filter(array $event)
{
return $this->accept;
}
}
PK AP]z z src/Filter/Priority.phpnu W+A priority = (int) $priority;
$this->operator = $operator === null ? '<=' : $operator;
}
/**
* Returns TRUE to accept the message, FALSE to block it.
*
* @param array $event event data
* @return bool accepted?
*/
public function filter(array $event)
{
return version_compare($event['priority'], $this->priority, $this->operator);
}
}
PK APl % src/FormatterPluginManagerFactory.phpnu W+A has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have log_formatters configuration, nothing more to do
if (! isset($config['log_formatters']) || ! is_array($config['log_formatters'])) {
return $pluginManager;
}
// Wire service configuration for log_formatters
(new Config($config['log_formatters']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return FormatterPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this($container, $requestedName ?: FormatterPluginManager::class, $this->creationOptions);
}
/**
* laminas-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
PK APϥ} src/FilterPluginManager.phpnu W+A Filter\Mock::class,
'priority' => Filter\Priority::class,
'regex' => Filter\Regex::class,
'suppress' => Filter\SuppressFilter::class,
'suppressfilter' => Filter\SuppressFilter::class,
'validator' => Filter\Validator::class,
// Legacy Zend Framework aliases
\Zend\Log\Filter\Mock::class => Filter\Mock::class,
\Zend\Log\Filter\Priority::class => Filter\Priority::class,
\Zend\Log\Filter\Regex::class => Filter\Regex::class,
\Zend\Log\Filter\SuppressFilter::class => Filter\SuppressFilter::class,
\Zend\Log\Filter\Validator::class => Filter\Validator::class,
// v2 normalized FQCNs
'zendlogfiltermock' => Filter\Mock::class,
'zendlogfilterpriority' => Filter\Priority::class,
'zendlogfilterregex' => Filter\Regex::class,
'zendlogfiltersuppressfilter' => Filter\SuppressFilter::class,
'zendlogfiltervalidator' => Filter\Validator::class,
];
protected $factories = [
Filter\Mock::class => InvokableFactory::class,
Filter\Priority::class => InvokableFactory::class,
Filter\Regex::class => InvokableFactory::class,
Filter\SuppressFilter::class => InvokableFactory::class,
Filter\Validator::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'laminaslogfiltermock' => InvokableFactory::class,
'laminaslogfilterpriority' => InvokableFactory::class,
'laminaslogfilterregex' => InvokableFactory::class,
'laminaslogfiltersuppressfilter' => InvokableFactory::class,
'laminaslogfiltervalidator' => InvokableFactory::class,
];
protected $instanceOf = Filter\FilterInterface::class;
/**
* Allow many filters of the same type (v2)
* @param bool
*/
protected $shareByDefault = false;
/**
* Allow many filters of the same type (v3)
* @param bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $plugin
* @throws InvalidServiceException
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Filter\FilterInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
}
}
PK AP> > src/ProcessorPluginManager.phpnu W+A Processor\Backtrace::class,
'psrplaceholder' => Processor\PsrPlaceholder::class,
'referenceid' => Processor\ReferenceId::class,
'requestid' => Processor\RequestId::class,
// Legacy Zend Framework aliases
\Zend\Log\Processor\Backtrace::class => Processor\Backtrace::class,
\Zend\Log\Processor\PsrPlaceholder::class => Processor\PsrPlaceholder::class,
\Zend\Log\Processor\ReferenceId::class => Processor\ReferenceId::class,
\Zend\Log\Processor\RequestId::class => Processor\RequestId::class,
// v2 normalized FQCNs
'zendlogprocessorbacktrace' => Processor\Backtrace::class,
'zendlogprocessorpsrplaceholder' => Processor\PsrPlaceholder::class,
'zendlogprocessorreferenceid' => Processor\ReferenceId::class,
'zendlogprocessorrequestid' => Processor\RequestId::class,
];
protected $factories = [
Processor\Backtrace::class => InvokableFactory::class,
Processor\PsrPlaceholder::class => InvokableFactory::class,
Processor\ReferenceId::class => InvokableFactory::class,
Processor\RequestId::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'laminaslogprocessorbacktrace' => InvokableFactory::class,
'laminaslogprocessorpsrplaceholder' => InvokableFactory::class,
'laminaslogprocessorreferenceid' => InvokableFactory::class,
'laminaslogprocessorrequestid' => InvokableFactory::class,
];
protected $instanceOf = Processor\ProcessorInterface::class;
/**
* Allow many processors of the same type (v2)
* @param bool
*/
protected $shareByDefault = false;
/**
* Allow many processors of the same type (v3)
* @param bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $plugin
* @throws InvalidServiceException
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Processor\ProcessorInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
}
}
PK APF $ src/LoggerAbstractServiceFactory.phpnu W+A getConfig($container);
if (empty($config)) {
return false;
}
return isset($config[$requestedName]);
}
/**
* {@inheritdoc}
*/
public function canCreateServiceWithName(ServiceLocatorInterface $container, $name, $requestedName)
{
return $this->canCreate($container, $requestedName);
}
/**
* {@inheritdoc}
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $this->getConfig($container);
$config = $config[$requestedName];
$this->processConfig($config, $container);
return new Logger($config);
}
/**
* {@inheritDoc}
*/
public function createServiceWithName(ServiceLocatorInterface $container, $name, $requestedName)
{
return $this($container, $requestedName);
}
/**
* Retrieve configuration for loggers, if any
*
* @param ContainerInterface $services
*
* @return array
*/
protected function getConfig(ContainerInterface $services)
{
if ($this->config !== null) {
return $this->config;
}
if (! $services->has('config')) {
$this->config = [];
return $this->config;
}
$config = $services->get('config');
if (! isset($config[$this->configKey])) {
$this->config = [];
return $this->config;
}
$this->config = $config[$this->configKey];
return $this->config;
}
/**
* Process and return the configuration from the container.
*
* @param array $config Passed by reference
* @param ContainerInterface $services
*/
protected function processConfig(&$config, ContainerInterface $services)
{
if (isset($config['writer_plugin_manager'])
&& is_string($config['writer_plugin_manager'])
&& $services->has($config['writer_plugin_manager'])
) {
$config['writer_plugin_manager'] = $services->get($config['writer_plugin_manager']);
}
if ((! isset($config['writer_plugin_manager'])
|| ! $config['writer_plugin_manager'] instanceof AbstractPluginManager)
&& $services->has('LogWriterManager')
) {
$config['writer_plugin_manager'] = $services->get('LogWriterManager');
}
if (isset($config['processor_plugin_manager'])
&& is_string($config['processor_plugin_manager'])
&& $services->has($config['processor_plugin_manager'])
) {
$config['processor_plugin_manager'] = $services->get($config['processor_plugin_manager']);
}
if ((! isset($config['processor_plugin_manager'])
|| ! $config['processor_plugin_manager'] instanceof AbstractPluginManager)
&& $services->has('LogProcessorManager')
) {
$config['processor_plugin_manager'] = $services->get('LogProcessorManager');
}
if (! isset($config['writers'])) {
return;
}
foreach ($config['writers'] as $index => $writerConfig) {
if (isset($writerConfig['name'])
&& ('db' === $writerConfig['name']
|| Writer\Db::class === $writerConfig['name']
|| 'laminaslogwriterdb' === $writerConfig['name']
)
&& isset($writerConfig['options']['db'])
&& is_string($writerConfig['options']['db'])
&& $services->has($writerConfig['options']['db'])
) {
// Retrieve the DB service from the service locator, and
// inject it into the configuration.
$db = $services->get($writerConfig['options']['db']);
$config['writers'][$index]['options']['db'] = $db;
continue;
}
if (isset($writerConfig['name'])
&& ('mongo' === $writerConfig['name']
|| Writer\Mongo::class === $writerConfig['name']
|| 'laminaslogwritermongo' === $writerConfig['name']
)
&& isset($writerConfig['options']['mongo'])
&& is_string($writerConfig['options']['mongo'])
&& $services->has($writerConfig['options']['mongo'])
) {
// Retrieve the Mongo service from the service locator, and
// inject it into the configuration.
$mongoClient = $services->get($writerConfig['options']['mongo']);
$config['writers'][$index]['options']['mongo'] = $mongoClient;
continue;
}
if (isset($writerConfig['name'])
&& ('mongodb' === $writerConfig['name']
|| Writer\MongoDB::class === $writerConfig['name']
|| 'laminaslogwritermongodb' === $writerConfig['name']
)
&& isset($writerConfig['options']['manager'])
&& is_string($writerConfig['options']['manager'])
&& $services->has($writerConfig['options']['manager'])
) {
// Retrieve the MongoDB Manager service from the service locator, and
// inject it into the configuration.
$manager = $services->get($writerConfig['options']['manager']);
$config['writers'][$index]['options']['manager'] = $manager;
continue;
}
}
}
}
PK APz src/LoggerAwareTrait.phpnu W+A logger = $logger;
return $this;
}
/**
* Get logger object
*
* @return null|LoggerInterface
*/
public function getLogger()
{
return $this->logger;
}
}
PK AP &. . src/Writer/WriterInterface.phpnu W+A src/Writer/Mail.phpnu W+A setSubjectPrependText($mail['subject_prepend_text']);
}
$transport = isset($mail['transport']) ? $mail['transport'] : null;
$mail = isset($mail['mail']) ? $mail['mail'] : null;
if (is_array($mail)) {
$mail = MailMessageFactory::getInstance($mail);
}
if (is_array($transport)) {
$transport = Transport\Factory::create($transport);
}
}
// Ensure we have a valid mail message
if (! $mail instanceof MailMessage) {
throw new Exception\InvalidArgumentException(sprintf(
'Mail parameter of type %s is invalid; must be of type Laminas\Mail\Message',
(is_object($mail) ? get_class($mail) : gettype($mail))
));
}
$this->mail = $mail;
// Ensure we have a valid mail transport
if (null === $transport) {
$transport = new Transport\Sendmail();
}
if (! $transport instanceof Transport\TransportInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Transport parameter of type %s is invalid; must be of type Laminas\Mail\Transport\TransportInterface',
(is_object($transport) ? get_class($transport) : gettype($transport))
));
}
$this->setTransport($transport);
if ($this->formatter === null) {
$this->formatter = new SimpleFormatter();
}
}
/**
* Set the transport message
*
* @param Transport\TransportInterface $transport
* @return Mail
*/
public function setTransport(Transport\TransportInterface $transport)
{
$this->transport = $transport;
return $this;
}
/**
* Places event line into array of lines to be used as message body.
*
* @param array $event Event data
*/
protected function doWrite(array $event)
{
// Track the number of entries per priority level.
if (! isset($this->numEntriesPerPriority[$event['priorityName']])) {
$this->numEntriesPerPriority[$event['priorityName']] = 1;
} else {
$this->numEntriesPerPriority[$event['priorityName']]++;
}
// All plaintext events are to use the standard formatter.
$this->eventsToMail[] = $this->formatter->format($event);
}
/**
* Allows caller to have the mail subject dynamically set to contain the
* entry counts per-priority level.
*
* Sets the text for use in the subject, with entry counts per-priority
* level appended to the end. Since a Laminas\Mail\Message subject can only be set
* once, this method cannot be used if the Laminas\Mail\Message object already has a
* subject set.
*
* @param string $subject Subject prepend text
* @return Mail
*/
public function setSubjectPrependText($subject)
{
$this->subjectPrependText = (string) $subject;
return $this;
}
/**
* Sends mail to recipient(s) if log entries are present. Note that both
* plaintext and HTML portions of email are handled here.
*/
public function shutdown()
{
// If there are events to mail, use them as message body. Otherwise,
// there is no mail to be sent.
if (empty($this->eventsToMail)) {
return;
}
if ($this->subjectPrependText !== null) {
// Tack on the summary of entries per-priority to the subject
// line and set it on the Laminas\Mail object.
$numEntries = $this->getFormattedNumEntriesPerPriority();
$this->mail->setSubject("{$this->subjectPrependText} ({$numEntries})");
}
// Always provide events to mail as plaintext.
$this->mail->setBody(implode(PHP_EOL, $this->eventsToMail));
// Finally, send the mail. If an exception occurs, convert it into a
// warning-level message so we can avoid an exception thrown without a
// stack frame.
try {
$this->transport->send($this->mail);
} catch (TransportException\ExceptionInterface $e) {
trigger_error(
"unable to send log entries via email; " .
"message = {$e->getMessage()}; " .
"code = {$e->getCode()}; " .
"exception class = " . get_class($e),
E_USER_WARNING
);
}
}
/**
* Gets a string of number of entries per-priority level that occurred, or
* an empty string if none occurred.
*
* @return string
*/
protected function getFormattedNumEntriesPerPriority()
{
$strings = [];
foreach ($this->numEntriesPerPriority as $priority => $numEntries) {
$strings[] = "{$priority}={$numEntries}";
}
return implode(', ', $strings);
}
}
PK APdCw
w
src/Writer/ChromePhp.phpnu W+A chromephp = $instance === null ? $this->getChromePhp() : $instance;
$this->formatter = new ChromePhpFormatter();
}
/**
* Write a message to the log.
*
* @param array $event event data
* @return void
*/
protected function doWrite(array $event)
{
$line = $this->formatter->format($event);
switch ($event['priority']) {
case Logger::EMERG:
case Logger::ALERT:
case Logger::CRIT:
case Logger::ERR:
$this->chromephp->error($line);
break;
case Logger::WARN:
$this->chromephp->warn($line);
break;
case Logger::NOTICE:
case Logger::INFO:
$this->chromephp->info($line);
break;
case Logger::DEBUG:
$this->chromephp->trace($line);
break;
default:
$this->chromephp->log($line);
break;
}
}
/**
* Gets the ChromePhpInterface instance that is used for logging.
*
* @return ChromePhpInterface
*/
public function getChromePhp()
{
// Remember: class names in strings are absolute; thus the class_exists
// here references the canonical name for the ChromePhp class
if (! $this->chromephp instanceof ChromePhpInterface
&& class_exists('ChromePhp')
) {
$this->setChromePhp(new ChromePhpBridge());
}
return $this->chromephp;
}
/**
* Sets the ChromePhpInterface instance that is used for logging.
*
* @param ChromePhpInterface $instance The instance to set.
* @return ChromePhp
*/
public function setChromePhp(ChromePhpInterface $instance)
{
$this->chromephp = $instance;
return $this;
}
}
PK APLo o src/Writer/Mock.phpnu W+A events[] = $event;
}
/**
* Record shutdown
*
* @return void
*/
public function shutdown()
{
$this->shutdown = true;
}
}
PK AP , , src/Writer/FirePhp.phpnu W+A firephp = $instance;
$this->formatter = new FirePhpFormatter();
}
/**
* Write a message to the log.
*
* @param array $event event data
* @return void
*/
protected function doWrite(array $event)
{
$firephp = $this->getFirePhp();
if (! $firephp->getEnabled()) {
return;
}
list($line, $label) = $this->formatter->format($event);
switch ($event['priority']) {
case Logger::EMERG:
case Logger::ALERT:
case Logger::CRIT:
case Logger::ERR:
$firephp->error($line, $label);
break;
case Logger::WARN:
$firephp->warn($line, $label);
break;
case Logger::NOTICE:
case Logger::INFO:
$firephp->info($line, $label);
break;
case Logger::DEBUG:
$firephp->trace($line);
break;
default:
$firephp->log($line, $label);
break;
}
}
/**
* Gets the FirePhpInterface instance that is used for logging.
*
* @return FirePhp\FirePhpInterface
* @throws Exception\RuntimeException
*/
public function getFirePhp()
{
if (! $this->firephp instanceof FirePhp\FirePhpInterface
&& ! class_exists('FirePHP')
) {
// No FirePHP instance, and no way to create one
throw new Exception\RuntimeException('FirePHP Class not found');
}
// Remember: class names in strings are absolute; thus the class_exists
// here references the canonical name for the FirePHP class
if (! $this->firephp instanceof FirePhp\FirePhpInterface
&& class_exists('FirePHP')
) {
// FirePHPService is an alias for FirePHP; otherwise the class
// names would clash in this file on this line.
$this->setFirePhp(new FirePhp\FirePhpBridge(new FirePHPService()));
}
return $this->firephp;
}
/**
* Sets the FirePhpInterface instance that is used for logging.
*
* @param FirePhp\FirePhpInterface $instance A FirePhpInterface instance to set.
* @return FirePhp
*/
public function setFirePhp(FirePhp\FirePhpInterface $instance)
{
$this->firephp = $instance;
return $this;
}
}
PK AP!N src/Writer/Syslog.phpnu W+A LOG_EMERG,
Logger::ALERT => LOG_ALERT,
Logger::CRIT => LOG_CRIT,
Logger::ERR => LOG_ERR,
Logger::WARN => LOG_WARNING,
Logger::NOTICE => LOG_NOTICE,
Logger::INFO => LOG_INFO,
Logger::DEBUG => LOG_DEBUG,
];
/**
* The default log priority - for unmapped custom priorities
*
* @var string
*/
protected $defaultPriority = LOG_NOTICE;
/**
* Last application name set by a syslog-writer instance
*
* @var string
*/
protected static $lastApplication;
/**
* Last facility name set by a syslog-writer instance
*
* @var string
*/
protected static $lastFacility;
/**
* Application name used by this syslog-writer instance
*
* @var string
*/
protected $appName = 'Laminas\Log';
/**
* Facility used by this syslog-writer instance
*
* @var int
*/
protected $facility = LOG_USER;
/**
* Types of program available to logging of message
*
* @var array
*/
protected $validFacilities = [];
/**
* Constructor
*
* @param array $params Array of options; may include "application" and "facility" keys
* @return Syslog
*/
public function __construct($params = null)
{
if ($params instanceof Traversable) {
$params = iterator_to_array($params);
}
$runInitializeSyslog = true;
if (is_array($params)) {
parent::__construct($params);
if (isset($params['application'])) {
$this->appName = $params['application'];
}
if (isset($params['facility'])) {
$this->setFacility($params['facility']);
$runInitializeSyslog = false;
}
}
if ($runInitializeSyslog) {
$this->initializeSyslog();
}
if ($this->formatter === null) {
$this->setFormatter(new SimpleFormatter('%message%'));
}
}
/**
* Initialize values facilities
*
* @return void
*/
protected function initializeValidFacilities()
{
$constants = [
'LOG_AUTH',
'LOG_AUTHPRIV',
'LOG_CRON',
'LOG_DAEMON',
'LOG_KERN',
'LOG_LOCAL0',
'LOG_LOCAL1',
'LOG_LOCAL2',
'LOG_LOCAL3',
'LOG_LOCAL4',
'LOG_LOCAL5',
'LOG_LOCAL6',
'LOG_LOCAL7',
'LOG_LPR',
'LOG_MAIL',
'LOG_NEWS',
'LOG_SYSLOG',
'LOG_USER',
'LOG_UUCP'
];
foreach ($constants as $constant) {
if (defined($constant)) {
$this->validFacilities[] = constant($constant);
}
}
}
/**
* Initialize syslog / set application name and facility
*
* @return void
*/
protected function initializeSyslog()
{
static::$lastApplication = $this->appName;
static::$lastFacility = $this->facility;
openlog($this->appName, LOG_PID, $this->facility);
}
/**
* Set syslog facility
*
* @param int $facility Syslog facility
* @return Syslog
* @throws Exception\InvalidArgumentException for invalid log facility
*/
public function setFacility($facility)
{
if ($this->facility === $facility) {
return $this;
}
if (empty($this->validFacilities)) {
$this->initializeValidFacilities();
}
if (! in_array($facility, $this->validFacilities)) {
throw new Exception\InvalidArgumentException(
'Invalid log facility provided; please see http://php.net/openlog for a list of valid facility values'
);
}
if (0 === stripos(PHP_OS, 'WIN')
&& ($facility !== LOG_USER)
) {
throw new Exception\InvalidArgumentException(
'Only LOG_USER is a valid log facility on Windows'
);
}
$this->facility = $facility;
$this->initializeSyslog();
return $this;
}
/**
* Set application name
*
* @param string $appName Application name
* @return Syslog
*/
public function setApplicationName($appName)
{
if ($this->appName === $appName) {
return $this;
}
$this->appName = $appName;
$this->initializeSyslog();
return $this;
}
/**
* Close syslog.
*
* @return void
*/
public function shutdown()
{
closelog();
}
/**
* Write a message to syslog.
*
* @param array $event event data
* @return void
*/
protected function doWrite(array $event)
{
if (array_key_exists($event['priority'], $this->priorities)) {
$priority = $this->priorities[$event['priority']];
} else {
$priority = $this->defaultPriority;
}
if ($this->appName !== static::$lastApplication
|| $this->facility !== static::$lastFacility
) {
$this->initializeSyslog();
}
$message = $this->formatter->format($event);
syslog($priority, $message);
}
}
PK AP( src/Writer/Noop.phpnu W+A firephp = $firephp;
}
/**
* Retrieve FirePHP instance
*
* @return FirePHP
*/
public function getFirePhp()
{
return $this->firephp;
}
/**
* Determine whether or not FirePHP is enabled
*
* @return bool
*/
public function getEnabled()
{
return $this->firephp->getEnabled();
}
/**
* Log an error message
*
* @param string $line
* @param string|null $label
* @return void
*/
public function error($line, $label = null)
{
return $this->firephp->error($line, $label);
}
/**
* Log a warning
*
* @param string $line
* @param string|null $label
* @return void
*/
public function warn($line, $label = null)
{
return $this->firephp->warn($line, $label);
}
/**
* Log informational message
*
* @param string $line
* @param string|null $label
* @return void
*/
public function info($line, $label = null)
{
return $this->firephp->info($line, $label);
}
/**
* Log a trace
*
* @param string $line
* @return void
*/
public function trace($line)
{
return $this->firephp->trace($line);
}
/**
* Log a message
*
* @param string $line
* @param string|null $label
* @return void
*/
public function log($line, $label = null)
{
return $this->firephp->trace($line, $label);
}
}
PK AP2 ' src/Writer/FirePhp/FirePhpInterface.phpnu W+A setFilterPluginManager($options['filter_manager']);
}
if (isset($options['formatter_manager'])) {
$this->setFormatterPluginManager($options['formatter_manager']);
}
if (isset($options['filters'])) {
$filters = $options['filters'];
if (is_int($filters) || is_string($filters) || $filters instanceof Filter\FilterInterface) {
$this->addFilter($filters);
} elseif (is_array($filters)) {
foreach ($filters as $filter) {
if (is_int($filter) || is_string($filter) || $filter instanceof Filter\FilterInterface) {
$this->addFilter($filter);
} elseif (is_array($filter)) {
if (! isset($filter['name'])) {
throw new Exception\InvalidArgumentException(
'Options must contain a name for the filter'
);
}
$filterOptions = (isset($filter['options'])) ? $filter['options'] : null;
$this->addFilter($filter['name'], $filterOptions);
}
}
}
}
if (isset($options['formatter'])) {
$formatter = $options['formatter'];
if (is_string($formatter) || $formatter instanceof Formatter\FormatterInterface) {
$this->setFormatter($formatter);
} elseif (is_array($formatter)) {
if (! isset($formatter['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the formatter');
}
$formatterOptions = (isset($formatter['options'])) ? $formatter['options'] : null;
$this->setFormatter($formatter['name'], $formatterOptions);
}
}
}
}
/**
* Add a filter specific to this writer.
*
* @param int|string|Filter\FilterInterface $filter
* @param array|null $options
* @return AbstractWriter
* @throws Exception\InvalidArgumentException
*/
public function addFilter($filter, array $options = null)
{
if (is_int($filter)) {
$filter = new Filter\Priority($filter);
}
if (is_string($filter)) {
$filter = $this->filterPlugin($filter, $options);
}
if (! $filter instanceof Filter\FilterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Filter must implement %s\Filter\FilterInterface; received "%s"',
__NAMESPACE__,
is_object($filter) ? get_class($filter) : gettype($filter)
));
}
$this->filters[] = $filter;
return $this;
}
/**
* Get filter plugin manager
*
* @return LogFilterPluginManager
*/
public function getFilterPluginManager()
{
if (null === $this->filterPlugins) {
$this->setFilterPluginManager(new LogFilterPluginManager(new ServiceManager()));
}
return $this->filterPlugins;
}
/**
* Set filter plugin manager
*
* @param string|LogFilterPluginManager $plugins
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setFilterPluginManager($plugins)
{
if (is_string($plugins)) {
$plugins = new $plugins;
}
if (! $plugins instanceof LogFilterPluginManager) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer plugin manager must extend %s; received %s',
LogFilterPluginManager::class,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
));
}
$this->filterPlugins = $plugins;
return $this;
}
/**
* Get filter instance
*
* @param string $name
* @param array|null $options
* @return Filter\FilterInterface
*/
public function filterPlugin($name, array $options = null)
{
return $this->getFilterPluginManager()->get($name, $options);
}
/**
* Get formatter plugin manager
*
* @return LogFormatterPluginManager
*/
public function getFormatterPluginManager()
{
if (null === $this->formatterPlugins) {
$this->setFormatterPluginManager(new LogFormatterPluginManager(new ServiceManager()));
}
return $this->formatterPlugins;
}
/**
* Set formatter plugin manager
*
* @param string|LogFormatterPluginManager $plugins
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setFormatterPluginManager($plugins)
{
if (is_string($plugins)) {
$plugins = new $plugins;
}
if (! $plugins instanceof LogFormatterPluginManager) {
throw new Exception\InvalidArgumentException(
sprintf(
'Writer plugin manager must extend %s; received %s',
LogFormatterPluginManager::class,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
)
);
}
$this->formatterPlugins = $plugins;
return $this;
}
/**
* Get formatter instance
*
* @param string $name
* @param array|null $options
* @return Formatter\FormatterInterface
*/
public function formatterPlugin($name, array $options = null)
{
return $this->getFormatterPluginManager()->get($name, $options);
}
/**
* Log a message to this writer.
*
* @param array $event log data event
* @return void
*/
public function write(array $event)
{
foreach ($this->filters as $filter) {
if (! $filter->filter($event)) {
return;
}
}
$errorHandlerStarted = false;
if ($this->convertWriteErrorsToExceptions && ! ErrorHandler::started()) {
ErrorHandler::start($this->errorsToExceptionsConversionLevel);
$errorHandlerStarted = true;
}
try {
$this->doWrite($event);
} catch (\Exception $e) {
if ($errorHandlerStarted) {
ErrorHandler::stop();
}
throw $e;
}
if ($errorHandlerStarted) {
$error = ErrorHandler::stop();
if ($error) {
throw new Exception\RuntimeException("Unable to write", 0, $error);
}
}
}
/**
* Set a new formatter for this writer
*
* @param string|Formatter\FormatterInterface $formatter
* @param array|null $options
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setFormatter($formatter, array $options = null)
{
if (is_string($formatter)) {
$formatter = $this->formatterPlugin($formatter, $options);
}
if (! $formatter instanceof Formatter\FormatterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Formatter must implement %s\Formatter\FormatterInterface; received "%s"',
__NAMESPACE__,
is_object($formatter) ? get_class($formatter) : gettype($formatter)
));
}
$this->formatter = $formatter;
return $this;
}
/**
* Get formatter
*
* @return Formatter\FormatterInterface
*/
protected function getFormatter()
{
return $this->formatter;
}
/**
* Check if the writer has a formatter
*
* @return bool
*/
protected function hasFormatter()
{
return $this->formatter instanceof Formatter\FormatterInterface;
}
/**
* Set convert write errors to exception flag
*
* @param bool $convertErrors
*/
public function setConvertWriteErrorsToExceptions($convertErrors)
{
$this->convertWriteErrorsToExceptions = $convertErrors;
}
/**
* Perform shutdown activities such as closing open resources
*
* @return void
*/
public function shutdown()
{
}
/**
* Write a message to the log
*
* @param array $event log data event
* @return void
*/
abstract protected function doWrite(array $event);
}
PK APxd src/Writer/Stream.phpnu W+A stream = $streamOrUrl;
} else {
ErrorHandler::start();
if (isset($filePermissions) && ! file_exists($streamOrUrl) && is_writable(dirname($streamOrUrl))) {
touch($streamOrUrl);
chmod($streamOrUrl, $filePermissions);
}
$this->stream = fopen($streamOrUrl, $mode, false);
$error = ErrorHandler::stop();
if (! $this->stream) {
throw new Exception\RuntimeException(sprintf(
'"%s" cannot be opened with mode "%s"',
$streamOrUrl,
$mode
), 0, $error);
}
}
if (null !== $logSeparator) {
$this->setLogSeparator($logSeparator);
}
if ($this->formatter === null) {
$this->formatter = new SimpleFormatter();
}
}
/**
* Write a message to the log.
*
* @param array $event event data
* @return void
* @throws Exception\RuntimeException
*/
protected function doWrite(array $event)
{
$line = $this->formatter->format($event) . $this->logSeparator;
fwrite($this->stream, $line);
}
/**
* Set log separator string
*
* @param string $logSeparator
* @return Stream
*/
public function setLogSeparator($logSeparator)
{
$this->logSeparator = (string) $logSeparator;
return $this;
}
/**
* Get log separator string
*
* @return string
*/
public function getLogSeparator()
{
return $this->logSeparator;
}
/**
* Close the stream resource.
*
* @return void
*/
public function shutdown()
{
if (is_resource($this->stream)) {
fclose($this->stream);
}
}
}
PK AP8oe e src/Writer/FingersCrossed.phpnu W+A writer = $writer;
if ($writer instanceof Traversable) {
$writer = ArrayUtils::iteratorToArray($writer);
}
if (is_array($writer)) {
$filterOrPriority = isset($writer['priority']) ? $writer['priority'] : null;
$bufferSize = isset($writer['bufferSize']) ? $writer['bufferSize'] : null;
$writer = isset($writer['writer']) ? $writer['writer'] : null;
}
if (null === $filterOrPriority) {
$filterOrPriority = new PriorityFilter(Logger::WARN);
} elseif (! $filterOrPriority instanceof FilterInterface) {
$filterOrPriority = new PriorityFilter($filterOrPriority);
}
if (is_array($writer) && isset($writer['name'])) {
$this->setWriter($writer['name'], $writer['options']);
} else {
$this->setWriter($writer);
}
$this->addFilter($filterOrPriority);
$this->bufferSize = $bufferSize;
}
/**
* Set a new writer
*
* @param string|WriterInterface $writer
* @param array|null $options
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setWriter($writer, array $options = null)
{
if (is_string($writer)) {
$writer = $this->writerPlugin($writer, $options);
}
if (! $writer instanceof WriterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer must implement %s\WriterInterface; received "%s"',
__NAMESPACE__,
is_object($writer) ? get_class($writer) : gettype($writer)
));
}
$this->writer = $writer;
return $this;
}
/**
* Get writer plugin manager
*
* @return WriterPluginManager
*/
public function getWriterPluginManager()
{
if (null === $this->writerPlugins) {
$this->setWriterPluginManager(new WriterPluginManager(new ServiceManager()));
}
return $this->writerPlugins;
}
/**
* Set writer plugin manager
*
* @param string|WriterPluginManager $plugins
* @return FingersCrossed
* @throws Exception\InvalidArgumentException
*/
public function setWriterPluginManager($plugins)
{
if (is_string($plugins)) {
$plugins = new $plugins;
}
if (! $plugins instanceof WriterPluginManager) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer plugin manager must extend %s\WriterPluginManager; received %s',
__NAMESPACE__,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
));
}
$this->writerPlugins = $plugins;
return $this;
}
/**
* Get writer instance
*
* @param string $name
* @param array|null $options
* @return WriterInterface
*/
public function writerPlugin($name, array $options = null)
{
return $this->getWriterPluginManager()->get($name, $options);
}
/**
* Log a message to this writer.
*
* @param array $event log data event
* @return void
*/
public function write(array $event)
{
$this->doWrite($event);
}
/**
* Check if buffered data should be flushed
*
* @param array $event event data
* @return bool true if buffered data should be flushed
*/
protected function isActivated(array $event)
{
foreach ($this->filters as $filter) {
if (! $filter->filter($event)) {
return false;
}
}
return true;
}
/**
* Write message to buffer or delegate event data to the wrapped writer
*
* @param array $event event data
* @return void
*/
protected function doWrite(array $event)
{
if (! $this->buffering) {
$this->writer->write($event);
return;
}
$this->buffer[] = $event;
if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
array_shift($this->buffer);
}
if (! $this->isActivated($event)) {
return;
}
$this->buffering = false;
foreach ($this->buffer as $bufferedEvent) {
$this->writer->write($bufferedEvent);
}
}
/**
* Resets the state of the handler.
* Stops forwarding records to the wrapped writer
*/
public function reset()
{
$this->buffering = true;
}
/**
* Stub in accordance to parent method signature.
* Fomatters must be set on the wrapped writer.
*
* @param string|FormatterInterface $formatter
* @param array|null $options (unused)
* @return WriterInterface
*/
public function setFormatter($formatter, array $options = null)
{
return $this->writer;
}
/**
* Record shutdown
*
* @return void
*/
public function shutdown()
{
$this->writer->shutdown();
$this->buffer = null;
}
}
PK AP6 " src/Writer/FilterPluginManager.phpnu W+A manager = $manager;
$this->database = $database;
$this->writeConcern = $writeConcern;
}
/**
* This writer does not support formatting.
*
* @param string|FormatterInterface $formatter
* @param array|null $options (unused)
* @return WriterInterface
*/
public function setFormatter($formatter, array $options = null)
{
return $this;
}
/**
* Write a message to the log.
*
* @param array $event Event data
* @return void
* @throws Exception\RuntimeException
*/
protected function doWrite(array $event)
{
if (null === $this->manager) {
throw new Exception\RuntimeException('MongoDB\Driver\Manager must be defined');
}
if (isset($event['timestamp']) && $event['timestamp'] instanceof DateTimeInterface) {
$millis = (int) floor((float) $event['timestamp']->format('U.u') * 1000);
$event['timestamp'] = new UTCDateTime($millis);
}
$bulkWrite = new BulkWrite();
$bulkWrite->insert($event);
$this->manager->executeBulkWrite($this->database, $bulkWrite, $this->writeConcern);
}
}
PK AP/M9Q src/Writer/Null.phpnu W+A isEnabled = false;
}
if (function_exists('zend_monitor_custom_event')) {
$this->isZendServer = true;
}
}
/**
* Is logging to this writer enabled?
*
* If the Zend Monitor extension is not enabled, this log writer will
* fail silently. You can query this method to determine if the log
* writer is enabled.
*
* @return bool
*/
public function isEnabled()
{
return $this->isEnabled;
}
/**
* Log a message to this writer.
*
* @param array $event log data event
* @return void
*/
public function write(array $event)
{
if (! $this->isEnabled()) {
return;
}
parent::write($event);
}
/**
* Write a message to the log.
*
* @param array $event log data event
* @return void
*/
protected function doWrite(array $event)
{
$priority = $event['priority'];
$message = $event['message'];
unset($event['priority'], $event['message']);
if (! empty($event)) {
if ($this->isZendServer) {
// On Zend Server; third argument should be the event
zend_monitor_custom_event($priority, $message, $event);
} else {
// On Zend Platform; third argument is severity -- either
// 0 or 1 -- and fourth is optional (event)
// Severity is either 0 (normal) or 1 (severe); classifying
// notice, info, and debug as "normal", and all others as
// "severe"
monitor_custom_event($priority, $message, ($priority > 4) ? 0 : 1, $event);
}
} else {
monitor_custom_event($priority, $message);
}
}
}
PK AP{|
|
src/Writer/Psr.phpnu W+A LogLevel::EMERGENCY,
Logger::ALERT => LogLevel::ALERT,
Logger::CRIT => LogLevel::CRITICAL,
Logger::ERR => LogLevel::ERROR,
Logger::WARN => LogLevel::WARNING,
Logger::NOTICE => LogLevel::NOTICE,
Logger::INFO => LogLevel::INFO,
Logger::DEBUG => LogLevel::DEBUG,
];
/**
* Default log level (warning)
*
* @var int
*/
protected $defaultLogLevel = LogLevel::WARNING;
/**
* Constructor
*
* Set options for a writer. Accepted options are:
*
* - filters: array of filters to add to this filter
* - formatter: formatter for this writer
* - logger: PsrLoggerInterface implementation
*
* @param array|Traversable|PsrLoggerInterface $options
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = null)
{
if ($options instanceof PsrLoggerInterface) {
$this->setLogger($options);
}
if ($options instanceof Traversable) {
$options = iterator_to_array($options);
}
if (is_array($options) && isset($options['logger'])) {
$this->setLogger($options['logger']);
}
parent::__construct($options);
if (null === $this->logger) {
$this->setLogger(new NullLogger);
}
}
/**
* Write a message to the PSR-3 compliant logger.
*
* @param array $event event data
* @return void
*/
protected function doWrite(array $event)
{
$priority = $event['priority'];
$message = $event['message'];
$context = $event['extra'];
$level = isset($this->psrPriorityMap[$priority])
? $this->psrPriorityMap[$priority]
: $this->defaultLogLevel;
$this->logger->log($level, $message, $context);
}
}
PK AP5<= = src/Writer/Mongo.phpnu W+A mongoCollection = $mongo->selectCollection($database, $collection);
$this->saveOptions = $saveOptions;
}
/**
* This writer does not support formatting.
*
* @param string|FormatterInterface $formatter
* @param array|null $options (unused)
* @return WriterInterface
*/
public function setFormatter($formatter, array $options = null)
{
return $this;
}
/**
* Write a message to the log.
*
* @param array $event Event data
* @return void
* @throws Exception\RuntimeException
*/
protected function doWrite(array $event)
{
if (null === $this->mongoCollection) {
throw new Exception\RuntimeException('MongoCollection must be defined');
}
if (isset($event['timestamp']) && $event['timestamp'] instanceof DateTimeInterface) {
$event['timestamp'] = new MongoDate($event['timestamp']->getTimestamp());
}
$this->mongoCollection->save($event, $this->saveOptions);
}
}
PK APp p src/Writer/Db.phpnu W+A db = $db;
$this->tableName = $tableName;
$this->columnMap = $columnMap;
if (! empty($separator)) {
$this->separator = $separator;
}
if (! $this->hasFormatter()) {
$this->setFormatter(new DbFormatter());
}
}
/**
* Remove reference to database adapter
*
* @return void
*/
public function shutdown()
{
$this->db = null;
}
/**
* Write a message to the log.
*
* @param array $event event data
* @return void
* @throws Exception\RuntimeException
*/
protected function doWrite(array $event)
{
if (null === $this->db) {
throw new Exception\RuntimeException('Database adapter is null');
}
$event = $this->formatter->format($event);
// Transform the event array into fields
if (null === $this->columnMap) {
$dataToInsert = $this->eventIntoColumn($event);
} else {
$dataToInsert = $this->mapEventIntoColumn($event, $this->columnMap);
}
$statement = $this->db->query($this->prepareInsert($dataToInsert));
$statement->execute($dataToInsert);
}
/**
* Prepare the INSERT SQL statement
*
* @param array $fields
* @return string
*/
protected function prepareInsert(array $fields)
{
$keys = array_keys($fields);
$sql = 'INSERT INTO ' . $this->db->platform->quoteIdentifier($this->tableName) . ' (' .
implode(",", array_map([$this->db->platform, 'quoteIdentifier'], $keys)) . ') VALUES (' .
implode(",", array_map([$this->db->driver, 'formatParameterName'], $keys)) . ')';
return $sql;
}
/**
* Map event into column using the $columnMap array
*
* @param array $event
* @param array $columnMap
* @return array
*/
protected function mapEventIntoColumn(array $event, array $columnMap = null)
{
if (empty($event)) {
return [];
}
$data = [];
foreach ($event as $name => $value) {
if (is_array($value)) {
foreach ($value as $key => $subvalue) {
if (isset($columnMap[$name][$key])) {
if (is_scalar($subvalue)) {
$data[$columnMap[$name][$key]] = $subvalue;
continue;
}
$data[$columnMap[$name][$key]] = var_export($subvalue, true);
}
}
} elseif (isset($columnMap[$name])) {
$data[$columnMap[$name]] = $value;
}
}
return $data;
}
/**
* Transform event into column for the db table
*
* @param array $event
* @return array
*/
protected function eventIntoColumn(array $event)
{
if (empty($event)) {
return [];
}
$data = [];
foreach ($event as $name => $value) {
if (is_array($value)) {
foreach ($value as $key => $subvalue) {
if (is_scalar($subvalue)) {
$data[$name . $this->separator . $key] = $subvalue;
continue;
}
$data[$name . $this->separator . $key] = var_export($subvalue, true);
}
} else {
$data[$name] = $value;
}
}
return $data;
}
}
PK APZy{ { + src/Writer/ChromePhp/ChromePhpInterface.phpnu W+A setCreationOptions($creationOptions);
}
}
/**
* Create an instance of the requested class name.
*
* @param ContainerInterface $container
* @param string $requestedName
* @param null|array $options
* @return object
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$options = (array)$options;
$options = $this->populateOptions($options, $container, 'filter_manager', 'LogFilterManager');
$options = $this->populateOptions($options, $container, 'formatter_manager', 'LogFormatterManager');
return new $requestedName($options);
}
/**
* Populates the options array with the correct container value.
*
* @param array $options
* @param ContainerInterface $container
* @param string $name
* @param string $defaultService
* @return array
*/
private function populateOptions(array $options, ContainerInterface $container, $name, $defaultService)
{
if (isset($options[$name]) && is_string($options[$name])) {
$options[$name] = $container->get($options[$name]);
return $options;
}
if (! isset($options[$name]) && $container->has($defaultService)) {
$options[$name] = $container->get($defaultService);
return $options;
}
return $options;
}
/**
* Create an instance of the named service.
*
* First, it checks if `$canonicalName` resolves to a class, and, if so, uses
* that value to proxy to `__invoke()`.
*
* Next, if `$requestedName` is non-empty and resolves to a class, this
* method uses that value to proxy to `__invoke()`.
*
* Finally, if the above each fail, it raises an exception.
*
* The approach above is performed as version 2 has two distinct behaviors
* under which factories are invoked:
*
* - If an alias was used, $canonicalName is the resolved name, and
* $requestedName is the service name requested, in which case $canonicalName
* is likely the qualified class name;
* - Otherwise, $canonicalName is the normalized name, and $requestedName
* is the original service name requested (typically the qualified class name).
*
* @param ServiceLocatorInterface $serviceLocator
* @param null|string $canonicalName
* @param null|string $requestedName
* @return object
* @throws InvalidServiceException
*/
public function createService(ServiceLocatorInterface $serviceLocator, $canonicalName = null, $requestedName = null)
{
if (is_string($canonicalName) && class_exists($canonicalName)) {
return $this($serviceLocator->getServiceLocator(), $canonicalName, $this->creationOptions);
}
if (is_string($requestedName) && class_exists($requestedName)) {
return $this($serviceLocator->getServiceLocator(), $requestedName, $this->creationOptions);
}
throw new InvalidServiceException(sprintf(
'%s requires that the requested name is provided on invocation; '
.'please update your tests or consuming container',
__CLASS__
));
}
/**
* {@inheritdoc}
*/
public function setCreationOptions(array $creationOptions)
{
$this->creationOptions = $creationOptions;
}
}
PK APk src/FormatterPluginManager.phpnu W+A Formatter\Base::class,
'simple' => Formatter\Simple::class,
'xml' => Formatter\Xml::class,
'db' => Formatter\Db::class,
'errorhandler' => Formatter\ErrorHandler::class,
'exceptionhandler' => Formatter\ExceptionHandler::class,
// Legacy Zend Framework aliases
\Zend\Log\Formatter\Base::class => Formatter\Base::class,
\Zend\Log\Formatter\Simple::class => Formatter\Simple::class,
\Zend\Log\Formatter\Xml::class => Formatter\Xml::class,
\Zend\Log\Formatter\Db::class => Formatter\Db::class,
\Zend\Log\Formatter\ErrorHandler::class => Formatter\ErrorHandler::class,
\Zend\Log\Formatter\ExceptionHandler::class => Formatter\ExceptionHandler::class,
// v2 normalized FQCNs
'zendlogformatterbase' => Formatter\Base::class,
'zendlogformattersimple' => Formatter\Simple::class,
'zendlogformatterxml' => Formatter\Xml::class,
'zendlogformatterdb' => Formatter\Db::class,
'zendlogformattererrorhandler' => Formatter\ErrorHandler::class,
'zendlogformatterexceptionhandler' => Formatter\ExceptionHandler::class,
];
protected $factories = [
Formatter\Base::class => InvokableFactory::class,
Formatter\Simple::class => InvokableFactory::class,
Formatter\Xml::class => InvokableFactory::class,
Formatter\Db::class => InvokableFactory::class,
Formatter\ErrorHandler::class => InvokableFactory::class,
Formatter\ExceptionHandler::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'laminaslogformatterbase' => InvokableFactory::class,
'laminaslogformattersimple' => InvokableFactory::class,
'laminaslogformatterxml' => InvokableFactory::class,
'laminaslogformatterdb' => InvokableFactory::class,
'laminaslogformattererrorhandler' => InvokableFactory::class,
'laminaslogformatterexceptionhandler' => InvokableFactory::class,
];
protected $instanceOf = Formatter\FormatterInterface::class;
/**
* Allow many formatters of the same type (v2)
* @param bool
*/
protected $shareByDefault = false;
/**
* Allow many formatters of the same type (v3)
* @param bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $plugin
* @throws Exception\InvalidArgumentException
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Formatter\FormatterInterface',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
}
}
PK APϕ+ src/LoggerInterface.phpnu W+A 5.4.0)
* @var int
*/
protected $traceLimit = 10;
/**
* Classes within these namespaces in the stack are ignored
* @var array
*/
protected $ignoredNamespaces = ['Laminas\\Log'];
/**
* Set options for a backtrace processor. Accepted options are:
* - ignoredNamespaces: array of namespaces to be excluded from the logged backtrace
*
* @param array|null $options
*/
public function __construct(array $options = null)
{
if (! empty($options['ignoredNamespaces'])) {
$this->ignoredNamespaces = array_merge($this->ignoredNamespaces, (array) $options['ignoredNamespaces']);
}
}
/**
* Adds the origin of the log() call to the event extras
*
* @param array $event event data
* @return array event data
*/
public function process(array $event)
{
$trace = $this->getBacktrace();
array_shift($trace); // ignore $this->getBacktrace();
array_shift($trace); // ignore $this->process()
$i = 0;
while (isset($trace[$i]['class'])
&& $this->shouldIgnoreFrame($trace[$i]['class'])
) {
$i++;
}
$origin = [
'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null,
'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null,
'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
];
$extra = $origin;
if (isset($event['extra'])) {
$extra = array_merge($origin, $event['extra']);
}
$event['extra'] = $extra;
return $event;
}
/**
* Get all ignored namespaces
*
* @return array
*/
public function getIgnoredNamespaces()
{
return $this->ignoredNamespaces;
}
/**
* Provide backtrace as slim as possible
*
* @return array[]
*/
protected function getBacktrace()
{
return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $this->traceLimit);
}
/**
* Determine whether the current frame in the backtrace should be ignored based on the class name
*
* @param string $class
* @return bool
*/
protected function shouldIgnoreFrame($class)
{
foreach ($this->ignoredNamespaces as $ignoredNamespace) {
if (false !== strpos($class, $ignoredNamespace)) {
return true;
}
}
return false;
}
}
PK APCi i src/Processor/RequestId.phpnu W+A getIdentifier();
return $event;
}
/**
* Provide unique identifier for a request
*
* @return string
*/
protected function getIdentifier()
{
if ($this->identifier) {
return $this->identifier;
}
$identifier = (string) $_SERVER['REQUEST_TIME_FLOAT'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$identifier .= $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
$identifier .= $_SERVER['REMOTE_ADDR'];
}
$this->identifier = md5($identifier);
return $this->identifier;
}
}
PK APs#
k k src/Processor/PsrPlaceholder.phpnu W+A $val) {
if (is_null($val)
|| is_scalar($val)
|| (is_object($val) && method_exists($val, "__toString"))
) {
$replacements['{'.$key.'}'] = $val;
continue;
}
if (is_object($val)) {
$replacements['{'.$key.'}'] = '[object '.get_class($val).']';
continue;
}
$replacements['{'.$key.'}'] = '['.gettype($val).']';
}
$event['message'] = strtr($event['message'], $replacements);
return $event;
}
}
PK API:
() ) src/Processor/ReferenceId.phpnu W+A getIdentifier();
return $event;
}
/**
* Sets identifier.
*
* @param string $identifier
* @return self
*/
public function setReferenceId($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* Returns identifier.
*
* @return string
*/
public function getReferenceId()
{
return $this->getIdentifier();
}
}
PK AP![
$ src/Processor/ProcessorInterface.phpnu W+A self::NOTICE,
E_USER_NOTICE => self::NOTICE,
E_WARNING => self::WARN,
E_CORE_WARNING => self::WARN,
E_USER_WARNING => self::WARN,
E_ERROR => self::ERR,
E_USER_ERROR => self::ERR,
E_CORE_ERROR => self::ERR,
E_RECOVERABLE_ERROR => self::ERR,
E_PARSE => self::ERR,
E_COMPILE_ERROR => self::ERR,
E_COMPILE_WARNING => self::ERR,
E_STRICT => self::DEBUG,
E_DEPRECATED => self::DEBUG,
E_USER_DEPRECATED => self::DEBUG,
];
/**
* Registered error handler
*
* @var bool
*/
protected static $registeredErrorHandler = false;
/**
* Registered shutdown error handler
*
* @var bool
*/
protected static $registeredFatalErrorShutdownFunction = false;
/**
* Registered exception handler
*
* @var bool
*/
protected static $registeredExceptionHandler = false;
/**
* List of priority code => priority (short) name
*
* @var array
*/
protected $priorities = [
self::EMERG => 'EMERG',
self::ALERT => 'ALERT',
self::CRIT => 'CRIT',
self::ERR => 'ERR',
self::WARN => 'WARN',
self::NOTICE => 'NOTICE',
self::INFO => 'INFO',
self::DEBUG => 'DEBUG',
];
/**
* Writers
*
* @var SplPriorityQueue
*/
protected $writers;
/**
* Processors
*
* @var SplPriorityQueue
*/
protected $processors;
/**
* Writer writerPlugins
*
* @var WriterPluginManager
*/
protected $writerPlugins;
/**
* Processor writerPlugins
*
* @var ProcessorPluginManager
*/
protected $processorPlugins;
/**
* Constructor
*
* Set options for a logger. Accepted options are:
* - writers: array of writers to add to this logger
* - exceptionhandler: if true register this logger as exceptionhandler
* - errorhandler: if true register this logger as errorhandler
*
* @param array|Traversable $options
* @return Logger
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = null)
{
$this->writers = new SplPriorityQueue();
$this->processors = new SplPriorityQueue();
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (! $options) {
return;
}
if (! is_array($options)) {
throw new Exception\InvalidArgumentException(
'Options must be an array or an object implementing \Traversable '
);
}
// Inject writer plugin manager, if available
if (isset($options['writer_plugin_manager'])
&& $options['writer_plugin_manager'] instanceof AbstractPluginManager
) {
$this->setWriterPluginManager($options['writer_plugin_manager']);
}
// Inject processor plugin manager, if available
if (isset($options['processor_plugin_manager'])
&& $options['processor_plugin_manager'] instanceof AbstractPluginManager
) {
$this->setProcessorPluginManager($options['processor_plugin_manager']);
}
if (isset($options['writers']) && is_array($options['writers'])) {
foreach ($options['writers'] as $writer) {
if (! isset($writer['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the writer');
}
$priority = (isset($writer['priority'])) ? $writer['priority'] : null;
$writerOptions = (isset($writer['options'])) ? $writer['options'] : null;
$this->addWriter($writer['name'], $priority, $writerOptions);
}
}
if (isset($options['processors']) && is_array($options['processors'])) {
foreach ($options['processors'] as $processor) {
if (! isset($processor['name'])) {
throw new Exception\InvalidArgumentException('Options must contain a name for the processor');
}
$priority = (isset($processor['priority'])) ? $processor['priority'] : null;
$processorOptions = (isset($processor['options'])) ? $processor['options'] : null;
$this->addProcessor($processor['name'], $priority, $processorOptions);
}
}
if (isset($options['exceptionhandler']) && $options['exceptionhandler'] === true) {
static::registerExceptionHandler($this);
}
if (isset($options['errorhandler']) && $options['errorhandler'] === true) {
static::registerErrorHandler($this);
}
if (isset($options['fatal_error_shutdownfunction']) && $options['fatal_error_shutdownfunction'] === true) {
static::registerFatalErrorShutdownFunction($this);
}
}
/**
* Shutdown all writers
*
* @return void
*/
public function __destruct()
{
foreach ($this->writers as $writer) {
try {
$writer->shutdown();
} catch (\Exception $e) {
}
}
}
/**
* Get writer plugin manager
*
* @return WriterPluginManager
*/
public function getWriterPluginManager()
{
if (null === $this->writerPlugins) {
$this->setWriterPluginManager(new WriterPluginManager(new ServiceManager()));
}
return $this->writerPlugins;
}
/**
* Set writer plugin manager
*
* @param WriterPluginManager $writerPlugins
*
* @return Logger
*/
public function setWriterPluginManager(WriterPluginManager $writerPlugins)
{
$this->writerPlugins = $writerPlugins;
return $this;
}
/**
* Get writer instance
*
* @param string $name
* @param array|null $options
* @return Writer\WriterInterface
*/
public function writerPlugin($name, array $options = null)
{
return $this->getWriterPluginManager()->get($name, $options);
}
/**
* Add a writer to a logger
*
* @param string|Writer\WriterInterface $writer
* @param int $priority
* @param array|null $options
* @return Logger
* @throws Exception\InvalidArgumentException
*/
public function addWriter($writer, $priority = 1, array $options = null)
{
if (is_string($writer)) {
$writer = $this->writerPlugin($writer, $options);
} elseif (! $writer instanceof Writer\WriterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer must implement %s\Writer\WriterInterface; received "%s"',
__NAMESPACE__,
is_object($writer) ? get_class($writer) : gettype($writer)
));
}
$this->writers->insert($writer, $priority);
return $this;
}
/**
* Get writers
*
* @return SplPriorityQueue
*/
public function getWriters()
{
return $this->writers;
}
/**
* Set the writers
*
* @param SplPriorityQueue $writers
* @return Logger
* @throws Exception\InvalidArgumentException
*/
public function setWriters(SplPriorityQueue $writers)
{
foreach ($writers->toArray() as $writer) {
if (! $writer instanceof Writer\WriterInterface) {
throw new Exception\InvalidArgumentException(
'Writers must be a SplPriorityQueue of Laminas\Log\Writer'
);
}
}
$this->writers = $writers;
return $this;
}
/**
* Get processor plugin manager
*
* @return ProcessorPluginManager
*/
public function getProcessorPluginManager()
{
if (null === $this->processorPlugins) {
$this->setProcessorPluginManager(new ProcessorPluginManager(new ServiceManager()));
}
return $this->processorPlugins;
}
/**
* Set processor plugin manager
*
* @param string|ProcessorPluginManager $plugins
* @return Logger
* @throws Exception\InvalidArgumentException
*/
public function setProcessorPluginManager($plugins)
{
if (is_string($plugins)) {
$plugins = new $plugins;
}
if (! $plugins instanceof ProcessorPluginManager) {
throw new Exception\InvalidArgumentException(sprintf(
'processor plugin manager must extend %s\ProcessorPluginManager; received %s',
__NAMESPACE__,
is_object($plugins) ? get_class($plugins) : gettype($plugins)
));
}
$this->processorPlugins = $plugins;
return $this;
}
/**
* Get processor instance
*
* @param string $name
* @param array|null $options
* @return Processor\ProcessorInterface
*/
public function processorPlugin($name, array $options = null)
{
return $this->getProcessorPluginManager()->get($name, $options);
}
/**
* Add a processor to a logger
*
* @param string|Processor\ProcessorInterface $processor
* @param int $priority
* @param array|null $options
* @return Logger
* @throws Exception\InvalidArgumentException
*/
public function addProcessor($processor, $priority = 1, array $options = null)
{
if (is_string($processor)) {
$processor = $this->processorPlugin($processor, $options);
} elseif (! $processor instanceof Processor\ProcessorInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Processor must implement Laminas\Log\ProcessorInterface; received "%s"',
is_object($processor) ? get_class($processor) : gettype($processor)
));
}
$this->processors->insert($processor, $priority);
return $this;
}
/**
* Get processors
*
* @return SplPriorityQueue
*/
public function getProcessors()
{
return $this->processors;
}
/**
* Add a message as a log entry
*
* @param int $priority
* @param mixed $message
* @param array|Traversable $extra
* @return Logger
* @throws Exception\InvalidArgumentException if message can't be cast to string
* @throws Exception\InvalidArgumentException if extra can't be iterated over
* @throws Exception\RuntimeException if no log writer specified
*/
public function log($priority, $message, $extra = [])
{
if (! is_int($priority) || ($priority < 0) || ($priority >= count($this->priorities))) {
throw new Exception\InvalidArgumentException(sprintf(
'$priority must be an integer >= 0 and < %d; received %s',
count($this->priorities),
var_export($priority, 1)
));
}
if (is_object($message) && ! method_exists($message, '__toString')) {
throw new Exception\InvalidArgumentException(
'$message must implement magic __toString() method'
);
}
if (! is_array($extra) && ! $extra instanceof Traversable) {
throw new Exception\InvalidArgumentException(
'$extra must be an array or implement Traversable'
);
} elseif ($extra instanceof Traversable) {
$extra = ArrayUtils::iteratorToArray($extra);
}
if ($this->writers->count() === 0) {
throw new Exception\RuntimeException('No log writer specified');
}
$timestamp = new DateTime();
if (is_array($message)) {
$message = var_export($message, true);
}
$event = [
'timestamp' => $timestamp,
'priority' => (int) $priority,
'priorityName' => $this->priorities[$priority],
'message' => (string) $message,
'extra' => $extra,
];
/* @var $processor ProcessorInterface */
foreach ($this->processors->toArray() as $processor) {
$event = $processor->process($event);
}
/* @var $writer WriterInterface */
foreach ($this->writers->toArray() as $writer) {
$writer->write($event);
}
return $this;
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function emerg($message, $extra = [])
{
return $this->log(self::EMERG, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function alert($message, $extra = [])
{
return $this->log(self::ALERT, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function crit($message, $extra = [])
{
return $this->log(self::CRIT, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function err($message, $extra = [])
{
return $this->log(self::ERR, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function warn($message, $extra = [])
{
return $this->log(self::WARN, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function notice($message, $extra = [])
{
return $this->log(self::NOTICE, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function info($message, $extra = [])
{
return $this->log(self::INFO, $message, $extra);
}
/**
* @param string $message
* @param array|Traversable $extra
* @return Logger
*/
public function debug($message, $extra = [])
{
return $this->log(self::DEBUG, $message, $extra);
}
/**
* Register logging system as an error handler to log PHP errors
*
* @link http://www.php.net/manual/function.set-error-handler.php
* @param Logger $logger
* @param bool $continueNativeHandler
* @return mixed Returns result of set_error_handler
* @throws Exception\InvalidArgumentException if logger is null
*/
public static function registerErrorHandler(Logger $logger, $continueNativeHandler = false)
{
// Only register once per instance
if (static::$registeredErrorHandler) {
return false;
}
$errorPriorityMap = static::$errorPriorityMap;
$previous = set_error_handler(
function ($level, $message, $file, $line) use ($logger, $errorPriorityMap, $continueNativeHandler) {
$iniLevel = error_reporting();
if ($iniLevel & $level) {
if (isset($errorPriorityMap[$level])) {
$priority = $errorPriorityMap[$level];
} else {
$priority = Logger::INFO;
}
$logger->log($priority, $message, [
'errno' => $level,
'file' => $file,
'line' => $line,
]);
}
return ! $continueNativeHandler;
}
);
static::$registeredErrorHandler = true;
return $previous;
}
/**
* Unregister error handler
*
*/
public static function unregisterErrorHandler()
{
restore_error_handler();
static::$registeredErrorHandler = false;
}
/**
* Register a shutdown handler to log fatal errors
*
* @link http://www.php.net/manual/function.register-shutdown-function.php
* @param Logger $logger
* @return bool
*/
public static function registerFatalErrorShutdownFunction(Logger $logger)
{
// Only register once per instance
if (static::$registeredFatalErrorShutdownFunction) {
return false;
}
$errorPriorityMap = static::$errorPriorityMap;
register_shutdown_function(function () use ($logger, $errorPriorityMap) {
$error = error_get_last();
if (null === $error
|| ! in_array(
$error['type'],
[
E_ERROR,
E_PARSE,
E_CORE_ERROR,
E_CORE_WARNING,
E_COMPILE_ERROR,
E_COMPILE_WARNING
],
true
)
) {
return;
}
$logger->log(
$errorPriorityMap[$error['type']],
$error['message'],
[
'file' => $error['file'],
'line' => $error['line'],
]
);
});
static::$registeredFatalErrorShutdownFunction = true;
return true;
}
/**
* Register logging system as an exception handler to log PHP exceptions
*
* @link http://www.php.net/manual/en/function.set-exception-handler.php
* @param Logger $logger
* @return bool
* @throws Exception\InvalidArgumentException if logger is null
*/
public static function registerExceptionHandler(Logger $logger)
{
// Only register once per instance
if (static::$registeredExceptionHandler) {
return false;
}
if ($logger === null) {
throw new Exception\InvalidArgumentException('Invalid Logger specified');
}
$errorPriorityMap = static::$errorPriorityMap;
set_exception_handler(function ($exception) use ($logger, $errorPriorityMap) {
$logMessages = [];
do {
$priority = Logger::ERR;
if ($exception instanceof ErrorException && isset($errorPriorityMap[$exception->getSeverity()])) {
$priority = $errorPriorityMap[$exception->getSeverity()];
}
$extra = [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTrace(),
];
if (isset($exception->xdebug_message)) {
$extra['xdebug'] = $exception->xdebug_message;
}
$logMessages[] = [
'priority' => $priority,
'message' => $exception->getMessage(),
'extra' => $extra,
];
$exception = $exception->getPrevious();
} while ($exception);
foreach (array_reverse($logMessages) as $logMessage) {
$logger->log($logMessage['priority'], $logMessage['message'], $logMessage['extra']);
}
});
static::$registeredExceptionHandler = true;
return true;
}
/**
* Unregister exception handler
*/
public static function unregisterExceptionHandler()
{
restore_exception_handler();
static::$registeredExceptionHandler = false;
}
}
PK APEq src/ConfigProvider.phpnu W+A $this->getDependencyConfig(),
];
}
/**
* Return dependency mappings for this component.
*
* @return array
*/
public function getDependencyConfig()
{
return [
// Legacy Zend Framework aliases
'aliases' => [
\Zend\Log\Logger::class => Logger::class,
],
'abstract_factories' => [
LoggerAbstractServiceFactory::class,
PsrLoggerAbstractAdapterFactory::class,
],
'factories' => [
Logger::class => LoggerServiceFactory::class,
'LogFilterManager' => FilterPluginManagerFactory::class,
'LogFormatterManager' => FormatterPluginManagerFactory::class,
'LogProcessorManager' => ProcessorPluginManagerFactory::class,
'LogWriterManager' => WriterPluginManagerFactory::class,
],
];
}
}
PK AP21> src/LoggerAwareInterface.phpnu W+A $provider->getDependencyConfig(),
];
}
/**
* Register specifications for all laminas-log plugin managers with the ServiceListener.
*
* @param \Laminas\ModuleManager\ModuleManager $moduleManager
* @return void
*/
public function init($moduleManager)
{
$event = $moduleManager->getEvent();
$container = $event->getParam('ServiceManager');
$serviceListener = $container->get('ServiceListener');
$serviceListener->addServiceManager(
'LogProcessorManager',
'log_processors',
'Laminas\ModuleManager\Feature\LogProcessorProviderInterface',
'getLogProcessorConfig'
);
$serviceListener->addServiceManager(
'LogWriterManager',
'log_writers',
'Laminas\ModuleManager\Feature\LogWriterProviderInterface',
'getLogWriterConfig'
);
$serviceListener->addServiceManager(
'LogFilterManager',
'log_filters',
'Laminas\Log\Filter\LogFilterProviderInterface',
'getLogFilterConfig'
);
$serviceListener->addServiceManager(
'LogFormatterManager',
'log_formatters',
'Laminas\Log\Formatter\LogFormatterProviderInterface',
'getLogFormatterConfig'
);
}
}
PK APA
mkdocs.ymlnu W+A docs_dir: docs/book
site_dir: docs/html
nav:
- Home: index.md
- Introduction: intro.md
- Reference:
- Writers: writers.md
- Filters: filters.md
- Formatters: formatters.md
- Processors: processors.md
- "Service Manager Integration": service-manager.md
- 'PSR-3 Support': psr3.md
site_name: laminas-log
site_description: 'Robust, composite logger with filtering, formatting, and PSR-3 support.'
repo_url: 'https://github.com/laminas/laminas-log'
extra:
project: Components
PK AP;bJ J .github/workflows/docs-build.ymlnu W+A name: docs-build
on:
push:
branches:
- master
repository_dispatch:
types: docs-build
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Build Docs
uses: laminas/documentation-theme/github-actions/docs@master
env:
DOCS_DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }}
PK APRa .gitattributesnu W+A /.coveralls.yml export-ignore
/.gitattributes export-ignore
/.github/ export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/docs/ export-ignore
/mkdocs.yml export-ignore
/phpcs.xml export-ignore
/phpunit.xml.dist export-ignore
/test/ export-ignore
PK AP@n1 1 - test/WriterPluginManagerCompatibilityTest.phpnu W+A getPluginManager();
$r = new ReflectionProperty($pluginManager, 'aliases');
$r->setAccessible(true);
$aliases = $r->getValue($pluginManager);
foreach ($aliases as $alias => $target) {
switch ($target) {
case Writer\Mail::class:
// intentionally fall-through
case Writer\Db::class:
// intentionally fall-through
case Writer\FingersCrossed::class:
// intentionally fall-through
case Writer\Mongo::class:
// intentionally fall-through
case Writer\MongoDB::class:
// intentionally fall-through
case Writer\Stream::class:
// always skip; these implementations have required arguments
break;
default:
yield $alias => [$alias, $target];
}
}
}
}
PK APؔ * test/ProcessorPluginManagerFactoryTest.phpnu W+A prophesize(ContainerInterface::class)->reveal();
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container, ProcessorPluginManagerFactory::class);
$this->assertInstanceOf(ProcessorPluginManager::class, $processors);
if (method_exists($processors, 'configure')) {
// laminas-servicemanager v3
$this->assertAttributeSame($container, 'creationContext', $processors);
} else {
// laminas-servicemanager v2
$this->assertSame($container, $processors->getServiceLocator());
}
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderContainerInterop()
{
$container = $this->prophesize(ContainerInterface::class)->reveal();
$processor = $this->prophesize(ProcessorInterface::class)->reveal();
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container, ProcessorPluginManagerFactory::class, [
'services' => [
'test' => $processor,
],
]);
$this->assertSame($processor, $processors->get('test'));
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderServiceManagerV2()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$processor = $this->prophesize(ProcessorInterface::class)->reveal();
$factory = new ProcessorPluginManagerFactory();
$factory->setCreationOptions([
'services' => [
'test' => $processor,
],
]);
$processors = $factory->createService($container->reveal());
$this->assertSame($processor, $processors->get('test'));
}
public function testConfiguresProcessorServicesWhenFound()
{
$processor = $this->prophesize(ProcessorInterface::class)->reveal();
$config = [
'log_processors' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($processor) {
return $processor;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn($config);
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container->reveal(), 'ProcessorManager');
$this->assertInstanceOf(ProcessorPluginManager::class, $processors);
$this->assertTrue($processors->has('test'));
$this->assertSame($processor, $processors->get('test'));
$this->assertTrue($processors->has('test-too'));
$this->assertSame($processor, $processors->get('test-too'));
}
public function testDoesNotConfigureProcessorServicesWhenServiceListenerPresent()
{
$processor = $this->prophesize(ProcessorInterface::class)->reveal();
$config = [
'log_processors' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($processor) {
return $processor;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(true);
$container->has('config')->shouldNotBeCalled();
$container->get('config')->shouldNotBeCalled();
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container->reveal(), 'ProcessorManager');
$this->assertInstanceOf(ProcessorPluginManager::class, $processors);
$this->assertFalse($processors->has('test'));
$this->assertFalse($processors->has('test-too'));
}
public function testDoesNotConfigureProcessorServicesWhenConfigServiceNotPresent()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(false);
$container->get('config')->shouldNotBeCalled();
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container->reveal(), 'ProcessorManager');
$this->assertInstanceOf(ProcessorPluginManager::class, $processors);
}
public function testDoesNotConfigureProcessorServicesWhenConfigServiceDoesNotContainProcessorsConfig()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn(['foo' => 'bar']);
$factory = new ProcessorPluginManagerFactory();
$processors = $factory($container->reveal(), 'ProcessorManager');
$this->assertInstanceOf(ProcessorPluginManager::class, $processors);
$this->assertFalse($processors->has('foo'));
}
}
PK AP
' test/FilterPluginManagerFactoryTest.phpnu W+A prophesize(ContainerInterface::class)->reveal();
$factory = new FilterPluginManagerFactory();
$filters = $factory($container, FilterPluginManagerFactory::class);
$this->assertInstanceOf(FilterPluginManager::class, $filters);
if (method_exists($filters, 'configure')) {
// laminas-servicemanager v3
$this->assertAttributeSame($container, 'creationContext', $filters);
} else {
// laminas-servicemanager v2
$this->assertSame($container, $filters->getServiceLocator());
}
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderContainerInterop()
{
$container = $this->prophesize(ContainerInterface::class)->reveal();
$filter = $this->prophesize(FilterInterface::class)->reveal();
$factory = new FilterPluginManagerFactory();
$filters = $factory($container, FilterPluginManagerFactory::class, [
'services' => [
'test' => $filter,
],
]);
$this->assertSame($filter, $filters->get('test'));
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderServiceManagerV2()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$filter = $this->prophesize(FilterInterface::class)->reveal();
$factory = new FilterPluginManagerFactory();
$factory->setCreationOptions([
'services' => [
'test' => $filter,
],
]);
$filters = $factory->createService($container->reveal());
$this->assertSame($filter, $filters->get('test'));
}
public function testConfiguresFilterServicesWhenFound()
{
$filter = $this->prophesize(FilterInterface::class)->reveal();
$config = [
'log_filters' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($filter) {
return $filter;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn($config);
$factory = new FilterPluginManagerFactory();
$filters = $factory($container->reveal(), 'FilterManager');
$this->assertInstanceOf(FilterPluginManager::class, $filters);
$this->assertTrue($filters->has('test'));
$this->assertSame($filter, $filters->get('test'));
$this->assertTrue($filters->has('test-too'));
$this->assertSame($filter, $filters->get('test-too'));
}
public function testDoesNotConfigureFilterServicesWhenServiceListenerPresent()
{
$filter = $this->prophesize(FilterInterface::class)->reveal();
$config = [
'log_filters' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($filter) {
return $filter;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(true);
$container->has('config')->shouldNotBeCalled();
$container->get('config')->shouldNotBeCalled();
$factory = new FilterPluginManagerFactory();
$filters = $factory($container->reveal(), 'FilterManager');
$this->assertInstanceOf(FilterPluginManager::class, $filters);
$this->assertFalse($filters->has('test'));
$this->assertFalse($filters->has('test-too'));
}
public function testDoesNotConfigureFilterServicesWhenConfigServiceNotPresent()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(false);
$container->get('config')->shouldNotBeCalled();
$factory = new FilterPluginManagerFactory();
$filters = $factory($container->reveal(), 'FilterManager');
$this->assertInstanceOf(FilterPluginManager::class, $filters);
}
public function testDoesNotConfigureFilterServicesWhenConfigServiceDoesNotContainFiltersConfig()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn(['foo' => 'bar']);
$factory = new FilterPluginManagerFactory();
$filters = $factory($container->reveal(), 'FilterManager');
$this->assertInstanceOf(FilterPluginManager::class, $filters);
$this->assertFalse($filters->has('foo'));
}
}
PK APitS)> )> test/LoggerTest.phpnu W+A logger = new Logger;
}
public function testUsesWriterPluginManagerByDefault()
{
$this->assertInstanceOf('Laminas\Log\WriterPluginManager', $this->logger->getWriterPluginManager());
}
public function testPassingShortNameToPluginReturnsWriterByThatName()
{
$writer = $this->logger->writerPlugin('mock');
$this->assertInstanceOf('Laminas\Log\Writer\Mock', $writer);
}
public function testPassWriterAsString()
{
$this->logger->addWriter('mock');
$writers = $this->logger->getWriters();
$this->assertInstanceOf('Laminas\Stdlib\SplPriorityQueue', $writers);
}
public function testEmptyWriter()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('No log writer specified');
$this->logger->log(Logger::INFO, 'test');
}
public function testSetWriters()
{
$writer1 = $this->logger->writerPlugin('mock');
$writer2 = $this->logger->writerPlugin('null');
$writers = new SplPriorityQueue();
$writers->insert($writer1, 1);
$writers->insert($writer2, 2);
$this->logger->setWriters($writers);
$writers = $this->logger->getWriters();
$this->assertInstanceOf('Laminas\Stdlib\SplPriorityQueue', $writers);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Noop', $writer);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Mock', $writer);
}
public function testAddWriterWithPriority()
{
$writer1 = $this->logger->writerPlugin('mock');
$this->logger->addWriter($writer1, 1);
$writer2 = $this->logger->writerPlugin('null');
$this->logger->addWriter($writer2, 2);
$writers = $this->logger->getWriters();
$this->assertInstanceOf('Laminas\Stdlib\SplPriorityQueue', $writers);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Noop', $writer);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Mock', $writer);
}
public function testAddWithSamePriority()
{
$writer1 = $this->logger->writerPlugin('mock');
$this->logger->addWriter($writer1, 1);
$writer2 = $this->logger->writerPlugin('null');
$this->logger->addWriter($writer2, 1);
$writers = $this->logger->getWriters();
$this->assertInstanceOf('Laminas\Stdlib\SplPriorityQueue', $writers);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Mock', $writer);
$writer = $writers->extract();
$this->assertInstanceOf('Laminas\Log\Writer\Noop', $writer);
}
public function testLogging()
{
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->logger->log(Logger::INFO, 'tottakai');
$this->assertEquals(count($writer->events), 1);
$this->assertContains('tottakai', $writer->events[0]['message']);
}
public function testLoggingArray()
{
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->logger->log(Logger::INFO, ['test']);
$this->assertEquals(count($writer->events), 1);
$this->assertContains('test', $writer->events[0]['message']);
}
public function testAddFilter()
{
$writer = new MockWriter;
$filter = new MockFilter;
$writer->addFilter($filter);
$this->logger->addWriter($writer);
$this->logger->log(Logger::INFO, ['test']);
$this->assertEquals(count($filter->events), 1);
$this->assertContains('test', $filter->events[0]['message']);
}
public function testAddFilterByName()
{
$writer = new MockWriter;
$writer->addFilter('mock');
$this->logger->addWriter($writer);
$this->logger->log(Logger::INFO, ['test']);
$this->assertEquals(count($writer->events), 1);
$this->assertContains('test', $writer->events[0]['message']);
}
/**
* provideTestFilters
*/
public function provideTestFilters()
{
$data = [
['priority', ['priority' => Logger::INFO]],
['regex', [ 'regex' => '/[0-9]+/' ]],
];
// Conditionally enabled until laminas-validator is forwards-compatible
// with laminas-servicemanager v3.
if (class_exists(DigitsFilter::class)) {
$data[] = ['validator', ['validator' => new DigitsFilter]];
}
return $data;
}
/**
* @dataProvider provideTestFilters
*/
public function testAddFilterByNameWithParams($filter, $options)
{
$writer = new MockWriter;
$writer->addFilter($filter, $options);
$this->logger->addWriter($writer);
$this->logger->log(Logger::INFO, '123');
$this->assertEquals(count($writer->events), 1);
$this->assertContains('123', $writer->events[0]['message']);
}
public static function provideAttributes()
{
return [
[[]],
[['user' => 'foo', 'ip' => '127.0.0.1']],
[new \ArrayObject(['id' => 42])],
];
}
/**
* @dataProvider provideAttributes
*/
public function testLoggingCustomAttributesForUserContext($extra)
{
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->logger->log(Logger::ERR, 'tottakai', $extra);
$this->assertEquals(count($writer->events), 1);
$this->assertInternalType('array', $writer->events[0]['extra']);
$this->assertEquals(count($writer->events[0]['extra']), count($extra));
}
public static function provideInvalidArguments()
{
return [
[new \stdClass(), ['valid']],
['valid', null],
['valid', true],
['valid', 10],
['valid', 'invalid'],
['valid', new \stdClass()],
];
}
/**
* @dataProvider provideInvalidArguments
*/
public function testPassingInvalidArgumentToLogRaisesException($message, $extra)
{
$this->expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->logger->log(Logger::ERR, $message, $extra);
}
public function testRegisterErrorHandler()
{
$writer = new MockWriter;
$this->logger->addWriter($writer);
$previous = Logger::registerErrorHandler($this->logger);
$this->assertNotNull($previous);
$this->assertNotFalse($previous);
// check for single error handler instance
$this->assertFalse(Logger::registerErrorHandler($this->logger));
// generate a warning
echo $test; // $test is not defined
Logger::unregisterErrorHandler();
$this->assertEquals($writer->events[0]['message'], 'Undefined variable: test');
}
public function testOptionsWithMock()
{
$options = ['writers' => [
'first_writer' => [
'name' => 'mock',
]
]];
$logger = new Logger($options);
$writers = $logger->getWriters()->toArray();
$this->assertCount(1, $writers);
$this->assertInstanceOf('Laminas\Log\Writer\Mock', $writers[0]);
}
public function testOptionsWithWriterOptions()
{
$options = ['writers' => [
[
'name' => 'stream',
'options' => [
'stream' => 'php://output',
'log_separator' => 'foo'
],
]
]];
$logger = new Logger($options);
$writers = $logger->getWriters()->toArray();
$this->assertCount(1, $writers);
$this->assertInstanceOf('Laminas\Log\Writer\Stream', $writers[0]);
$this->assertEquals('foo', $writers[0]->getLogSeparator());
}
public function testOptionsWithMockAndProcessor()
{
$options = [
'writers' => [
'first_writer' => [
'name' => 'mock',
],
],
'processors' => [
'first_processor' => [
'name' => 'requestid',
],
]
];
$logger = new Logger($options);
$processors = $logger->getProcessors()->toArray();
$this->assertCount(1, $processors);
$this->assertInstanceOf('Laminas\Log\Processor\RequestId', $processors[0]);
}
public function testAddProcessor()
{
$processor = new Backtrace();
$this->logger->addProcessor($processor);
$processors = $this->logger->getProcessors()->toArray();
$this->assertEquals($processor, $processors[0]);
}
public function testAddProcessorByName()
{
$this->logger->addProcessor('backtrace');
$processors = $this->logger->getProcessors()->toArray();
$this->assertInstanceOf('Laminas\Log\Processor\Backtrace', $processors[0]);
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->logger->log(Logger::ERR, 'foo');
}
public function testProcessorOutputAdded()
{
$processor = new Backtrace();
$this->logger->addProcessor($processor);
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->logger->log(Logger::ERR, 'foo');
$this->assertEquals(__FILE__, $writer->events[0]['extra']['file']);
}
public function testExceptionHandler()
{
$writer = new MockWriter;
$this->logger->addWriter($writer);
$this->assertTrue(Logger::registerExceptionHandler($this->logger));
// check for single error handler instance
$this->assertFalse(Logger::registerExceptionHandler($this->logger));
// get the internal exception handler
$exceptionHandler = set_exception_handler(function ($e) {
});
set_exception_handler($exceptionHandler);
// reset the exception handler
Logger::unregisterExceptionHandler();
// call the exception handler
$exceptionHandler(new Exception('error', 200, new Exception('previos', 100)));
$exceptionHandler(new ErrorException('user notice', 1000, E_USER_NOTICE, __FILE__, __LINE__));
// check logged messages
$expectedEvents = [
['priority' => Logger::ERR, 'message' => 'previos', 'file' => __FILE__],
['priority' => Logger::ERR, 'message' => 'error', 'file' => __FILE__],
['priority' => Logger::NOTICE, 'message' => 'user notice', 'file' => __FILE__],
];
for ($i = 0; $i < count($expectedEvents); $i++) {
$expectedEvent = $expectedEvents[$i];
$event = $writer->events[$i];
$this->assertEquals($expectedEvent['priority'], $event['priority'], 'Unexpected priority');
$this->assertEquals($expectedEvent['message'], $event['message'], 'Unexpected message');
$this->assertEquals($expectedEvent['file'], $event['extra']['file'], 'Unexpected file');
}
}
public function testLogExtraArrayKeyWithNonArrayValue()
{
$stream = fopen("php://memory", "r+");
$options = [
'writers' => [
[
'name' => 'stream',
'options' => [
'stream' => $stream
],
],
],
];
$logger = new Logger($options);
$this->assertInstanceOf('Laminas\Log\Logger', $logger->info('Hi', ['extra' => '']));
fclose($stream);
}
/**
* @group 5383
*/
public function testErrorHandlerWithStreamWriter()
{
$options = ['errorhandler' => true];
$logger = new Logger($options);
$stream = fopen('php://memory', 'w+');
$streamWriter = new StreamWriter($stream);
// error handler does not like this feature so turn it off
$streamWriter->setConvertWriteErrorsToExceptions(false);
$logger->addWriter($streamWriter);
// we raise two notices - both should be logged
echo $test;
echo $second;
rewind($stream);
$contents = stream_get_contents($stream);
$this->assertContains('test', $contents);
$this->assertContains('second', $contents);
}
/**
* @runInSeparateProcess
*/
public function testRegisterFatalShutdownFunction()
{
if (PHP_VERSION_ID >= 70000) {
$this->markTestSkipped('PHP7: cannot test as code now raises E_ERROR');
}
$writer = new MockWriter;
$this->logger->addWriter($writer);
$result = Logger::registerFatalErrorShutdownFunction($this->logger);
$this->assertTrue($result);
// check for single error handler instance
$this->assertFalse(Logger::registerFatalErrorShutdownFunction($this->logger));
register_shutdown_function(function () use ($writer) {
$this->assertEquals(
'Call to undefined method LaminasTest\Log\LoggerTest::callToNonExistingMethod()',
$writer->events[0]['message']
);
});
// Temporarily hide errors, because we don't want the fatal error to fail the test
@$this->callToNonExistingMethod();
}
/**
* @runInSeparateProcess
*
* @group 6424
*/
public function testRegisterFatalErrorShutdownFunctionHandlesCompileTimeErrors()
{
if (PHP_VERSION_ID >= 70000) {
$this->markTestSkipped('PHP7: cannot test as code now raises E_ERROR');
}
$writer = new MockWriter;
$this->logger->addWriter($writer);
$result = Logger::registerFatalErrorShutdownFunction($this->logger);
$this->assertTrue($result);
// check for single error handler instance
$this->assertFalse(Logger::registerFatalErrorShutdownFunction($this->logger));
register_shutdown_function(function () use ($writer) {
$this->assertStringMatchesFormat(
'syntax error%A',
$writer->events[0]['message']
);
});
// Temporarily hide errors, because we don't want the fatal error to fail the test
@eval('this::code::is::invalid {}');
}
/**
* @group Laminas-7238
*/
public function testCatchExceptionNotValidPriority()
{
$this->expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('$priority must be an integer >= 0 and < 8; received -1');
$writer = new MockWriter();
$this->logger->addWriter($writer);
$this->logger->log(-1, 'Foo');
}
}
PK AP
vȖs s test/Formatter/FirePhpTest.phpnu W+A 'foo',
'extra' => new \stdClass() ];
$f = new FirePhp();
list($line, $label) = $f->format($fields);
$this->assertContains($fields['message'], $label);
$this->assertEquals($fields['extra'], $line);
}
public function testFormatWithoutExtra()
{
$fields = [ 'message' => 'foo' ];
$f = new FirePhp();
list($line, $label) = $f->format($fields);
$this->assertContains($fields['message'], $line);
$this->assertNull($label);
}
public function testFormatWithEmptyExtra()
{
$fields = [ 'message' => 'foo',
'extra' => [] ];
$f = new FirePhp();
list($line, $label) = $f->format($fields);
$this->assertContains($fields['message'], $line);
$this->assertNull($label);
}
public function testSetDateTimeFormatDoesNothing()
{
$formatter = new FirePhp();
$this->assertEquals('', $formatter->getDateTimeFormat());
$this->assertSame($formatter, $formatter->setDateTimeFormat('r'));
$this->assertEquals('', $formatter->getDateTimeFormat());
}
}
PK APjȣ
# test/Formatter/ErrorHandlerTest.phpnu W+A $date,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'errno' => 1,
'file' => 'test.php',
'line' => 1,
'context' => ['object' => new DateTime(), 'string' => 'test']
]
];
$formatter = new ErrorHandler();
$output = $formatter->format($event);
$this->assertEquals($date->format('c') . ' CRIT (1) test (errno 1) in test.php on line 1', $output);
}
public function testSetDateTimeFormat()
{
$formatter = new ErrorHandler();
$this->assertEquals('c', $formatter->getDateTimeFormat());
$this->assertSame($formatter, $formatter->setDateTimeFormat('r'));
$this->assertEquals('r', $formatter->getDateTimeFormat());
}
public function testComplexEvent()
{
$date = new DateTime();
$stringObject = new StringObject();
$event = [
'timestamp' => $date,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'errno' => 1,
'file' => 'test.php',
'line' => 1,
'context' => [
'object1' => new StringObject(),
'object2' => new NotStringObject(),
'string' => 'test1',
'array' => [
'key' => 'test2'
]
]
]
];
$formatString = '%extra[context][object1]% %extra[context][object2]% %extra[context][string]% '
.'%extra[context][array]% %extra[context][array][key]%';
$formatter = new ErrorHandler($formatString);
$output = $formatter->format($event);
$this->assertEquals(
$stringObject->__toString() .' %extra[context][object2]% test1 %extra[context][array]% test2',
$output
);
}
}
PK AP}d
d
test/Formatter/SimpleTest.phpnu W+A expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('must be a string');
new Simple(1);
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testConstructorWithOptions($dateTimeFormat)
{
$options = ['dateTimeFormat' => $dateTimeFormat, 'format' => '%timestamp%'];
$formatter = new Simple($options);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
$this->assertAttributeEquals('%timestamp%', 'format', $formatter);
}
public function testDefaultFormat()
{
$date = new DateTime('2012-08-28T18:15:00Z');
$fields = [
'timestamp' => $date,
'message' => 'foo',
'priority' => 42,
'priorityName' => 'bar',
'extra' => []
];
$outputExpected = '2012-08-28T18:15:00+00:00 bar (42): foo';
$formatter = new Simple();
$this->assertEquals($outputExpected, $formatter->format($fields));
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testCustomDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$event = ['timestamp' => $date];
$formatter = new Simple('%timestamp%', $dateTimeFormat);
$this->assertEquals($date->format($dateTimeFormat), $formatter->format($event));
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$event = ['timestamp' => $date];
$formatter = new Simple('%timestamp%');
$this->assertSame($formatter, $formatter->setDateTimeFormat($dateTimeFormat));
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
$this->assertEquals($date->format($dateTimeFormat), $formatter->format($event));
}
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
];
}
/**
* @group Laminas-10427
*/
public function testDefaultFormatShouldDisplayExtraInformations()
{
$message = 'custom message';
$exception = new RuntimeException($message);
$event = [
'timestamp' => new DateTime(),
'message' => 'Application error',
'priority' => 2,
'priorityName' => 'CRIT',
'extra' => [$exception],
];
$formatter = new Simple();
$output = $formatter->format($event);
$this->assertContains($message, $output);
}
public function testAllowsSpecifyingFormatAsConstructorArgument()
{
$format = '[%timestamp%] %message%';
$formatter = new Simple($format);
$this->assertEquals($format, $formatter->format([]));
}
}
PK APp
' test/Formatter/ExceptionHandlerTest.phpnu W+A $date,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'file' => 'test.php',
'line' => 1,
'trace' => [
[
'file' => 'test.php',
'line' => 1,
'function' => 'test',
'class' => 'Test',
'type' => '::',
'args' => [1]
],
[
'file' => 'test.php',
'line' => 2,
'function' => 'test',
'class' => 'Test',
'type' => '::',
'args' => [1]
]
]
]
];
// The formatter ends with unix style line endings so make sure we expect that
// output as well:
$expected = $date->format('c') . " CRIT (1) test in test.php on line 1\n";
$expected .= "[Trace]\n";
$expected .= "File : test.php\n";
$expected .= "Line : 1\n";
$expected .= "Func : test\n";
$expected .= "Class : Test\n";
$expected .= "Type : static\n";
$expected .= "Args : Array\n";
$expected .= "(\n";
$expected .= " [0] => 1\n";
$expected .= ")\n\n";
$expected .= "File : test.php\n";
$expected .= "Line : 2\n";
$expected .= "Func : test\n";
$expected .= "Class : Test\n";
$expected .= "Type : static\n";
$expected .= "Args : Array\n";
$expected .= "(\n";
$expected .= " [0] => 1\n";
$expected .= ")\n\n";
$formatter = new ExceptionHandler();
$output = $formatter->format($event);
$this->assertEquals($expected, $output);
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$event = [
'timestamp' => $date,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'file' => 'test.php',
'line' => 1,
],
];
$expected = $date->format($dateTimeFormat) . ' CRIT (1) test in test.php on line 1';
$formatter = new ExceptionHandler();
$this->assertSame($formatter, $formatter->setDateTimeFormat($dateTimeFormat));
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
$this->assertEquals($expected, $formatter->format($event));
}
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
];
}
}
PK AP
vG) G) test/Formatter/XmlTest.phpnu W+A format(['timestamp' => $date, 'message' => 'foo', 'priority' => 42]);
$this->assertContains($date->format('c'), $line);
$this->assertContains('foo', $line);
$this->assertContains((string)42, $line);
}
public function testConfiguringElementMapping()
{
$f = new XmlFormatter('log', ['foo' => 'bar']);
$line = $f->format(['bar' => 'baz']);
$this->assertContains('baz', $line);
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testConfiguringDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$f = new XmlFormatter('log', null, 'UTF-8', $dateTimeFormat);
$this->assertContains($date->format($dateTimeFormat), $f->format(['timestamp' => $date]));
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$f = new XmlFormatter();
$this->assertSame($f, $f->setDateTimeFormat($dateTimeFormat));
$this->assertContains($dateTimeFormat, $f->getDateTimeFormat());
$this->assertContains($date->format($dateTimeFormat), $f->format(['timestamp' => $date]));
}
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
];
}
public function testXmlDeclarationIsStripped()
{
$f = new XmlFormatter();
$line = $f->format(['message' => 'foo', 'priority' => 42]);
$this->assertNotContains('<\?xml version=', $line);
}
public function testXmlValidates()
{
$f = new XmlFormatter();
$line = $f->format(['message' => 'foo', 'priority' => 42]);
$sxml = @simplexml_load_string($line);
$this->assertInstanceOf('SimpleXMLElement', $sxml, 'Formatted XML is invalid');
}
/**
* @group Laminas-2062
* @group Laminas-4190
*/
public function testHtmlSpecialCharsInMessageGetEscapedForValidXml()
{
$f = new XmlFormatter();
$line = $f->format(['message' => '&key1=value1&key2=value2', 'priority' => 42]);
$this->assertContains("&", $line);
$this->assertEquals(2, substr_count($line, "&"));
}
/**
* @group Laminas-2062
* @group Laminas-4190
*/
public function testFixingBrokenCharsSoXmlIsValid()
{
$f = new XmlFormatter();
$line = $f->format(['message' => '&', 'priority' => 42]);
$this->assertContains('&', $line);
}
public function testConstructorWithArray()
{
$date = new DateTime();
$options = [
'rootElement' => 'log',
'elementMap' => [
'date' => 'timestamp',
'word' => 'message',
'priority' => 'priority'
],
'dateTimeFormat' => 'r',
];
$event = [
'timestamp' => $date,
'message' => 'tottakai',
'priority' => 4
];
$expected = sprintf(
'%stottakai4',
$date->format('r')
);
$formatter = new XmlFormatter($options);
$output = $formatter->format($event);
$this->assertContains($expected, $output);
$this->assertEquals('UTF-8', $formatter->getEncoding());
}
/**
* @group Laminas-11161
*/
public function testNonScalarValuesAreExcludedFromFormattedString()
{
$options = [
'rootElement' => 'log'
];
$event = [
'message' => 'tottakai',
'priority' => 4,
'context' => ['test' => 'one'],
'reference' => new XmlFormatter()
];
$expected = 'tottakai4';
$formatter = new XmlFormatter($options);
$output = $formatter->format($event);
$this->assertContains($expected, $output);
}
/**
* @group Laminas-11161
*/
public function testObjectsWithStringSerializationAreIncludedInFormattedString()
{
$options = [
'rootElement' => 'log'
];
$event = [
'message' => 'tottakai',
'priority' => 4,
'context' => ['test' => 'one'],
'reference' => new SerializableObject()
];
$expected = 'tottakai4'
.'LaminasTest\Log\TestAsset\SerializableObject';
$formatter = new XmlFormatter($options);
$output = $formatter->format($event);
$this->assertContains($expected, $output);
}
/**
* @group Laminas-453
*/
public function testFormatWillRemoveExtraEmptyArrayFromEvent()
{
$formatter = new XmlFormatter;
$d = new DateTime('2001-01-01T12:00:00-06:00');
$event = [
'timestamp' => $d,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => []
];
$expected = '2001-01-01T12:00:00-06:00test'
.'1CRIT';
$expected .= "\n" . PHP_EOL;
$this->assertEquals($expected, $formatter->format($event));
}
public function testFormatWillAcceptSimpleArrayFromExtra()
{
$formatter = new XmlFormatter;
$d = new DateTime('2001-01-01T12:00:00-06:00');
$event = [
'timestamp' => $d,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'test' => 'one',
'bar' => 'foo',
'wrong message' => 'dasdasd'
]
];
$expected = '2001-01-01T12:00:00-06:00test'
.'1CRITone'
.'foo';
$expected .= "\n" . PHP_EOL;
$this->assertEquals($expected, $formatter->format($event));
}
public function testFormatWillAcceptNestedArrayFromExtraEvent()
{
$formatter = new XmlFormatter;
$d = new DateTime('2001-01-01T12:00:00-06:00');
$event = [
'timestamp' => $d,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'test' => [
'one',
'two' => [
'three' => [
'four' => 'four'
],
'five' => ['']
]
],
'1111' => '2222',
'test_null' => null,
'test_int' => 14,
'test_object' => new \stdClass(),
new SerializableObject(),
'serializable_object' => new SerializableObject(),
null,
'test_empty_array' => [],
'bar' => 'foo',
'foobar'
]
];
$expected = '2001-01-01T12:00:00-06:00test'
.'1CRITfour'
.'14'
.'"Object" of type stdClass does not support __toString() method'
.'LaminasTest\Log\TestAsset\SerializableObject'
.'foo';
$expected .= "\n" . PHP_EOL;
$this->assertEquals($expected, $formatter->format($event));
}
public function testFormatWillEscapeAmpersand()
{
$formatter = new XmlFormatter;
$d = new DateTime('2001-01-01T12:00:00-06:00');
$event = [
'timestamp' => $d,
'message' => 'test',
'priority' => 1,
'priorityName' => 'CRIT',
'extra' => [
'test' => [
'one',
'two' => [
'three' => [
'four' => 'four&four'
],
'five' => ['']
]
],
'1111' => '2222',
'test_null' => null,
'test_int' => 14,
'test_object' => new \stdClass(),
new SerializableObject(),
'serializable_object' => new SerializableObject(),
null,
'test_empty_array' => [],
'bar' => 'foo',
'foobar'
]
];
// @codingStandardsIgnoreStart
$expected = '2001-01-01T12:00:00-06:00test1CRITfour&four14"Object" of type stdClass does not support __toString() methodLaminasTest\Log\TestAsset\SerializableObjectfoo';
$expected .= "\n" . PHP_EOL;
// @codingStandardsIgnoreEnd
$this->assertEquals($expected, $formatter->format($event));
}
}
PK API08[ [ test/Formatter/JsonTest.phpnu W+A format(['timestamp' => $date, 'message' => 'foo', 'priority' => 42]);
$json = json_decode($line);
$this->assertEquals($date->format('c'), $json->timestamp);
$this->assertEquals('foo', $json->message);
$this->assertEquals((string)42, $json->priority);
}
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
];
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$date = new DateTime();
$f = new Json();
$f->setDateTimeFormat($dateTimeFormat);
$line = $f->format(['timestamp' => $date]);
$json = json_decode($line);
$this->assertEquals($date->format($dateTimeFormat), $json->timestamp);
}
}
PK APX, test/Formatter/BaseTest.phpnu W+A assertEquals(BaseFormatter::DEFAULT_DATETIME_FORMAT, $formatter->getDateTimeFormat());
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testAllowsSpecifyingDateTimeFormatAsConstructorArgument($dateTimeFormat)
{
$formatter = new BaseFormatter($dateTimeFormat);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}
/**
* @return array
*/
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
[DateTime::RSS],
];
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$formatter = new BaseFormatter();
$formatter->setDateTimeFormat($dateTimeFormat);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormatInConstructor($dateTimeFormat)
{
$options = ['dateTimeFormat' => $dateTimeFormat];
$formatter = new BaseFormatter($options);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}
public function testFormatAllTypes()
{
$datetime = new DateTime();
$object = new stdClass();
$object->foo = 'bar';
$formatter = new BaseFormatter();
$event = [
'timestamp' => $datetime,
'priority' => 1,
'message' => 'tottakai',
'extra' => [
'float' => 0.2,
'boolean' => false,
'array_empty' => [],
'array' => range(0, 4),
'traversable_empty' => new EmptyIterator(),
'traversable' => new ArrayIterator(['id', 42]),
'null' => null,
'object_empty' => new stdClass(),
'object' => $object,
'string object' => new StringObject(),
'resource' => fopen('php://stdout', 'w'),
],
];
$outputExpected = [
'timestamp' => $datetime->format($formatter->getDateTimeFormat()),
'priority' => 1,
'message' => 'tottakai',
'extra' => [
'boolean' => false,
'float' => 0.2,
'array_empty' => '[]',
'array' => '[0,1,2,3,4]',
'traversable_empty' => '[]',
'traversable' => '["id",42]',
'null' => null,
'object_empty' => 'object(stdClass) {}',
'object' => 'object(stdClass) {"foo":"bar"}',
'string object' => 'Hello World',
'resource' => 'resource(stream)',
],
];
$this->assertEquals($outputExpected, $formatter->format($event));
}
public function testFormatNoInfiniteLoopOnSelfReferencingArrayValues()
{
$datetime = new DateTime();
$formatter = new BaseFormatter();
$selfRefArr = [];
$selfRefArr['selfRefArr'] = & $selfRefArr;
$event = [
'timestamp' => $datetime,
'priority' => 1,
'message' => 'tottakai',
'extra' => [
'selfRefArr' => $selfRefArr,
],
];
$outputExpected = [
'timestamp' => $datetime->format($formatter->getDateTimeFormat()),
'priority' => 1,
'message' => 'tottakai',
'extra' => [
'selfRefArr' => '',
],
];
$this->assertEquals($outputExpected, $formatter->format($event));
}
public function testFormatExtraArrayKeyWithNonArrayValue()
{
$formatter = new BaseFormatter();
$event = [
'message' => 'Hi',
'extra' => '',
];
$outputExpected = [
'message' => 'Hi',
'extra' => '',
];
$this->assertEquals($outputExpected, $formatter->format($event));
}
}
PK APj test/Formatter/DbTest.phpnu W+A assertEquals(DbFormatter::DEFAULT_DATETIME_FORMAT, $formatter->getDateTimeFormat());
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testSetDateTimeFormat($dateTimeFormat)
{
$formatter = new DbFormatter();
$formatter->setDateTimeFormat($dateTimeFormat);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}
/**
* @return array
*/
public function provideDateTimeFormats()
{
return [
['r'],
['U'],
[DateTime::RSS],
];
}
/**
* @dataProvider provideDateTimeFormats
*/
public function testAllowsSpecifyingDateTimeFormatAsConstructorArgument($dateTimeFormat)
{
$formatter = new DbFormatter($dateTimeFormat);
$this->assertEquals($dateTimeFormat, $formatter->getDateTimeFormat());
}
public function testFormatDateTimeInEvent()
{
$datetime = new DateTime();
$event = ['timestamp' => $datetime];
$formatter = new DbFormatter();
$format = DbFormatter::DEFAULT_DATETIME_FORMAT;
$this->assertContains($datetime->format($format), $formatter->format($event));
}
}
PK APw test/TestAsset/StringObject.phpnu W+A calls[$method][] = $params;
}
}
PK APql/ / test/TestAsset/MockChromePhp.phpnu W+A enabled = $enabled;
}
public function getEnabled()
{
return $this->enabled;
}
public function error($line)
{
$this->calls['error'][] = $line;
}
public function warn($line)
{
$this->calls['warn'][] = $line;
}
public function info($line)
{
$this->calls['info'][] = $line;
}
public function trace($line)
{
$this->calls['trace'][] = $line;
}
public function log($line)
{
$this->calls['log'][] = $line;
}
}
PK AP:e| test/TestAsset/MockDbAdapter.phpnu W+A calls[$method][] = $params;
}
public function __construct()
{
$this->platform = new MockDbPlatform;
$this->driver = new MockDbDriver;
}
public function query(
$sql,
$parametersOrQueryMode = DbAdapter::QUERY_MODE_PREPARE,
ResultSetInterface $resultPrototype = null
) {
$this->calls[__FUNCTION__][] = $sql;
return $this;
}
}
PK AP test/TestAsset/MockDbDriver.phpnu W+A calls[$method][] = $params;
}
}
PK APq;> > % test/TestAsset/CustomSyslogWriter.phpnu W+A facility;
}
public function getApplicationName()
{
return $this->appName;
}
}
PK APޮ~ ~ " test/TestAsset/NotStringObject.phpnu W+A enabled = $enabled;
}
public function getEnabled()
{
return $this->enabled;
}
public function error($line)
{
$this->calls['error'][] = $line;
}
public function warn($line)
{
$this->calls['warn'][] = $line;
}
public function info($line)
{
$this->calls['info'][] = $line;
}
public function trace($line)
{
$this->calls['trace'][] = $line;
}
public function log($line)
{
$this->calls['log'][] = $line;
}
}
PK APh9 9 ( test/TestAsset/ErrorGeneratingWriter.phpnu W+A getPluginManager();
$r = new ReflectionProperty($pluginManager, 'aliases');
$r->setAccessible(true);
$aliases = $r->getValue($pluginManager);
foreach ($aliases as $alias => $target) {
switch ($target) {
case Filter\Priority::class:
// intentionally fall through
case Filter\Regex::class:
// intentionally fall through
case Filter\Timestamp::class:
// intentionally fall through
case Filter\Validator::class:
// Skip, as these each have required arguments
break;
default:
yield $alias => [$alias, $target];
}
}
}
}
PK APp test/LoggerAwareTraitTest.phpnu W+A getObjectForTrait('\Laminas\Log\LoggerAwareTrait');
$this->assertAttributeEquals(null, 'logger', $object);
$logger = new Logger;
$object->setLogger($logger);
$this->assertAttributeEquals($logger, 'logger', $object);
}
}
PK APhK~ ( test/ServicesNotSharedByDefaultTrait.phpnu W+A getPluginManager();
$r = method_exists($plugins, 'configure')
? new ReflectionProperty($plugins, 'sharedByDefault')
: new ReflectionProperty($plugins, 'shareByDefault');
$r->setAccessible(true);
$this->assertFalse($r->getValue($plugins));
}
}
PK AP5) ) ) test/LoggerAbstractServiceFactoryTest.phpnu W+A serviceManager = new ServiceManager();
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'config' => [
'log' => [
'Application\Frontend' => [],
'Application\Backend' => [],
],
],
],
]);
$config->configureServiceManager($this->serviceManager);
}
/**
* @return array
*/
public function providerValidLoggerService()
{
return [
['Application\Frontend'],
['Application\Backend'],
];
}
/**
* @return array
*/
public function providerInvalidLoggerService()
{
return [
['Logger\Application\Unknown'],
['Logger\Application\Frontend'],
['Application\Backend\Logger'],
];
}
/**
* @param string $service
* @dataProvider providerValidLoggerService
*/
public function testValidLoggerService($service)
{
$actual = $this->serviceManager->get($service);
$this->assertInstanceOf('Laminas\Log\Logger', $actual);
}
/**
* @dataProvider providerInvalidLoggerService
*
* @param string $service
*/
public function testInvalidLoggerService($service)
{
$this->expectException(ServiceNotFoundException::class);
$this->serviceManager->get($service);
}
/**
* @group 5254
*/
public function testRetrievesDatabaseServiceFromServiceManagerWhenEncounteringDbWriter()
{
$db = $this->getMockBuilder('Laminas\Db\Adapter\Adapter')
->disableOriginalConstructor()
->getMock();
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'Db\Logger' => $db,
'config' => [
'log' => [
'Application\Log' => [
'writers' => [
[
'name' => 'db',
'priority' => 1,
'options' => [
'separator' => '_',
'column' => [],
'table' => 'applicationlog',
'db' => 'Db\Logger',
],
],
],
],
],
],
],
]);
$serviceManager = new ServiceManager();
$config->configureServiceManager($serviceManager);
$logger = $serviceManager->get('Application\Log');
$this->assertInstanceOf('Laminas\Log\Logger', $logger);
$writers = $logger->getWriters();
$found = false;
foreach ($writers as $writer) {
if ($writer instanceof DbWriter) {
$found = true;
break;
}
}
$this->assertTrue($found, 'Did not find expected DB writer');
$this->assertAttributeSame($db, 'db', $writer);
}
public function testRetrievesMongoServiceFromServiceManagerWhenEncounteringMongoWriter()
{
if (! extension_loaded('mongo')) {
$this->markTestSkipped('The mongo PHP extension is not available');
}
if (PHP_VERSION_ID >= 70000) {
$this->markTestIncomplete('Code to test is not compatible with PHP 7 ');
}
$mongoClient = $this->getMockBuilder('MongoClient')
->disableOriginalConstructor()
->getMock();
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'mongo_client' => $mongoClient,
'config' => [
'log' => [
'Application\Log' => [
'writers' => [
[
'name' => 'mongo',
'priority' => 1,
'options' => [
'database' => 'applicationdb',
'collection' => 'applicationlog',
'mongo' => 'mongo_client',
],
],
],
],
],
],
],
]);
$serviceManager = new ServiceManager();
$config->configureServiceManager($serviceManager);
$logger = $serviceManager->get('Application\Log');
$this->assertInstanceOf('Laminas\Log\Logger', $logger);
$writers = $logger->getWriters();
$found = false;
foreach ($writers as $writer) {
if ($writer instanceof MongoWriter) {
$found = true;
break;
}
}
$this->assertTrue($found, 'Did not find expected mongo writer');
}
public function testRetrievesMongoDBServiceFromServiceManagerWhenEncounteringMongoDbWriter()
{
if (! extension_loaded('mongodb')) {
$this->markTestSkipped('The mongodb PHP extension is not available');
}
$manager = new Manager('mongodb://localhost:27017');
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'mongo_manager' => $manager,
'config' => [
'log' => [
'Application\Log' => [
'writers' => [
[
'name' => 'mongodb',
'priority' => 1,
'options' => [
'database' => 'applicationdb',
'collection' => 'applicationlog',
'manager' => 'mongo_manager',
],
],
],
],
],
],
],
]);
$serviceManager = new ServiceManager();
$config->configureServiceManager($serviceManager);
$logger = $serviceManager->get('Application\Log');
$this->assertInstanceOf('Laminas\Log\Logger', $logger);
$writers = $logger->getWriters();
$found = false;
foreach ($writers as $writer) {
if ($writer instanceof MongoDBWriter) {
$found = true;
break;
}
}
$this->assertTrue($found, 'Did not find expected mongo db writer');
}
/**
* @group 4455
*/
public function testWillInjectWriterPluginManagerIfAvailable()
{
$writers = new WriterPluginManager(new ServiceManager());
$mockWriter = $this->createMock('Laminas\Log\Writer\WriterInterface');
$writers->setService('CustomWriter', $mockWriter);
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'LogWriterManager' => $writers,
'config' => [
'log' => [
'Application\Frontend' => [
'writers' => [['name' => 'CustomWriter']],
],
],
],
],
]);
$services = new ServiceManager();
$config->configureServiceManager($services);
$log = $services->get('Application\Frontend');
$logWriters = $log->getWriters();
$this->assertEquals(1, count($logWriters));
$writer = $logWriters->current();
$this->assertSame($mockWriter, $writer);
}
/**
* @group 4455
*/
public function testWillInjectProcessorPluginManagerIfAvailable()
{
$processors = new ProcessorPluginManager(new ServiceManager());
$mockProcessor = $this->createMock('Laminas\Log\Processor\ProcessorInterface');
$processors->setService('CustomProcessor', $mockProcessor);
$config = new Config([
'abstract_factories' => [LoggerAbstractServiceFactory::class],
'services' => [
'LogProcessorManager' => $processors,
'config' => [
'log' => [
'Application\Frontend' => [
'writers' => [['name' => Noop::class]],
'processors' => [['name' => 'CustomProcessor']],
],
],
],
],
]);
$services = new ServiceManager();
$config->configureServiceManager($services);
$log = $services->get('Application\Frontend');
$logProcessors = $log->getProcessors();
$this->assertEquals(1, count($logProcessors));
$processor = $logProcessors->current();
$this->assertSame($mockProcessor, $processor);
}
}
PK AP̠: : " test/Filter/SuppressFilterTest.phpnu W+A filter = new SuppressFilter();
}
public function testSuppressIsInitiallyOff()
{
$this->assertTrue($this->filter->filter([]));
}
public function testSuppressByConstructorBoolean()
{
$this->filter = new SuppressFilter(true);
$this->assertFalse($this->filter->filter([]));
$this->assertFalse($this->filter->filter([]));
}
public function testSuppressByConstructorArray()
{
$this->filter = new SuppressFilter(['suppress' => true]);
$this->assertFalse($this->filter->filter([]));
$this->assertFalse($this->filter->filter([]));
}
public function testConstructorThrowsOnInvalidSuppressValue()
{
$this->expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Suppress must be a boolean');
new SuppressFilter('foo');
}
public function testSuppressOn()
{
$this->filter->suppress(true);
$this->assertFalse($this->filter->filter([]));
$this->assertFalse($this->filter->filter([]));
}
public function testSuppressOff()
{
$this->filter->suppress(false);
$this->assertTrue($this->filter->filter([]));
$this->assertTrue($this->filter->filter([]));
}
public function testSuppressCanBeReset()
{
$this->filter->suppress(true);
$this->assertFalse($this->filter->filter([]));
$this->filter->suppress(false);
$this->assertTrue($this->filter->filter([]));
$this->filter->suppress(true);
$this->assertFalse($this->filter->filter([]));
}
}
PK APh1 test/Filter/PriorityTest.phpnu W+A assertTrue($filter->filter(['priority' => 2]));
$this->assertTrue($filter->filter(['priority' => 1]));
$this->assertFalse($filter->filter(['priority' => 3]));
}
public function testComparisonOperatorCanBeChanged()
{
// accept above priority 2
$filter = new Priority(2, '>');
$this->assertTrue($filter->filter(['priority' => 3]));
$this->assertFalse($filter->filter(['priority' => 2]));
$this->assertFalse($filter->filter(['priority' => 1]));
}
public function testConstructorThrowsOnInvalidPriority()
{
$this->expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('must be a number');
new Priority('foo');
}
public function testComparisonStringSupport()
{
// accept at or below priority '2'
$filter = new Priority('2');
$this->assertTrue($filter->filter(['priority' => 2]));
$this->assertTrue($filter->filter(['priority' => 1]));
$this->assertFalse($filter->filter(['priority' => 3]));
}
}
PK APW test/Filter/SampleTest.phpnu W+A expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('must be numeric');
new Sample('bar');
}
public function testSampleLimit0()
{
// Should log nothing.
$filter = new Sample(0);
// Since sampling is a random process, let's test several times.
$ret = false;
for ($i = 0; $i < 100; $i ++) {
if ($filter->filter([])) {
break;
$ret = true;
}
}
$this->assertFalse($ret);
}
public function testSampleLimit1()
{
// Should log all events.
$filter = new Sample(1);
// Since sampling is a random process, let's test several times.
$ret = true;
for ($i = 0; $i < 100; $i ++) {
if (! $filter->filter([])) {
break;
$ret = false;
}
}
$this->assertTrue($ret);
}
}
PK AP^n- - test/Filter/ValidatorTest.phpnu W+A assertTrue($filter->filter(['message' => '123']));
$this->assertFalse($filter->filter(['message' => 'test']));
$this->assertFalse($filter->filter(['message' => 'test123']));
$this->assertFalse($filter->filter(['message' => '(%$']));
}
public function testValidatorChain()
{
$validatorChain = new ValidatorChain();
$validatorChain->attach(new NotEmptyFilter());
$validatorChain->attach(new DigitsFilter());
$filter = new Validator($validatorChain);
$this->assertTrue($filter->filter(['message' => '123']));
$this->assertFalse($filter->filter(['message' => 'test']));
}
}
PK APK test/Filter/MockTest.phpnu W+A assertSame([], $filter->events);
$fields = ['foo' => 'bar'];
$this->assertTrue($filter->filter($fields));
$this->assertSame([$fields], $filter->events);
}
}
PK AP\) test/Filter/TimestampTest.phpnu W+A
*
* @covers \Laminas\Log\Filter\Timestamp
*/
class TimestampTest extends TestCase
{
/**
* @dataProvider dateTimeDataProvider
*/
public function testComparisonWhenValueIsSuppliedAsDateTimeObject(
$timestamp,
$dateTimeValue,
$operator,
$expectation
) {
$filter = new TimestampFilter($dateTimeValue, null, $operator);
$result = $filter->filter(['timestamp' => $timestamp]);
if ($expectation === true) {
$this->assertTrue($result);
} else {
$this->assertFalse($result);
}
}
/**
* @dataProvider datePartDataProvider
*/
public function testComparisonWhenValueIsSuppliedAsDatePartValue(
$timestamp,
$datePartVal,
$datePartChar,
$operator,
$expectation
) {
$filter = new TimestampFilter($datePartVal, $datePartChar, $operator);
$result = $filter->filter(['timestamp' => $timestamp]);
if ($expectation === true) {
$this->assertTrue($result);
} else {
$this->assertFalse($result);
}
}
/**
* @expectedException \Laminas\Log\Exception\InvalidArgumentException
*/
public function testConstructorThrowsOnInvalidValue()
{
new TimestampFilter('foo');
}
/**
* @expectedException \Laminas\Log\Exception\InvalidArgumentException
*/
public function testConstructorThrowsWhenDateFormatCharIsMissing()
{
new TimestampFilter(3);
}
/**
* @expectedException \Laminas\Log\Exception\InvalidArgumentException
*/
public function testConstructorThrowsOnUnsupportedComparisonOperator()
{
new TimestampFilter(10, 'H', 'foobar');
}
public function testFilterCreatedFromArray()
{
$config = [
'value' => 10,
'dateFormatChar' => 'm',
'operator' => '==',
];
$filter = new TimestampFilter($config);
$this->assertAttributeEquals($config['value'], 'value', $filter);
$this->assertAttributeEquals($config['dateFormatChar'], 'dateFormatChar', $filter);
$this->assertAttributeEquals($config['operator'], 'operator', $filter);
}
public function testFilterCreatedFromTraversable()
{
$config = new ArrayObject([
'value' => 10,
'dateFormatChar' => 'm',
'operator' => '==',
]);
$filter = new TimestampFilter($config);
$this->assertAttributeEquals($config['value'], 'value', $filter);
$this->assertAttributeEquals($config['dateFormatChar'], 'dateFormatChar', $filter);
$this->assertAttributeEquals($config['operator'], 'operator', $filter);
}
/**
* @param array $message
*
* @dataProvider ignoredMessages
*/
public function testIgnoresMessagesWithoutTimestamp(array $message)
{
$filter = new TimestampFilter(new DateTime('-10 years'));
$this->assertFalse($filter->filter($message));
}
public function dateTimeDataProvider()
{
$march2 = new DateTime('2014-03-02');
$march3 = new DateTime('2014-03-03');
return [
[new DateTime('2014-03-03'), new DateTime('2014-03-03'), '>=', true],
[new DateTime('2014-10-10'), new DateTime('2014-03-03'),'>=', true],
[new DateTime('2014-03-03'), new DateTime('2014-10-10'), 'gt', false],
[new DateTime('2013-03-03'), new DateTime('2014-03-03'), 'ge', false],
[new DateTime('2014-03-03'), new DateTime('2014-03-03'), '==', true],
[new DateTime('2014-02-02'), new DateTime('2014-03-03'), '<', true],
[new DateTime('2014-03-03'), new DateTime('2014-03-03'), 'lt', false],
[$march3->getTimestamp(), new DateTime('2014-03-03'), 'lt', false],
[$march2->getTimestamp(), new DateTime('2014-03-03'), 'lt', true],
[(string) $march3->getTimestamp(), new DateTime('2014-03-03'), 'lt', false],
[(string) $march2->getTimestamp(), new DateTime('2014-03-03'), 'lt', true],
];
}
public function datePartDataProvider()
{
return [
[new DateTime('2014-03-03 10:15:00'), 10, 'H', '==', true],
[new DateTime('2013-03-03 22:00:00'), 10, 'H', '=', false],
[new DateTime('2014-03-04 10:15:00'), 3, 'd', 'gt', true],
[new DateTime('2014-03-04 10:15:00'), 10, 'd', '<', true],
[new DateTime('2014-03-03 10:15:00'), 1, 'm', 'eq', false],
[new DateTime('2014-03-03 10:15:00'), 2, 'm', 'ge', true],
[new DateTime('2014-03-03 10:15:00'), 20, 'H', '!=', true],
];
}
public function ignoredMessages()
{
return [
[[]],
[['hello world']],
[['timestamp' => null]],
];
}
}
PK AP,{jX test/Filter/RegexTest.phpnu W+A expectException('Laminas\Log\Exception\InvalidArgumentException');
$this->expectExceptionMessage('invalid reg');
new Regex('invalid regexp');
}
public function testMessageFilter()
{
$filter = new Regex('/accept/');
$this->assertTrue($filter->filter(['message' => 'foo accept bar']));
$this->assertFalse($filter->filter(['message' => 'foo reject bar']));
}
}
PK AP\
' test/WriterPluginManagerFactoryTest.phpnu W+A prophesize(ContainerInterface::class)->reveal();
$factory = new WriterPluginManagerFactory();
$writers = $factory($container, WriterPluginManagerFactory::class);
$this->assertInstanceOf(WriterPluginManager::class, $writers);
if (method_exists($writers, 'configure')) {
// laminas-servicemanager v3
$this->assertAttributeSame($container, 'creationContext', $writers);
} else {
// laminas-servicemanager v2
$this->assertSame($container, $writers->getServiceLocator());
}
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderContainerInterop()
{
$container = $this->prophesize(ContainerInterface::class)->reveal();
$writer = $this->prophesize(WriterInterface::class)->reveal();
$factory = new WriterPluginManagerFactory();
$writers = $factory($container, WriterPluginManagerFactory::class, [
'services' => [
'test' => $writer,
],
]);
$this->assertSame($writer, $writers->get('test'));
}
/**
* @depends testFactoryReturnsPluginManager
*/
public function testFactoryConfiguresPluginManagerUnderServiceManagerV2()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$writer = $this->prophesize(WriterInterface::class)->reveal();
$factory = new WriterPluginManagerFactory();
$factory->setCreationOptions([
'services' => [
'test' => $writer,
],
]);
$writers = $factory->createService($container->reveal());
$this->assertSame($writer, $writers->get('test'));
}
public function testConfiguresWriterServicesWhenFound()
{
$writer = $this->prophesize(WriterInterface::class)->reveal();
$config = [
'log_writers' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($writer) {
return $writer;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn($config);
$factory = new WriterPluginManagerFactory();
$writers = $factory($container->reveal(), 'WriterManager');
$this->assertInstanceOf(WriterPluginManager::class, $writers);
$this->assertTrue($writers->has('test'));
$this->assertSame($writer, $writers->get('test'));
$this->assertTrue($writers->has('test-too'));
$this->assertSame($writer, $writers->get('test-too'));
}
public function testDoesNotConfigureWriterServicesWhenServiceListenerPresent()
{
$writer = $this->prophesize(WriterInterface::class)->reveal();
$config = [
'log_writers' => [
'aliases' => [
'test' => 'test-too',
],
'factories' => [
'test-too' => function ($container) use ($writer) {
return $writer;
},
],
],
];
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(true);
$container->has('config')->shouldNotBeCalled();
$container->get('config')->shouldNotBeCalled();
$factory = new WriterPluginManagerFactory();
$writers = $factory($container->reveal(), 'WriterManager');
$this->assertInstanceOf(WriterPluginManager::class, $writers);
$this->assertFalse($writers->has('test'));
$this->assertFalse($writers->has('test-too'));
}
public function testDoesNotConfigureWriterServicesWhenConfigServiceNotPresent()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(false);
$container->get('config')->shouldNotBeCalled();
$factory = new WriterPluginManagerFactory();
$writers = $factory($container->reveal(), 'WriterManager');
$this->assertInstanceOf(WriterPluginManager::class, $writers);
}
public function testDoesNotConfigureWriterServicesWhenConfigServiceDoesNotContainWritersConfig()
{
$container = $this->prophesize(ServiceLocatorInterface::class);
$container->willImplement(ContainerInterface::class);
$container->has('ServiceListener')->willReturn(false);
$container->has('config')->willReturn(true);
$container->get('config')->willReturn(['foo' => 'bar']);
$factory = new WriterPluginManagerFactory();
$writers = $factory($container->reveal(), 'WriterManager');
$this->assertInstanceOf(WriterPluginManager::class, $writers);
$this->assertFalse($writers->has('foo'));
}
}
PK APh 0 test/ProcessorPluginManagerCompatibilityTest.phpnu W+A serviceManager = new ServiceManager();
$config = new Config([
'abstract_factories' => [PsrLoggerAbstractAdapterFactory::class],
'services' => [
'config' => [
'psr_log' => [
'Application\Frontend' => [],
'Application\Backend' => [],
],
],
],
]);
$config->configureServiceManager($this->serviceManager);
}
/**
* @return array
*/
public function providerValidLoggerService()
{
return [
['Application\Frontend'],
['Application\Backend'],
];
}
/**
* @return array
*/
public function providerInvalidLoggerService()
{
return [
['Logger\Application\Unknown'],
['Logger\Application\Frontend'],
['Application\Backend\Logger'],
];
}
/**
* @param string $service
* @dataProvider providerValidLoggerService
*/
public function testValidLoggerService($service)
{
$actual = $this->serviceManager->get($service);
$this->assertInstanceOf('Laminas\Log\PsrLoggerAdapter', $actual);
}
/**
* @dataProvider providerInvalidLoggerService
*
* @param string $service
*/
public function testInvalidLoggerService($service)
{
$this->expectException(ServiceNotFoundException::class);
$this->serviceManager->get($service);
}
}
PK APoyH H test/WriterPluginManagerTest.phpnu W+A plugins = new WriterPluginManager(new ServiceManager());
}
public function testInvokableClassFirephp()
{
$firephp = $this->plugins->get('firephp');
$this->assertInstanceOf('Laminas\Log\Writer\Firephp', $firephp);
}
}
PK AP