Your IP : 216.73.216.162


Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/
Upload File :
Current File : /home/x/b/o/xbodynamge/namtation/wp-content/Monolog.tar

Processor/ProcessIdProcessor.php000066600000001151151136154450013036 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Adds value of getmypid into records
 *
 * @author Andreas Hörnicke
 */
class ProcessIdProcessor implements ProcessorInterface
{
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        $record['extra']['process_id'] = \getmypid();
        return $record;
    }
}
Processor/TagProcessor.php000066600000001533151136154450011662 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Adds a tags array into record
 *
 * @author Martijn Riemers
 */
class TagProcessor implements ProcessorInterface
{
    private $tags;
    public function __construct(array $tags = array())
    {
        $this->setTags($tags);
    }
    public function addTags(array $tags = array())
    {
        $this->tags = \array_merge($this->tags, $tags);
    }
    public function setTags(array $tags = array())
    {
        $this->tags = $tags;
    }
    public function __invoke(array $record)
    {
        $record['extra']['tags'] = $this->tags;
        return $record;
    }
}
Processor/GitProcessor.php000066600000002621151136154450011671 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Injects Git branch and Git commit SHA in all records
 *
 * @author Nick Otter
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class GitProcessor implements ProcessorInterface
{
    private $level;
    private static $cache;
    public function __construct($level = Logger::DEBUG)
    {
        $this->level = Logger::toMonologLevel($level);
    }
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        // return if the level is not high enough
        if ($record['level'] < $this->level) {
            return $record;
        }
        $record['extra']['git'] = self::getGitInfo();
        return $record;
    }
    private static function getGitInfo()
    {
        if (self::$cache) {
            return self::$cache;
        }
        $branches = `git branch -v --no-abbrev`;
        if ($branches && \preg_match('{^\\* (.+?)\\s+([a-f0-9]{40})(?:\\s|$)}m', $branches, $matches)) {
            return self::$cache = array('branch' => $matches[1], 'commit' => $matches[2]);
        }
        return self::$cache = array();
    }
}
Processor/PsrLogMessageProcessor.php000066600000004743151136154450013670 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

use AIOSEO\Vendor\Monolog\Utils;
/**
 * Processes a record's message according to PSR-3 rules
 *
 * It replaces {foo} with the value from $context['foo']
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class PsrLogMessageProcessor implements ProcessorInterface
{
    const SIMPLE_DATE = "Y-m-d\\TH:i:s.uP";
    /** @var string|null */
    private $dateFormat;
    /** @var bool */
    private $removeUsedContextFields;
    /**
     * @param string|null $dateFormat              The format of the timestamp: one supported by DateTime::format
     * @param bool        $removeUsedContextFields If set to true the fields interpolated into message gets unset
     */
    public function __construct($dateFormat = null, $removeUsedContextFields = \false)
    {
        $this->dateFormat = $dateFormat;
        $this->removeUsedContextFields = $removeUsedContextFields;
    }
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        if (\false === \strpos($record['message'], '{')) {
            return $record;
        }
        $replacements = array();
        foreach ($record['context'] as $key => $val) {
            $placeholder = '{' . $key . '}';
            if (\strpos($record['message'], $placeholder) === \false) {
                continue;
            }
            if (\is_null($val) || \is_scalar($val) || \is_object($val) && \method_exists($val, "__toString")) {
                $replacements[$placeholder] = $val;
            } elseif ($val instanceof \DateTime) {
                $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE);
            } elseif (\is_object($val)) {
                $replacements[$placeholder] = '[object ' . Utils::getClass($val) . ']';
            } elseif (\is_array($val)) {
                $replacements[$placeholder] = 'array' . Utils::jsonEncode($val, null, \true);
            } else {
                $replacements[$placeholder] = '[' . \gettype($val) . ']';
            }
            if ($this->removeUsedContextFields) {
                unset($record['context'][$key]);
            }
        }
        $record['message'] = \strtr($record['message'], $replacements);
        return $record;
    }
}
Processor/MercurialProcessor.php000066600000002552151136154450013074 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jonathan A. Schweder <jonathanschweder@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Injects Hg branch and Hg revision number in all records
 *
 * @author Jonathan A. Schweder <jonathanschweder@gmail.com>
 */
class MercurialProcessor implements ProcessorInterface
{
    private $level;
    private static $cache;
    public function __construct($level = Logger::DEBUG)
    {
        $this->level = Logger::toMonologLevel($level);
    }
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        // return if the level is not high enough
        if ($record['level'] < $this->level) {
            return $record;
        }
        $record['extra']['hg'] = self::getMercurialInfo();
        return $record;
    }
    private static function getMercurialInfo()
    {
        if (self::$cache) {
            return self::$cache;
        }
        $result = \explode(' ', \trim(`hg id -nb`));
        if (\count($result) >= 3) {
            return self::$cache = array('branch' => $result[1], 'revision' => $result[2]);
        }
        return self::$cache = array();
    }
}
Processor/MemoryPeakUsageProcessor.php000066600000001442151136154450014204 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Injects memory_get_peak_usage in all records
 *
 * @see Monolog\Processor\MemoryProcessor::__construct() for options
 * @author Rob Jensen
 */
class MemoryPeakUsageProcessor extends MemoryProcessor
{
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        $bytes = \memory_get_peak_usage($this->realUsage);
        $formatted = $this->formatBytes($bytes);
        $record['extra']['memory_peak_usage'] = $formatted;
        return $record;
    }
}
Processor/MemoryUsageProcessor.php000066600000001417151136154450013405 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Injects memory_get_usage in all records
 *
 * @see Monolog\Processor\MemoryProcessor::__construct() for options
 * @author Rob Jensen
 */
class MemoryUsageProcessor extends MemoryProcessor
{
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        $bytes = \memory_get_usage($this->realUsage);
        $formatted = $this->formatBytes($bytes);
        $record['extra']['memory_usage'] = $formatted;
        return $record;
    }
}
Processor/WebProcessor.php000066600000006140151136154450011663 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Injects url/method and remote IP of the current web request in all records
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class WebProcessor implements ProcessorInterface
{
    /**
     * @var array|\ArrayAccess
     */
    protected $serverData;
    /**
     * Default fields
     *
     * Array is structured as [key in record.extra => key in $serverData]
     *
     * @var array
     */
    protected $extraFields = array('url' => 'REQUEST_URI', 'ip' => 'REMOTE_ADDR', 'http_method' => 'REQUEST_METHOD', 'server' => 'SERVER_NAME', 'referrer' => 'HTTP_REFERER');
    /**
     * @param array|\ArrayAccess $serverData  Array or object w/ ArrayAccess that provides access to the $_SERVER data
     * @param array|null         $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer
     */
    public function __construct($serverData = null, array $extraFields = null)
    {
        if (null === $serverData) {
            $this->serverData =& $_SERVER;
        } elseif (\is_array($serverData) || $serverData instanceof \ArrayAccess) {
            $this->serverData = $serverData;
        } else {
            throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.');
        }
        if (isset($this->serverData['UNIQUE_ID'])) {
            $this->extraFields['unique_id'] = 'UNIQUE_ID';
        }
        if (null !== $extraFields) {
            if (isset($extraFields[0])) {
                foreach (\array_keys($this->extraFields) as $fieldName) {
                    if (!\in_array($fieldName, $extraFields)) {
                        unset($this->extraFields[$fieldName]);
                    }
                }
            } else {
                $this->extraFields = $extraFields;
            }
        }
    }
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        // skip processing if for some reason request data
        // is not present (CLI or wonky SAPIs)
        if (!isset($this->serverData['REQUEST_URI'])) {
            return $record;
        }
        $record['extra'] = $this->appendExtraFields($record['extra']);
        return $record;
    }
    /**
     * @param  string $extraName
     * @param  string $serverName
     * @return $this
     */
    public function addExtraField($extraName, $serverName)
    {
        $this->extraFields[$extraName] = $serverName;
        return $this;
    }
    /**
     * @param  array $extra
     * @return array
     */
    private function appendExtraFields(array $extra)
    {
        foreach ($this->extraFields as $extraName => $serverName) {
            $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null;
        }
        return $extra;
    }
}
Processor/MemoryProcessor.php000066600000003470151136154450012421 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * Some methods that are common for all memory processors
 *
 * @author Rob Jensen
 */
abstract class MemoryProcessor implements ProcessorInterface
{
    /**
     * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported.
     */
    protected $realUsage;
    /**
     * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size)
     */
    protected $useFormatting;
    /**
     * @param bool $realUsage     Set this to true to get the real size of memory allocated from system.
     * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size)
     */
    public function __construct($realUsage = \true, $useFormatting = \true)
    {
        $this->realUsage = (bool) $realUsage;
        $this->useFormatting = (bool) $useFormatting;
    }
    /**
     * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is
     *
     * @param  int        $bytes
     * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is
     */
    protected function formatBytes($bytes)
    {
        $bytes = (int) $bytes;
        if (!$this->useFormatting) {
            return $bytes;
        }
        if ($bytes > 1024 * 1024) {
            return \round($bytes / 1024 / 1024, 2) . ' MB';
        } elseif ($bytes > 1024) {
            return \round($bytes / 1024, 2) . ' KB';
        }
        return $bytes . ' B';
    }
}
Processor/ProcessorInterface.php000066600000001026151136154450013044 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

/**
 * An optional interface to allow labelling Monolog processors.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface ProcessorInterface
{
    /**
     * @return array The processed records
     */
    public function __invoke(array $records);
}
Processor/UidProcessor.php000066600000002347151136154450011674 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

use AIOSEO\Vendor\Monolog\ResettableInterface;
/**
 * Adds a unique identifier into records
 *
 * @author Simon Mönch <sm@webfactory.de>
 */
class UidProcessor implements ProcessorInterface, ResettableInterface
{
    private $uid;
    public function __construct($length = 7)
    {
        if (!\is_int($length) || $length > 32 || $length < 1) {
            throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32');
        }
        $this->uid = $this->generateUid($length);
    }
    public function __invoke(array $record)
    {
        $record['extra']['uid'] = $this->uid;
        return $record;
    }
    /**
     * @return string
     */
    public function getUid()
    {
        return $this->uid;
    }
    public function reset()
    {
        $this->uid = $this->generateUid(\strlen($this->uid));
    }
    private function generateUid($length)
    {
        return \substr(\hash('md5', \uniqid('', \true)), 0, $length);
    }
}
Processor/IntrospectionProcessor.php000066600000006577151136154450014024 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Processor;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Injects line/file:class/function where the log message came from
 *
 * Warning: This only works if the handler processes the logs directly.
 * If you put the processor on a handler that is behind a FingersCrossedHandler
 * for example, the processor will only be called once the trigger level is reached,
 * and all the log records will have the same file/line/.. data from the call that
 * triggered the FingersCrossedHandler.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class IntrospectionProcessor implements ProcessorInterface
{
    private $level;
    private $skipClassesPartials;
    private $skipStackFramesCount;
    private $skipFunctions = array('call_user_func', 'call_user_func_array');
    public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0)
    {
        $this->level = Logger::toMonologLevel($level);
        $this->skipClassesPartials = \array_merge(array('AIOSEO\\Vendor\\Monolog\\'), $skipClassesPartials);
        $this->skipStackFramesCount = $skipStackFramesCount;
    }
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
        // return if the level is not high enough
        if ($record['level'] < $this->level) {
            return $record;
        }
        /*
         * http://php.net/manual/en/function.debug-backtrace.php
         * As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added.
         * Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'.
         */
        $trace = \debug_backtrace(\PHP_VERSION_ID < 50306 ? 2 : \DEBUG_BACKTRACE_IGNORE_ARGS);
        // skip first since it's always the current method
        \array_shift($trace);
        // the call_user_func call is also skipped
        \array_shift($trace);
        $i = 0;
        while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
            if (isset($trace[$i]['class'])) {
                foreach ($this->skipClassesPartials as $part) {
                    if (\strpos($trace[$i]['class'], $part) !== \false) {
                        $i++;
                        continue 2;
                    }
                }
            } elseif (\in_array($trace[$i]['function'], $this->skipFunctions)) {
                $i++;
                continue;
            }
            break;
        }
        $i += $this->skipStackFramesCount;
        // we should have the call source now
        $record['extra'] = \array_merge($record['extra'], array('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));
        return $record;
    }
    private function isTraceClassOrSkippedFunction(array $trace, $index)
    {
        if (!isset($trace[$index])) {
            return \false;
        }
        return isset($trace[$index]['class']) || \in_array($trace[$index]['function'], $this->skipFunctions);
    }
}
ErrorHandler.php000066600000020261151136154450007656 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

use AIOSEO\Vendor\Psr\Log\LoggerInterface;
use AIOSEO\Vendor\Psr\Log\LogLevel;
use AIOSEO\Vendor\Monolog\Handler\AbstractHandler;
/**
 * Monolog error handler
 *
 * A facility to enable logging of runtime errors, exceptions and fatal errors.
 *
 * Quick setup: <code>ErrorHandler::register($logger);</code>
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class ErrorHandler
{
    private $logger;
    private $previousExceptionHandler;
    private $uncaughtExceptionLevel;
    private $previousErrorHandler;
    private $errorLevelMap;
    private $handleOnlyReportedErrors;
    private $hasFatalErrorHandler;
    private $fatalLevel;
    private $reservedMemory;
    private $lastFatalTrace;
    private static $fatalErrors = array(\E_ERROR, \E_PARSE, \E_CORE_ERROR, \E_COMPILE_ERROR, \E_USER_ERROR);
    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
    /**
     * Registers a new ErrorHandler for a given Logger
     *
     * By default it will handle errors, exceptions and fatal errors
     *
     * @param  LoggerInterface $logger
     * @param  array|false     $errorLevelMap  an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
     * @param  int|false       $exceptionLevel a LogLevel::* constant, or false to disable exception handling
     * @param  int|false       $fatalLevel     a LogLevel::* constant, or false to disable fatal error handling
     * @return ErrorHandler
     */
    public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
    {
        //Forces the autoloader to run for LogLevel. Fixes an autoload issue at compile-time on PHP5.3. See https://github.com/Seldaek/monolog/pull/929
        \class_exists('AIOSEO\\Vendor\\Psr\\Log\\LogLevel', \true);
        /** @phpstan-ignore-next-line */
        $handler = new static($logger);
        if ($errorLevelMap !== \false) {
            $handler->registerErrorHandler($errorLevelMap);
        }
        if ($exceptionLevel !== \false) {
            $handler->registerExceptionHandler($exceptionLevel);
        }
        if ($fatalLevel !== \false) {
            $handler->registerFatalHandler($fatalLevel);
        }
        return $handler;
    }
    public function registerExceptionHandler($level = null, $callPrevious = \true)
    {
        $prev = \set_exception_handler(array($this, 'handleException'));
        $this->uncaughtExceptionLevel = $level;
        if ($callPrevious && $prev) {
            $this->previousExceptionHandler = $prev;
        }
    }
    public function registerErrorHandler(array $levelMap = array(), $callPrevious = \true, $errorTypes = -1, $handleOnlyReportedErrors = \true)
    {
        $prev = \set_error_handler(array($this, 'handleError'), $errorTypes);
        $this->errorLevelMap = \array_replace($this->defaultErrorLevelMap(), $levelMap);
        if ($callPrevious) {
            $this->previousErrorHandler = $prev ?: \true;
        }
        $this->handleOnlyReportedErrors = $handleOnlyReportedErrors;
    }
    public function registerFatalHandler($level = null, $reservedMemorySize = 20)
    {
        \register_shutdown_function(array($this, 'handleFatalError'));
        $this->reservedMemory = \str_repeat(' ', 1024 * $reservedMemorySize);
        $this->fatalLevel = $level;
        $this->hasFatalErrorHandler = \true;
    }
    protected function defaultErrorLevelMap()
    {
        return array(\E_ERROR => LogLevel::CRITICAL, \E_WARNING => LogLevel::WARNING, \E_PARSE => LogLevel::ALERT, \E_NOTICE => LogLevel::NOTICE, \E_CORE_ERROR => LogLevel::CRITICAL, \E_CORE_WARNING => LogLevel::WARNING, \E_COMPILE_ERROR => LogLevel::ALERT, \E_COMPILE_WARNING => LogLevel::WARNING, \E_USER_ERROR => LogLevel::ERROR, \E_USER_WARNING => LogLevel::WARNING, \E_USER_NOTICE => LogLevel::NOTICE, \E_STRICT => LogLevel::NOTICE, \E_RECOVERABLE_ERROR => LogLevel::ERROR, \E_DEPRECATED => LogLevel::NOTICE, \E_USER_DEPRECATED => LogLevel::NOTICE);
    }
    /**
     * @private
     */
    public function handleException($e)
    {
        $this->logger->log($this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, \sprintf('Uncaught Exception %s: "%s" at %s line %s', Utils::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine()), array('exception' => $e));
        if ($this->previousExceptionHandler) {
            \call_user_func($this->previousExceptionHandler, $e);
        }
        exit(255);
    }
    /**
     * @private
     */
    public function handleError($code, $message, $file = '', $line = 0, $context = array())
    {
        if ($this->handleOnlyReportedErrors && !(\error_reporting() & $code)) {
            return;
        }
        // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
        if (!$this->hasFatalErrorHandler || !\in_array($code, self::$fatalErrors, \true)) {
            $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL;
            $this->logger->log($level, self::codeToString($code) . ': ' . $message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line));
        } else {
            // http://php.net/manual/en/function.debug-backtrace.php
            // As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added.
            // Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'.
            $trace = \debug_backtrace(\PHP_VERSION_ID < 50306 ? 2 : \DEBUG_BACKTRACE_IGNORE_ARGS);
            \array_shift($trace);
            // Exclude handleError from trace
            $this->lastFatalTrace = $trace;
        }
        if ($this->previousErrorHandler === \true) {
            return \false;
        } elseif ($this->previousErrorHandler) {
            return \call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context);
        }
    }
    /**
     * @private
     */
    public function handleFatalError()
    {
        $this->reservedMemory = null;
        $lastError = \error_get_last();
        if ($lastError && \in_array($lastError['type'], self::$fatalErrors, \true)) {
            $this->logger->log($this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, 'Fatal Error (' . self::codeToString($lastError['type']) . '): ' . $lastError['message'], array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace));
            if ($this->logger instanceof Logger) {
                foreach ($this->logger->getHandlers() as $handler) {
                    if ($handler instanceof AbstractHandler) {
                        $handler->close();
                    }
                }
            }
        }
    }
    private static function codeToString($code)
    {
        switch ($code) {
            case \E_ERROR:
                return 'E_ERROR';
            case \E_WARNING:
                return 'E_WARNING';
            case \E_PARSE:
                return 'E_PARSE';
            case \E_NOTICE:
                return 'E_NOTICE';
            case \E_CORE_ERROR:
                return 'E_CORE_ERROR';
            case \E_CORE_WARNING:
                return 'E_CORE_WARNING';
            case \E_COMPILE_ERROR:
                return 'E_COMPILE_ERROR';
            case \E_COMPILE_WARNING:
                return 'E_COMPILE_WARNING';
            case \E_USER_ERROR:
                return 'E_USER_ERROR';
            case \E_USER_WARNING:
                return 'E_USER_WARNING';
            case \E_USER_NOTICE:
                return 'E_USER_NOTICE';
            case \E_STRICT:
                return 'E_STRICT';
            case \E_RECOVERABLE_ERROR:
                return 'E_RECOVERABLE_ERROR';
            case \E_DEPRECATED:
                return 'E_DEPRECATED';
            case \E_USER_DEPRECATED:
                return 'E_USER_DEPRECATED';
        }
        return 'Unknown PHP error';
    }
}
Handler/FingersCrossed/ActivationStrategyInterface.php000066600000001225151136154450017230 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\FingersCrossed;

/**
 * Interface for activation strategies for the FingersCrossedHandler.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface ActivationStrategyInterface
{
    /**
     * Returns whether the given record activates the handler.
     *
     * @param  array   $record
     * @return bool
     */
    public function isHandlerActivated(array $record);
}
Handler/FingersCrossed/ChannelLevelActivationStrategy.php000066600000003666151136154450017703 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\FingersCrossed;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Channel and Error level based monolog activation strategy. Allows to trigger activation
 * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except
 * for records of the 'sql' channel; those should trigger activation on level 'WARN'.
 *
 * Example:
 *
 * <code>
 *   $activationStrategy = new ChannelLevelActivationStrategy(
 *       Logger::CRITICAL,
 *       array(
 *           'request' => Logger::ALERT,
 *           'sensitive' => Logger::ERROR,
 *       )
 *   );
 *   $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy);
 * </code>
 *
 * @author Mike Meessen <netmikey@gmail.com>
 */
class ChannelLevelActivationStrategy implements ActivationStrategyInterface
{
    private $defaultActionLevel;
    private $channelToActionLevel;
    /**
     * @param int   $defaultActionLevel   The default action level to be used if the record's category doesn't match any
     * @param array $channelToActionLevel An array that maps channel names to action levels.
     */
    public function __construct($defaultActionLevel, $channelToActionLevel = array())
    {
        $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel);
        $this->channelToActionLevel = \array_map('AIOSEO\\Vendor\\Monolog\\Logger::toMonologLevel', $channelToActionLevel);
    }
    public function isHandlerActivated(array $record)
    {
        if (isset($this->channelToActionLevel[$record['channel']])) {
            return $record['level'] >= $this->channelToActionLevel[$record['channel']];
        }
        return $record['level'] >= $this->defaultActionLevel;
    }
}
Handler/FingersCrossed/ErrorLevelActivationStrategy.php000066600000001417151136154450017414 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\FingersCrossed;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Error level based activation strategy.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ErrorLevelActivationStrategy implements ActivationStrategyInterface
{
    private $actionLevel;
    public function __construct($actionLevel)
    {
        $this->actionLevel = Logger::toMonologLevel($actionLevel);
    }
    public function isHandlerActivated(array $record)
    {
        return $record['level'] >= $this->actionLevel;
    }
}
Handler/SlackHandler.php000066600000014330151136154450011177 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\Monolog\Handler\Slack\SlackRecord;
/**
 * Sends notifications through Slack API
 *
 * @author Greg Kedzierski <greg@gregkedzierski.com>
 * @see    https://api.slack.com/
 */
class SlackHandler extends SocketHandler
{
    /**
     * Slack API token
     * @var string
     */
    private $token;
    /**
     * Instance of the SlackRecord util class preparing data for Slack API.
     * @var SlackRecord
     */
    private $slackRecord;
    /**
     * @param  string                    $token                  Slack API token
     * @param  string                    $channel                Slack channel (encoded ID or name)
     * @param  string|null               $username               Name of a bot
     * @param  bool                      $useAttachment          Whether the message should be added to Slack as attachment (plain text otherwise)
     * @param  string|null               $iconEmoji              The emoji name to use (or null)
     * @param  int                       $level                  The minimum logging level at which this handler will be triggered
     * @param  bool                      $bubble                 Whether the messages that are handled can bubble up the stack or not
     * @param  bool                      $useShortAttachment     Whether the the context/extra messages added to Slack as attachments are in a short style
     * @param  bool                      $includeContextAndExtra Whether the attachment should include context and extra data
     * @param  array                     $excludeFields          Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
     * @throws MissingExtensionException If no OpenSSL PHP extension configured
     */
    public function __construct($token, $channel, $username = null, $useAttachment = \true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = \true, $useShortAttachment = \false, $includeContextAndExtra = \false, array $excludeFields = array())
    {
        if (!\extension_loaded('openssl')) {
            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler');
        }
        parent::__construct('ssl://slack.com:443', $level, $bubble);
        $this->slackRecord = new SlackRecord($channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields, $this->formatter);
        $this->token = $token;
    }
    public function getSlackRecord()
    {
        return $this->slackRecord;
    }
    public function getToken()
    {
        return $this->token;
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        $content = $this->buildContent($record);
        return $this->buildHeader($content) . $content;
    }
    /**
     * Builds the body of API call
     *
     * @param  array  $record
     * @return string
     */
    private function buildContent($record)
    {
        $dataArray = $this->prepareContentData($record);
        return \http_build_query($dataArray);
    }
    /**
     * Prepares content data
     *
     * @param  array $record
     * @return array
     */
    protected function prepareContentData($record)
    {
        $dataArray = $this->slackRecord->getSlackData($record);
        $dataArray['token'] = $this->token;
        if (!empty($dataArray['attachments'])) {
            $dataArray['attachments'] = Utils::jsonEncode($dataArray['attachments']);
        }
        return $dataArray;
    }
    /**
     * Builds the header of the API Call
     *
     * @param  string $content
     * @return string
     */
    private function buildHeader($content)
    {
        $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
        $header .= "Host: slack.com\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . \strlen($content) . "\r\n";
        $header .= "\r\n";
        return $header;
    }
    /**
     * {@inheritdoc}
     *
     * @param array $record
     */
    protected function write(array $record)
    {
        parent::write($record);
        $this->finalizeWrite();
    }
    /**
     * Finalizes the request by reading some bytes and then closing the socket
     *
     * If we do not read some but close the socket too early, slack sometimes
     * drops the request entirely.
     */
    protected function finalizeWrite()
    {
        $res = $this->getResource();
        if (\is_resource($res)) {
            @\fread($res, 2048);
        }
        $this->closeSocket();
    }
    /**
     * Returned a Slack message attachment color associated with
     * provided level.
     *
     * @param  int    $level
     * @return string
     * @deprecated Use underlying SlackRecord instead
     */
    protected function getAttachmentColor($level)
    {
        \trigger_error('SlackHandler::getAttachmentColor() is deprecated. Use underlying SlackRecord instead.', \E_USER_DEPRECATED);
        return $this->slackRecord->getAttachmentColor($level);
    }
    /**
     * Stringifies an array of key/value pairs to be used in attachment fields
     *
     * @param  array  $fields
     * @return string
     * @deprecated Use underlying SlackRecord instead
     */
    protected function stringify($fields)
    {
        \trigger_error('SlackHandler::stringify() is deprecated. Use underlying SlackRecord instead.', \E_USER_DEPRECATED);
        return $this->slackRecord->stringify($fields);
    }
    public function setFormatter(FormatterInterface $formatter)
    {
        parent::setFormatter($formatter);
        $this->slackRecord->setFormatter($formatter);
        return $this;
    }
    public function getFormatter()
    {
        $formatter = parent::getFormatter();
        $this->slackRecord->setFormatter($formatter);
        return $formatter;
    }
}
Handler/SyslogHandler.php000066600000003527151136154450011430 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Logs to syslog service.
 *
 * usage example:
 *
 *   $log = new Logger('application');
 *   $syslog = new SyslogHandler('myfacility', 'local6');
 *   $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");
 *   $syslog->setFormatter($formatter);
 *   $log->pushHandler($syslog);
 *
 * @author Sven Paulus <sven@karlsruhe.org>
 */
class SyslogHandler extends AbstractSyslogHandler
{
    protected $ident;
    protected $logopts;
    /**
     * @param string $ident
     * @param mixed  $facility
     * @param int    $level    The minimum logging level at which this handler will be triggered
     * @param bool   $bubble   Whether the messages that are handled can bubble up the stack or not
     * @param int    $logopts  Option flags for the openlog() call, defaults to LOG_PID
     */
    public function __construct($ident, $facility = \LOG_USER, $level = Logger::DEBUG, $bubble = \true, $logopts = \LOG_PID)
    {
        parent::__construct($facility, $level, $bubble);
        $this->ident = $ident;
        $this->logopts = $logopts;
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        \closelog();
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        if (!\openlog($this->ident, $this->logopts, $this->facility)) {
            throw new \LogicException('Can\'t open syslog for ident "' . $this->ident . '" and facility "' . $this->facility . '"');
        }
        \syslog($this->logLevels[$record['level']], (string) $record['formatted']);
    }
}
Handler/DeduplicationHandler.php000066600000012623151136154450012731 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Simple handler wrapper that deduplicates log records across multiple requests
 *
 * It also includes the BufferHandler functionality and will buffer
 * all messages until the end of the request or flush() is called.
 *
 * This works by storing all log records' messages above $deduplicationLevel
 * to the file specified by $deduplicationStore. When further logs come in at the end of the
 * request (or when flush() is called), all those above $deduplicationLevel are checked
 * against the existing stored logs. If they match and the timestamps in the stored log is
 * not older than $time seconds, the new log record is discarded. If no log record is new, the
 * whole data set is discarded.
 *
 * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers
 * that send messages to people, to avoid spamming with the same message over and over in case of
 * a major component failure like a database server being down which makes all requests fail in the
 * same way.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class DeduplicationHandler extends BufferHandler
{
    /**
     * @var string
     */
    protected $deduplicationStore;
    /**
     * @var int
     */
    protected $deduplicationLevel;
    /**
     * @var int
     */
    protected $time;
    /**
     * @var bool
     */
    private $gc = \false;
    /**
     * @param HandlerInterface $handler            Handler.
     * @param string           $deduplicationStore The file/path where the deduplication log should be kept
     * @param int              $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes
     * @param int              $time               The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through
     * @param bool             $bubble             Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(HandlerInterface $handler, $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, $time = 60, $bubble = \true)
    {
        parent::__construct($handler, 0, Logger::DEBUG, $bubble, \false);
        $this->deduplicationStore = $deduplicationStore === null ? \sys_get_temp_dir() . '/monolog-dedup-' . \substr(\md5(__FILE__), 0, 20) . '.log' : $deduplicationStore;
        $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel);
        $this->time = $time;
    }
    public function flush()
    {
        if ($this->bufferSize === 0) {
            return;
        }
        $passthru = null;
        foreach ($this->buffer as $record) {
            if ($record['level'] >= $this->deduplicationLevel) {
                $passthru = $passthru || !$this->isDuplicate($record);
                if ($passthru) {
                    $this->appendRecord($record);
                }
            }
        }
        // default of null is valid as well as if no record matches duplicationLevel we just pass through
        if ($passthru === \true || $passthru === null) {
            $this->handler->handleBatch($this->buffer);
        }
        $this->clear();
        if ($this->gc) {
            $this->collectLogs();
        }
    }
    private function isDuplicate(array $record)
    {
        if (!\file_exists($this->deduplicationStore)) {
            return \false;
        }
        $store = \file($this->deduplicationStore, \FILE_IGNORE_NEW_LINES | \FILE_SKIP_EMPTY_LINES);
        if (!\is_array($store)) {
            return \false;
        }
        $yesterday = \time() - 86400;
        $timestampValidity = $record['datetime']->getTimestamp() - $this->time;
        $expectedMessage = \preg_replace('{[\\r\\n].*}', '', $record['message']);
        for ($i = \count($store) - 1; $i >= 0; $i--) {
            list($timestamp, $level, $message) = \explode(':', $store[$i], 3);
            if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) {
                return \true;
            }
            if ($timestamp < $yesterday) {
                $this->gc = \true;
            }
        }
        return \false;
    }
    private function collectLogs()
    {
        if (!\file_exists($this->deduplicationStore)) {
            return \false;
        }
        $handle = \fopen($this->deduplicationStore, 'rw+');
        \flock($handle, \LOCK_EX);
        $validLogs = array();
        $timestampValidity = \time() - $this->time;
        while (!\feof($handle)) {
            $log = \fgets($handle);
            if (\substr($log, 0, 10) >= $timestampValidity) {
                $validLogs[] = $log;
            }
        }
        \ftruncate($handle, 0);
        \rewind($handle);
        foreach ($validLogs as $log) {
            \fwrite($handle, $log);
        }
        \flock($handle, \LOCK_UN);
        \fclose($handle);
        $this->gc = \false;
    }
    private function appendRecord(array $record)
    {
        \file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . \preg_replace('{[\\r\\n].*}', '', $record['message']) . "\n", \FILE_APPEND);
    }
}
Handler/ProcessableHandlerInterface.php000066600000002025151136154450014223 0ustar00<?php

declare (strict_types=1);
/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Processor\ProcessorInterface;
/**
 * Interface to describe loggers that have processors
 *
 * This interface is present in monolog 1.x to ease forward compatibility.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
interface ProcessableHandlerInterface
{
    /**
     * Adds a processor in the stack.
     *
     * @param  ProcessorInterface|callable $callback
     * @return HandlerInterface            self
     */
    public function pushProcessor($callback) : HandlerInterface;
    /**
     * Removes the processor on top of the stack and returns it.
     *
     * @throws \LogicException In case the processor stack is empty
     * @return callable
     */
    public function popProcessor() : callable;
}
Handler/FingersCrossedHandler.php000066600000015047151136154450013070 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
use AIOSEO\Vendor\Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\ResettableInterface;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Buffers all records until a certain level is reached
 *
 * The advantage of this approach is that you don't get any clutter in your log files.
 * Only requests which actually trigger an error (or whatever your actionLevel is) will be
 * in the logs, but they will contain all records, not only those above the level threshold.
 *
 * You can find the various activation strategies in the
 * Monolog\Handler\FingersCrossed\ namespace.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class FingersCrossedHandler extends AbstractHandler
{
    protected $handler;
    protected $activationStrategy;
    protected $buffering = \true;
    protected $bufferSize;
    protected $buffer = array();
    protected $stopBuffering;
    protected $passthruLevel;
    /**
     * @param callable|HandlerInterface       $handler            Handler or factory callable($record|null, $fingersCrossedHandler).
     * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action
     * @param int                             $bufferSize         How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
     * @param bool                            $bubble             Whether the messages that are handled can bubble up the stack or not
     * @param bool                            $stopBuffering      Whether the handler should stop buffering after being triggered (default true)
     * @param int                             $passthruLevel      Minimum level to always flush to handler on close, even if strategy not triggered
     */
    public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = \true, $stopBuffering = \true, $passthruLevel = null)
    {
        if (null === $activationStrategy) {
            $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING);
        }
        // convert simple int activationStrategy to an object
        if (!$activationStrategy instanceof ActivationStrategyInterface) {
            $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy);
        }
        $this->handler = $handler;
        $this->activationStrategy = $activationStrategy;
        $this->bufferSize = $bufferSize;
        $this->bubble = $bubble;
        $this->stopBuffering = $stopBuffering;
        if ($passthruLevel !== null) {
            $this->passthruLevel = Logger::toMonologLevel($passthruLevel);
        }
        if (!$this->handler instanceof HandlerInterface && !\is_callable($this->handler)) {
            throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a Monolog\\Handler\\HandlerInterface object");
        }
    }
    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        return \true;
    }
    /**
     * Manually activate this logger regardless of the activation strategy
     */
    public function activate()
    {
        if ($this->stopBuffering) {
            $this->buffering = \false;
        }
        $this->getHandler(\end($this->buffer) ?: null)->handleBatch($this->buffer);
        $this->buffer = array();
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        if ($this->buffering) {
            $this->buffer[] = $record;
            if ($this->bufferSize > 0 && \count($this->buffer) > $this->bufferSize) {
                \array_shift($this->buffer);
            }
            if ($this->activationStrategy->isHandlerActivated($record)) {
                $this->activate();
            }
        } else {
            $this->getHandler($record)->handle($record);
        }
        return \false === $this->bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        $this->flushBuffer();
    }
    public function reset()
    {
        $this->flushBuffer();
        parent::reset();
        if ($this->getHandler() instanceof ResettableInterface) {
            $this->getHandler()->reset();
        }
    }
    /**
     * Clears the buffer without flushing any messages down to the wrapped handler.
     *
     * It also resets the handler to its initial buffering state.
     */
    public function clear()
    {
        $this->buffer = array();
        $this->reset();
    }
    /**
     * Resets the state of the handler. Stops forwarding records to the wrapped handler.
     */
    private function flushBuffer()
    {
        if (null !== $this->passthruLevel) {
            $level = $this->passthruLevel;
            $this->buffer = \array_filter($this->buffer, function ($record) use($level) {
                return $record['level'] >= $level;
            });
            if (\count($this->buffer) > 0) {
                $this->getHandler(\end($this->buffer) ?: null)->handleBatch($this->buffer);
            }
        }
        $this->buffer = array();
        $this->buffering = \true;
    }
    /**
     * Return the nested handler
     *
     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
     *
     * @return HandlerInterface
     */
    public function getHandler(array $record = null)
    {
        if (!$this->handler instanceof HandlerInterface) {
            $this->handler = \call_user_func($this->handler, $record, $this);
            if (!$this->handler instanceof HandlerInterface) {
                throw new \RuntimeException("The factory callable should return a HandlerInterface");
            }
        }
        return $this->handler;
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->getHandler()->setFormatter($formatter);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->getHandler()->getFormatter();
    }
}
Handler/SlackbotHandler.php000066600000004464151136154450011713 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Sends notifications through Slack's Slackbot
 *
 * @author     Haralan Dobrev <hkdobrev@gmail.com>
 * @see        https://slack.com/apps/A0F81R8ET-slackbot
 * @deprecated According to Slack the API used on this handler it is deprecated.
 *             Therefore this handler will be removed on 2.x
 *             Slack suggests to use webhooks instead. Please contact slack for more information.
 */
class SlackbotHandler extends AbstractProcessingHandler
{
    /**
     * The slug of the Slack team
     * @var string
     */
    private $slackTeam;
    /**
     * Slackbot token
     * @var string
     */
    private $token;
    /**
     * Slack channel name
     * @var string
     */
    private $channel;
    /**
     * @param  string $slackTeam Slack team slug
     * @param  string $token     Slackbot token
     * @param  string $channel   Slack channel (encoded ID or name)
     * @param  int    $level     The minimum logging level at which this handler will be triggered
     * @param  bool   $bubble    Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($slackTeam, $token, $channel, $level = Logger::CRITICAL, $bubble = \true)
    {
        @\trigger_error('SlackbotHandler is deprecated and will be removed on 2.x', \E_USER_DEPRECATED);
        parent::__construct($level, $bubble);
        $this->slackTeam = $slackTeam;
        $this->token = $token;
        $this->channel = $channel;
    }
    /**
     * {@inheritdoc}
     *
     * @param array $record
     */
    protected function write(array $record)
    {
        $slackbotUrl = \sprintf('https://%s.slack.com/services/hooks/slackbot?token=%s&channel=%s', $this->slackTeam, $this->token, $this->channel);
        $ch = \curl_init();
        \curl_setopt($ch, \CURLOPT_URL, $slackbotUrl);
        \curl_setopt($ch, \CURLOPT_POST, \true);
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true);
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $record['message']);
        Curl\Util::execute($ch);
    }
}
Handler/DynamoDbHandler.php000066600000004742151136154450011645 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Aws\Sdk;
use AIOSEO\Vendor\Aws\DynamoDb\DynamoDbClient;
use AIOSEO\Vendor\Aws\DynamoDb\Marshaler;
use AIOSEO\Vendor\Monolog\Formatter\ScalarFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
 *
 * @link https://github.com/aws/aws-sdk-php/
 * @author Andrew Lawson <adlawson@gmail.com>
 */
class DynamoDbHandler extends AbstractProcessingHandler
{
    const DATE_FORMAT = 'Y-m-d\\TH:i:s.uO';
    /**
     * @var DynamoDbClient
     */
    protected $client;
    /**
     * @var string
     */
    protected $table;
    /**
     * @var int
     */
    protected $version;
    /**
     * @var Marshaler
     */
    protected $marshaler;
    /**
     * @param DynamoDbClient $client
     * @param string         $table
     * @param int            $level
     * @param bool           $bubble
     */
    public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = \true)
    {
        if (\defined('Aws\\Sdk::VERSION') && \version_compare(Sdk::VERSION, '3.0', '>=')) {
            $this->version = 3;
            $this->marshaler = new Marshaler();
        } else {
            $this->version = 2;
        }
        $this->client = $client;
        $this->table = $table;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $filtered = $this->filterEmptyFields($record['formatted']);
        if ($this->version === 3) {
            $formatted = $this->marshaler->marshalItem($filtered);
        } else {
            /** @phpstan-ignore-next-line */
            $formatted = $this->client->formatAttributes($filtered);
        }
        $this->client->putItem(array('TableName' => $this->table, 'Item' => $formatted));
    }
    /**
     * @param  array $record
     * @return array
     */
    protected function filterEmptyFields(array $record)
    {
        return \array_filter($record, function ($value) {
            return !empty($value) || \false === $value || 0 === $value;
        });
    }
    /**
     * {@inheritdoc}
     */
    protected function getDefaultFormatter()
    {
        return new ScalarFormatter(self::DATE_FORMAT);
    }
}
Handler/CouchDBHandler.php000066600000003375151136154450011420 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\JsonFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * CouchDB handler
 *
 * @author Markus Bachmann <markus.bachmann@bachi.biz>
 */
class CouchDBHandler extends AbstractProcessingHandler
{
    private $options;
    public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = \true)
    {
        $this->options = \array_merge(array('host' => 'localhost', 'port' => 5984, 'dbname' => 'logger', 'username' => null, 'password' => null), $options);
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        $basicAuth = null;
        if ($this->options['username']) {
            $basicAuth = \sprintf('%s:%s@', $this->options['username'], $this->options['password']);
        }
        $url = 'http://' . $basicAuth . $this->options['host'] . ':' . $this->options['port'] . '/' . $this->options['dbname'];
        $context = \stream_context_create(array('http' => array('method' => 'POST', 'content' => $record['formatted'], 'ignore_errors' => \true, 'max_redirects' => 0, 'header' => 'Content-type: application/json')));
        if (\false === @\file_get_contents($url, null, $context)) {
            throw new \RuntimeException(\sprintf('Could not connect to %s', $url));
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, \false);
    }
}
Handler/HipChatHandler.php000066600000024723151136154450011471 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Sends notifications through the hipchat api to a hipchat room
 *
 * Notes:
 * API token - HipChat API token
 * Room      - HipChat Room Id or name, where messages are sent
 * Name      - Name used to send the message (from)
 * notify    - Should the message trigger a notification in the clients
 * version   - The API version to use (HipChatHandler::API_V1 | HipChatHandler::API_V2)
 *
 * @author Rafael Dohms <rafael@doh.ms>
 * @see    https://www.hipchat.com/docs/api
 */
class HipChatHandler extends SocketHandler
{
    /**
     * Use API version 1
     */
    const API_V1 = 'v1';
    /**
     * Use API version v2
     */
    const API_V2 = 'v2';
    /**
     * The maximum allowed length for the name used in the "from" field.
     */
    const MAXIMUM_NAME_LENGTH = 15;
    /**
     * The maximum allowed length for the message.
     */
    const MAXIMUM_MESSAGE_LENGTH = 9500;
    /**
     * @var string
     */
    private $token;
    /**
     * @var string
     */
    private $room;
    /**
     * @var string
     */
    private $name;
    /**
     * @var bool
     */
    private $notify;
    /**
     * @var string
     */
    private $format;
    /**
     * @var string
     */
    private $host;
    /**
     * @var string
     */
    private $version;
    /**
     * @param string $token   HipChat API Token
     * @param string $room    The room that should be alerted of the message (Id or Name)
     * @param string $name    Name used in the "from" field.
     * @param bool   $notify  Trigger a notification in clients or not
     * @param int    $level   The minimum logging level at which this handler will be triggered
     * @param bool   $bubble  Whether the messages that are handled can bubble up the stack or not
     * @param bool   $useSSL  Whether to connect via SSL.
     * @param string $format  The format of the messages (default to text, can be set to html if you have html in the messages)
     * @param string $host    The HipChat server hostname.
     * @param string $version The HipChat API version (default HipChatHandler::API_V1)
     */
    public function __construct($token, $room, $name = 'Monolog', $notify = \false, $level = Logger::CRITICAL, $bubble = \true, $useSSL = \true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1)
    {
        @\trigger_error('The Monolog\\Handler\\HipChatHandler class is deprecated. You should migrate to Slack and the SlackWebhookHandler / SlackbotHandler, see https://www.atlassian.com/partnerships/slack', \E_USER_DEPRECATED);
        if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) {
            throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.');
        }
        $connectionString = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80';
        parent::__construct($connectionString, $level, $bubble);
        $this->token = $token;
        $this->name = $name;
        $this->notify = $notify;
        $this->room = $room;
        $this->format = $format;
        $this->host = $host;
        $this->version = $version;
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        $content = $this->buildContent($record);
        return $this->buildHeader($content) . $content;
    }
    /**
     * Builds the body of API call
     *
     * @param  array  $record
     * @return string
     */
    private function buildContent($record)
    {
        $dataArray = array('notify' => $this->version == self::API_V1 ? $this->notify ? 1 : 0 : ($this->notify ? 'true' : 'false'), 'message' => $record['formatted'], 'message_format' => $this->format, 'color' => $this->getAlertColor($record['level']));
        if (!$this->validateStringLength($dataArray['message'], static::MAXIMUM_MESSAGE_LENGTH)) {
            if (\function_exists('mb_substr')) {
                $dataArray['message'] = \mb_substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH) . ' [truncated]';
            } else {
                $dataArray['message'] = \substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH) . ' [truncated]';
            }
        }
        // if we are using the legacy API then we need to send some additional information
        if ($this->version == self::API_V1) {
            $dataArray['room_id'] = $this->room;
        }
        // append the sender name if it is set
        // always append it if we use the v1 api (it is required in v1)
        if ($this->version == self::API_V1 || $this->name !== null) {
            $dataArray['from'] = (string) $this->name;
        }
        return \http_build_query($dataArray);
    }
    /**
     * Builds the header of the API Call
     *
     * @param  string $content
     * @return string
     */
    private function buildHeader($content)
    {
        if ($this->version == self::API_V1) {
            $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n";
        } else {
            // needed for rooms with special (spaces, etc) characters in the name
            $room = \rawurlencode($this->room);
            $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n";
        }
        $header .= "Host: {$this->host}\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . \strlen($content) . "\r\n";
        $header .= "\r\n";
        return $header;
    }
    /**
     * Assigns a color to each level of log records.
     *
     * @param  int    $level
     * @return string
     */
    protected function getAlertColor($level)
    {
        switch (\true) {
            case $level >= Logger::ERROR:
                return 'red';
            case $level >= Logger::WARNING:
                return 'yellow';
            case $level >= Logger::INFO:
                return 'green';
            case $level == Logger::DEBUG:
                return 'gray';
            default:
                return 'yellow';
        }
    }
    /**
     * {@inheritdoc}
     *
     * @param array $record
     */
    protected function write(array $record)
    {
        parent::write($record);
        $this->finalizeWrite();
    }
    /**
     * Finalizes the request by reading some bytes and then closing the socket
     *
     * If we do not read some but close the socket too early, hipchat sometimes
     * drops the request entirely.
     */
    protected function finalizeWrite()
    {
        $res = $this->getResource();
        if (\is_resource($res)) {
            @\fread($res, 2048);
        }
        $this->closeSocket();
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        if (\count($records) == 0) {
            return \true;
        }
        $batchRecords = $this->combineRecords($records);
        $handled = \false;
        foreach ($batchRecords as $batchRecord) {
            if ($this->isHandling($batchRecord)) {
                $this->write($batchRecord);
                $handled = \true;
            }
        }
        if (!$handled) {
            return \false;
        }
        return \false === $this->bubble;
    }
    /**
     * Combines multiple records into one. Error level of the combined record
     * will be the highest level from the given records. Datetime will be taken
     * from the first record.
     *
     * @param array $records
     * @return array
     */
    private function combineRecords(array $records)
    {
        $batchRecord = null;
        $batchRecords = array();
        $messages = array();
        $formattedMessages = array();
        $level = 0;
        $levelName = null;
        $datetime = null;
        foreach ($records as $record) {
            $record = $this->processRecord($record);
            if ($record['level'] > $level) {
                $level = $record['level'];
                $levelName = $record['level_name'];
            }
            if (null === $datetime) {
                $datetime = $record['datetime'];
            }
            $messages[] = $record['message'];
            $messageStr = \implode(\PHP_EOL, $messages);
            $formattedMessages[] = $this->getFormatter()->format($record);
            $formattedMessageStr = \implode('', $formattedMessages);
            $batchRecord = array('message' => $messageStr, 'formatted' => $formattedMessageStr, 'context' => array(), 'extra' => array());
            if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) {
                // Pop the last message and implode the remaining messages
                $lastMessage = \array_pop($messages);
                $lastFormattedMessage = \array_pop($formattedMessages);
                $batchRecord['message'] = \implode(\PHP_EOL, $messages);
                $batchRecord['formatted'] = \implode('', $formattedMessages);
                $batchRecords[] = $batchRecord;
                $messages = array($lastMessage);
                $formattedMessages = array($lastFormattedMessage);
                $batchRecord = null;
            }
        }
        if (null !== $batchRecord) {
            $batchRecords[] = $batchRecord;
        }
        // Set the max level and datetime for all records
        foreach ($batchRecords as &$batchRecord) {
            $batchRecord = \array_merge($batchRecord, array('level' => $level, 'level_name' => $levelName, 'datetime' => $datetime));
        }
        return $batchRecords;
    }
    /**
     * Validates the length of a string.
     *
     * If the `mb_strlen()` function is available, it will use that, as HipChat
     * allows UTF-8 characters. Otherwise, it will fall back to `strlen()`.
     *
     * Note that this might cause false failures in the specific case of using
     * a valid name with less than 16 characters, but 16 or more bytes, on a
     * system where `mb_strlen()` is unavailable.
     *
     * @param string $str
     * @param int    $length
     *
     * @return bool
     */
    private function validateStringLength($str, $length)
    {
        if (\function_exists('mb_strlen')) {
            return \mb_strlen($str) <= $length;
        }
        return \strlen($str) <= $length;
    }
}
Handler/StreamHandler.php000066600000012406151136154450011377 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Stores to any stream resource
 *
 * Can be used to store into php://stderr, remote and local files, etc.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class StreamHandler extends AbstractProcessingHandler
{
    protected $stream;
    protected $url;
    private $errorMessage;
    protected $filePermission;
    protected $useLocking;
    private $dirCreated;
    /**
     * @param resource|string $stream
     * @param int             $level          The minimum logging level at which this handler will be triggered
     * @param bool            $bubble         Whether the messages that are handled can bubble up the stack or not
     * @param int|null        $filePermission Optional file permissions (default (0644) are only for owner read/write)
     * @param bool            $useLocking     Try to lock log file before doing any writes
     *
     * @throws \Exception                If a missing directory is not buildable
     * @throws \InvalidArgumentException If stream is not a resource or string
     */
    public function __construct($stream, $level = Logger::DEBUG, $bubble = \true, $filePermission = null, $useLocking = \false)
    {
        parent::__construct($level, $bubble);
        if (\is_resource($stream)) {
            $this->stream = $stream;
        } elseif (\is_string($stream)) {
            $this->url = Utils::canonicalizePath($stream);
        } else {
            throw new \InvalidArgumentException('A stream must either be a resource or a string.');
        }
        $this->filePermission = $filePermission;
        $this->useLocking = $useLocking;
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        if ($this->url && \is_resource($this->stream)) {
            \fclose($this->stream);
        }
        $this->stream = null;
        $this->dirCreated = null;
    }
    /**
     * Return the currently active stream if it is open
     *
     * @return resource|null
     */
    public function getStream()
    {
        return $this->stream;
    }
    /**
     * Return the stream URL if it was configured with a URL and not an active resource
     *
     * @return string|null
     */
    public function getUrl()
    {
        return $this->url;
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        if (!\is_resource($this->stream)) {
            if (null === $this->url || '' === $this->url) {
                throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
            }
            $this->createDir();
            $this->errorMessage = null;
            \set_error_handler(array($this, 'customErrorHandler'));
            $this->stream = \fopen($this->url, 'a');
            if ($this->filePermission !== null) {
                @\chmod($this->url, $this->filePermission);
            }
            \restore_error_handler();
            if (!\is_resource($this->stream)) {
                $this->stream = null;
                throw new \UnexpectedValueException(\sprintf('The stream or file "%s" could not be opened in append mode: ' . $this->errorMessage, $this->url));
            }
        }
        if ($this->useLocking) {
            // ignoring errors here, there's not much we can do about them
            \flock($this->stream, \LOCK_EX);
        }
        $this->streamWrite($this->stream, $record);
        if ($this->useLocking) {
            \flock($this->stream, \LOCK_UN);
        }
    }
    /**
     * Write to stream
     * @param resource $stream
     * @param array $record
     */
    protected function streamWrite($stream, array $record)
    {
        \fwrite($stream, (string) $record['formatted']);
    }
    private function customErrorHandler($code, $msg)
    {
        $this->errorMessage = \preg_replace('{^(fopen|mkdir)\\(.*?\\): }', '', $msg);
    }
    /**
     * @param string $stream
     *
     * @return null|string
     */
    private function getDirFromStream($stream)
    {
        $pos = \strpos($stream, '://');
        if ($pos === \false) {
            return \dirname($stream);
        }
        if ('file://' === \substr($stream, 0, 7)) {
            return \dirname(\substr($stream, 7));
        }
        return null;
    }
    private function createDir()
    {
        // Do not try to create dir if it has already been tried.
        if ($this->dirCreated) {
            return;
        }
        $dir = $this->getDirFromStream($this->url);
        if (null !== $dir && !\is_dir($dir)) {
            $this->errorMessage = null;
            \set_error_handler(array($this, 'customErrorHandler'));
            $status = \mkdir($dir, 0777, \true);
            \restore_error_handler();
            if (\false === $status && !\is_dir($dir)) {
                throw new \UnexpectedValueException(\sprintf('There is no existing directory at "%s" and its not buildable: ' . $this->errorMessage, $dir));
            }
        }
        $this->dirCreated = \true;
    }
}
Handler/FleepHookHandler.php000066600000006455151136154450012027 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Sends logs to Fleep.io using Webhook integrations
 *
 * You'll need a Fleep.io account to use this handler.
 *
 * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation
 * @author Ando Roots <ando@sqroot.eu>
 */
class FleepHookHandler extends SocketHandler
{
    const FLEEP_HOST = 'fleep.io';
    const FLEEP_HOOK_URI = '/hook/';
    /**
     * @var string Webhook token (specifies the conversation where logs are sent)
     */
    protected $token;
    /**
     * Construct a new Fleep.io Handler.
     *
     * For instructions on how to create a new web hook in your conversations
     * see https://fleep.io/integrations/webhooks/
     *
     * @param  string                    $token  Webhook token
     * @param  bool|int                  $level  The minimum logging level at which this handler will be triggered
     * @param  bool                      $bubble Whether the messages that are handled can bubble up the stack or not
     * @throws MissingExtensionException
     */
    public function __construct($token, $level = Logger::DEBUG, $bubble = \true)
    {
        if (!\extension_loaded('openssl')) {
            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler');
        }
        $this->token = $token;
        $connectionString = 'ssl://' . self::FLEEP_HOST . ':443';
        parent::__construct($connectionString, $level, $bubble);
    }
    /**
     * Returns the default formatter to use with this handler
     *
     * Overloaded to remove empty context and extra arrays from the end of the log message.
     *
     * @return LineFormatter
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter(null, null, \true, \true);
    }
    /**
     * Handles a log record
     *
     * @param array $record
     */
    public function write(array $record)
    {
        parent::write($record);
        $this->closeSocket();
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        $content = $this->buildContent($record);
        return $this->buildHeader($content) . $content;
    }
    /**
     * Builds the header of the API Call
     *
     * @param  string $content
     * @return string
     */
    private function buildHeader($content)
    {
        $header = "POST " . self::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n";
        $header .= "Host: " . self::FLEEP_HOST . "\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . \strlen($content) . "\r\n";
        $header .= "\r\n";
        return $header;
    }
    /**
     * Builds the body of API call
     *
     * @param  array  $record
     * @return string
     */
    private function buildContent($record)
    {
        $dataArray = array('message' => $record['formatted']);
        return \http_build_query($dataArray);
    }
}
Handler/ErrorLogHandler.php000066600000004512151136154450011676 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Stores to PHP error_log() handler.
 *
 * @author Elan Ruusamäe <glen@delfi.ee>
 */
class ErrorLogHandler extends AbstractProcessingHandler
{
    const OPERATING_SYSTEM = 0;
    const SAPI = 4;
    protected $messageType;
    protected $expandNewlines;
    /**
     * @param int  $messageType    Says where the error should go.
     * @param int  $level          The minimum logging level at which this handler will be triggered
     * @param bool $bubble         Whether the messages that are handled can bubble up the stack or not
     * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
     */
    public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = \true, $expandNewlines = \false)
    {
        parent::__construct($level, $bubble);
        if (\false === \in_array($messageType, self::getAvailableTypes())) {
            $message = \sprintf('The given message type "%s" is not supported', \print_r($messageType, \true));
            throw new \InvalidArgumentException($message);
        }
        $this->messageType = $messageType;
        $this->expandNewlines = $expandNewlines;
    }
    /**
     * @return array With all available types
     */
    public static function getAvailableTypes()
    {
        return array(self::OPERATING_SYSTEM, self::SAPI);
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%');
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        if ($this->expandNewlines) {
            $lines = \preg_split('{[\\r\\n]+}', (string) $record['formatted']);
            foreach ($lines as $line) {
                \error_log($line, $this->messageType);
            }
        } else {
            \error_log((string) $record['formatted'], $this->messageType);
        }
    }
}
Handler/Slack/SlackRecord.php000066600000017627151136154450012111 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\Slack;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\Monolog\Formatter\NormalizerFormatter;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Slack record utility helping to log to Slack webhooks or API.
 *
 * @author Greg Kedzierski <greg@gregkedzierski.com>
 * @author Haralan Dobrev <hkdobrev@gmail.com>
 * @see    https://api.slack.com/incoming-webhooks
 * @see    https://api.slack.com/docs/message-attachments
 */
class SlackRecord
{
    const COLOR_DANGER = 'danger';
    const COLOR_WARNING = 'warning';
    const COLOR_GOOD = 'good';
    const COLOR_DEFAULT = '#e3e4e6';
    /**
     * Slack channel (encoded ID or name)
     * @var string|null
     */
    private $channel;
    /**
     * Name of a bot
     * @var string|null
     */
    private $username;
    /**
     * User icon e.g. 'ghost', 'http://example.com/user.png'
     * @var string
     */
    private $userIcon;
    /**
     * Whether the message should be added to Slack as attachment (plain text otherwise)
     * @var bool
     */
    private $useAttachment;
    /**
     * Whether the the context/extra messages added to Slack as attachments are in a short style
     * @var bool
     */
    private $useShortAttachment;
    /**
     * Whether the attachment should include context and extra data
     * @var bool
     */
    private $includeContextAndExtra;
    /**
     * Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
     * @var array
     */
    private $excludeFields;
    /**
     * @var FormatterInterface
     */
    private $formatter;
    /**
     * @var NormalizerFormatter
     */
    private $normalizerFormatter;
    public function __construct($channel = null, $username = null, $useAttachment = \true, $userIcon = null, $useShortAttachment = \false, $includeContextAndExtra = \false, array $excludeFields = array(), FormatterInterface $formatter = null)
    {
        $this->channel = $channel;
        $this->username = $username;
        $this->userIcon = \trim($userIcon, ':');
        $this->useAttachment = $useAttachment;
        $this->useShortAttachment = $useShortAttachment;
        $this->includeContextAndExtra = $includeContextAndExtra;
        $this->excludeFields = $excludeFields;
        $this->formatter = $formatter;
        if ($this->includeContextAndExtra) {
            $this->normalizerFormatter = new NormalizerFormatter();
        }
    }
    public function getSlackData(array $record)
    {
        $dataArray = array();
        $record = $this->excludeFields($record);
        if ($this->username) {
            $dataArray['username'] = $this->username;
        }
        if ($this->channel) {
            $dataArray['channel'] = $this->channel;
        }
        if ($this->formatter && !$this->useAttachment) {
            $message = $this->formatter->format($record);
        } else {
            $message = $record['message'];
        }
        if ($this->useAttachment) {
            $attachment = array('fallback' => $message, 'text' => $message, 'color' => $this->getAttachmentColor($record['level']), 'fields' => array(), 'mrkdwn_in' => array('fields'), 'ts' => $record['datetime']->getTimestamp());
            if ($this->useShortAttachment) {
                $attachment['title'] = $record['level_name'];
            } else {
                $attachment['title'] = 'Message';
                $attachment['fields'][] = $this->generateAttachmentField('Level', $record['level_name']);
            }
            if ($this->includeContextAndExtra) {
                foreach (array('extra', 'context') as $key) {
                    if (empty($record[$key])) {
                        continue;
                    }
                    if ($this->useShortAttachment) {
                        $attachment['fields'][] = $this->generateAttachmentField($key, $record[$key]);
                    } else {
                        // Add all extra fields as individual fields in attachment
                        $attachment['fields'] = \array_merge($attachment['fields'], $this->generateAttachmentFields($record[$key]));
                    }
                }
            }
            $dataArray['attachments'] = array($attachment);
        } else {
            $dataArray['text'] = $message;
        }
        if ($this->userIcon) {
            if (\filter_var($this->userIcon, \FILTER_VALIDATE_URL)) {
                $dataArray['icon_url'] = $this->userIcon;
            } else {
                $dataArray['icon_emoji'] = ":{$this->userIcon}:";
            }
        }
        return $dataArray;
    }
    /**
     * Returned a Slack message attachment color associated with
     * provided level.
     *
     * @param  int    $level
     * @return string
     */
    public function getAttachmentColor($level)
    {
        switch (\true) {
            case $level >= Logger::ERROR:
                return self::COLOR_DANGER;
            case $level >= Logger::WARNING:
                return self::COLOR_WARNING;
            case $level >= Logger::INFO:
                return self::COLOR_GOOD;
            default:
                return self::COLOR_DEFAULT;
        }
    }
    /**
     * Stringifies an array of key/value pairs to be used in attachment fields
     *
     * @param array $fields
     *
     * @return string
     */
    public function stringify($fields)
    {
        $normalized = $this->normalizerFormatter->format($fields);
        $prettyPrintFlag = \defined('JSON_PRETTY_PRINT') ? \JSON_PRETTY_PRINT : 128;
        $flags = 0;
        if (\PHP_VERSION_ID >= 50400) {
            $flags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE;
        }
        $hasSecondDimension = \count(\array_filter($normalized, 'is_array'));
        $hasNonNumericKeys = !\count(\array_filter(\array_keys($normalized), 'is_numeric'));
        return $hasSecondDimension || $hasNonNumericKeys ? Utils::jsonEncode($normalized, $prettyPrintFlag | $flags) : Utils::jsonEncode($normalized, $flags);
    }
    /**
     * Sets the formatter
     *
     * @param FormatterInterface $formatter
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->formatter = $formatter;
    }
    /**
     * Generates attachment field
     *
     * @param string       $title
     * @param string|array $value
     *
     * @return array
     */
    private function generateAttachmentField($title, $value)
    {
        $value = \is_array($value) ? \sprintf('```%s```', $this->stringify($value)) : $value;
        return array('title' => \ucfirst($title), 'value' => $value, 'short' => \false);
    }
    /**
     * Generates a collection of attachment fields from array
     *
     * @param array $data
     *
     * @return array
     */
    private function generateAttachmentFields(array $data)
    {
        $fields = array();
        foreach ($this->normalizerFormatter->format($data) as $key => $value) {
            $fields[] = $this->generateAttachmentField($key, $value);
        }
        return $fields;
    }
    /**
     * Get a copy of record with fields excluded according to $this->excludeFields
     *
     * @param array $record
     *
     * @return array
     */
    private function excludeFields(array $record)
    {
        foreach ($this->excludeFields as $field) {
            $keys = \explode('.', $field);
            $node =& $record;
            $lastKey = \end($keys);
            foreach ($keys as $key) {
                if (!isset($node[$key])) {
                    break;
                }
                if ($lastKey === $key) {
                    unset($node[$key]);
                    break;
                }
                $node =& $node[$key];
            }
        }
        return $record;
    }
}
Handler/Curl/Util.php000066600000002663151136154450010474 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\Curl;

class Util
{
    private static $retriableErrorCodes = array(\CURLE_COULDNT_RESOLVE_HOST, \CURLE_COULDNT_CONNECT, \CURLE_HTTP_NOT_FOUND, \CURLE_READ_ERROR, \CURLE_OPERATION_TIMEOUTED, \CURLE_HTTP_POST_ERROR, \CURLE_SSL_CONNECT_ERROR);
    /**
     * Executes a CURL request with optional retries and exception on failure
     *
     * @param  resource          $ch curl handler
     * @throws \RuntimeException
     */
    public static function execute($ch, $retries = 5, $closeAfterDone = \true)
    {
        while ($retries--) {
            if (\curl_exec($ch) === \false) {
                $curlErrno = \curl_errno($ch);
                if (\false === \in_array($curlErrno, self::$retriableErrorCodes, \true) || !$retries) {
                    $curlError = \curl_error($ch);
                    if ($closeAfterDone) {
                        \curl_close($ch);
                    }
                    throw new \RuntimeException(\sprintf('Curl error (code %s): %s', $curlErrno, $curlError));
                }
                continue;
            }
            if ($closeAfterDone) {
                \curl_close($ch);
            }
            break;
        }
    }
}
Handler/HandlerInterface.php000066600000005063151136154450012045 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Interface that all Monolog Handlers must implement
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
interface HandlerInterface
{
    /**
     * Checks whether the given record will be handled by this handler.
     *
     * This is mostly done for performance reasons, to avoid calling processors for nothing.
     *
     * Handlers should still check the record levels within handle(), returning false in isHandling()
     * is no guarantee that handle() will not be called, and isHandling() might not be called
     * for a given record.
     *
     * @param array $record Partial log record containing only a level key
     *
     * @return bool
     */
    public function isHandling(array $record);
    /**
     * Handles a record.
     *
     * All records may be passed to this method, and the handler should discard
     * those that it does not want to handle.
     *
     * The return value of this function controls the bubbling process of the handler stack.
     * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
     * calling further handlers in the stack with a given log record.
     *
     * @param  array   $record The record to handle
     * @return bool true means that this handler handled the record, and that bubbling is not permitted.
     *                        false means the record was either not processed or that this handler allows bubbling.
     */
    public function handle(array $record);
    /**
     * Handles a set of records at once.
     *
     * @param array $records The records to handle (an array of record arrays)
     */
    public function handleBatch(array $records);
    /**
     * Adds a processor in the stack.
     *
     * @param  callable $callback
     * @return self
     */
    public function pushProcessor($callback);
    /**
     * Removes the processor on top of the stack and returns it.
     *
     * @return callable
     */
    public function popProcessor();
    /**
     * Sets the formatter.
     *
     * @param  FormatterInterface $formatter
     * @return self
     */
    public function setFormatter(FormatterInterface $formatter);
    /**
     * Gets the formatter.
     *
     * @return FormatterInterface
     */
    public function getFormatter();
}
Handler/RotatingFileHandler.php000066600000013215151136154450012532 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Stores logs to files that are rotated every day and a limited number of files are kept.
 *
 * This rotation is only intended to be used as a workaround. Using logrotate to
 * handle the rotation is strongly encouraged when you can use it.
 *
 * @author Christophe Coevoet <stof@notk.org>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class RotatingFileHandler extends StreamHandler
{
    const FILE_PER_DAY = 'Y-m-d';
    const FILE_PER_MONTH = 'Y-m';
    const FILE_PER_YEAR = 'Y';
    protected $filename;
    protected $maxFiles;
    protected $mustRotate;
    protected $nextRotation;
    protected $filenameFormat;
    protected $dateFormat;
    /**
     * @param string   $filename
     * @param int      $maxFiles       The maximal amount of files to keep (0 means unlimited)
     * @param int      $level          The minimum logging level at which this handler will be triggered
     * @param bool     $bubble         Whether the messages that are handled can bubble up the stack or not
     * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
     * @param bool     $useLocking     Try to lock log file before doing any writes
     */
    public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = \true, $filePermission = null, $useLocking = \false)
    {
        $this->filename = Utils::canonicalizePath($filename);
        $this->maxFiles = (int) $maxFiles;
        $this->nextRotation = new \DateTime('tomorrow');
        $this->filenameFormat = '{filename}-{date}';
        $this->dateFormat = 'Y-m-d';
        parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        parent::close();
        if (\true === $this->mustRotate) {
            $this->rotate();
        }
    }
    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        parent::reset();
        if (\true === $this->mustRotate) {
            $this->rotate();
        }
    }
    public function setFilenameFormat($filenameFormat, $dateFormat)
    {
        if (!\preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {
            \trigger_error('Invalid date format - format must be one of ' . 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") ' . 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the ' . 'date formats using slashes, underscores and/or dots instead of dashes.', \E_USER_DEPRECATED);
        }
        if (\substr_count($filenameFormat, '{date}') === 0) {
            \trigger_error('Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.', \E_USER_DEPRECATED);
        }
        $this->filenameFormat = $filenameFormat;
        $this->dateFormat = $dateFormat;
        $this->url = $this->getTimedFilename();
        $this->close();
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        // on the first record written, if the log is new, we should rotate (once per day)
        if (null === $this->mustRotate) {
            $this->mustRotate = !\file_exists($this->url);
        }
        if ($this->nextRotation < $record['datetime']) {
            $this->mustRotate = \true;
            $this->close();
        }
        parent::write($record);
    }
    /**
     * Rotates the files.
     */
    protected function rotate()
    {
        // update filename
        $this->url = $this->getTimedFilename();
        $this->nextRotation = new \DateTime('tomorrow');
        // skip GC of old logs if files are unlimited
        if (0 === $this->maxFiles) {
            return;
        }
        $logFiles = \glob($this->getGlobPattern());
        if ($this->maxFiles >= \count($logFiles)) {
            // no files to remove
            return;
        }
        // Sorting the files by name to remove the older ones
        \usort($logFiles, function ($a, $b) {
            return \strcmp($b, $a);
        });
        foreach (\array_slice($logFiles, $this->maxFiles) as $file) {
            if (\is_writable($file)) {
                // suppress errors here as unlink() might fail if two processes
                // are cleaning up/rotating at the same time
                \set_error_handler(function ($errno, $errstr, $errfile, $errline) {
                });
                \unlink($file);
                \restore_error_handler();
            }
        }
        $this->mustRotate = \false;
    }
    protected function getTimedFilename()
    {
        $fileInfo = \pathinfo($this->filename);
        $timedFilename = \str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], \date($this->dateFormat)), $fileInfo['dirname'] . '/' . $this->filenameFormat);
        if (!empty($fileInfo['extension'])) {
            $timedFilename .= '.' . $fileInfo['extension'];
        }
        return $timedFilename;
    }
    protected function getGlobPattern()
    {
        $fileInfo = \pathinfo($this->filename);
        $glob = \str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], '[0-9][0-9][0-9][0-9]*'), $fileInfo['dirname'] . '/' . $this->filenameFormat);
        if (!empty($fileInfo['extension'])) {
            $glob .= '.' . $fileInfo['extension'];
        }
        return $glob;
    }
}
Handler/RavenHandler.php000066600000016315151136154450011222 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Raven_Client;
/**
 * Handler to send messages to a Sentry (https://github.com/getsentry/sentry) server
 * using sentry-php (https://github.com/getsentry/sentry-php)
 *
 * @author Marc Abramowitz <marc@marc-abramowitz.com>
 */
class RavenHandler extends AbstractProcessingHandler
{
    /**
     * Translates Monolog log levels to Raven log levels.
     */
    protected $logLevels = array(Logger::DEBUG => Raven_Client::DEBUG, Logger::INFO => Raven_Client::INFO, Logger::NOTICE => Raven_Client::INFO, Logger::WARNING => Raven_Client::WARNING, Logger::ERROR => Raven_Client::ERROR, Logger::CRITICAL => Raven_Client::FATAL, Logger::ALERT => Raven_Client::FATAL, Logger::EMERGENCY => Raven_Client::FATAL);
    /**
     * @var string should represent the current version of the calling
     *             software. Can be any string (git commit, version number)
     */
    protected $release;
    /**
     * @var Raven_Client the client object that sends the message to the server
     */
    protected $ravenClient;
    /**
     * @var FormatterInterface The formatter to use for the logs generated via handleBatch()
     */
    protected $batchFormatter;
    /**
     * @param Raven_Client $ravenClient
     * @param int          $level       The minimum logging level at which this handler will be triggered
     * @param bool         $bubble      Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = \true)
    {
        @\trigger_error('The Monolog\\Handler\\RavenHandler class is deprecated. You should rather upgrade to the sentry/sentry 2.x and use Sentry\\Monolog\\Handler, see https://github.com/getsentry/sentry-php/blob/master/src/Monolog/Handler.php', \E_USER_DEPRECATED);
        parent::__construct($level, $bubble);
        $this->ravenClient = $ravenClient;
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        $level = $this->level;
        // filter records based on their level
        $records = \array_filter($records, function ($record) use($level) {
            return $record['level'] >= $level;
        });
        if (!$records) {
            return;
        }
        // the record with the highest severity is the "main" one
        $record = \array_reduce($records, function ($highest, $record) {
            if (null === $highest || $record['level'] > $highest['level']) {
                return $record;
            }
            return $highest;
        });
        // the other ones are added as a context item
        $logs = array();
        foreach ($records as $r) {
            $logs[] = $this->processRecord($r);
        }
        if ($logs) {
            $record['context']['logs'] = (string) $this->getBatchFormatter()->formatBatch($logs);
        }
        $this->handle($record);
    }
    /**
     * Sets the formatter for the logs generated by handleBatch().
     *
     * @param FormatterInterface $formatter
     */
    public function setBatchFormatter(FormatterInterface $formatter)
    {
        $this->batchFormatter = $formatter;
    }
    /**
     * Gets the formatter for the logs generated by handleBatch().
     *
     * @return FormatterInterface
     */
    public function getBatchFormatter()
    {
        if (!$this->batchFormatter) {
            $this->batchFormatter = $this->getDefaultBatchFormatter();
        }
        return $this->batchFormatter;
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $previousUserContext = \false;
        $options = array();
        $options['level'] = $this->logLevels[$record['level']];
        $options['tags'] = array();
        if (!empty($record['extra']['tags'])) {
            $options['tags'] = \array_merge($options['tags'], $record['extra']['tags']);
            unset($record['extra']['tags']);
        }
        if (!empty($record['context']['tags'])) {
            $options['tags'] = \array_merge($options['tags'], $record['context']['tags']);
            unset($record['context']['tags']);
        }
        if (!empty($record['context']['fingerprint'])) {
            $options['fingerprint'] = $record['context']['fingerprint'];
            unset($record['context']['fingerprint']);
        }
        if (!empty($record['context']['logger'])) {
            $options['logger'] = $record['context']['logger'];
            unset($record['context']['logger']);
        } else {
            $options['logger'] = $record['channel'];
        }
        foreach ($this->getExtraParameters() as $key) {
            foreach (array('extra', 'context') as $source) {
                if (!empty($record[$source][$key])) {
                    $options[$key] = $record[$source][$key];
                    unset($record[$source][$key]);
                }
            }
        }
        if (!empty($record['context'])) {
            $options['extra']['context'] = $record['context'];
            if (!empty($record['context']['user'])) {
                $previousUserContext = $this->ravenClient->context->user;
                $this->ravenClient->user_context($record['context']['user']);
                unset($options['extra']['context']['user']);
            }
        }
        if (!empty($record['extra'])) {
            $options['extra']['extra'] = $record['extra'];
        }
        if (!empty($this->release) && !isset($options['release'])) {
            $options['release'] = $this->release;
        }
        if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || \PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable)) {
            $options['message'] = $record['formatted'];
            $this->ravenClient->captureException($record['context']['exception'], $options);
        } else {
            $this->ravenClient->captureMessage($record['formatted'], array(), $options);
        }
        if ($previousUserContext !== \false) {
            $this->ravenClient->user_context($previousUserContext);
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter('[%channel%] %message%');
    }
    /**
     * Gets the default formatter for the logs generated by handleBatch().
     *
     * @return FormatterInterface
     */
    protected function getDefaultBatchFormatter()
    {
        return new LineFormatter();
    }
    /**
     * Gets extra parameters supported by Raven that can be found in "extra" and "context"
     *
     * @return array
     */
    protected function getExtraParameters()
    {
        return array('contexts', 'checksum', 'release', 'event_id');
    }
    /**
     * @param string $value
     * @return self
     */
    public function setRelease($value)
    {
        $this->release = $value;
        return $this;
    }
}
Handler/SyslogUdp/UdpSocket.php000066600000002622151136154450012477 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler\SyslogUdp;

class UdpSocket
{
    const DATAGRAM_MAX_LENGTH = 65023;
    protected $ip;
    protected $port;
    protected $socket;
    public function __construct($ip, $port = 514)
    {
        $this->ip = $ip;
        $this->port = $port;
        $this->socket = \socket_create(\AF_INET, \SOCK_DGRAM, \SOL_UDP);
    }
    public function write($line, $header = "")
    {
        $this->send($this->assembleMessage($line, $header));
    }
    public function close()
    {
        if (\is_resource($this->socket)) {
            \socket_close($this->socket);
            $this->socket = null;
        }
    }
    protected function send($chunk)
    {
        if (!\is_resource($this->socket)) {
            throw new \LogicException('The UdpSocket to ' . $this->ip . ':' . $this->port . ' has been closed and can not be written to anymore');
        }
        \socket_sendto($this->socket, $chunk, \strlen($chunk), $flags = 0, $this->ip, $this->port);
    }
    protected function assembleMessage($line, $header)
    {
        $chunkSize = self::DATAGRAM_MAX_LENGTH - \strlen($header);
        return $header . \substr($line, 0, $chunkSize);
    }
}
Handler/NullHandler.php000066600000001724151136154450011057 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Blackhole
 *
 * Any record it can handle will be thrown away. This can be used
 * to put on top of an existing stack to override it temporarily.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class NullHandler extends AbstractHandler
{
    /**
     * @param int $level The minimum logging level at which this handler will be triggered
     */
    public function __construct($level = Logger::DEBUG)
    {
        parent::__construct($level, \false);
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if ($record['level'] < $this->level) {
            return \false;
        }
        return \true;
    }
}
Handler/PHPConsoleHandler.php000066600000023634151136154450012123 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use Exception;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\PhpConsole\Connector;
use AIOSEO\Vendor\PhpConsole\Handler;
use AIOSEO\Vendor\PhpConsole\Helper;
/**
 * Monolog handler for Google Chrome extension "PHP Console"
 *
 * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely
 *
 * Usage:
 * 1. Install Google Chrome extension https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef
 * 2. See overview https://github.com/barbushin/php-console#overview
 * 3. Install PHP Console library https://github.com/barbushin/php-console#installation
 * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png)
 *
 *      $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler()));
 *      \Monolog\ErrorHandler::register($logger);
 *      echo $undefinedVar;
 *      $logger->addDebug('SELECT * FROM users', array('db', 'time' => 0.012));
 *      PC::debug($_SERVER); // PHP Console debugger for any type of vars
 *
 * @author Sergey Barbushin https://www.linkedin.com/in/barbushin
 */
class PHPConsoleHandler extends AbstractProcessingHandler
{
    private $options = array(
        'enabled' => \true,
        // bool Is PHP Console server enabled
        'classesPartialsTraceIgnore' => array('AIOSEO\\Vendor\\Monolog\\'),
        // array Hide calls of classes started with...
        'debugTagsKeysInContext' => array(0, 'tag'),
        // bool Is PHP Console server enabled
        'useOwnErrorsHandler' => \false,
        // bool Enable errors handling
        'useOwnExceptionsHandler' => \false,
        // bool Enable exceptions handling
        'sourcesBasePath' => null,
        // string Base path of all project sources to strip in errors source paths
        'registerHelper' => \true,
        // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s')
        'serverEncoding' => null,
        // string|null Server internal encoding
        'headersLimit' => null,
        // int|null Set headers size limit for your web-server
        'password' => null,
        // string|null Protect PHP Console connection by password
        'enableSslOnlyMode' => \false,
        // bool Force connection by SSL for clients with PHP Console installed
        'ipMasks' => array(),
        // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1')
        'enableEvalListener' => \false,
        // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required)
        'dumperDetectCallbacks' => \false,
        // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings
        'dumperLevelLimit' => 5,
        // int Maximum dumped vars array or object nested dump level
        'dumperItemsCountLimit' => 100,
        // int Maximum dumped var same level array items or object properties number
        'dumperItemSizeLimit' => 5000,
        // int Maximum length of any string or dumped array item
        'dumperDumpSizeLimit' => 500000,
        // int Maximum approximate size of dumped vars result formatted in JSON
        'detectDumpTraceAndSource' => \false,
        // bool Autodetect and append trace data to debug
        'dataStorage' => null,
    );
    /** @var Connector */
    private $connector;
    /**
     * @param  array          $options   See \Monolog\Handler\PHPConsoleHandler::$options for more details
     * @param  Connector|null $connector Instance of \PhpConsole\Connector class (optional)
     * @param  int            $level
     * @param  bool           $bubble
     * @throws Exception
     */
    public function __construct(array $options = array(), Connector $connector = null, $level = Logger::DEBUG, $bubble = \true)
    {
        if (!\class_exists('AIOSEO\\Vendor\\PhpConsole\\Connector')) {
            throw new Exception('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
        }
        parent::__construct($level, $bubble);
        $this->options = $this->initOptions($options);
        $this->connector = $this->initConnector($connector);
    }
    private function initOptions(array $options)
    {
        $wrongOptions = \array_diff(\array_keys($options), \array_keys($this->options));
        if ($wrongOptions) {
            throw new Exception('Unknown options: ' . \implode(', ', $wrongOptions));
        }
        return \array_replace($this->options, $options);
    }
    private function initConnector(Connector $connector = null)
    {
        if (!$connector) {
            if ($this->options['dataStorage']) {
                Connector::setPostponeStorage($this->options['dataStorage']);
            }
            $connector = Connector::getInstance();
        }
        if ($this->options['registerHelper'] && !Helper::isRegistered()) {
            Helper::register();
        }
        if ($this->options['enabled'] && $connector->isActiveClient()) {
            if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) {
                $handler = Handler::getInstance();
                $handler->setHandleErrors($this->options['useOwnErrorsHandler']);
                $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']);
                $handler->start();
            }
            if ($this->options['sourcesBasePath']) {
                $connector->setSourcesBasePath($this->options['sourcesBasePath']);
            }
            if ($this->options['serverEncoding']) {
                $connector->setServerEncoding($this->options['serverEncoding']);
            }
            if ($this->options['password']) {
                $connector->setPassword($this->options['password']);
            }
            if ($this->options['enableSslOnlyMode']) {
                $connector->enableSslOnlyMode();
            }
            if ($this->options['ipMasks']) {
                $connector->setAllowedIpMasks($this->options['ipMasks']);
            }
            if ($this->options['headersLimit']) {
                $connector->setHeadersLimit($this->options['headersLimit']);
            }
            if ($this->options['detectDumpTraceAndSource']) {
                $connector->getDebugDispatcher()->detectTraceAndSource = \true;
            }
            $dumper = $connector->getDumper();
            $dumper->levelLimit = $this->options['dumperLevelLimit'];
            $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit'];
            $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit'];
            $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit'];
            $dumper->detectCallbacks = $this->options['dumperDetectCallbacks'];
            if ($this->options['enableEvalListener']) {
                $connector->startEvalRequestsListener();
            }
        }
        return $connector;
    }
    public function getConnector()
    {
        return $this->connector;
    }
    public function getOptions()
    {
        return $this->options;
    }
    public function handle(array $record)
    {
        if ($this->options['enabled'] && $this->connector->isActiveClient()) {
            return parent::handle($record);
        }
        return !$this->bubble;
    }
    /**
     * Writes the record down to the log of the implementing handler
     *
     * @param  array $record
     * @return void
     */
    protected function write(array $record)
    {
        if ($record['level'] < Logger::NOTICE) {
            $this->handleDebugRecord($record);
        } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) {
            $this->handleExceptionRecord($record);
        } else {
            $this->handleErrorRecord($record);
        }
    }
    private function handleDebugRecord(array $record)
    {
        $tags = $this->getRecordTags($record);
        $message = $record['message'];
        if ($record['context']) {
            $message .= ' ' . Utils::jsonEncode($this->connector->getDumper()->dump(\array_filter($record['context'])), null, \true);
        }
        $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']);
    }
    private function handleExceptionRecord(array $record)
    {
        $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']);
    }
    private function handleErrorRecord(array $record)
    {
        $context = $record['context'];
        $this->connector->getErrorsDispatcher()->dispatchError(isset($context['code']) ? $context['code'] : null, isset($context['message']) ? $context['message'] : $record['message'], isset($context['file']) ? $context['file'] : null, isset($context['line']) ? $context['line'] : null, $this->options['classesPartialsTraceIgnore']);
    }
    private function getRecordTags(array &$record)
    {
        $tags = null;
        if (!empty($record['context'])) {
            $context =& $record['context'];
            foreach ($this->options['debugTagsKeysInContext'] as $key) {
                if (!empty($context[$key])) {
                    $tags = $context[$key];
                    if ($key === 0) {
                        \array_shift($context);
                    } else {
                        unset($context[$key]);
                    }
                    break;
                }
            }
        }
        return $tags ?: \strtolower($record['level_name']);
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter('%message%');
    }
}
Handler/SyslogUdpHandler.php000066600000006065151136154450012101 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Handler\SyslogUdp\UdpSocket;
/**
 * A Handler for logging to a remote syslogd server.
 *
 * @author Jesper Skovgaard Nielsen <nulpunkt@gmail.com>
 * @author Dominik Kukacka <dominik.kukacka@gmail.com>
 */
class SyslogUdpHandler extends AbstractSyslogHandler
{
    const RFC3164 = 0;
    const RFC5424 = 1;
    private $dateFormats = array(self::RFC3164 => 'M d H:i:s', self::RFC5424 => \DateTime::RFC3339);
    protected $socket;
    protected $ident;
    protected $rfc;
    /**
     * @param string $host
     * @param int    $port
     * @param mixed  $facility
     * @param int    $level    The minimum logging level at which this handler will be triggered
     * @param bool   $bubble   Whether the messages that are handled can bubble up the stack or not
     * @param string $ident    Program name or tag for each log message.
     * @param int    $rfc      RFC to format the message for.
     */
    public function __construct($host, $port = 514, $facility = \LOG_USER, $level = Logger::DEBUG, $bubble = \true, $ident = 'php', $rfc = self::RFC5424)
    {
        parent::__construct($facility, $level, $bubble);
        $this->ident = $ident;
        $this->rfc = $rfc;
        $this->socket = new UdpSocket($host, $port ?: 514);
    }
    protected function write(array $record)
    {
        $lines = $this->splitMessageIntoLines($record['formatted']);
        $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]);
        foreach ($lines as $line) {
            $this->socket->write($line, $header);
        }
    }
    public function close()
    {
        $this->socket->close();
    }
    private function splitMessageIntoLines($message)
    {
        if (\is_array($message)) {
            $message = \implode("\n", $message);
        }
        return \preg_split('/$\\R?^/m', $message, -1, \PREG_SPLIT_NO_EMPTY);
    }
    /**
     * Make common syslog header (see rfc5424 or rfc3164)
     */
    protected function makeCommonSyslogHeader($severity)
    {
        $priority = $severity + $this->facility;
        if (!($pid = \getmypid())) {
            $pid = '-';
        }
        if (!($hostname = \gethostname())) {
            $hostname = '-';
        }
        $date = $this->getDateTime();
        if ($this->rfc === self::RFC3164) {
            return "<{$priority}>" . $date . " " . $hostname . " " . $this->ident . "[" . $pid . "]: ";
        } else {
            return "<{$priority}>1 " . $date . " " . $hostname . " " . $this->ident . " " . $pid . " - - ";
        }
    }
    protected function getDateTime()
    {
        return \date($this->dateFormats[$this->rfc]);
    }
    /**
     * Inject your own socket, mainly used for testing
     */
    public function setSocket($socket)
    {
        $this->socket = $socket;
    }
}
Handler/SlackWebhookHandler.php000066600000007233151136154450012522 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\Monolog\Handler\Slack\SlackRecord;
/**
 * Sends notifications through Slack Webhooks
 *
 * @author Haralan Dobrev <hkdobrev@gmail.com>
 * @see    https://api.slack.com/incoming-webhooks
 */
class SlackWebhookHandler extends AbstractProcessingHandler
{
    /**
     * Slack Webhook token
     * @var string
     */
    private $webhookUrl;
    /**
     * Instance of the SlackRecord util class preparing data for Slack API.
     * @var SlackRecord
     */
    private $slackRecord;
    /**
     * @param  string      $webhookUrl             Slack Webhook URL
     * @param  string|null $channel                Slack channel (encoded ID or name)
     * @param  string|null $username               Name of a bot
     * @param  bool        $useAttachment          Whether the message should be added to Slack as attachment (plain text otherwise)
     * @param  string|null $iconEmoji              The emoji name to use (or null)
     * @param  bool        $useShortAttachment     Whether the the context/extra messages added to Slack as attachments are in a short style
     * @param  bool        $includeContextAndExtra Whether the attachment should include context and extra data
     * @param  int         $level                  The minimum logging level at which this handler will be triggered
     * @param  bool        $bubble                 Whether the messages that are handled can bubble up the stack or not
     * @param  array       $excludeFields          Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
     */
    public function __construct($webhookUrl, $channel = null, $username = null, $useAttachment = \true, $iconEmoji = null, $useShortAttachment = \false, $includeContextAndExtra = \false, $level = Logger::CRITICAL, $bubble = \true, array $excludeFields = array())
    {
        parent::__construct($level, $bubble);
        $this->webhookUrl = $webhookUrl;
        $this->slackRecord = new SlackRecord($channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields, $this->formatter);
    }
    public function getSlackRecord()
    {
        return $this->slackRecord;
    }
    public function getWebhookUrl()
    {
        return $this->webhookUrl;
    }
    /**
     * {@inheritdoc}
     *
     * @param array $record
     */
    protected function write(array $record)
    {
        $postData = $this->slackRecord->getSlackData($record);
        $postString = Utils::jsonEncode($postData);
        $ch = \curl_init();
        $options = array(\CURLOPT_URL => $this->webhookUrl, \CURLOPT_POST => \true, \CURLOPT_RETURNTRANSFER => \true, \CURLOPT_HTTPHEADER => array('Content-type: application/json'), \CURLOPT_POSTFIELDS => $postString);
        if (\defined('CURLOPT_SAFE_UPLOAD')) {
            $options[\CURLOPT_SAFE_UPLOAD] = \true;
        }
        \curl_setopt_array($ch, $options);
        Curl\Util::execute($ch);
    }
    public function setFormatter(FormatterInterface $formatter)
    {
        parent::setFormatter($formatter);
        $this->slackRecord->setFormatter($formatter);
        return $this;
    }
    public function getFormatter()
    {
        $formatter = parent::getFormatter();
        $this->slackRecord->setFormatter($formatter);
        return $formatter;
    }
}
Handler/ChromePHPHandler.php000066600000012666151136154450011741 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\ChromePHPFormatter;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
 *
 * This also works out of the box with Firefox 43+
 *
 * @author Christophe Coevoet <stof@notk.org>
 */
class ChromePHPHandler extends AbstractProcessingHandler
{
    /**
     * Version of the extension
     */
    const VERSION = '4.0';
    /**
     * Header name
     */
    const HEADER_NAME = 'X-ChromeLogger-Data';
    /**
     * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+)
     */
    const USER_AGENT_REGEX = '{\\b(?:Chrome/\\d+(?:\\.\\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\\d|\\d{3,})(?:\\.\\d)*)\\b}';
    protected static $initialized = \false;
    /**
     * Tracks whether we sent too much data
     *
     * Chrome limits the headers to 4KB, so when we sent 3KB we stop sending
     *
     * @var bool
     */
    protected static $overflowed = \false;
    protected static $json = array('version' => self::VERSION, 'columns' => array('label', 'log', 'backtrace', 'type'), 'rows' => array());
    protected static $sendHeaders = \true;
    /**
     * @param int  $level  The minimum logging level at which this handler will be triggered
     * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        if (!\function_exists('json_encode')) {
            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler');
        }
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        $messages = array();
        foreach ($records as $record) {
            if ($record['level'] < $this->level) {
                continue;
            }
            $messages[] = $this->processRecord($record);
        }
        if (!empty($messages)) {
            $messages = $this->getFormatter()->formatBatch($messages);
            self::$json['rows'] = \array_merge(self::$json['rows'], $messages);
            $this->send();
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new ChromePHPFormatter();
    }
    /**
     * Creates & sends header for a record
     *
     * @see sendHeader()
     * @see send()
     * @param array $record
     */
    protected function write(array $record)
    {
        self::$json['rows'][] = $record['formatted'];
        $this->send();
    }
    /**
     * Sends the log header
     *
     * @see sendHeader()
     */
    protected function send()
    {
        if (self::$overflowed || !self::$sendHeaders) {
            return;
        }
        if (!self::$initialized) {
            self::$initialized = \true;
            self::$sendHeaders = $this->headersAccepted();
            if (!self::$sendHeaders) {
                return;
            }
            self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
        }
        $json = Utils::jsonEncode(self::$json, null, \true);
        $data = \base64_encode(\utf8_encode($json));
        if (\strlen($data) > 3 * 1024) {
            self::$overflowed = \true;
            $record = array('message' => 'Incomplete logs, chrome header size limit reached', 'context' => array(), 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'monolog', 'datetime' => new \DateTime(), 'extra' => array());
            self::$json['rows'][\count(self::$json['rows']) - 1] = $this->getFormatter()->format($record);
            $json = Utils::jsonEncode(self::$json, null, \true);
            $data = \base64_encode(\utf8_encode($json));
        }
        if (\trim($data) !== '') {
            $this->sendHeader(self::HEADER_NAME, $data);
        }
    }
    /**
     * Send header string to the client
     *
     * @param string $header
     * @param string $content
     */
    protected function sendHeader($header, $content)
    {
        if (!\headers_sent() && self::$sendHeaders) {
            \header(\sprintf('%s: %s', $header, $content));
        }
    }
    /**
     * Verifies if the headers are accepted by the current user agent
     *
     * @return bool
     */
    protected function headersAccepted()
    {
        if (empty($_SERVER['HTTP_USER_AGENT'])) {
            return \false;
        }
        return \preg_match(self::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']);
    }
    /**
     * BC getter for the sendHeaders property that has been made static
     */
    public function __get($property)
    {
        if ('sendHeaders' !== $property) {
            throw new \InvalidArgumentException('Undefined property ' . $property);
        }
        return static::$sendHeaders;
    }
    /**
     * BC setter for the sendHeaders property that has been made static
     */
    public function __set($property, $value)
    {
        if ('sendHeaders' !== $property) {
            throw new \InvalidArgumentException('Undefined property ' . $property);
        }
        static::$sendHeaders = $value;
    }
}
Handler/AbstractProcessingHandler.php000066600000003022151136154450013736 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\ResettableInterface;
/**
 * Base Handler class providing the Handler structure
 *
 * Classes extending it should (in most cases) only implement write($record)
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @author Christophe Coevoet <stof@notk.org>
 */
abstract class AbstractProcessingHandler extends AbstractHandler
{
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if (!$this->isHandling($record)) {
            return \false;
        }
        $record = $this->processRecord($record);
        $record['formatted'] = $this->getFormatter()->format($record);
        $this->write($record);
        return \false === $this->bubble;
    }
    /**
     * Writes the record down to the log of the implementing handler
     *
     * @param  array $record
     * @return void
     */
    protected abstract function write(array $record);
    /**
     * Processes a record.
     *
     * @param  array $record
     * @return array
     */
    protected function processRecord(array $record)
    {
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        return $record;
    }
}
Handler/SwiftMailerHandler.php000066600000006727151136154450012403 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Swift;
/**
 * SwiftMailerHandler uses Swift_Mailer to send the emails
 *
 * @author Gyula Sallai
 */
class SwiftMailerHandler extends MailHandler
{
    protected $mailer;
    private $messageTemplate;
    /**
     * @param \Swift_Mailer           $mailer  The mailer to use
     * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
     * @param int                     $level   The minimum logging level at which this handler will be triggered
     * @param bool                    $bubble  Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(\AIOSEO\Vendor\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        $this->mailer = $mailer;
        $this->messageTemplate = $message;
    }
    /**
     * {@inheritdoc}
     */
    protected function send($content, array $records)
    {
        $this->mailer->send($this->buildMessage($content, $records));
    }
    /**
     * Gets the formatter for the Swift_Message subject.
     *
     * @param  string             $format The format of the subject
     * @return FormatterInterface
     */
    protected function getSubjectFormatter($format)
    {
        return new LineFormatter($format);
    }
    /**
     * Creates instance of Swift_Message to be sent
     *
     * @param  string         $content formatted email body to be sent
     * @param  array          $records Log records that formed the content
     * @return \Swift_Message
     */
    protected function buildMessage($content, array $records)
    {
        $message = null;
        if ($this->messageTemplate instanceof \AIOSEO\Vendor\Swift_Message) {
            $message = clone $this->messageTemplate;
            $message->generateId();
        } elseif (\is_callable($this->messageTemplate)) {
            $message = \call_user_func($this->messageTemplate, $content, $records);
        }
        if (!$message instanceof \AIOSEO\Vendor\Swift_Message) {
            throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it');
        }
        if ($records) {
            $subjectFormatter = $this->getSubjectFormatter($message->getSubject());
            $message->setSubject($subjectFormatter->format($this->getHighestRecord($records)));
        }
        $message->setBody($content);
        if (\version_compare(Swift::VERSION, '6.0.0', '>=')) {
            $message->setDate(new \DateTimeImmutable());
        } else {
            $message->setDate(\time());
        }
        return $message;
    }
    /**
     * BC getter, to be removed in 2.0
     */
    public function __get($name)
    {
        if ($name === 'message') {
            \trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', \E_USER_DEPRECATED);
            return $this->buildMessage(null, array());
        }
        throw new \InvalidArgumentException('Invalid property ' . $name);
    }
}
Handler/FormattableHandlerInterface.php000066600000001667151136154450014234 0ustar00<?php

declare (strict_types=1);
/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Interface to describe loggers that have a formatter
 *
 * This interface is present in monolog 1.x to ease forward compatibility.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
interface FormattableHandlerInterface
{
    /**
     * Sets the formatter.
     *
     * @param  FormatterInterface $formatter
     * @return HandlerInterface   self
     */
    public function setFormatter(FormatterInterface $formatter) : HandlerInterface;
    /**
     * Gets the formatter.
     *
     * @return FormatterInterface
     */
    public function getFormatter() : FormatterInterface;
}
Handler/HandlerWrapper.php000066600000004533151136154450011566 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\ResettableInterface;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * This simple wrapper class can be used to extend handlers functionality.
 *
 * Example: A custom filtering that can be applied to any handler.
 *
 * Inherit from this class and override handle() like this:
 *
 *   public function handle(array $record)
 *   {
 *        if ($record meets certain conditions) {
 *            return false;
 *        }
 *        return $this->handler->handle($record);
 *   }
 *
 * @author Alexey Karapetov <alexey@karapetov.com>
 */
class HandlerWrapper implements HandlerInterface, ResettableInterface
{
    /**
     * @var HandlerInterface
     */
    protected $handler;
    /**
     * HandlerWrapper constructor.
     * @param HandlerInterface $handler
     */
    public function __construct(HandlerInterface $handler)
    {
        $this->handler = $handler;
    }
    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        return $this->handler->isHandling($record);
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        return $this->handler->handle($record);
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        return $this->handler->handleBatch($records);
    }
    /**
     * {@inheritdoc}
     */
    public function pushProcessor($callback)
    {
        $this->handler->pushProcessor($callback);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function popProcessor()
    {
        return $this->handler->popProcessor();
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->handler->setFormatter($formatter);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->handler->getFormatter();
    }
    public function reset()
    {
        if ($this->handler instanceof ResettableInterface) {
            return $this->handler->reset();
        }
    }
}
Handler/ElasticSearchHandler.php000066600000006477151136154450012671 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Formatter\ElasticaFormatter;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Elastica\Client;
use AIOSEO\Vendor\Elastica\Exception\ExceptionInterface;
/**
 * Elastic Search handler
 *
 * Usage example:
 *
 *    $client = new \Elastica\Client();
 *    $options = array(
 *        'index' => 'elastic_index_name',
 *        'type' => 'elastic_doc_type',
 *    );
 *    $handler = new ElasticSearchHandler($client, $options);
 *    $log = new Logger('application');
 *    $log->pushHandler($handler);
 *
 * @author Jelle Vink <jelle.vink@gmail.com>
 */
class ElasticSearchHandler extends AbstractProcessingHandler
{
    /**
     * @var Client
     */
    protected $client;
    /**
     * @var array Handler config options
     */
    protected $options = array();
    /**
     * @param Client $client  Elastica Client object
     * @param array  $options Handler configuration
     * @param int    $level   The minimum logging level at which this handler will be triggered
     * @param bool   $bubble  Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        $this->client = $client;
        $this->options = \array_merge(array(
            'index' => 'monolog',
            // Elastic index name
            'type' => 'record',
            // Elastic document type
            'ignore_error' => \false,
        ), $options);
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        $this->bulkSend(array($record['formatted']));
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        if ($formatter instanceof ElasticaFormatter) {
            return parent::setFormatter($formatter);
        }
        throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter');
    }
    /**
     * Getter options
     * @return array
     */
    public function getOptions()
    {
        return $this->options;
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new ElasticaFormatter($this->options['index'], $this->options['type']);
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        $documents = $this->getFormatter()->formatBatch($records);
        $this->bulkSend($documents);
    }
    /**
     * Use Elasticsearch bulk API to send list of documents
     * @param  array             $documents
     * @throws \RuntimeException
     */
    protected function bulkSend(array $documents)
    {
        try {
            $this->client->addDocuments($documents);
        } catch (ExceptionInterface $e) {
            if (!$this->options['ignore_error']) {
                throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e);
            }
        }
    }
}
Handler/ZendMonitorHandler.php000066600000005606151136154450012420 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\NormalizerFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Handler sending logs to Zend Monitor
 *
 * @author  Christian Bergau <cbergau86@gmail.com>
 * @author  Jason Davis <happydude@jasondavis.net>
 */
class ZendMonitorHandler extends AbstractProcessingHandler
{
    /**
     * Monolog level / ZendMonitor Custom Event priority map
     *
     * @var array
     */
    protected $levelMap = array();
    /**
     * Construct
     *
     * @param  int                       $level
     * @param  bool                      $bubble
     * @throws MissingExtensionException
     */
    public function __construct($level = Logger::DEBUG, $bubble = \true)
    {
        if (!\function_exists('AIOSEO\\Vendor\\zend_monitor_custom_event')) {
            throw new MissingExtensionException('You must have Zend Server installed with Zend Monitor enabled in order to use this handler');
        }
        //zend monitor constants are not defined if zend monitor is not enabled.
        $this->levelMap = array(Logger::DEBUG => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::INFO => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::NOTICE => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::WARNING => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_WARNING, Logger::ERROR => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::CRITICAL => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::ALERT => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::EMERGENCY => \AIOSEO\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR);
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $this->writeZendMonitorCustomEvent(Logger::getLevelName($record['level']), $record['message'], $record['formatted'], $this->levelMap[$record['level']]);
    }
    /**
     * Write to Zend Monitor Events
     * @param string $type Text displayed in "Class Name (custom)" field
     * @param string $message Text displayed in "Error String"
     * @param mixed $formatted Displayed in Custom Variables tab
     * @param int $severity Set the event severity level (-1,0,1)
     */
    protected function writeZendMonitorCustomEvent($type, $message, $formatted, $severity)
    {
        zend_monitor_custom_event($type, $message, $formatted, $severity);
    }
    /**
     * {@inheritdoc}
     */
    public function getDefaultFormatter()
    {
        return new NormalizerFormatter();
    }
    /**
     * Get the level map
     *
     * @return array
     */
    public function getLevelMap()
    {
        return $this->levelMap;
    }
}
Handler/MongoDBHandler.php000066600000003207151136154450011430 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\NormalizerFormatter;
/**
 * Logs to a MongoDB database.
 *
 * usage example:
 *
 *   $log = new Logger('application');
 *   $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod");
 *   $log->pushHandler($mongodb);
 *
 * @author Thomas Tourlourat <thomas@tourlourat.com>
 */
class MongoDBHandler extends AbstractProcessingHandler
{
    protected $mongoCollection;
    public function __construct($mongo, $database, $collection, $level = Logger::DEBUG, $bubble = \true)
    {
        if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo || $mongo instanceof \AIOSEO\Vendor\MongoDB\Client)) {
            throw new \InvalidArgumentException('MongoClient, Mongo or MongoDB\\Client instance required');
        }
        $this->mongoCollection = $mongo->selectCollection($database, $collection);
        parent::__construct($level, $bubble);
    }
    protected function write(array $record)
    {
        if ($this->mongoCollection instanceof \AIOSEO\Vendor\MongoDB\Collection) {
            $this->mongoCollection->insertOne($record["formatted"]);
        } else {
            $this->mongoCollection->save($record["formatted"]);
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new NormalizerFormatter();
    }
}
Handler/SocketHandler.php000066600000023163151136154450011376 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Stores to any socket - uses fsockopen() or pfsockopen().
 *
 * @author Pablo de Leon Belloc <pablolb@gmail.com>
 * @see    http://php.net/manual/en/function.fsockopen.php
 */
class SocketHandler extends AbstractProcessingHandler
{
    private $connectionString;
    private $connectionTimeout;
    private $resource;
    private $timeout = 0;
    private $writingTimeout = 10;
    private $lastSentBytes = null;
    private $chunkSize = null;
    private $persistent = \false;
    private $errno;
    private $errstr;
    private $lastWritingAt;
    /**
     * @param string $connectionString Socket connection string
     * @param int    $level            The minimum logging level at which this handler will be triggered
     * @param bool   $bubble           Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($connectionString, $level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        $this->connectionString = $connectionString;
        $this->connectionTimeout = (float) \ini_get('default_socket_timeout');
    }
    /**
     * Connect (if necessary) and write to the socket
     *
     * @param array $record
     *
     * @throws \UnexpectedValueException
     * @throws \RuntimeException
     */
    protected function write(array $record)
    {
        $this->connectIfNotConnected();
        $data = $this->generateDataStream($record);
        $this->writeToSocket($data);
    }
    /**
     * We will not close a PersistentSocket instance so it can be reused in other requests.
     */
    public function close()
    {
        if (!$this->isPersistent()) {
            $this->closeSocket();
        }
    }
    /**
     * Close socket, if open
     */
    public function closeSocket()
    {
        if (\is_resource($this->resource)) {
            \fclose($this->resource);
            $this->resource = null;
        }
    }
    /**
     * Set socket connection to nbe persistent. It only has effect before the connection is initiated.
     *
     * @param bool $persistent
     */
    public function setPersistent($persistent)
    {
        $this->persistent = (bool) $persistent;
    }
    /**
     * Set connection timeout.  Only has effect before we connect.
     *
     * @param float $seconds
     *
     * @see http://php.net/manual/en/function.fsockopen.php
     */
    public function setConnectionTimeout($seconds)
    {
        $this->validateTimeout($seconds);
        $this->connectionTimeout = (float) $seconds;
    }
    /**
     * Set write timeout. Only has effect before we connect.
     *
     * @param float $seconds
     *
     * @see http://php.net/manual/en/function.stream-set-timeout.php
     */
    public function setTimeout($seconds)
    {
        $this->validateTimeout($seconds);
        $this->timeout = (float) $seconds;
    }
    /**
     * Set writing timeout. Only has effect during connection in the writing cycle.
     *
     * @param float $seconds 0 for no timeout
     */
    public function setWritingTimeout($seconds)
    {
        $this->validateTimeout($seconds);
        $this->writingTimeout = (float) $seconds;
    }
    /**
     * Set chunk size. Only has effect during connection in the writing cycle.
     *
     * @param float $bytes
     */
    public function setChunkSize($bytes)
    {
        $this->chunkSize = $bytes;
    }
    /**
     * Get current connection string
     *
     * @return string
     */
    public function getConnectionString()
    {
        return $this->connectionString;
    }
    /**
     * Get persistent setting
     *
     * @return bool
     */
    public function isPersistent()
    {
        return $this->persistent;
    }
    /**
     * Get current connection timeout setting
     *
     * @return float
     */
    public function getConnectionTimeout()
    {
        return $this->connectionTimeout;
    }
    /**
     * Get current in-transfer timeout
     *
     * @return float
     */
    public function getTimeout()
    {
        return $this->timeout;
    }
    /**
     * Get current local writing timeout
     *
     * @return float
     */
    public function getWritingTimeout()
    {
        return $this->writingTimeout;
    }
    /**
     * Get current chunk size
     *
     * @return float
     */
    public function getChunkSize()
    {
        return $this->chunkSize;
    }
    /**
     * Check to see if the socket is currently available.
     *
     * UDP might appear to be connected but might fail when writing.  See http://php.net/fsockopen for details.
     *
     * @return bool
     */
    public function isConnected()
    {
        return \is_resource($this->resource) && !\feof($this->resource);
        // on TCP - other party can close connection.
    }
    /**
     * Wrapper to allow mocking
     */
    protected function pfsockopen()
    {
        return @\pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
    }
    /**
     * Wrapper to allow mocking
     */
    protected function fsockopen()
    {
        return @\fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
    }
    /**
     * Wrapper to allow mocking
     *
     * @see http://php.net/manual/en/function.stream-set-timeout.php
     */
    protected function streamSetTimeout()
    {
        $seconds = \floor($this->timeout);
        $microseconds = \round(($this->timeout - $seconds) * 1000000.0);
        return \stream_set_timeout($this->resource, $seconds, $microseconds);
    }
    /**
     * Wrapper to allow mocking
     *
     * @see http://php.net/manual/en/function.stream-set-chunk-size.php
     */
    protected function streamSetChunkSize()
    {
        return \stream_set_chunk_size($this->resource, $this->chunkSize);
    }
    /**
     * Wrapper to allow mocking
     */
    protected function fwrite($data)
    {
        return @\fwrite($this->resource, $data);
    }
    /**
     * Wrapper to allow mocking
     */
    protected function streamGetMetadata()
    {
        return \stream_get_meta_data($this->resource);
    }
    private function validateTimeout($value)
    {
        $ok = \filter_var($value, \FILTER_VALIDATE_FLOAT);
        if ($ok === \false || $value < 0) {
            throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got {$value})");
        }
    }
    private function connectIfNotConnected()
    {
        if ($this->isConnected()) {
            return;
        }
        $this->connect();
    }
    protected function generateDataStream($record)
    {
        return (string) $record['formatted'];
    }
    /**
     * @return resource|null
     */
    protected function getResource()
    {
        return $this->resource;
    }
    private function connect()
    {
        $this->createSocketResource();
        $this->setSocketTimeout();
        $this->setStreamChunkSize();
    }
    private function createSocketResource()
    {
        if ($this->isPersistent()) {
            $resource = $this->pfsockopen();
        } else {
            $resource = $this->fsockopen();
        }
        if (!$resource) {
            throw new \UnexpectedValueException("Failed connecting to {$this->connectionString} ({$this->errno}: {$this->errstr})");
        }
        $this->resource = $resource;
    }
    private function setSocketTimeout()
    {
        if (!$this->streamSetTimeout()) {
            throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()");
        }
    }
    private function setStreamChunkSize()
    {
        if ($this->chunkSize && !$this->streamSetChunkSize()) {
            throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()");
        }
    }
    private function writeToSocket($data)
    {
        $length = \strlen($data);
        $sent = 0;
        $this->lastSentBytes = $sent;
        while ($this->isConnected() && $sent < $length) {
            if (0 == $sent) {
                $chunk = $this->fwrite($data);
            } else {
                $chunk = $this->fwrite(\substr($data, $sent));
            }
            if ($chunk === \false) {
                throw new \RuntimeException("Could not write to socket");
            }
            $sent += $chunk;
            $socketInfo = $this->streamGetMetadata();
            if ($socketInfo['timed_out']) {
                throw new \RuntimeException("Write timed-out");
            }
            if ($this->writingIsTimedOut($sent)) {
                throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent {$sent} of {$length})");
            }
        }
        if (!$this->isConnected() && $sent < $length) {
            throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent {$sent} of {$length})");
        }
    }
    private function writingIsTimedOut($sent)
    {
        $writingTimeout = (int) \floor($this->writingTimeout);
        if (0 === $writingTimeout) {
            return \false;
        }
        if ($sent !== $this->lastSentBytes) {
            $this->lastWritingAt = \time();
            $this->lastSentBytes = $sent;
            return \false;
        } else {
            \usleep(100);
        }
        if (\time() - $this->lastWritingAt >= $writingTimeout) {
            $this->closeSocket();
            return \true;
        }
        return \false;
    }
}
Handler/AbstractHandler.php000066600000010537151136154450011712 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\ResettableInterface;
/**
 * Base Handler class providing the Handler structure
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
abstract class AbstractHandler implements HandlerInterface, ResettableInterface
{
    protected $level = Logger::DEBUG;
    protected $bubble = \true;
    /**
     * @var FormatterInterface
     */
    protected $formatter;
    protected $processors = array();
    /**
     * @param int|string $level  The minimum logging level at which this handler will be triggered
     * @param bool       $bubble Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($level = Logger::DEBUG, $bubble = \true)
    {
        $this->setLevel($level);
        $this->bubble = $bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        return $record['level'] >= $this->level;
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        foreach ($records as $record) {
            $this->handle($record);
        }
    }
    /**
     * Closes the handler.
     *
     * This will be called automatically when the object is destroyed
     */
    public function close()
    {
    }
    /**
     * {@inheritdoc}
     */
    public function pushProcessor($callback)
    {
        if (!\is_callable($callback)) {
            throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . \var_export($callback, \true) . ' given');
        }
        \array_unshift($this->processors, $callback);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function popProcessor()
    {
        if (!$this->processors) {
            throw new \LogicException('You tried to pop from an empty processor stack.');
        }
        return \array_shift($this->processors);
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->formatter = $formatter;
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        if (!$this->formatter) {
            $this->formatter = $this->getDefaultFormatter();
        }
        return $this->formatter;
    }
    /**
     * Sets minimum logging level at which this handler will be triggered.
     *
     * @param  int|string $level Level or level name
     * @return self
     */
    public function setLevel($level)
    {
        $this->level = Logger::toMonologLevel($level);
        return $this;
    }
    /**
     * Gets minimum logging level at which this handler will be triggered.
     *
     * @return int
     */
    public function getLevel()
    {
        return $this->level;
    }
    /**
     * Sets the bubbling behavior.
     *
     * @param  bool $bubble true means that this handler allows bubbling.
     *                      false means that bubbling is not permitted.
     * @return self
     */
    public function setBubble($bubble)
    {
        $this->bubble = $bubble;
        return $this;
    }
    /**
     * Gets the bubbling behavior.
     *
     * @return bool true means that this handler allows bubbling.
     *              false means that bubbling is not permitted.
     */
    public function getBubble()
    {
        return $this->bubble;
    }
    public function __destruct()
    {
        try {
            $this->close();
        } catch (\Exception $e) {
            // do nothing
        } catch (\Throwable $e) {
            // do nothing
        }
    }
    public function reset()
    {
        foreach ($this->processors as $processor) {
            if ($processor instanceof ResettableInterface) {
                $processor->reset();
            }
        }
    }
    /**
     * Gets the default formatter.
     *
     * @return FormatterInterface
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter();
    }
}
Handler/DoctrineCouchDBHandler.php000066600000002036151136154450013101 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\NormalizerFormatter;
use AIOSEO\Vendor\Doctrine\CouchDB\CouchDBClient;
/**
 * CouchDB handler for Doctrine CouchDB ODM
 *
 * @author Markus Bachmann <markus.bachmann@bachi.biz>
 */
class DoctrineCouchDBHandler extends AbstractProcessingHandler
{
    private $client;
    public function __construct(CouchDBClient $client, $level = Logger::DEBUG, $bubble = \true)
    {
        $this->client = $client;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        $this->client->postDocument($record['formatted']);
    }
    protected function getDefaultFormatter()
    {
        return new NormalizerFormatter();
    }
}
Handler/MissingExtensionException.php000066600000000717151136154450014035 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

/**
 * Exception can be thrown if an extension for an handler is missing
 *
 * @author  Christian Bergau <cbergau86@gmail.com>
 */
class MissingExtensionException extends \Exception
{
}
Handler/NewRelicHandler.php000066600000014147151136154450011660 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\Monolog\Formatter\NormalizerFormatter;
/**
 * Class to record a log on a NewRelic application.
 * Enabling New Relic High Security mode may prevent capture of useful information.
 *
 * This handler requires a NormalizerFormatter to function and expects an array in $record['formatted']
 *
 * @see https://docs.newrelic.com/docs/agents/php-agent
 * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security
 */
class NewRelicHandler extends AbstractProcessingHandler
{
    /**
     * Name of the New Relic application that will receive logs from this handler.
     *
     * @var string
     */
    protected $appName;
    /**
     * Name of the current transaction
     *
     * @var string
     */
    protected $transactionName;
    /**
     * Some context and extra data is passed into the handler as arrays of values. Do we send them as is
     * (useful if we are using the API), or explode them for display on the NewRelic RPM website?
     *
     * @var bool
     */
    protected $explodeArrays;
    /**
     * {@inheritDoc}
     *
     * @param string $appName
     * @param bool   $explodeArrays
     * @param string $transactionName
     */
    public function __construct($level = Logger::ERROR, $bubble = \true, $appName = null, $explodeArrays = \false, $transactionName = null)
    {
        parent::__construct($level, $bubble);
        $this->appName = $appName;
        $this->explodeArrays = $explodeArrays;
        $this->transactionName = $transactionName;
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        if (!$this->isNewRelicEnabled()) {
            throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler');
        }
        if ($appName = $this->getAppName($record['context'])) {
            $this->setNewRelicAppName($appName);
        }
        if ($transactionName = $this->getTransactionName($record['context'])) {
            $this->setNewRelicTransactionName($transactionName);
            unset($record['formatted']['context']['transaction_name']);
        }
        if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || \PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable)) {
            \newrelic_notice_error($record['message'], $record['context']['exception']);
            unset($record['formatted']['context']['exception']);
        } else {
            \newrelic_notice_error($record['message']);
        }
        if (isset($record['formatted']['context']) && \is_array($record['formatted']['context'])) {
            foreach ($record['formatted']['context'] as $key => $parameter) {
                if (\is_array($parameter) && $this->explodeArrays) {
                    foreach ($parameter as $paramKey => $paramValue) {
                        $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue);
                    }
                } else {
                    $this->setNewRelicParameter('context_' . $key, $parameter);
                }
            }
        }
        if (isset($record['formatted']['extra']) && \is_array($record['formatted']['extra'])) {
            foreach ($record['formatted']['extra'] as $key => $parameter) {
                if (\is_array($parameter) && $this->explodeArrays) {
                    foreach ($parameter as $paramKey => $paramValue) {
                        $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue);
                    }
                } else {
                    $this->setNewRelicParameter('extra_' . $key, $parameter);
                }
            }
        }
    }
    /**
     * Checks whether the NewRelic extension is enabled in the system.
     *
     * @return bool
     */
    protected function isNewRelicEnabled()
    {
        return \extension_loaded('newrelic');
    }
    /**
     * Returns the appname where this log should be sent. Each log can override the default appname, set in this
     * handler's constructor, by providing the appname in it's context.
     *
     * @param  array       $context
     * @return null|string
     */
    protected function getAppName(array $context)
    {
        if (isset($context['appname'])) {
            return $context['appname'];
        }
        return $this->appName;
    }
    /**
     * Returns the name of the current transaction. Each log can override the default transaction name, set in this
     * handler's constructor, by providing the transaction_name in it's context
     *
     * @param array $context
     *
     * @return null|string
     */
    protected function getTransactionName(array $context)
    {
        if (isset($context['transaction_name'])) {
            return $context['transaction_name'];
        }
        return $this->transactionName;
    }
    /**
     * Sets the NewRelic application that should receive this log.
     *
     * @param string $appName
     */
    protected function setNewRelicAppName($appName)
    {
        \newrelic_set_appname($appName);
    }
    /**
     * Overwrites the name of the current transaction
     *
     * @param string $transactionName
     */
    protected function setNewRelicTransactionName($transactionName)
    {
        \newrelic_name_transaction($transactionName);
    }
    /**
     * @param string $key
     * @param mixed  $value
     */
    protected function setNewRelicParameter($key, $value)
    {
        if (null === $value || \is_scalar($value)) {
            \newrelic_add_custom_parameter($key, $value);
        } else {
            \newrelic_add_custom_parameter($key, Utils::jsonEncode($value, null, \true));
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new NormalizerFormatter();
    }
}
Handler/CubeHandler.php000066600000011060151136154450011015 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Logs to Cube.
 *
 * @link http://square.github.com/cube/
 * @author Wan Chen <kami@kamisama.me>
 */
class CubeHandler extends AbstractProcessingHandler
{
    private $udpConnection;
    private $httpConnection;
    private $scheme;
    private $host;
    private $port;
    private $acceptedSchemes = array('http', 'udp');
    /**
     * Create a Cube handler
     *
     * @throws \UnexpectedValueException when given url is not a valid url.
     *                                   A valid url must consist of three parts : protocol://host:port
     *                                   Only valid protocols used by Cube are http and udp
     */
    public function __construct($url, $level = Logger::DEBUG, $bubble = \true)
    {
        $urlInfo = \parse_url($url);
        if (!isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
            throw new \UnexpectedValueException('URL "' . $url . '" is not valid');
        }
        if (!\in_array($urlInfo['scheme'], $this->acceptedSchemes)) {
            throw new \UnexpectedValueException('Invalid protocol (' . $urlInfo['scheme'] . ').' . ' Valid options are ' . \implode(', ', $this->acceptedSchemes));
        }
        $this->scheme = $urlInfo['scheme'];
        $this->host = $urlInfo['host'];
        $this->port = $urlInfo['port'];
        parent::__construct($level, $bubble);
    }
    /**
     * Establish a connection to an UDP socket
     *
     * @throws \LogicException           when unable to connect to the socket
     * @throws MissingExtensionException when there is no socket extension
     */
    protected function connectUdp()
    {
        if (!\extension_loaded('sockets')) {
            throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
        }
        $this->udpConnection = \socket_create(\AF_INET, \SOCK_DGRAM, 0);
        if (!$this->udpConnection) {
            throw new \LogicException('Unable to create a socket');
        }
        if (!\socket_connect($this->udpConnection, $this->host, $this->port)) {
            throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
        }
    }
    /**
     * Establish a connection to a http server
     * @throws \LogicException when no curl extension
     */
    protected function connectHttp()
    {
        if (!\extension_loaded('curl')) {
            throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler');
        }
        $this->httpConnection = \curl_init('http://' . $this->host . ':' . $this->port . '/1.0/event/put');
        if (!$this->httpConnection) {
            throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
        }
        \curl_setopt($this->httpConnection, \CURLOPT_CUSTOMREQUEST, "POST");
        \curl_setopt($this->httpConnection, \CURLOPT_RETURNTRANSFER, \true);
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $date = $record['datetime'];
        $data = array('time' => $date->format('Y-m-d\\TH:i:s.uO'));
        unset($record['datetime']);
        if (isset($record['context']['type'])) {
            $data['type'] = $record['context']['type'];
            unset($record['context']['type']);
        } else {
            $data['type'] = $record['channel'];
        }
        $data['data'] = $record['context'];
        $data['data']['level'] = $record['level'];
        if ($this->scheme === 'http') {
            $this->writeHttp(Utils::jsonEncode($data));
        } else {
            $this->writeUdp(Utils::jsonEncode($data));
        }
    }
    private function writeUdp($data)
    {
        if (!$this->udpConnection) {
            $this->connectUdp();
        }
        \socket_send($this->udpConnection, $data, \strlen($data), 0);
    }
    private function writeHttp($data)
    {
        if (!$this->httpConnection) {
            $this->connectHttp();
        }
        \curl_setopt($this->httpConnection, \CURLOPT_POSTFIELDS, '[' . $data . ']');
        \curl_setopt($this->httpConnection, \CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . \strlen('[' . $data . ']')));
        Curl\Util::execute($this->httpConnection, 5, \false);
    }
}
Handler/TestHandler.php000066600000012435151136154450011065 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

/**
 * Used for testing purposes.
 *
 * It records all records and gives you access to them for verification.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 *
 * @method bool hasEmergency($record)
 * @method bool hasAlert($record)
 * @method bool hasCritical($record)
 * @method bool hasError($record)
 * @method bool hasWarning($record)
 * @method bool hasNotice($record)
 * @method bool hasInfo($record)
 * @method bool hasDebug($record)
 *
 * @method bool hasEmergencyRecords()
 * @method bool hasAlertRecords()
 * @method bool hasCriticalRecords()
 * @method bool hasErrorRecords()
 * @method bool hasWarningRecords()
 * @method bool hasNoticeRecords()
 * @method bool hasInfoRecords()
 * @method bool hasDebugRecords()
 *
 * @method bool hasEmergencyThatContains($message)
 * @method bool hasAlertThatContains($message)
 * @method bool hasCriticalThatContains($message)
 * @method bool hasErrorThatContains($message)
 * @method bool hasWarningThatContains($message)
 * @method bool hasNoticeThatContains($message)
 * @method bool hasInfoThatContains($message)
 * @method bool hasDebugThatContains($message)
 *
 * @method bool hasEmergencyThatMatches($message)
 * @method bool hasAlertThatMatches($message)
 * @method bool hasCriticalThatMatches($message)
 * @method bool hasErrorThatMatches($message)
 * @method bool hasWarningThatMatches($message)
 * @method bool hasNoticeThatMatches($message)
 * @method bool hasInfoThatMatches($message)
 * @method bool hasDebugThatMatches($message)
 *
 * @method bool hasEmergencyThatPasses($message)
 * @method bool hasAlertThatPasses($message)
 * @method bool hasCriticalThatPasses($message)
 * @method bool hasErrorThatPasses($message)
 * @method bool hasWarningThatPasses($message)
 * @method bool hasNoticeThatPasses($message)
 * @method bool hasInfoThatPasses($message)
 * @method bool hasDebugThatPasses($message)
 */
class TestHandler extends AbstractProcessingHandler
{
    protected $records = array();
    protected $recordsByLevel = array();
    private $skipReset = \false;
    public function getRecords()
    {
        return $this->records;
    }
    public function clear()
    {
        $this->records = array();
        $this->recordsByLevel = array();
    }
    public function reset()
    {
        if (!$this->skipReset) {
            $this->clear();
        }
    }
    public function setSkipReset($skipReset)
    {
        $this->skipReset = $skipReset;
    }
    public function hasRecords($level)
    {
        return isset($this->recordsByLevel[$level]);
    }
    /**
     * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records
     * @param int          $level  Logger::LEVEL constant value
     */
    public function hasRecord($record, $level)
    {
        if (\is_string($record)) {
            $record = array('message' => $record);
        }
        return $this->hasRecordThatPasses(function ($rec) use($record) {
            if ($rec['message'] !== $record['message']) {
                return \false;
            }
            if (isset($record['context']) && $rec['context'] !== $record['context']) {
                return \false;
            }
            return \true;
        }, $level);
    }
    public function hasRecordThatContains($message, $level)
    {
        return $this->hasRecordThatPasses(function ($rec) use($message) {
            return \strpos($rec['message'], $message) !== \false;
        }, $level);
    }
    public function hasRecordThatMatches($regex, $level)
    {
        return $this->hasRecordThatPasses(function ($rec) use($regex) {
            return \preg_match($regex, $rec['message']) > 0;
        }, $level);
    }
    public function hasRecordThatPasses($predicate, $level)
    {
        if (!\is_callable($predicate)) {
            throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds");
        }
        if (!isset($this->recordsByLevel[$level])) {
            return \false;
        }
        foreach ($this->recordsByLevel[$level] as $i => $rec) {
            if (\call_user_func($predicate, $rec, $i)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $this->recordsByLevel[$record['level']][] = $record;
        $this->records[] = $record;
    }
    public function __call($method, $args)
    {
        if (\preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
            $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
            $level = \constant('AIOSEO\\Vendor\\Monolog\\Logger::' . \strtoupper($matches[2]));
            if (\method_exists($this, $genericMethod)) {
                $args[] = $level;
                return \call_user_func_array(array($this, $genericMethod), $args);
            }
        }
        throw new \BadMethodCallException('Call to undefined method ' . \get_class($this) . '::' . $method . '()');
    }
}
Handler/BrowserConsoleHandler.php000066600000016277151136154450013124 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
/**
 * Handler sending logs to browser's javascript console with no browser extension required
 *
 * @author Olivier Poitrey <rs@dailymotion.com>
 */
class BrowserConsoleHandler extends AbstractProcessingHandler
{
    protected static $initialized = \false;
    protected static $records = array();
    /**
     * {@inheritDoc}
     *
     * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format.
     *
     * Example of formatted string:
     *
     *     You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        // Accumulate records
        static::$records[] = $record;
        // Register shutdown handler if not already done
        if (!static::$initialized) {
            static::$initialized = \true;
            $this->registerShutdownFunction();
        }
    }
    /**
     * Convert records to javascript console commands and send it to the browser.
     * This method is automatically called on PHP shutdown if output is HTML or Javascript.
     */
    public static function send()
    {
        $format = static::getResponseFormat();
        if ($format === 'unknown') {
            return;
        }
        if (\count(static::$records)) {
            if ($format === 'html') {
                static::writeOutput('<script>' . static::generateScript() . '</script>');
            } elseif ($format === 'js') {
                static::writeOutput(static::generateScript());
            }
            static::resetStatic();
        }
    }
    public function close()
    {
        self::resetStatic();
    }
    public function reset()
    {
        self::resetStatic();
    }
    /**
     * Forget all logged records
     */
    public static function resetStatic()
    {
        static::$records = array();
    }
    /**
     * Wrapper for register_shutdown_function to allow overriding
     */
    protected function registerShutdownFunction()
    {
        if (\PHP_SAPI !== 'cli') {
            \register_shutdown_function(array('AIOSEO\\Vendor\\Monolog\\Handler\\BrowserConsoleHandler', 'send'));
        }
    }
    /**
     * Wrapper for echo to allow overriding
     *
     * @param string $str
     */
    protected static function writeOutput($str)
    {
        echo $str;
    }
    /**
     * Checks the format of the response
     *
     * If Content-Type is set to application/javascript or text/javascript -> js
     * If Content-Type is set to text/html, or is unset -> html
     * If Content-Type is anything else -> unknown
     *
     * @return string One of 'js', 'html' or 'unknown'
     */
    protected static function getResponseFormat()
    {
        // Check content type
        foreach (\headers_list() as $header) {
            if (\stripos($header, 'content-type:') === 0) {
                // This handler only works with HTML and javascript outputs
                // text/javascript is obsolete in favour of application/javascript, but still used
                if (\stripos($header, 'application/javascript') !== \false || \stripos($header, 'text/javascript') !== \false) {
                    return 'js';
                }
                if (\stripos($header, 'text/html') === \false) {
                    return 'unknown';
                }
                break;
            }
        }
        return 'html';
    }
    private static function generateScript()
    {
        $script = array();
        foreach (static::$records as $record) {
            $context = static::dump('Context', $record['context']);
            $extra = static::dump('Extra', $record['extra']);
            if (empty($context) && empty($extra)) {
                $script[] = static::call_array('log', static::handleStyles($record['formatted']));
            } else {
                $script = \array_merge($script, array(static::call_array('groupCollapsed', static::handleStyles($record['formatted']))), $context, $extra, array(static::call('groupEnd')));
            }
        }
        return "(function (c) {if (c && c.groupCollapsed) {\n" . \implode("\n", $script) . "\n}})(console);";
    }
    private static function handleStyles($formatted)
    {
        $args = array();
        $format = '%c' . $formatted;
        \preg_match_all('/\\[\\[(.*?)\\]\\]\\{([^}]*)\\}/s', $format, $matches, \PREG_OFFSET_CAPTURE | \PREG_SET_ORDER);
        foreach (\array_reverse($matches) as $match) {
            $args[] = '"font-weight: normal"';
            $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0]));
            $pos = $match[0][1];
            $format = \substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . \substr($format, $pos + \strlen($match[0][0]));
        }
        $args[] = static::quote('font-weight: normal');
        $args[] = static::quote($format);
        return \array_reverse($args);
    }
    private static function handleCustomStyles($style, $string)
    {
        static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey');
        static $labels = array();
        return \preg_replace_callback('/macro\\s*:(.*?)(?:;|$)/', function ($m) use($string, &$colors, &$labels) {
            if (\trim($m[1]) === 'autolabel') {
                // Format the string as a label with consistent auto assigned background color
                if (!isset($labels[$string])) {
                    $labels[$string] = $colors[\count($labels) % \count($colors)];
                }
                $color = $labels[$string];
                return "background-color: {$color}; color: white; border-radius: 3px; padding: 0 2px 0 2px";
            }
            return $m[1];
        }, $style);
    }
    private static function dump($title, array $dict)
    {
        $script = array();
        $dict = \array_filter($dict);
        if (empty($dict)) {
            return $script;
        }
        $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title));
        foreach ($dict as $key => $value) {
            $value = \json_encode($value);
            if (empty($value)) {
                $value = static::quote('');
            }
            $script[] = static::call('log', static::quote('%s: %o'), static::quote($key), $value);
        }
        return $script;
    }
    private static function quote($arg)
    {
        return '"' . \addcslashes($arg, "\"\n\\") . '"';
    }
    private static function call()
    {
        $args = \func_get_args();
        $method = \array_shift($args);
        return static::call_array($method, $args);
    }
    private static function call_array($method, array $args)
    {
        return 'c.' . $method . '(' . \implode(', ', $args) . ');';
    }
}
Handler/AbstractSyslogHandler.php000066600000006362151136154450013114 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
/**
 * Common syslog functionality
 */
abstract class AbstractSyslogHandler extends AbstractProcessingHandler
{
    protected $facility;
    /**
     * Translates Monolog log levels to syslog log priorities.
     */
    protected $logLevels = array(Logger::DEBUG => \LOG_DEBUG, Logger::INFO => \LOG_INFO, Logger::NOTICE => \LOG_NOTICE, Logger::WARNING => \LOG_WARNING, Logger::ERROR => \LOG_ERR, Logger::CRITICAL => \LOG_CRIT, Logger::ALERT => \LOG_ALERT, Logger::EMERGENCY => \LOG_EMERG);
    /**
     * List of valid log facility names.
     */
    protected $facilities = array('auth' => \LOG_AUTH, 'authpriv' => \LOG_AUTHPRIV, 'cron' => \LOG_CRON, 'daemon' => \LOG_DAEMON, 'kern' => \LOG_KERN, 'lpr' => \LOG_LPR, 'mail' => \LOG_MAIL, 'news' => \LOG_NEWS, 'syslog' => \LOG_SYSLOG, 'user' => \LOG_USER, 'uucp' => \LOG_UUCP);
    /**
     * @param mixed $facility
     * @param int   $level The minimum logging level at which this handler will be triggered
     * @param bool  $bubble Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($facility = \LOG_USER, $level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        if (!\defined('PHP_WINDOWS_VERSION_BUILD')) {
            $this->facilities['local0'] = \LOG_LOCAL0;
            $this->facilities['local1'] = \LOG_LOCAL1;
            $this->facilities['local2'] = \LOG_LOCAL2;
            $this->facilities['local3'] = \LOG_LOCAL3;
            $this->facilities['local4'] = \LOG_LOCAL4;
            $this->facilities['local5'] = \LOG_LOCAL5;
            $this->facilities['local6'] = \LOG_LOCAL6;
            $this->facilities['local7'] = \LOG_LOCAL7;
        } else {
            $this->facilities['local0'] = 128;
            // LOG_LOCAL0
            $this->facilities['local1'] = 136;
            // LOG_LOCAL1
            $this->facilities['local2'] = 144;
            // LOG_LOCAL2
            $this->facilities['local3'] = 152;
            // LOG_LOCAL3
            $this->facilities['local4'] = 160;
            // LOG_LOCAL4
            $this->facilities['local5'] = 168;
            // LOG_LOCAL5
            $this->facilities['local6'] = 176;
            // LOG_LOCAL6
            $this->facilities['local7'] = 184;
            // LOG_LOCAL7
        }
        // convert textual description of facility to syslog constant
        if (\array_key_exists(\strtolower($facility), $this->facilities)) {
            $facility = $this->facilities[\strtolower($facility)];
        } elseif (!\in_array($facility, \array_values($this->facilities), \true)) {
            throw new \UnexpectedValueException('Unknown facility value "' . $facility . '" given');
        }
        $this->facility = $facility;
    }
    /**
     * {@inheritdoc}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
    }
}
Handler/SamplingHandler.php000066600000006356151136154450011725 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Sampling handler
 *
 * A sampled event stream can be useful for logging high frequency events in
 * a production environment where you only need an idea of what is happening
 * and are not concerned with capturing every occurrence. Since the decision to
 * handle or not handle a particular event is determined randomly, the
 * resulting sampled log is not guaranteed to contain 1/N of the events that
 * occurred in the application, but based on the Law of large numbers, it will
 * tend to be close to this ratio with a large number of attempts.
 *
 * @author Bryan Davis <bd808@wikimedia.org>
 * @author Kunal Mehta <legoktm@gmail.com>
 */
class SamplingHandler extends AbstractHandler
{
    /**
     * @var callable|HandlerInterface $handler
     */
    protected $handler;
    /**
     * @var int $factor
     */
    protected $factor;
    /**
     * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler).
     * @param int                       $factor  Sample factor
     */
    public function __construct($handler, $factor)
    {
        parent::__construct();
        $this->handler = $handler;
        $this->factor = $factor;
        if (!$this->handler instanceof HandlerInterface && !\is_callable($this->handler)) {
            throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a Monolog\\Handler\\HandlerInterface object");
        }
    }
    public function isHandling(array $record)
    {
        return $this->getHandler($record)->isHandling($record);
    }
    public function handle(array $record)
    {
        if ($this->isHandling($record) && \mt_rand(1, $this->factor) === 1) {
            if ($this->processors) {
                foreach ($this->processors as $processor) {
                    $record = \call_user_func($processor, $record);
                }
            }
            $this->getHandler($record)->handle($record);
        }
        return \false === $this->bubble;
    }
    /**
     * Return the nested handler
     *
     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
     *
     * @return HandlerInterface
     */
    public function getHandler(array $record = null)
    {
        if (!$this->handler instanceof HandlerInterface) {
            $this->handler = \call_user_func($this->handler, $record, $this);
            if (!$this->handler instanceof HandlerInterface) {
                throw new \RuntimeException("The factory callable should return a HandlerInterface");
            }
        }
        return $this->handler;
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->getHandler()->setFormatter($formatter);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->getHandler()->getFormatter();
    }
}
Handler/RedisHandler.php000066600000005615151136154450011216 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Logs to a Redis key using rpush
 *
 * usage example:
 *
 *   $log = new Logger('application');
 *   $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod");
 *   $log->pushHandler($redis);
 *
 * @author Thomas Tourlourat <thomas@tourlourat.com>
 */
class RedisHandler extends AbstractProcessingHandler
{
    private $redisClient;
    private $redisKey;
    protected $capSize;
    /**
     * @param \Predis\Client|\Redis $redis   The redis instance
     * @param string                $key     The key name to push records to
     * @param int                   $level   The minimum logging level at which this handler will be triggered
     * @param bool                  $bubble  Whether the messages that are handled can bubble up the stack or not
     * @param int|false             $capSize Number of entries to limit list size to
     */
    public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = \true, $capSize = \false)
    {
        if (!($redis instanceof \AIOSEO\Vendor\Predis\Client || $redis instanceof \Redis)) {
            throw new \InvalidArgumentException('Predis\\Client or Redis instance required');
        }
        $this->redisClient = $redis;
        $this->redisKey = $key;
        $this->capSize = $capSize;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        if ($this->capSize) {
            $this->writeCapped($record);
        } else {
            $this->redisClient->rpush($this->redisKey, $record["formatted"]);
        }
    }
    /**
     * Write and cap the collection
     * Writes the record to the redis list and caps its
     *
     * @param  array $record associative record array
     * @return void
     */
    protected function writeCapped(array $record)
    {
        if ($this->redisClient instanceof \Redis) {
            $mode = \defined('\\Redis::MULTI') ? \Redis::MULTI : 1;
            $this->redisClient->multi($mode)->rpush($this->redisKey, $record["formatted"])->ltrim($this->redisKey, -$this->capSize, -1)->exec();
        } else {
            $redisKey = $this->redisKey;
            $capSize = $this->capSize;
            $this->redisClient->transaction(function ($tx) use($record, $redisKey, $capSize) {
                $tx->rpush($redisKey, $record["formatted"]);
                $tx->ltrim($redisKey, -$capSize, -1);
            });
        }
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new LineFormatter();
    }
}
Handler/WhatFailureGroupHandler.php000066600000003475151136154450013402 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

/**
 * Forwards records to multiple handlers suppressing failures of each handler
 * and continuing through to give every handler a chance to succeed.
 *
 * @author Craig D'Amelio <craig@damelio.ca>
 */
class WhatFailureGroupHandler extends GroupHandler
{
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        foreach ($this->handlers as $handler) {
            try {
                $handler->handle($record);
            } catch (\Exception $e) {
                // What failure?
            } catch (\Throwable $e) {
                // What failure?
            }
        }
        return \false === $this->bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        if ($this->processors) {
            $processed = array();
            foreach ($records as $record) {
                foreach ($this->processors as $processor) {
                    $record = \call_user_func($processor, $record);
                }
                $processed[] = $record;
            }
            $records = $processed;
        }
        foreach ($this->handlers as $handler) {
            try {
                $handler->handleBatch($records);
            } catch (\Exception $e) {
                // What failure?
            } catch (\Throwable $e) {
                // What failure?
            }
        }
    }
}
Handler/RollbarHandler.php000066600000007237151136154450011547 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\RollbarNotifier;
use Exception;
use AIOSEO\Vendor\Monolog\Logger;
/**
 * Sends errors to Rollbar
 *
 * If the context data contains a `payload` key, that is used as an array
 * of payload options to RollbarNotifier's report_message/report_exception methods.
 *
 * Rollbar's context info will contain the context + extra keys from the log record
 * merged, and then on top of that a few keys:
 *
 *  - level (rollbar level name)
 *  - monolog_level (monolog level name, raw level, as rollbar only has 5 but monolog 8)
 *  - channel
 *  - datetime (unix timestamp)
 *
 * @author Paul Statezny <paulstatezny@gmail.com>
 */
class RollbarHandler extends AbstractProcessingHandler
{
    /**
     * Rollbar notifier
     *
     * @var RollbarNotifier
     */
    protected $rollbarNotifier;
    protected $levelMap = array(Logger::DEBUG => 'debug', Logger::INFO => 'info', Logger::NOTICE => 'info', Logger::WARNING => 'warning', Logger::ERROR => 'error', Logger::CRITICAL => 'critical', Logger::ALERT => 'critical', Logger::EMERGENCY => 'critical');
    /**
     * Records whether any log records have been added since the last flush of the rollbar notifier
     *
     * @var bool
     */
    private $hasRecords = \false;
    protected $initialized = \false;
    /**
     * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token
     * @param int             $level           The minimum logging level at which this handler will be triggered
     * @param bool            $bubble          Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = \true)
    {
        $this->rollbarNotifier = $rollbarNotifier;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        if (!$this->initialized) {
            // __destructor() doesn't get called on Fatal errors
            \register_shutdown_function(array($this, 'close'));
            $this->initialized = \true;
        }
        $context = $record['context'];
        $payload = array();
        if (isset($context['payload'])) {
            $payload = $context['payload'];
            unset($context['payload']);
        }
        $context = \array_merge($context, $record['extra'], array('level' => $this->levelMap[$record['level']], 'monolog_level' => $record['level_name'], 'channel' => $record['channel'], 'datetime' => $record['datetime']->format('U')));
        if (isset($context['exception']) && $context['exception'] instanceof Exception) {
            $payload['level'] = $context['level'];
            $exception = $context['exception'];
            unset($context['exception']);
            $this->rollbarNotifier->report_exception($exception, $context, $payload);
        } else {
            $this->rollbarNotifier->report_message($record['message'], $context['level'], $context, $payload);
        }
        $this->hasRecords = \true;
    }
    public function flush()
    {
        if ($this->hasRecords) {
            $this->rollbarNotifier->flush();
            $this->hasRecords = \false;
        }
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        $this->flush();
    }
    /**
     * {@inheritdoc}
     */
    public function reset()
    {
        $this->flush();
        parent::reset();
    }
}
Handler/FlowdockHandler.php000066600000006565151136154450011725 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
use AIOSEO\Vendor\Monolog\Formatter\FlowdockFormatter;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Sends notifications through the Flowdock push API
 *
 * This must be configured with a FlowdockFormatter instance via setFormatter()
 *
 * Notes:
 * API token - Flowdock API token
 *
 * @author Dominik Liebler <liebler.dominik@gmail.com>
 * @see https://www.flowdock.com/api/push
 */
class FlowdockHandler extends SocketHandler
{
    /**
     * @var string
     */
    protected $apiToken;
    /**
     * @param string   $apiToken
     * @param bool|int $level    The minimum logging level at which this handler will be triggered
     * @param bool     $bubble   Whether the messages that are handled can bubble up the stack or not
     *
     * @throws MissingExtensionException if OpenSSL is missing
     */
    public function __construct($apiToken, $level = Logger::DEBUG, $bubble = \true)
    {
        if (!\extension_loaded('openssl')) {
            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler');
        }
        parent::__construct('ssl://api.flowdock.com:443', $level, $bubble);
        $this->apiToken = $apiToken;
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        if (!$formatter instanceof FlowdockFormatter) {
            throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\\Formatter\\FlowdockFormatter to function correctly');
        }
        return parent::setFormatter($formatter);
    }
    /**
     * Gets the default formatter.
     *
     * @return FormatterInterface
     */
    protected function getDefaultFormatter()
    {
        throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\\Formatter\\FlowdockFormatter to function correctly');
    }
    /**
     * {@inheritdoc}
     *
     * @param array $record
     */
    protected function write(array $record)
    {
        parent::write($record);
        $this->closeSocket();
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        $content = $this->buildContent($record);
        return $this->buildHeader($content) . $content;
    }
    /**
     * Builds the body of API call
     *
     * @param  array  $record
     * @return string
     */
    private function buildContent($record)
    {
        return Utils::jsonEncode($record['formatted']['flowdock']);
    }
    /**
     * Builds the header of the API Call
     *
     * @param  string $content
     * @return string
     */
    private function buildHeader($content)
    {
        $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
        $header .= "Host: api.flowdock.com\r\n";
        $header .= "Content-Type: application/json\r\n";
        $header .= "Content-Length: " . \strlen($content) . "\r\n";
        $header .= "\r\n";
        return $header;
    }
}
Handler/PsrHandler.php000066600000002700151136154450010704 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Psr\Log\LoggerInterface;
/**
 * Proxies log messages to an existing PSR-3 compliant logger.
 *
 * @author Michael Moussa <michael.moussa@gmail.com>
 */
class PsrHandler extends AbstractHandler
{
    /**
     * PSR-3 compliant logger
     *
     * @var LoggerInterface
     */
    protected $logger;
    /**
     * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied
     * @param int             $level  The minimum logging level at which this handler will be triggered
     * @param bool            $bubble Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        $this->logger = $logger;
    }
    /**
     * {@inheritDoc}
     */
    public function handle(array $record)
    {
        if (!$this->isHandling($record)) {
            return \false;
        }
        $this->logger->log(\strtolower($record['level_name']), $record['message'], $record['context']);
        return \false === $this->bubble;
    }
}
Handler/MailHandler.php000066600000003135151136154450011025 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

/**
 * Base class for all mail handlers
 *
 * @author Gyula Sallai
 */
abstract class MailHandler extends AbstractProcessingHandler
{
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        $messages = array();
        foreach ($records as $record) {
            if ($record['level'] < $this->level) {
                continue;
            }
            $messages[] = $this->processRecord($record);
        }
        if (!empty($messages)) {
            $this->send((string) $this->getFormatter()->formatBatch($messages), $messages);
        }
    }
    /**
     * Send a mail with the given content
     *
     * @param string $content formatted email body to be sent
     * @param array  $records the array of log records that formed this content
     */
    protected abstract function send($content, array $records);
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $this->send((string) $record['formatted'], array($record));
    }
    protected function getHighestRecord(array $records)
    {
        $highestRecord = null;
        foreach ($records as $record) {
            if ($highestRecord === null || $highestRecord['level'] < $record['level']) {
                $highestRecord = $record;
            }
        }
        return $highestRecord;
    }
}
Handler/PushoverHandler.php000066600000014446151136154450011765 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Sends notifications through the pushover api to mobile phones
 *
 * @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
 * @see    https://www.pushover.net/api
 */
class PushoverHandler extends SocketHandler
{
    private $token;
    private $users;
    private $title;
    private $user;
    private $retry;
    private $expire;
    private $highPriorityLevel;
    private $emergencyLevel;
    private $useFormattedMessage = \false;
    /**
     * All parameters that can be sent to Pushover
     * @see https://pushover.net/api
     * @var array
     */
    private $parameterNames = array('token' => \true, 'user' => \true, 'message' => \true, 'device' => \true, 'title' => \true, 'url' => \true, 'url_title' => \true, 'priority' => \true, 'timestamp' => \true, 'sound' => \true, 'retry' => \true, 'expire' => \true, 'callback' => \true);
    /**
     * Sounds the api supports by default
     * @see https://pushover.net/api#sounds
     * @var array
     */
    private $sounds = array('pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none');
    /**
     * @param string       $token             Pushover api token
     * @param string|array $users             Pushover user id or array of ids the message will be sent to
     * @param string       $title             Title sent to the Pushover API
     * @param int          $level             The minimum logging level at which this handler will be triggered
     * @param bool         $bubble            Whether the messages that are handled can bubble up the stack or not
     * @param bool         $useSSL            Whether to connect via SSL. Required when pushing messages to users that are not
     *                                        the pushover.net app owner. OpenSSL is required for this option.
     * @param int          $highPriorityLevel The minimum logging level at which this handler will start
     *                                        sending "high priority" requests to the Pushover API
     * @param int          $emergencyLevel    The minimum logging level at which this handler will start
     *                                        sending "emergency" requests to the Pushover API
     * @param int          $retry             The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user.
     * @param int          $expire            The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds).
     */
    public function __construct($token, $users, $title = null, $level = Logger::CRITICAL, $bubble = \true, $useSSL = \true, $highPriorityLevel = Logger::CRITICAL, $emergencyLevel = Logger::EMERGENCY, $retry = 30, $expire = 25200)
    {
        $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80';
        parent::__construct($connectionString, $level, $bubble);
        $this->token = $token;
        $this->users = (array) $users;
        $this->title = $title ?: \gethostname();
        $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel);
        $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel);
        $this->retry = $retry;
        $this->expire = $expire;
    }
    protected function generateDataStream($record)
    {
        $content = $this->buildContent($record);
        return $this->buildHeader($content) . $content;
    }
    private function buildContent($record)
    {
        // Pushover has a limit of 512 characters on title and message combined.
        $maxMessageLength = 512 - \strlen($this->title);
        $message = $this->useFormattedMessage ? $record['formatted'] : $record['message'];
        $message = \substr($message, 0, $maxMessageLength);
        $timestamp = $record['datetime']->getTimestamp();
        $dataArray = array('token' => $this->token, 'user' => $this->user, 'message' => $message, 'title' => $this->title, 'timestamp' => $timestamp);
        if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) {
            $dataArray['priority'] = 2;
            $dataArray['retry'] = $this->retry;
            $dataArray['expire'] = $this->expire;
        } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) {
            $dataArray['priority'] = 1;
        }
        // First determine the available parameters
        $context = \array_intersect_key($record['context'], $this->parameterNames);
        $extra = \array_intersect_key($record['extra'], $this->parameterNames);
        // Least important info should be merged with subsequent info
        $dataArray = \array_merge($extra, $context, $dataArray);
        // Only pass sounds that are supported by the API
        if (isset($dataArray['sound']) && !\in_array($dataArray['sound'], $this->sounds)) {
            unset($dataArray['sound']);
        }
        return \http_build_query($dataArray);
    }
    private function buildHeader($content)
    {
        $header = "POST /1/messages.json HTTP/1.1\r\n";
        $header .= "Host: api.pushover.net\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Content-Length: " . \strlen($content) . "\r\n";
        $header .= "\r\n";
        return $header;
    }
    protected function write(array $record)
    {
        foreach ($this->users as $user) {
            $this->user = $user;
            parent::write($record);
            $this->closeSocket();
        }
        $this->user = null;
    }
    public function setHighPriorityLevel($value)
    {
        $this->highPriorityLevel = $value;
    }
    public function setEmergencyLevel($value)
    {
        $this->emergencyLevel = $value;
    }
    /**
     * Use the formatted message?
     * @param bool $value
     */
    public function useFormattedMessage($value)
    {
        $this->useFormattedMessage = (bool) $value;
    }
}
Handler/FormattableHandlerTrait.php000066600000002631151136154450013407 0ustar00<?php

declare (strict_types=1);
/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
/**
 * Helper trait for implementing FormattableInterface
 *
 * This trait is present in monolog 1.x to ease forward compatibility.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
trait FormattableHandlerTrait
{
    /**
     * @var FormatterInterface
     */
    protected $formatter;
    /**
     * {@inheritdoc}
     * @suppress PhanTypeMismatchReturn
     */
    public function setFormatter(FormatterInterface $formatter) : HandlerInterface
    {
        $this->formatter = $formatter;
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter() : FormatterInterface
    {
        if (!$this->formatter) {
            $this->formatter = $this->getDefaultFormatter();
        }
        return $this->formatter;
    }
    /**
     * Gets the default formatter.
     *
     * Overwrite this if the LineFormatter is not a good default for your handler.
     */
    protected function getDefaultFormatter() : FormatterInterface
    {
        return new LineFormatter();
    }
}
Handler/InsightOpsHandler.php000066600000003520151136154450012230 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Inspired on LogEntriesHandler.
 *
 * @author Robert Kaufmann III <rok3@rok3.me>
 * @author Gabriel Machado <gabriel.ms1@hotmail.com>
 */
class InsightOpsHandler extends SocketHandler
{
    /**
     * @var string
     */
    protected $logToken;
    /**
     * @param string $token  Log token supplied by InsightOps
     * @param string $region Region where InsightOps account is hosted. Could be 'us' or 'eu'.
     * @param bool   $useSSL Whether or not SSL encryption should be used
     * @param int    $level  The minimum logging level to trigger this handler
     * @param bool   $bubble Whether or not messages that are handled should bubble up the stack.
     *
     * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
     */
    public function __construct($token, $region = 'us', $useSSL = \true, $level = Logger::DEBUG, $bubble = \true)
    {
        if ($useSSL && !\extension_loaded('openssl')) {
            throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler');
        }
        $endpoint = $useSSL ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443' : $region . '.data.logs.insight.rapid7.com:80';
        parent::__construct($endpoint, $level, $bubble);
        $this->logToken = $token;
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        return $this->logToken . ' ' . $record['formatted'];
    }
}
Handler/FirePHPHandler.php000066600000012441151136154450011400 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\WildfireFormatter;
/**
 * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
 *
 * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
 */
class FirePHPHandler extends AbstractProcessingHandler
{
    /**
     * WildFire JSON header message format
     */
    const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2';
    /**
     * FirePHP structure for parsing messages & their presentation
     */
    const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
    /**
     * Must reference a "known" plugin, otherwise headers won't display in FirePHP
     */
    const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3';
    /**
     * Header prefix for Wildfire to recognize & parse headers
     */
    const HEADER_PREFIX = 'X-Wf';
    /**
     * Whether or not Wildfire vendor-specific headers have been generated & sent yet
     */
    protected static $initialized = \false;
    /**
     * Shared static message index between potentially multiple handlers
     * @var int
     */
    protected static $messageIndex = 1;
    protected static $sendHeaders = \true;
    /**
     * Base header creation function used by init headers & record headers
     *
     * @param  array  $meta    Wildfire Plugin, Protocol & Structure Indexes
     * @param  string $message Log message
     * @return array  Complete header string ready for the client as key and message as value
     */
    protected function createHeader(array $meta, $message)
    {
        $header = \sprintf('%s-%s', self::HEADER_PREFIX, \join('-', $meta));
        return array($header => $message);
    }
    /**
     * Creates message header from record
     *
     * @see createHeader()
     * @param  array  $record
     * @return array
     */
    protected function createRecordHeader(array $record)
    {
        // Wildfire is extensible to support multiple protocols & plugins in a single request,
        // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake.
        return $this->createHeader(array(1, 1, 1, self::$messageIndex++), $record['formatted']);
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new WildfireFormatter();
    }
    /**
     * Wildfire initialization headers to enable message parsing
     *
     * @see createHeader()
     * @see sendHeader()
     * @return array
     */
    protected function getInitHeaders()
    {
        // Initial payload consists of required headers for Wildfire
        return \array_merge($this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI));
    }
    /**
     * Send header string to the client
     *
     * @param string $header
     * @param string $content
     */
    protected function sendHeader($header, $content)
    {
        if (!\headers_sent() && self::$sendHeaders) {
            \header(\sprintf('%s: %s', $header, $content));
        }
    }
    /**
     * Creates & sends header for a record, ensuring init headers have been sent prior
     *
     * @see sendHeader()
     * @see sendInitHeaders()
     * @param array $record
     */
    protected function write(array $record)
    {
        if (!self::$sendHeaders) {
            return;
        }
        // WildFire-specific headers must be sent prior to any messages
        if (!self::$initialized) {
            self::$initialized = \true;
            self::$sendHeaders = $this->headersAccepted();
            if (!self::$sendHeaders) {
                return;
            }
            foreach ($this->getInitHeaders() as $header => $content) {
                $this->sendHeader($header, $content);
            }
        }
        $header = $this->createRecordHeader($record);
        if (\trim(\current($header)) !== '') {
            $this->sendHeader(\key($header), \current($header));
        }
    }
    /**
     * Verifies if the headers are accepted by the current user agent
     *
     * @return bool
     */
    protected function headersAccepted()
    {
        if (!empty($_SERVER['HTTP_USER_AGENT']) && \preg_match('{\\bFirePHP/\\d+\\.\\d+\\b}', $_SERVER['HTTP_USER_AGENT'])) {
            return \true;
        }
        return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
    }
    /**
     * BC getter for the sendHeaders property that has been made static
     */
    public function __get($property)
    {
        if ('sendHeaders' !== $property) {
            throw new \InvalidArgumentException('Undefined property ' . $property);
        }
        return static::$sendHeaders;
    }
    /**
     * BC setter for the sendHeaders property that has been made static
     */
    public function __set($property, $value)
    {
        if ('sendHeaders' !== $property) {
            throw new \InvalidArgumentException('Undefined property ' . $property);
        }
        static::$sendHeaders = $value;
    }
}
Handler/LogglyHandler.php000066600000005146151136154450011404 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\LogglyFormatter;
/**
 * Sends errors to Loggly.
 *
 * @author Przemek Sobstel <przemek@sobstel.org>
 * @author Adam Pancutt <adam@pancutt.com>
 * @author Gregory Barchard <gregory@barchard.net>
 */
class LogglyHandler extends AbstractProcessingHandler
{
    const HOST = 'logs-01.loggly.com';
    const ENDPOINT_SINGLE = 'inputs';
    const ENDPOINT_BATCH = 'bulk';
    protected $token;
    protected $tag = array();
    public function __construct($token, $level = Logger::DEBUG, $bubble = \true)
    {
        if (!\extension_loaded('curl')) {
            throw new \LogicException('The curl extension is needed to use the LogglyHandler');
        }
        $this->token = $token;
        parent::__construct($level, $bubble);
    }
    public function setTag($tag)
    {
        $tag = !empty($tag) ? $tag : array();
        $this->tag = \is_array($tag) ? $tag : array($tag);
    }
    public function addTag($tag)
    {
        if (!empty($tag)) {
            $tag = \is_array($tag) ? $tag : array($tag);
            $this->tag = \array_unique(\array_merge($this->tag, $tag));
        }
    }
    protected function write(array $record)
    {
        $this->send($record["formatted"], self::ENDPOINT_SINGLE);
    }
    public function handleBatch(array $records)
    {
        $level = $this->level;
        $records = \array_filter($records, function ($record) use($level) {
            return $record['level'] >= $level;
        });
        if ($records) {
            $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH);
        }
    }
    protected function send($data, $endpoint)
    {
        $url = \sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token);
        $headers = array('Content-Type: application/json');
        if (!empty($this->tag)) {
            $headers[] = 'X-LOGGLY-TAG: ' . \implode(',', $this->tag);
        }
        $ch = \curl_init();
        \curl_setopt($ch, \CURLOPT_URL, $url);
        \curl_setopt($ch, \CURLOPT_POST, \true);
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $data);
        \curl_setopt($ch, \CURLOPT_HTTPHEADER, $headers);
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true);
        Curl\Util::execute($ch);
    }
    protected function getDefaultFormatter()
    {
        return new LogglyFormatter();
    }
}
Handler/IFTTTHandler.php000066600000004106151136154450011034 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * IFTTTHandler uses cURL to trigger IFTTT Maker actions
 *
 * Register a secret key and trigger/event name at https://ifttt.com/maker
 *
 * value1 will be the channel from monolog's Logger constructor,
 * value2 will be the level name (ERROR, WARNING, ..)
 * value3 will be the log record's message
 *
 * @author Nehal Patel <nehal@nehalpatel.me>
 */
class IFTTTHandler extends AbstractProcessingHandler
{
    private $eventName;
    private $secretKey;
    /**
     * @param string $eventName The name of the IFTTT Maker event that should be triggered
     * @param string $secretKey A valid IFTTT secret key
     * @param int    $level     The minimum logging level at which this handler will be triggered
     * @param bool   $bubble    Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($eventName, $secretKey, $level = Logger::ERROR, $bubble = \true)
    {
        $this->eventName = $eventName;
        $this->secretKey = $secretKey;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritdoc}
     */
    public function write(array $record)
    {
        $postData = array("value1" => $record["channel"], "value2" => $record["level_name"], "value3" => $record["message"]);
        $postString = Utils::jsonEncode($postData);
        $ch = \curl_init();
        \curl_setopt($ch, \CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey);
        \curl_setopt($ch, \CURLOPT_POST, \true);
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true);
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, $postString);
        \curl_setopt($ch, \CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
        Curl\Util::execute($ch);
    }
}
Handler/MandrillHandler.php000066600000004174151136154450011711 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * MandrillHandler uses cURL to send the emails to the Mandrill API
 *
 * @author Adam Nicholson <adamnicholson10@gmail.com>
 */
class MandrillHandler extends MailHandler
{
    protected $message;
    protected $apiKey;
    /**
     * @param string                  $apiKey  A valid Mandrill API key
     * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
     * @param int                     $level   The minimum logging level at which this handler will be triggered
     * @param bool                    $bubble  Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        if (!$message instanceof \AIOSEO\Vendor\Swift_Message && \is_callable($message)) {
            $message = \call_user_func($message);
        }
        if (!$message instanceof \AIOSEO\Vendor\Swift_Message) {
            throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
        }
        $this->message = $message;
        $this->apiKey = $apiKey;
    }
    /**
     * {@inheritdoc}
     */
    protected function send($content, array $records)
    {
        $message = clone $this->message;
        $message->setBody($content);
        $message->setDate(\time());
        $ch = \curl_init();
        \curl_setopt($ch, \CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json');
        \curl_setopt($ch, \CURLOPT_POST, 1);
        \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
        \curl_setopt($ch, \CURLOPT_POSTFIELDS, \http_build_query(array('key' => $this->apiKey, 'raw_message' => (string) $message, 'async' => \false)));
        Curl\Util::execute($ch);
    }
}
Handler/GelfHandler.php000066600000004033151136154450011016 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Gelf\IMessagePublisher;
use AIOSEO\Vendor\Gelf\PublisherInterface;
use AIOSEO\Vendor\Gelf\Publisher;
use InvalidArgumentException;
use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\GelfMessageFormatter;
/**
 * Handler to send messages to a Graylog2 (http://www.graylog2.org) server
 *
 * @author Matt Lehner <mlehner@gmail.com>
 * @author Benjamin Zikarsky <benjamin@zikarsky.de>
 */
class GelfHandler extends AbstractProcessingHandler
{
    /**
     * @var Publisher|PublisherInterface|IMessagePublisher the publisher object that sends the message to the server
     */
    protected $publisher;
    /**
     * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object
     * @param int                                            $level     The minimum logging level at which this handler will be triggered
     * @param bool                                           $bubble    Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($publisher, $level = Logger::DEBUG, $bubble = \true)
    {
        parent::__construct($level, $bubble);
        if (!$publisher instanceof Publisher && !$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) {
            throw new InvalidArgumentException('Invalid publisher, expected a Gelf\\Publisher, Gelf\\IMessagePublisher or Gelf\\PublisherInterface instance');
        }
        $this->publisher = $publisher;
    }
    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        $this->publisher->publish($record['formatted']);
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new GelfMessageFormatter();
    }
}
Handler/ProcessableHandlerTrait.php000066600000003131151136154450013405 0ustar00<?php

declare (strict_types=1);
/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\ResettableInterface;
/**
 * Helper trait for implementing ProcessableInterface
 *
 * This trait is present in monolog 1.x to ease forward compatibility.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
trait ProcessableHandlerTrait
{
    /**
     * @var callable[]
     */
    protected $processors = [];
    /**
     * {@inheritdoc}
     * @suppress PhanTypeMismatchReturn
     */
    public function pushProcessor($callback) : HandlerInterface
    {
        \array_unshift($this->processors, $callback);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function popProcessor() : callable
    {
        if (!$this->processors) {
            throw new \LogicException('You tried to pop from an empty processor stack.');
        }
        return \array_shift($this->processors);
    }
    /**
     * Processes a record.
     */
    protected function processRecord(array $record) : array
    {
        foreach ($this->processors as $processor) {
            $record = $processor($record);
        }
        return $record;
    }
    protected function resetProcessors() : void
    {
        foreach ($this->processors as $processor) {
            if ($processor instanceof ResettableInterface) {
                $processor->reset();
            }
        }
    }
}
Handler/GroupHandler.php000066600000005412151136154450011237 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
use AIOSEO\Vendor\Monolog\ResettableInterface;
/**
 * Forwards records to multiple handlers
 *
 * @author Lenar Lõhmus <lenar@city.ee>
 */
class GroupHandler extends AbstractHandler
{
    protected $handlers;
    /**
     * @param array $handlers Array of Handlers.
     * @param bool  $bubble   Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct(array $handlers, $bubble = \true)
    {
        foreach ($handlers as $handler) {
            if (!$handler instanceof HandlerInterface) {
                throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.');
            }
        }
        $this->handlers = $handlers;
        $this->bubble = $bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        foreach ($this->handlers as $handler) {
            if ($handler->isHandling($record)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        foreach ($this->handlers as $handler) {
            $handler->handle($record);
        }
        return \false === $this->bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        if ($this->processors) {
            $processed = array();
            foreach ($records as $record) {
                foreach ($this->processors as $processor) {
                    $record = \call_user_func($processor, $record);
                }
                $processed[] = $record;
            }
            $records = $processed;
        }
        foreach ($this->handlers as $handler) {
            $handler->handleBatch($records);
        }
    }
    public function reset()
    {
        parent::reset();
        foreach ($this->handlers as $handler) {
            if ($handler instanceof ResettableInterface) {
                $handler->reset();
            }
        }
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        foreach ($this->handlers as $handler) {
            $handler->setFormatter($formatter);
        }
        return $this;
    }
}
Handler/AmqpHandler.php000066600000007000151136154450011034 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\JsonFormatter;
use AIOSEO\Vendor\PhpAmqpLib\Message\AMQPMessage;
use AIOSEO\Vendor\PhpAmqpLib\Channel\AMQPChannel;
use AMQPExchange;
class AmqpHandler extends AbstractProcessingHandler
{
    /**
     * @var AMQPExchange|AMQPChannel $exchange
     */
    protected $exchange;
    /**
     * @var string
     */
    protected $exchangeName;
    /**
     * @param AMQPExchange|AMQPChannel $exchange     AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
     * @param string                   $exchangeName
     * @param int                      $level
     * @param bool                     $bubble       Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = \true)
    {
        if ($exchange instanceof AMQPExchange) {
            $exchange->setName($exchangeName);
        } elseif ($exchange instanceof AMQPChannel) {
            $this->exchangeName = $exchangeName;
        } else {
            throw new \InvalidArgumentException('PhpAmqpLib\\Channel\\AMQPChannel or AMQPExchange instance required');
        }
        $this->exchange = $exchange;
        parent::__construct($level, $bubble);
    }
    /**
     * {@inheritDoc}
     */
    protected function write(array $record)
    {
        $data = $record["formatted"];
        $routingKey = $this->getRoutingKey($record);
        if ($this->exchange instanceof AMQPExchange) {
            $this->exchange->publish($data, $routingKey, 0, array('delivery_mode' => 2, 'content_type' => 'application/json'));
        } else {
            $this->exchange->basic_publish($this->createAmqpMessage($data), $this->exchangeName, $routingKey);
        }
    }
    /**
     * {@inheritDoc}
     */
    public function handleBatch(array $records)
    {
        if ($this->exchange instanceof AMQPExchange) {
            parent::handleBatch($records);
            return;
        }
        foreach ($records as $record) {
            if (!$this->isHandling($record)) {
                continue;
            }
            $record = $this->processRecord($record);
            $data = $this->getFormatter()->format($record);
            $this->exchange->batch_basic_publish($this->createAmqpMessage($data), $this->exchangeName, $this->getRoutingKey($record));
        }
        $this->exchange->publish_batch();
    }
    /**
     * Gets the routing key for the AMQP exchange
     *
     * @param  array  $record
     * @return string
     */
    protected function getRoutingKey(array $record)
    {
        $routingKey = \sprintf(
            '%s.%s',
            // TODO 2.0 remove substr call
            \substr($record['level_name'], 0, 4),
            $record['channel']
        );
        return \strtolower($routingKey);
    }
    /**
     * @param  string      $data
     * @return AMQPMessage
     */
    private function createAmqpMessage($data)
    {
        return new AMQPMessage((string) $data, array('delivery_mode' => 2, 'content_type' => 'application/json'));
    }
    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter()
    {
        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, \false);
    }
}
Handler/LogEntriesHandler.php000066600000003151151136154450012214 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * @author Robert Kaufmann III <rok3@rok3.me>
 */
class LogEntriesHandler extends SocketHandler
{
    /**
     * @var string
     */
    protected $logToken;
    /**
     * @param string $token  Log token supplied by LogEntries
     * @param bool   $useSSL Whether or not SSL encryption should be used.
     * @param int    $level  The minimum logging level to trigger this handler
     * @param bool   $bubble Whether or not messages that are handled should bubble up the stack.
     *
     * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
     */
    public function __construct($token, $useSSL = \true, $level = Logger::DEBUG, $bubble = \true, $host = 'data.logentries.com')
    {
        if ($useSSL && !\extension_loaded('openssl')) {
            throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler');
        }
        $endpoint = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80';
        parent::__construct($endpoint, $level, $bubble);
        $this->logToken = $token;
    }
    /**
     * {@inheritdoc}
     *
     * @param  array  $record
     * @return string
     */
    protected function generateDataStream($record)
    {
        return $this->logToken . ' ' . $record['formatted'];
    }
}
Handler/NativeMailerHandler.php000066600000012177151136154450012531 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\LineFormatter;
/**
 * NativeMailerHandler uses the mail() function to send the emails
 *
 * @author Christophe Coevoet <stof@notk.org>
 * @author Mark Garrett <mark@moderndeveloperllc.com>
 */
class NativeMailerHandler extends MailHandler
{
    /**
     * The email addresses to which the message will be sent
     * @var array
     */
    protected $to;
    /**
     * The subject of the email
     * @var string
     */
    protected $subject;
    /**
     * Optional headers for the message
     * @var array
     */
    protected $headers = array();
    /**
     * Optional parameters for the message
     * @var array
     */
    protected $parameters = array();
    /**
     * The wordwrap length for the message
     * @var int
     */
    protected $maxColumnWidth;
    /**
     * The Content-type for the message
     * @var string
     */
    protected $contentType = 'text/plain';
    /**
     * The encoding for the message
     * @var string
     */
    protected $encoding = 'utf-8';
    /**
     * @param string|array $to             The receiver of the mail
     * @param string       $subject        The subject of the mail
     * @param string       $from           The sender of the mail
     * @param int          $level          The minimum logging level at which this handler will be triggered
     * @param bool         $bubble         Whether the messages that are handled can bubble up the stack or not
     * @param int          $maxColumnWidth The maximum column width that the message lines will have
     */
    public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = \true, $maxColumnWidth = 70)
    {
        parent::__construct($level, $bubble);
        $this->to = \is_array($to) ? $to : array($to);
        $this->subject = $subject;
        $this->addHeader(\sprintf('From: %s', $from));
        $this->maxColumnWidth = $maxColumnWidth;
    }
    /**
     * Add headers to the message
     *
     * @param  string|array $headers Custom added headers
     * @return self
     */
    public function addHeader($headers)
    {
        foreach ((array) $headers as $header) {
            if (\strpos($header, "\n") !== \false || \strpos($header, "\r") !== \false) {
                throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons');
            }
            $this->headers[] = $header;
        }
        return $this;
    }
    /**
     * Add parameters to the message
     *
     * @param  string|array $parameters Custom added parameters
     * @return self
     */
    public function addParameter($parameters)
    {
        $this->parameters = \array_merge($this->parameters, (array) $parameters);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    protected function send($content, array $records)
    {
        $content = \wordwrap($content, $this->maxColumnWidth);
        $headers = \ltrim(\implode("\r\n", $this->headers) . "\r\n", "\r\n");
        $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n";
        if ($this->getContentType() == 'text/html' && \false === \strpos($headers, 'MIME-Version:')) {
            $headers .= 'MIME-Version: 1.0' . "\r\n";
        }
        $subject = $this->subject;
        if ($records) {
            $subjectFormatter = new LineFormatter($this->subject);
            $subject = $subjectFormatter->format($this->getHighestRecord($records));
        }
        $parameters = \implode(' ', $this->parameters);
        foreach ($this->to as $to) {
            \mail($to, $subject, $content, $headers, $parameters);
        }
    }
    /**
     * @return string $contentType
     */
    public function getContentType()
    {
        return $this->contentType;
    }
    /**
     * @return string $encoding
     */
    public function getEncoding()
    {
        return $this->encoding;
    }
    /**
     * @param  string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML
     *                             messages.
     * @return self
     */
    public function setContentType($contentType)
    {
        if (\strpos($contentType, "\n") !== \false || \strpos($contentType, "\r") !== \false) {
            throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection');
        }
        $this->contentType = $contentType;
        return $this;
    }
    /**
     * @param  string $encoding
     * @return self
     */
    public function setEncoding($encoding)
    {
        if (\strpos($encoding, "\n") !== \false || \strpos($encoding, "\r") !== \false) {
            throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection');
        }
        $this->encoding = $encoding;
        return $this;
    }
}
Handler/BufferHandler.php000066600000007753151136154450011366 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\ResettableInterface;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Buffers all records until closing the handler and then pass them as batch.
 *
 * This is useful for a MailHandler to send only one mail per request instead of
 * sending one per log message.
 *
 * @author Christophe Coevoet <stof@notk.org>
 */
class BufferHandler extends AbstractHandler
{
    protected $handler;
    protected $bufferSize = 0;
    protected $bufferLimit;
    protected $flushOnOverflow;
    protected $buffer = array();
    protected $initialized = \false;
    /**
     * @param HandlerInterface $handler         Handler.
     * @param int              $bufferLimit     How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
     * @param int              $level           The minimum logging level at which this handler will be triggered
     * @param bool             $bubble          Whether the messages that are handled can bubble up the stack or not
     * @param bool             $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
     */
    public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = \true, $flushOnOverflow = \false)
    {
        parent::__construct($level, $bubble);
        $this->handler = $handler;
        $this->bufferLimit = (int) $bufferLimit;
        $this->flushOnOverflow = $flushOnOverflow;
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if ($record['level'] < $this->level) {
            return \false;
        }
        if (!$this->initialized) {
            // __destructor() doesn't get called on Fatal errors
            \register_shutdown_function(array($this, 'close'));
            $this->initialized = \true;
        }
        if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
            if ($this->flushOnOverflow) {
                $this->flush();
            } else {
                \array_shift($this->buffer);
                $this->bufferSize--;
            }
        }
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        $this->buffer[] = $record;
        $this->bufferSize++;
        return \false === $this->bubble;
    }
    public function flush()
    {
        if ($this->bufferSize === 0) {
            return;
        }
        $this->handler->handleBatch($this->buffer);
        $this->clear();
    }
    public function __destruct()
    {
        // suppress the parent behavior since we already have register_shutdown_function()
        // to call close(), and the reference contained there will prevent this from being
        // GC'd until the end of the request
    }
    /**
     * {@inheritdoc}
     */
    public function close()
    {
        $this->flush();
    }
    /**
     * Clears the buffer without flushing any messages down to the wrapped handler.
     */
    public function clear()
    {
        $this->bufferSize = 0;
        $this->buffer = array();
    }
    public function reset()
    {
        $this->flush();
        parent::reset();
        if ($this->handler instanceof ResettableInterface) {
            $this->handler->reset();
        }
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->handler->setFormatter($formatter);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->handler->getFormatter();
    }
}
Handler/FilterHandler.php000066600000012144151136154450011370 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Handler;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Formatter\FormatterInterface;
/**
 * Simple handler wrapper that filters records based on a list of levels
 *
 * It can be configured with an exact list of levels to allow, or a min/max level.
 *
 * @author Hennadiy Verkh
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class FilterHandler extends AbstractHandler
{
    /**
     * Handler or factory callable($record, $this)
     *
     * @var callable|\Monolog\Handler\HandlerInterface
     */
    protected $handler;
    /**
     * Minimum level for logs that are passed to handler
     *
     * @var int[]
     */
    protected $acceptedLevels;
    /**
     * Whether the messages that are handled can bubble up the stack or not
     *
     * @var bool
     */
    protected $bubble;
    /**
     * @param callable|HandlerInterface $handler        Handler or factory callable($record|null, $filterHandler).
     * @param int|array                 $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
     * @param int                       $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
     * @param bool                      $bubble         Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = \true)
    {
        $this->handler = $handler;
        $this->bubble = $bubble;
        $this->setAcceptedLevels($minLevelOrList, $maxLevel);
        if (!$this->handler instanceof HandlerInterface && !\is_callable($this->handler)) {
            throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a AIOSEO\\Vendor\\Monolog\\Handler\\HandlerInterface object");
        }
    }
    /**
     * @return array
     */
    public function getAcceptedLevels()
    {
        return \array_flip($this->acceptedLevels);
    }
    /**
     * @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided
     * @param int|string       $maxLevel       Maximum level or level name to accept, only used if $minLevelOrList is not an array
     */
    public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY)
    {
        if (\is_array($minLevelOrList)) {
            $acceptedLevels = \array_map('AIOSEO\\Vendor\\Monolog\\Logger::toMonologLevel', $minLevelOrList);
        } else {
            $minLevelOrList = Logger::toMonologLevel($minLevelOrList);
            $maxLevel = Logger::toMonologLevel($maxLevel);
            $acceptedLevels = \array_values(\array_filter(Logger::getLevels(), function ($level) use($minLevelOrList, $maxLevel) {
                return $level >= $minLevelOrList && $level <= $maxLevel;
            }));
        }
        $this->acceptedLevels = \array_flip($acceptedLevels);
    }
    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        return isset($this->acceptedLevels[$record['level']]);
    }
    /**
     * {@inheritdoc}
     */
    public function handle(array $record)
    {
        if (!$this->isHandling($record)) {
            return \false;
        }
        if ($this->processors) {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
        }
        $this->getHandler($record)->handle($record);
        return \false === $this->bubble;
    }
    /**
     * {@inheritdoc}
     */
    public function handleBatch(array $records)
    {
        $filtered = array();
        foreach ($records as $record) {
            if ($this->isHandling($record)) {
                $filtered[] = $record;
            }
        }
        if (\count($filtered) > 0) {
            $this->getHandler($filtered[\count($filtered) - 1])->handleBatch($filtered);
        }
    }
    /**
     * Return the nested handler
     *
     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
     *
     * @return HandlerInterface
     */
    public function getHandler(array $record = null)
    {
        if (!$this->handler instanceof HandlerInterface) {
            $this->handler = \call_user_func($this->handler, $record, $this);
            if (!$this->handler instanceof HandlerInterface) {
                throw new \RuntimeException("The factory callable should return a HandlerInterface");
            }
        }
        return $this->handler;
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(FormatterInterface $formatter)
    {
        $this->getHandler()->setFormatter($formatter);
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->getHandler()->getFormatter();
    }
}
Utils.php000066600000014510151136154450006367 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

class Utils
{
    /**
     * @internal
     */
    public static function getClass($object)
    {
        $class = \get_class($object);
        return 'c' === $class[0] && 0 === \strpos($class, "class@anonymous\x00") ? \get_parent_class($class) . '@anonymous' : $class;
    }
    /**
     * Makes sure if a relative path is passed in it is turned into an absolute path
     *
     * @param string $streamUrl stream URL or path without protocol
     *
     * @return string
     */
    public static function canonicalizePath($streamUrl)
    {
        $prefix = '';
        if ('file://' === \substr($streamUrl, 0, 7)) {
            $streamUrl = \substr($streamUrl, 7);
            $prefix = 'file://';
        }
        // other type of stream, not supported
        if (\false !== \strpos($streamUrl, '://')) {
            return $streamUrl;
        }
        // already absolute
        if (\substr($streamUrl, 0, 1) === '/' || \substr($streamUrl, 1, 1) === ':' || \substr($streamUrl, 0, 2) === '\\\\') {
            return $prefix . $streamUrl;
        }
        $streamUrl = \getcwd() . '/' . $streamUrl;
        return $prefix . $streamUrl;
    }
    /**
     * Return the JSON representation of a value
     *
     * @param  mixed             $data
     * @param  int               $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
     * @param  bool              $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null
     * @throws \RuntimeException if encoding fails and errors are not ignored
     * @return string
     */
    public static function jsonEncode($data, $encodeFlags = null, $ignoreErrors = \false)
    {
        if (null === $encodeFlags && \version_compare(\PHP_VERSION, '5.4.0', '>=')) {
            $encodeFlags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE;
        }
        if ($ignoreErrors) {
            $json = @\json_encode($data, $encodeFlags);
            if (\false === $json) {
                return 'null';
            }
            return $json;
        }
        $json = \json_encode($data, $encodeFlags);
        if (\false === $json) {
            $json = self::handleJsonError(\json_last_error(), $data);
        }
        return $json;
    }
    /**
     * Handle a json_encode failure.
     *
     * If the failure is due to invalid string encoding, try to clean the
     * input and encode again. If the second encoding attempt fails, the
     * inital error is not encoding related or the input can't be cleaned then
     * raise a descriptive exception.
     *
     * @param  int               $code return code of json_last_error function
     * @param  mixed             $data data that was meant to be encoded
     * @param  int               $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
     * @throws \RuntimeException if failure can't be corrected
     * @return string            JSON encoded data after error correction
     */
    public static function handleJsonError($code, $data, $encodeFlags = null)
    {
        if ($code !== \JSON_ERROR_UTF8) {
            self::throwEncodeError($code, $data);
        }
        if (\is_string($data)) {
            self::detectAndCleanUtf8($data);
        } elseif (\is_array($data)) {
            \array_walk_recursive($data, array('AIOSEO\\Vendor\\Monolog\\Utils', 'detectAndCleanUtf8'));
        } else {
            self::throwEncodeError($code, $data);
        }
        if (null === $encodeFlags && \version_compare(\PHP_VERSION, '5.4.0', '>=')) {
            $encodeFlags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE;
        }
        $json = \json_encode($data, $encodeFlags);
        if ($json === \false) {
            self::throwEncodeError(\json_last_error(), $data);
        }
        return $json;
    }
    /**
     * Throws an exception according to a given code with a customized message
     *
     * @param  int               $code return code of json_last_error function
     * @param  mixed             $data data that was meant to be encoded
     * @throws \RuntimeException
     */
    private static function throwEncodeError($code, $data)
    {
        switch ($code) {
            case \JSON_ERROR_DEPTH:
                $msg = 'Maximum stack depth exceeded';
                break;
            case \JSON_ERROR_STATE_MISMATCH:
                $msg = 'Underflow or the modes mismatch';
                break;
            case \JSON_ERROR_CTRL_CHAR:
                $msg = 'Unexpected control character found';
                break;
            case \JSON_ERROR_UTF8:
                $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
                break;
            default:
                $msg = 'Unknown error';
        }
        throw new \RuntimeException('JSON encoding failed: ' . $msg . '. Encoding: ' . \var_export($data, \true));
    }
    /**
     * Detect invalid UTF-8 string characters and convert to valid UTF-8.
     *
     * Valid UTF-8 input will be left unmodified, but strings containing
     * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed
     * original encoding of ISO-8859-15. This conversion may result in
     * incorrect output if the actual encoding was not ISO-8859-15, but it
     * will be clean UTF-8 output and will not rely on expensive and fragile
     * detection algorithms.
     *
     * Function converts the input in place in the passed variable so that it
     * can be used as a callback for array_walk_recursive.
     *
     * @param mixed $data Input to check and convert if needed, passed by ref
     * @private
     */
    public static function detectAndCleanUtf8(&$data)
    {
        if (\is_string($data) && !\preg_match('//u', $data)) {
            $data = \preg_replace_callback('/[\\x80-\\xFF]+/', function ($m) {
                return \utf8_encode($m[0]);
            }, $data);
            $data = \str_replace(array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'), array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'), $data);
        }
    }
}
ResettableInterface.php000066600000001674151136154450011211 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

/**
 * Handler or Processor implementing this interface will be reset when Logger::reset() is called.
 *
 * Resetting ends a log cycle gets them back to their initial state.
 *
 * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
 * state, and getting it back to a state in which it can receive log records again.
 *
 * This is useful in case you want to avoid logs leaking between two requests or jobs when you
 * have a long running process like a worker or an application server serving multiple requests
 * in one process.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
interface ResettableInterface
{
    public function reset();
}
Logger.php000066600000053242151136154450006513 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

use AIOSEO\Vendor\Monolog\Handler\HandlerInterface;
use AIOSEO\Vendor\Monolog\Handler\StreamHandler;
use AIOSEO\Vendor\Psr\Log\LoggerInterface;
use AIOSEO\Vendor\Psr\Log\InvalidArgumentException;
use Exception;
/**
 * Monolog log channel
 *
 * It contains a stack of Handlers and a stack of Processors,
 * and uses them to store records that are added to it.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class Logger implements LoggerInterface, ResettableInterface
{
    /**
     * Detailed debug information
     */
    const DEBUG = 100;
    /**
     * Interesting events
     *
     * Examples: User logs in, SQL logs.
     */
    const INFO = 200;
    /**
     * Uncommon events
     */
    const NOTICE = 250;
    /**
     * Exceptional occurrences that are not errors
     *
     * Examples: Use of deprecated APIs, poor use of an API,
     * undesirable things that are not necessarily wrong.
     */
    const WARNING = 300;
    /**
     * Runtime errors
     */
    const ERROR = 400;
    /**
     * Critical conditions
     *
     * Example: Application component unavailable, unexpected exception.
     */
    const CRITICAL = 500;
    /**
     * Action must be taken immediately
     *
     * Example: Entire website down, database unavailable, etc.
     * This should trigger the SMS alerts and wake you up.
     */
    const ALERT = 550;
    /**
     * Urgent alert.
     */
    const EMERGENCY = 600;
    /**
     * Monolog API version
     *
     * This is only bumped when API breaks are done and should
     * follow the major version of the library
     *
     * @var int
     */
    const API = 1;
    /**
     * Logging levels from syslog protocol defined in RFC 5424
     *
     * @var array $levels Logging levels
     */
    protected static $levels = array(self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::NOTICE => 'NOTICE', self::WARNING => 'WARNING', self::ERROR => 'ERROR', self::CRITICAL => 'CRITICAL', self::ALERT => 'ALERT', self::EMERGENCY => 'EMERGENCY');
    /**
     * @var \DateTimeZone
     */
    protected static $timezone;
    /**
     * @var string
     */
    protected $name;
    /**
     * The handler stack
     *
     * @var HandlerInterface[]
     */
    protected $handlers;
    /**
     * Processors that will process all log records
     *
     * To process records of a single handler instead, add the processor on that specific handler
     *
     * @var callable[]
     */
    protected $processors;
    /**
     * @var bool
     */
    protected $microsecondTimestamps = \true;
    /**
     * @var callable
     */
    protected $exceptionHandler;
    /**
     * @param string             $name       The logging channel
     * @param HandlerInterface[] $handlers   Optional stack of handlers, the first one in the array is called first, etc.
     * @param callable[]         $processors Optional array of processors
     */
    public function __construct($name, array $handlers = array(), array $processors = array())
    {
        $this->name = $name;
        $this->setHandlers($handlers);
        $this->processors = $processors;
    }
    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Return a new cloned instance with the name changed
     *
     * @return static
     */
    public function withName($name)
    {
        $new = clone $this;
        $new->name = $name;
        return $new;
    }
    /**
     * Pushes a handler on to the stack.
     *
     * @param  HandlerInterface $handler
     * @return $this
     */
    public function pushHandler(HandlerInterface $handler)
    {
        \array_unshift($this->handlers, $handler);
        return $this;
    }
    /**
     * Pops a handler from the stack
     *
     * @return HandlerInterface
     */
    public function popHandler()
    {
        if (!$this->handlers) {
            throw new \LogicException('You tried to pop from an empty handler stack.');
        }
        return \array_shift($this->handlers);
    }
    /**
     * Set handlers, replacing all existing ones.
     *
     * If a map is passed, keys will be ignored.
     *
     * @param  HandlerInterface[] $handlers
     * @return $this
     */
    public function setHandlers(array $handlers)
    {
        $this->handlers = array();
        foreach (\array_reverse($handlers) as $handler) {
            $this->pushHandler($handler);
        }
        return $this;
    }
    /**
     * @return HandlerInterface[]
     */
    public function getHandlers()
    {
        return $this->handlers;
    }
    /**
     * Adds a processor on to the stack.
     *
     * @param  callable $callback
     * @return $this
     */
    public function pushProcessor($callback)
    {
        if (!\is_callable($callback)) {
            throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . \var_export($callback, \true) . ' given');
        }
        \array_unshift($this->processors, $callback);
        return $this;
    }
    /**
     * Removes the processor on top of the stack and returns it.
     *
     * @return callable
     */
    public function popProcessor()
    {
        if (!$this->processors) {
            throw new \LogicException('You tried to pop from an empty processor stack.');
        }
        return \array_shift($this->processors);
    }
    /**
     * @return callable[]
     */
    public function getProcessors()
    {
        return $this->processors;
    }
    /**
     * Control the use of microsecond resolution timestamps in the 'datetime'
     * member of new records.
     *
     * Generating microsecond resolution timestamps by calling
     * microtime(true), formatting the result via sprintf() and then parsing
     * the resulting string via \DateTime::createFromFormat() can incur
     * a measurable runtime overhead vs simple usage of DateTime to capture
     * a second resolution timestamp in systems which generate a large number
     * of log events.
     *
     * @param bool $micro True to use microtime() to create timestamps
     */
    public function useMicrosecondTimestamps($micro)
    {
        $this->microsecondTimestamps = (bool) $micro;
    }
    /**
     * Adds a log record.
     *
     * @param  int     $level   The logging level
     * @param  string  $message The log message
     * @param  array   $context The log context
     * @return bool Whether the record has been processed
     */
    public function addRecord($level, $message, array $context = array())
    {
        if (!$this->handlers) {
            $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
        }
        $levelName = static::getLevelName($level);
        // check if any handler will handle this message so we can return early and save cycles
        $handlerKey = null;
        \reset($this->handlers);
        while ($handler = \current($this->handlers)) {
            if ($handler->isHandling(array('level' => $level))) {
                $handlerKey = \key($this->handlers);
                break;
            }
            \next($this->handlers);
        }
        if (null === $handlerKey) {
            return \false;
        }
        if (!static::$timezone) {
            static::$timezone = new \DateTimeZone(\date_default_timezone_get() ?: 'UTC');
        }
        // php7.1+ always has microseconds enabled, so we do not need this hack
        if ($this->microsecondTimestamps && \PHP_VERSION_ID < 70100) {
            $ts = \DateTime::createFromFormat('U.u', \sprintf('%.6F', \microtime(\true)), static::$timezone);
        } else {
            $ts = new \DateTime('now', static::$timezone);
        }
        $ts->setTimezone(static::$timezone);
        $record = array('message' => (string) $message, 'context' => $context, 'level' => $level, 'level_name' => $levelName, 'channel' => $this->name, 'datetime' => $ts, 'extra' => array());
        try {
            foreach ($this->processors as $processor) {
                $record = \call_user_func($processor, $record);
            }
            while ($handler = \current($this->handlers)) {
                if (\true === $handler->handle($record)) {
                    break;
                }
                \next($this->handlers);
            }
        } catch (Exception $e) {
            $this->handleException($e, $record);
        }
        return \true;
    }
    /**
     * Ends a log cycle and frees all resources used by handlers.
     *
     * Closing a Handler means flushing all buffers and freeing any open resources/handles.
     * Handlers that have been closed should be able to accept log records again and re-open
     * themselves on demand, but this may not always be possible depending on implementation.
     *
     * This is useful at the end of a request and will be called automatically on every handler
     * when they get destructed.
     */
    public function close()
    {
        foreach ($this->handlers as $handler) {
            if (\method_exists($handler, 'close')) {
                $handler->close();
            }
        }
    }
    /**
     * Ends a log cycle and resets all handlers and processors to their initial state.
     *
     * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
     * state, and getting it back to a state in which it can receive log records again.
     *
     * This is useful in case you want to avoid logs leaking between two requests or jobs when you
     * have a long running process like a worker or an application server serving multiple requests
     * in one process.
     */
    public function reset()
    {
        foreach ($this->handlers as $handler) {
            if ($handler instanceof ResettableInterface) {
                $handler->reset();
            }
        }
        foreach ($this->processors as $processor) {
            if ($processor instanceof ResettableInterface) {
                $processor->reset();
            }
        }
    }
    /**
     * Adds a log record at the DEBUG level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addDebug($message, array $context = array())
    {
        return $this->addRecord(static::DEBUG, $message, $context);
    }
    /**
     * Adds a log record at the INFO level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addInfo($message, array $context = array())
    {
        return $this->addRecord(static::INFO, $message, $context);
    }
    /**
     * Adds a log record at the NOTICE level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addNotice($message, array $context = array())
    {
        return $this->addRecord(static::NOTICE, $message, $context);
    }
    /**
     * Adds a log record at the WARNING level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addWarning($message, array $context = array())
    {
        return $this->addRecord(static::WARNING, $message, $context);
    }
    /**
     * Adds a log record at the ERROR level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addError($message, array $context = array())
    {
        return $this->addRecord(static::ERROR, $message, $context);
    }
    /**
     * Adds a log record at the CRITICAL level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addCritical($message, array $context = array())
    {
        return $this->addRecord(static::CRITICAL, $message, $context);
    }
    /**
     * Adds a log record at the ALERT level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addAlert($message, array $context = array())
    {
        return $this->addRecord(static::ALERT, $message, $context);
    }
    /**
     * Adds a log record at the EMERGENCY level.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function addEmergency($message, array $context = array())
    {
        return $this->addRecord(static::EMERGENCY, $message, $context);
    }
    /**
     * Gets all supported logging levels.
     *
     * @return array Assoc array with human-readable level names => level codes.
     */
    public static function getLevels()
    {
        return \array_flip(static::$levels);
    }
    /**
     * Gets the name of the logging level.
     *
     * @param  int    $level
     * @return string
     */
    public static function getLevelName($level)
    {
        if (!isset(static::$levels[$level])) {
            throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . \implode(', ', \array_keys(static::$levels)));
        }
        return static::$levels[$level];
    }
    /**
     * Converts PSR-3 levels to Monolog ones if necessary
     *
     * @param string|int $level Level number (monolog) or name (PSR-3)
     * @return int
     */
    public static function toMonologLevel($level)
    {
        if (\is_string($level)) {
            // Contains chars of all log levels and avoids using strtoupper() which may have
            // strange results depending on locale (for example, "i" will become "İ")
            $upper = \strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY');
            if (\defined(__CLASS__ . '::' . $upper)) {
                return \constant(__CLASS__ . '::' . $upper);
            }
        }
        return $level;
    }
    /**
     * Checks whether the Logger has a handler that listens on the given level
     *
     * @param  int     $level
     * @return bool
     */
    public function isHandling($level)
    {
        $record = array('level' => $level);
        foreach ($this->handlers as $handler) {
            if ($handler->isHandling($record)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * Set a custom exception handler
     *
     * @param  callable $callback
     * @return $this
     */
    public function setExceptionHandler($callback)
    {
        if (!\is_callable($callback)) {
            throw new \InvalidArgumentException('Exception handler must be valid callable (callback or object with an __invoke method), ' . \var_export($callback, \true) . ' given');
        }
        $this->exceptionHandler = $callback;
        return $this;
    }
    /**
     * @return callable
     */
    public function getExceptionHandler()
    {
        return $this->exceptionHandler;
    }
    /**
     * Delegates exception management to the custom exception handler,
     * or throws the exception if no custom handler is set.
     */
    protected function handleException(Exception $e, array $record)
    {
        if (!$this->exceptionHandler) {
            throw $e;
        }
        \call_user_func($this->exceptionHandler, $e, $record);
    }
    /**
     * Adds a log record at an arbitrary level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  mixed   $level   The log level
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function log($level, $message, array $context = array())
    {
        $level = static::toMonologLevel($level);
        return $this->addRecord($level, $message, $context);
    }
    /**
     * Adds a log record at the DEBUG level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function debug($message, array $context = array())
    {
        return $this->addRecord(static::DEBUG, $message, $context);
    }
    /**
     * Adds a log record at the INFO level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function info($message, array $context = array())
    {
        return $this->addRecord(static::INFO, $message, $context);
    }
    /**
     * Adds a log record at the NOTICE level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function notice($message, array $context = array())
    {
        return $this->addRecord(static::NOTICE, $message, $context);
    }
    /**
     * Adds a log record at the WARNING level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function warn($message, array $context = array())
    {
        return $this->addRecord(static::WARNING, $message, $context);
    }
    /**
     * Adds a log record at the WARNING level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function warning($message, array $context = array())
    {
        return $this->addRecord(static::WARNING, $message, $context);
    }
    /**
     * Adds a log record at the ERROR level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function err($message, array $context = array())
    {
        return $this->addRecord(static::ERROR, $message, $context);
    }
    /**
     * Adds a log record at the ERROR level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function error($message, array $context = array())
    {
        return $this->addRecord(static::ERROR, $message, $context);
    }
    /**
     * Adds a log record at the CRITICAL level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function crit($message, array $context = array())
    {
        return $this->addRecord(static::CRITICAL, $message, $context);
    }
    /**
     * Adds a log record at the CRITICAL level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function critical($message, array $context = array())
    {
        return $this->addRecord(static::CRITICAL, $message, $context);
    }
    /**
     * Adds a log record at the ALERT level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function alert($message, array $context = array())
    {
        return $this->addRecord(static::ALERT, $message, $context);
    }
    /**
     * Adds a log record at the EMERGENCY level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function emerg($message, array $context = array())
    {
        return $this->addRecord(static::EMERGENCY, $message, $context);
    }
    /**
     * Adds a log record at the EMERGENCY level.
     *
     * This method allows for compatibility with common interfaces.
     *
     * @param  string $message The log message
     * @param  array  $context The log context
     * @return bool   Whether the record has been processed
     */
    public function emergency($message, array $context = array())
    {
        return $this->addRecord(static::EMERGENCY, $message, $context);
    }
    /**
     * Set the timezone to be used for the timestamp of log records.
     *
     * This is stored globally for all Logger instances
     *
     * @param \DateTimeZone $tz Timezone object
     */
    public static function setTimezone(\DateTimeZone $tz)
    {
        self::$timezone = $tz;
    }
}
SignalHandler.php000066600000010201151136154450007773 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

use AIOSEO\Vendor\Psr\Log\LoggerInterface;
use AIOSEO\Vendor\Psr\Log\LogLevel;
use ReflectionExtension;
/**
 * Monolog POSIX signal handler
 *
 * @author Robert Gust-Bardon <robert@gust-bardon.org>
 */
class SignalHandler
{
    private $logger;
    private $previousSignalHandler = array();
    private $signalLevelMap = array();
    private $signalRestartSyscalls = array();
    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
    public function registerSignalHandler($signo, $level = LogLevel::CRITICAL, $callPrevious = \true, $restartSyscalls = \true, $async = \true)
    {
        if (!\extension_loaded('pcntl') || !\function_exists('pcntl_signal')) {
            return $this;
        }
        if ($callPrevious) {
            if (\function_exists('pcntl_signal_get_handler')) {
                $handler = \pcntl_signal_get_handler($signo);
                if ($handler === \false) {
                    return $this;
                }
                $this->previousSignalHandler[$signo] = $handler;
            } else {
                $this->previousSignalHandler[$signo] = \true;
            }
        } else {
            unset($this->previousSignalHandler[$signo]);
        }
        $this->signalLevelMap[$signo] = $level;
        $this->signalRestartSyscalls[$signo] = $restartSyscalls;
        if (\function_exists('pcntl_async_signals') && $async !== null) {
            \pcntl_async_signals($async);
        }
        \pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls);
        return $this;
    }
    public function handleSignal($signo, array $siginfo = null)
    {
        static $signals = array();
        if (!$signals && \extension_loaded('pcntl')) {
            $pcntl = new ReflectionExtension('pcntl');
            $constants = $pcntl->getConstants();
            if (!$constants) {
                // HHVM 3.24.2 returns an empty array.
                $constants = \get_defined_constants(\true);
                $constants = $constants['Core'];
            }
            foreach ($constants as $name => $value) {
                if (\substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && \is_int($value)) {
                    $signals[$value] = $name;
                }
            }
            unset($constants);
        }
        $level = isset($this->signalLevelMap[$signo]) ? $this->signalLevelMap[$signo] : LogLevel::CRITICAL;
        $signal = isset($signals[$signo]) ? $signals[$signo] : $signo;
        $context = isset($siginfo) ? $siginfo : array();
        $this->logger->log($level, \sprintf('Program received signal %s', $signal), $context);
        if (!isset($this->previousSignalHandler[$signo])) {
            return;
        }
        if ($this->previousSignalHandler[$signo] === \true || $this->previousSignalHandler[$signo] === \SIG_DFL) {
            if (\extension_loaded('pcntl') && \function_exists('pcntl_signal') && \function_exists('pcntl_sigprocmask') && \function_exists('pcntl_signal_dispatch') && \extension_loaded('posix') && \function_exists('posix_getpid') && \function_exists('posix_kill')) {
                $restartSyscalls = isset($this->signalRestartSyscalls[$signo]) ? $this->signalRestartSyscalls[$signo] : \true;
                \pcntl_signal($signo, \SIG_DFL, $restartSyscalls);
                \pcntl_sigprocmask(\SIG_UNBLOCK, array($signo), $oldset);
                \posix_kill(\posix_getpid(), $signo);
                \pcntl_signal_dispatch();
                \pcntl_sigprocmask(\SIG_SETMASK, $oldset);
                \pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls);
            }
        } elseif (\is_callable($this->previousSignalHandler[$signo])) {
            if (\PHP_VERSION_ID >= 70100) {
                $this->previousSignalHandler[$signo]($signo, $siginfo);
            } else {
                $this->previousSignalHandler[$signo]($signo);
            }
        }
    }
}
Formatter/FluentdFormatter.php000066600000004163151136154450012522 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Utils;
/**
 * Class FluentdFormatter
 *
 * Serializes a log message to Fluentd unix socket protocol
 *
 * Fluentd config:
 *
 * <source>
 *  type unix
 *  path /var/run/td-agent/td-agent.sock
 * </source>
 *
 * Monolog setup:
 *
 * $logger = new Monolog\Logger('fluent.tag');
 * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock');
 * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter());
 * $logger->pushHandler($fluentHandler);
 *
 * @author Andrius Putna <fordnox@gmail.com>
 */
class FluentdFormatter implements FormatterInterface
{
    /**
     * @var bool $levelTag should message level be a part of the fluentd tag
     */
    protected $levelTag = \false;
    public function __construct($levelTag = \false)
    {
        if (!\function_exists('json_encode')) {
            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter');
        }
        $this->levelTag = (bool) $levelTag;
    }
    public function isUsingLevelsInTag()
    {
        return $this->levelTag;
    }
    public function format(array $record)
    {
        $tag = $record['channel'];
        if ($this->levelTag) {
            $tag .= '.' . \strtolower($record['level_name']);
        }
        $message = array('message' => $record['message'], 'context' => $record['context'], 'extra' => $record['extra']);
        if (!$this->levelTag) {
            $message['level'] = $record['level'];
            $message['level_name'] = $record['level_name'];
        }
        return Utils::jsonEncode(array($tag, $record['datetime']->getTimestamp(), $message));
    }
    public function formatBatch(array $records)
    {
        $message = '';
        foreach ($records as $record) {
            $message .= $this->format($record);
        }
        return $message;
    }
}
Formatter/LogglyFormatter.php000066600000002465151136154450012361 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

/**
 * Encodes message information into JSON in a format compatible with Loggly.
 *
 * @author Adam Pancutt <adam@pancutt.com>
 */
class LogglyFormatter extends JsonFormatter
{
    /**
     * Overrides the default batch mode to new lines for compatibility with the
     * Loggly bulk API.
     *
     * @param int $batchMode
     */
    public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = \false)
    {
        parent::__construct($batchMode, $appendNewline);
    }
    /**
     * Appends the 'timestamp' parameter for indexing by Loggly.
     *
     * @see https://www.loggly.com/docs/automated-parsing/#json
     * @see \Monolog\Formatter\JsonFormatter::format()
     */
    public function format(array $record)
    {
        if (isset($record["datetime"]) && $record["datetime"] instanceof \DateTime) {
            $record["timestamp"] = $record["datetime"]->format("Y-m-d\\TH:i:s.uO");
            // TODO 2.0 unset the 'datetime' parameter, retained for BC
        }
        return parent::format($record);
    }
}
Formatter/GelfMessageFormatter.php000066600000010316151136154450013300 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Gelf\Message;
/**
 * Serializes a log message to GELF
 * @see http://www.graylog2.org/about/gelf
 *
 * @author Matt Lehner <mlehner@gmail.com>
 */
class GelfMessageFormatter extends NormalizerFormatter
{
    const DEFAULT_MAX_LENGTH = 32766;
    /**
     * @var string the name of the system for the Gelf log message
     */
    protected $systemName;
    /**
     * @var string a prefix for 'extra' fields from the Monolog record (optional)
     */
    protected $extraPrefix;
    /**
     * @var string a prefix for 'context' fields from the Monolog record (optional)
     */
    protected $contextPrefix;
    /**
     * @var int max length per field
     */
    protected $maxLength;
    /**
     * Translates Monolog log levels to Graylog2 log priorities.
     */
    private $logLevels = array(Logger::DEBUG => 7, Logger::INFO => 6, Logger::NOTICE => 5, Logger::WARNING => 4, Logger::ERROR => 3, Logger::CRITICAL => 2, Logger::ALERT => 1, Logger::EMERGENCY => 0);
    public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $maxLength = null)
    {
        parent::__construct('U.u');
        $this->systemName = $systemName ?: \gethostname();
        $this->extraPrefix = $extraPrefix;
        $this->contextPrefix = $contextPrefix;
        $this->maxLength = \is_null($maxLength) ? self::DEFAULT_MAX_LENGTH : $maxLength;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        $record = parent::format($record);
        if (!isset($record['datetime'], $record['message'], $record['level'])) {
            throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, ' . \var_export($record, \true) . ' given');
        }
        $message = new Message();
        $message->setTimestamp($record['datetime'])->setShortMessage((string) $record['message'])->setHost($this->systemName)->setLevel($this->logLevels[$record['level']]);
        // message length + system name length + 200 for padding / metadata
        $len = 200 + \strlen((string) $record['message']) + \strlen($this->systemName);
        if ($len > $this->maxLength) {
            $message->setShortMessage(\substr($record['message'], 0, $this->maxLength));
        }
        if (isset($record['channel'])) {
            $message->setFacility($record['channel']);
        }
        if (isset($record['extra']['line'])) {
            $message->setLine($record['extra']['line']);
            unset($record['extra']['line']);
        }
        if (isset($record['extra']['file'])) {
            $message->setFile($record['extra']['file']);
            unset($record['extra']['file']);
        }
        foreach ($record['extra'] as $key => $val) {
            $val = \is_scalar($val) || null === $val ? $val : $this->toJson($val);
            $len = \strlen($this->extraPrefix . $key . $val);
            if ($len > $this->maxLength) {
                $message->setAdditional($this->extraPrefix . $key, \substr($val, 0, $this->maxLength));
                break;
            }
            $message->setAdditional($this->extraPrefix . $key, $val);
        }
        foreach ($record['context'] as $key => $val) {
            $val = \is_scalar($val) || null === $val ? $val : $this->toJson($val);
            $len = \strlen($this->contextPrefix . $key . $val);
            if ($len > $this->maxLength) {
                $message->setAdditional($this->contextPrefix . $key, \substr($val, 0, $this->maxLength));
                break;
            }
            $message->setAdditional($this->contextPrefix . $key, $val);
        }
        if (null === $message->getFile() && isset($record['context']['exception']['file'])) {
            if (\preg_match("/^(.+):([0-9]+)\$/", $record['context']['exception']['file'], $matches)) {
                $message->setFile($matches[1]);
                $message->setLine($matches[2]);
            }
        }
        return $message;
    }
}
Formatter/NormalizerFormatter.php000066600000012062151136154450013240 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use Exception;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class NormalizerFormatter implements FormatterInterface
{
    const SIMPLE_DATE = "Y-m-d H:i:s";
    protected $dateFormat;
    /**
     * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
     */
    public function __construct($dateFormat = null)
    {
        $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE;
        if (!\function_exists('json_encode')) {
            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
        }
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        return $this->normalize($record);
    }
    /**
     * {@inheritdoc}
     */
    public function formatBatch(array $records)
    {
        foreach ($records as $key => $record) {
            $records[$key] = $this->format($record);
        }
        return $records;
    }
    protected function normalize($data, $depth = 0)
    {
        if ($depth > 9) {
            return 'Over 9 levels deep, aborting normalization';
        }
        if (null === $data || \is_scalar($data)) {
            if (\is_float($data)) {
                if (\is_infinite($data)) {
                    return ($data > 0 ? '' : '-') . 'INF';
                }
                if (\is_nan($data)) {
                    return 'NaN';
                }
            }
            return $data;
        }
        if (\is_array($data)) {
            $normalized = array();
            $count = 1;
            foreach ($data as $key => $value) {
                if ($count++ > 1000) {
                    $normalized['...'] = 'Over 1000 items (' . \count($data) . ' total), aborting normalization';
                    break;
                }
                $normalized[$key] = $this->normalize($value, $depth + 1);
            }
            return $normalized;
        }
        if ($data instanceof \DateTime) {
            return $data->format($this->dateFormat);
        }
        if (\is_object($data)) {
            // TODO 2.0 only check for Throwable
            if ($data instanceof Exception || \PHP_VERSION_ID > 70000 && $data instanceof \Throwable) {
                return $this->normalizeException($data);
            }
            // non-serializable objects that implement __toString stringified
            if (\method_exists($data, '__toString') && !$data instanceof \JsonSerializable) {
                $value = $data->__toString();
            } else {
                // the rest is json-serialized in some way
                $value = $this->toJson($data, \true);
            }
            return \sprintf("[object] (%s: %s)", Utils::getClass($data), $value);
        }
        if (\is_resource($data)) {
            return \sprintf('[resource] (%s)', \get_resource_type($data));
        }
        return '[unknown(' . \gettype($data) . ')]';
    }
    protected function normalizeException($e)
    {
        // TODO 2.0 only check for Throwable
        if (!$e instanceof Exception && !$e instanceof \Throwable) {
            throw new \InvalidArgumentException('Exception/Throwable expected, got ' . \gettype($e) . ' / ' . Utils::getClass($e));
        }
        $data = array('class' => Utils::getClass($e), 'message' => $e->getMessage(), 'code' => (int) $e->getCode(), 'file' => $e->getFile() . ':' . $e->getLine());
        if ($e instanceof \SoapFault) {
            if (isset($e->faultcode)) {
                $data['faultcode'] = $e->faultcode;
            }
            if (isset($e->faultactor)) {
                $data['faultactor'] = $e->faultactor;
            }
            if (isset($e->detail)) {
                if (\is_string($e->detail)) {
                    $data['detail'] = $e->detail;
                } elseif (\is_object($e->detail) || \is_array($e->detail)) {
                    $data['detail'] = $this->toJson($e->detail, \true);
                }
            }
        }
        $trace = $e->getTrace();
        foreach ($trace as $frame) {
            if (isset($frame['file'])) {
                $data['trace'][] = $frame['file'] . ':' . $frame['line'];
            }
        }
        if ($previous = $e->getPrevious()) {
            $data['previous'] = $this->normalizeException($previous);
        }
        return $data;
    }
    /**
     * Return the JSON representation of a value
     *
     * @param  mixed             $data
     * @param  bool              $ignoreErrors
     * @throws \RuntimeException if encoding fails and errors are not ignored
     * @return string
     */
    protected function toJson($data, $ignoreErrors = \false)
    {
        return Utils::jsonEncode($data, null, $ignoreErrors);
    }
}
Formatter/MongoDBFormatter.php000066600000006273151136154450012412 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Utils;
/**
 * Formats a record for use with the MongoDBHandler.
 *
 * @author Florian Plattner <me@florianplattner.de>
 */
class MongoDBFormatter implements FormatterInterface
{
    private $exceptionTraceAsString;
    private $maxNestingLevel;
    /**
     * @param int  $maxNestingLevel        0 means infinite nesting, the $record itself is level 1, $record['context'] is 2
     * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings
     */
    public function __construct($maxNestingLevel = 3, $exceptionTraceAsString = \true)
    {
        $this->maxNestingLevel = \max($maxNestingLevel, 0);
        $this->exceptionTraceAsString = (bool) $exceptionTraceAsString;
    }
    /**
     * {@inheritDoc}
     */
    public function format(array $record)
    {
        return $this->formatArray($record);
    }
    /**
     * {@inheritDoc}
     */
    public function formatBatch(array $records)
    {
        foreach ($records as $key => $record) {
            $records[$key] = $this->format($record);
        }
        return $records;
    }
    protected function formatArray(array $record, $nestingLevel = 0)
    {
        if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) {
            foreach ($record as $name => $value) {
                if ($value instanceof \DateTime) {
                    $record[$name] = $this->formatDate($value, $nestingLevel + 1);
                } elseif ($value instanceof \Exception) {
                    $record[$name] = $this->formatException($value, $nestingLevel + 1);
                } elseif (\is_array($value)) {
                    $record[$name] = $this->formatArray($value, $nestingLevel + 1);
                } elseif (\is_object($value)) {
                    $record[$name] = $this->formatObject($value, $nestingLevel + 1);
                }
            }
        } else {
            $record = '[...]';
        }
        return $record;
    }
    protected function formatObject($value, $nestingLevel)
    {
        $objectVars = \get_object_vars($value);
        $objectVars['class'] = Utils::getClass($value);
        return $this->formatArray($objectVars, $nestingLevel);
    }
    protected function formatException(\Exception $exception, $nestingLevel)
    {
        $formattedException = array('class' => Utils::getClass($exception), 'message' => $exception->getMessage(), 'code' => (int) $exception->getCode(), 'file' => $exception->getFile() . ':' . $exception->getLine());
        if ($this->exceptionTraceAsString === \true) {
            $formattedException['trace'] = $exception->getTraceAsString();
        } else {
            $formattedException['trace'] = $exception->getTrace();
        }
        return $this->formatArray($formattedException, $nestingLevel);
    }
    protected function formatDate(\DateTime $value, $nestingLevel)
    {
        return new \MongoDate($value->getTimestamp());
    }
}
Formatter/LogstashFormatter.php000066600000012140151136154450012677 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

/**
 * Serializes a log message to Logstash Event Format
 *
 * @see http://logstash.net/
 * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb
 *
 * @author Tim Mower <timothy.mower@gmail.com>
 */
class LogstashFormatter extends NormalizerFormatter
{
    const V0 = 0;
    const V1 = 1;
    /**
     * @var string the name of the system for the Logstash log message, used to fill the @source field
     */
    protected $systemName;
    /**
     * @var string an application name for the Logstash log message, used to fill the @type field
     */
    protected $applicationName;
    /**
     * @var string a prefix for 'extra' fields from the Monolog record (optional)
     */
    protected $extraPrefix;
    /**
     * @var string a prefix for 'context' fields from the Monolog record (optional)
     */
    protected $contextPrefix;
    /**
     * @var int logstash format version to use
     */
    protected $version;
    /**
     * @param string $applicationName the application that sends the data, used as the "type" field of logstash
     * @param string $systemName      the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
     * @param string $extraPrefix     prefix for extra keys inside logstash "fields"
     * @param string $contextPrefix   prefix for context keys inside logstash "fields", defaults to ctxt_
     * @param int    $version         the logstash format version to use, defaults to 0
     */
    public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0)
    {
        // logstash requires a ISO 8601 format date with optional millisecond precision.
        parent::__construct('Y-m-d\\TH:i:s.uP');
        $this->systemName = $systemName ?: \gethostname();
        $this->applicationName = $applicationName;
        $this->extraPrefix = $extraPrefix;
        $this->contextPrefix = $contextPrefix;
        $this->version = $version;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        $record = parent::format($record);
        if ($this->version === self::V1) {
            $message = $this->formatV1($record);
        } else {
            $message = $this->formatV0($record);
        }
        return $this->toJson($message) . "\n";
    }
    protected function formatV0(array $record)
    {
        if (empty($record['datetime'])) {
            $record['datetime'] = \gmdate('c');
        }
        $message = array('@timestamp' => $record['datetime'], '@source' => $this->systemName, '@fields' => array());
        if (isset($record['message'])) {
            $message['@message'] = $record['message'];
        }
        if (isset($record['channel'])) {
            $message['@tags'] = array($record['channel']);
            $message['@fields']['channel'] = $record['channel'];
        }
        if (isset($record['level'])) {
            $message['@fields']['level'] = $record['level'];
        }
        if ($this->applicationName) {
            $message['@type'] = $this->applicationName;
        }
        if (isset($record['extra']['server'])) {
            $message['@source_host'] = $record['extra']['server'];
        }
        if (isset($record['extra']['url'])) {
            $message['@source_path'] = $record['extra']['url'];
        }
        if (!empty($record['extra'])) {
            foreach ($record['extra'] as $key => $val) {
                $message['@fields'][$this->extraPrefix . $key] = $val;
            }
        }
        if (!empty($record['context'])) {
            foreach ($record['context'] as $key => $val) {
                $message['@fields'][$this->contextPrefix . $key] = $val;
            }
        }
        return $message;
    }
    protected function formatV1(array $record)
    {
        if (empty($record['datetime'])) {
            $record['datetime'] = \gmdate('c');
        }
        $message = array('@timestamp' => $record['datetime'], '@version' => 1, 'host' => $this->systemName);
        if (isset($record['message'])) {
            $message['message'] = $record['message'];
        }
        if (isset($record['channel'])) {
            $message['type'] = $record['channel'];
            $message['channel'] = $record['channel'];
        }
        if (isset($record['level_name'])) {
            $message['level'] = $record['level_name'];
        }
        if ($this->applicationName) {
            $message['type'] = $this->applicationName;
        }
        if (!empty($record['extra'])) {
            foreach ($record['extra'] as $key => $val) {
                $message[$this->extraPrefix . $key] = $val;
            }
        }
        if (!empty($record['context'])) {
            foreach ($record['context'] as $key => $val) {
                $message[$this->contextPrefix . $key] = $val;
            }
        }
        return $message;
    }
}
Formatter/LineFormatter.php000066600000013060151136154450012004 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Utils;
/**
 * Formats incoming records into a one-line string
 *
 * This is especially useful for logging to files
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @author Christophe Coevoet <stof@notk.org>
 */
class LineFormatter extends NormalizerFormatter
{
    const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
    protected $format;
    protected $allowInlineLineBreaks;
    protected $ignoreEmptyContextAndExtra;
    protected $includeStacktraces;
    /**
     * @param string $format                     The format of the message
     * @param string $dateFormat                 The format of the timestamp: one supported by DateTime::format
     * @param bool   $allowInlineLineBreaks      Whether to allow inline line breaks in log entries
     * @param bool   $ignoreEmptyContextAndExtra
     */
    public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = \false, $ignoreEmptyContextAndExtra = \false)
    {
        $this->format = $format ?: static::SIMPLE_FORMAT;
        $this->allowInlineLineBreaks = $allowInlineLineBreaks;
        $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
        parent::__construct($dateFormat);
    }
    public function includeStacktraces($include = \true)
    {
        $this->includeStacktraces = $include;
        if ($this->includeStacktraces) {
            $this->allowInlineLineBreaks = \true;
        }
    }
    public function allowInlineLineBreaks($allow = \true)
    {
        $this->allowInlineLineBreaks = $allow;
    }
    public function ignoreEmptyContextAndExtra($ignore = \true)
    {
        $this->ignoreEmptyContextAndExtra = $ignore;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        $vars = parent::format($record);
        $output = $this->format;
        foreach ($vars['extra'] as $var => $val) {
            if (\false !== \strpos($output, '%extra.' . $var . '%')) {
                $output = \str_replace('%extra.' . $var . '%', $this->stringify($val), $output);
                unset($vars['extra'][$var]);
            }
        }
        foreach ($vars['context'] as $var => $val) {
            if (\false !== \strpos($output, '%context.' . $var . '%')) {
                $output = \str_replace('%context.' . $var . '%', $this->stringify($val), $output);
                unset($vars['context'][$var]);
            }
        }
        if ($this->ignoreEmptyContextAndExtra) {
            if (empty($vars['context'])) {
                unset($vars['context']);
                $output = \str_replace('%context%', '', $output);
            }
            if (empty($vars['extra'])) {
                unset($vars['extra']);
                $output = \str_replace('%extra%', '', $output);
            }
        }
        foreach ($vars as $var => $val) {
            if (\false !== \strpos($output, '%' . $var . '%')) {
                $output = \str_replace('%' . $var . '%', $this->stringify($val), $output);
            }
        }
        // remove leftover %extra.xxx% and %context.xxx% if any
        if (\false !== \strpos($output, '%')) {
            $output = \preg_replace('/%(?:extra|context)\\..+?%/', '', $output);
        }
        return $output;
    }
    public function formatBatch(array $records)
    {
        $message = '';
        foreach ($records as $record) {
            $message .= $this->format($record);
        }
        return $message;
    }
    public function stringify($value)
    {
        return $this->replaceNewlines($this->convertToString($value));
    }
    protected function normalizeException($e)
    {
        // TODO 2.0 only check for Throwable
        if (!$e instanceof \Exception && !$e instanceof \Throwable) {
            throw new \InvalidArgumentException('Exception/Throwable expected, got ' . \gettype($e) . ' / ' . Utils::getClass($e));
        }
        $previousText = '';
        if ($previous = $e->getPrevious()) {
            do {
                $previousText .= ', ' . Utils::getClass($previous) . '(code: ' . $previous->getCode() . '): ' . $previous->getMessage() . ' at ' . $previous->getFile() . ':' . $previous->getLine();
            } while ($previous = $previous->getPrevious());
        }
        $str = '[object] (' . Utils::getClass($e) . '(code: ' . $e->getCode() . '): ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . $previousText . ')';
        if ($this->includeStacktraces) {
            $str .= "\n[stacktrace]\n" . $e->getTraceAsString() . "\n";
        }
        return $str;
    }
    protected function convertToString($data)
    {
        if (null === $data || \is_bool($data)) {
            return \var_export($data, \true);
        }
        if (\is_scalar($data)) {
            return (string) $data;
        }
        if (\version_compare(\PHP_VERSION, '5.4.0', '>=')) {
            return $this->toJson($data, \true);
        }
        return \str_replace('\\/', '/', $this->toJson($data, \true));
    }
    protected function replaceNewlines($str)
    {
        if ($this->allowInlineLineBreaks) {
            if (0 === \strpos($str, '{')) {
                return \str_replace(array('\\r', '\\n'), array("\r", "\n"), $str);
            }
            return $str;
        }
        return \str_replace(array("\r\n", "\r", "\n"), ' ', $str);
    }
}
Formatter/WildfireFormatter.php000066600000005716151136154450012673 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Serializes a log message according to Wildfire's header requirements
 *
 * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
 * @author Christophe Coevoet <stof@notk.org>
 * @author Kirill chEbba Chebunin <iam@chebba.org>
 */
class WildfireFormatter extends NormalizerFormatter
{
    const TABLE = 'table';
    /**
     * Translates Monolog log levels to Wildfire levels.
     */
    private $logLevels = array(Logger::DEBUG => 'LOG', Logger::INFO => 'INFO', Logger::NOTICE => 'INFO', Logger::WARNING => 'WARN', Logger::ERROR => 'ERROR', Logger::CRITICAL => 'ERROR', Logger::ALERT => 'ERROR', Logger::EMERGENCY => 'ERROR');
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        // Retrieve the line and file if set and remove them from the formatted extra
        $file = $line = '';
        if (isset($record['extra']['file'])) {
            $file = $record['extra']['file'];
            unset($record['extra']['file']);
        }
        if (isset($record['extra']['line'])) {
            $line = $record['extra']['line'];
            unset($record['extra']['line']);
        }
        $record = $this->normalize($record);
        $message = array('message' => $record['message']);
        $handleError = \false;
        if ($record['context']) {
            $message['context'] = $record['context'];
            $handleError = \true;
        }
        if ($record['extra']) {
            $message['extra'] = $record['extra'];
            $handleError = \true;
        }
        if (\count($message) === 1) {
            $message = \reset($message);
        }
        if (isset($record['context'][self::TABLE])) {
            $type = 'TABLE';
            $label = $record['channel'] . ': ' . $record['message'];
            $message = $record['context'][self::TABLE];
        } else {
            $type = $this->logLevels[$record['level']];
            $label = $record['channel'];
        }
        // Create JSON object describing the appearance of the message in the console
        $json = $this->toJson(array(array('Type' => $type, 'File' => $file, 'Line' => $line, 'Label' => $label), $message), $handleError);
        // The message itself is a serialization of the above JSON object + it's length
        return \sprintf('%s|%s|', \strlen($json), $json);
    }
    public function formatBatch(array $records)
    {
        throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter');
    }
    protected function normalize($data, $depth = 0)
    {
        if (\is_object($data) && !$data instanceof \DateTime) {
            return $data;
        }
        return parent::normalize($data, $depth);
    }
}
Formatter/HtmlFormatter.php000066600000010760151136154450012025 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Logger;
use AIOSEO\Vendor\Monolog\Utils;
/**
 * Formats incoming records into an HTML table
 *
 * This is especially useful for html email logging
 *
 * @author Tiago Brito <tlfbrito@gmail.com>
 */
class HtmlFormatter extends NormalizerFormatter
{
    /**
     * Translates Monolog log levels to html color priorities.
     */
    protected $logLevels = array(Logger::DEBUG => '#cccccc', Logger::INFO => '#468847', Logger::NOTICE => '#3a87ad', Logger::WARNING => '#c09853', Logger::ERROR => '#f0ad4e', Logger::CRITICAL => '#FF7708', Logger::ALERT => '#C12A19', Logger::EMERGENCY => '#000000');
    /**
     * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
     */
    public function __construct($dateFormat = null)
    {
        parent::__construct($dateFormat);
    }
    /**
     * Creates an HTML table row
     *
     * @param  string $th       Row header content
     * @param  string $td       Row standard cell content
     * @param  bool   $escapeTd false if td content must not be html escaped
     * @return string
     */
    protected function addRow($th, $td = ' ', $escapeTd = \true)
    {
        $th = \htmlspecialchars($th, \ENT_NOQUOTES, 'UTF-8');
        if ($escapeTd) {
            $td = '<pre>' . \htmlspecialchars($td, \ENT_NOQUOTES, 'UTF-8') . '</pre>';
        }
        return "<tr style=\"padding: 4px;text-align: left;\">\n<th style=\"vertical-align: top;background: #ccc;color: #000\" width=\"100\">{$th}:</th>\n<td style=\"padding: 4px;text-align: left;vertical-align: top;background: #eee;color: #000\">" . $td . "</td>\n</tr>";
    }
    /**
     * Create a HTML h1 tag
     *
     * @param  string $title Text to be in the h1
     * @param  int    $level Error level
     * @return string
     */
    protected function addTitle($title, $level)
    {
        $title = \htmlspecialchars($title, \ENT_NOQUOTES, 'UTF-8');
        return '<h1 style="background: ' . $this->logLevels[$level] . ';color: #ffffff;padding: 5px;" class="monolog-output">' . $title . '</h1>';
    }
    /**
     * Formats a log record.
     *
     * @param  array $record A record to format
     * @return mixed The formatted record
     */
    public function format(array $record)
    {
        $output = $this->addTitle($record['level_name'], $record['level']);
        $output .= '<table cellspacing="1" width="100%" class="monolog-output">';
        $output .= $this->addRow('Message', (string) $record['message']);
        $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat));
        $output .= $this->addRow('Channel', $record['channel']);
        if ($record['context']) {
            $embeddedTable = '<table cellspacing="1" width="100%">';
            foreach ($record['context'] as $key => $value) {
                $embeddedTable .= $this->addRow($key, $this->convertToString($value));
            }
            $embeddedTable .= '</table>';
            $output .= $this->addRow('Context', $embeddedTable, \false);
        }
        if ($record['extra']) {
            $embeddedTable = '<table cellspacing="1" width="100%">';
            foreach ($record['extra'] as $key => $value) {
                $embeddedTable .= $this->addRow($key, $this->convertToString($value));
            }
            $embeddedTable .= '</table>';
            $output .= $this->addRow('Extra', $embeddedTable, \false);
        }
        return $output . '</table>';
    }
    /**
     * Formats a set of log records.
     *
     * @param  array $records A set of records to format
     * @return mixed The formatted set of records
     */
    public function formatBatch(array $records)
    {
        $message = '';
        foreach ($records as $record) {
            $message .= $this->format($record);
        }
        return $message;
    }
    protected function convertToString($data)
    {
        if (null === $data || \is_scalar($data)) {
            return (string) $data;
        }
        $data = $this->normalize($data);
        if (\version_compare(\PHP_VERSION, '5.4.0', '>=')) {
            return Utils::jsonEncode($data, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE, \true);
        }
        return \str_replace('\\/', '/', Utils::jsonEncode($data, null, \true));
    }
}
Formatter/JsonFormatter.php000066600000012207151136154450012030 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use Exception;
use AIOSEO\Vendor\Monolog\Utils;
use Throwable;
/**
 * Encodes whatever record data is passed to it as json
 *
 * This can be useful to log to databases or remote APIs
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class JsonFormatter extends NormalizerFormatter
{
    const BATCH_MODE_JSON = 1;
    const BATCH_MODE_NEWLINES = 2;
    protected $batchMode;
    protected $appendNewline;
    /**
     * @var bool
     */
    protected $includeStacktraces = \false;
    /**
     * @param int $batchMode
     * @param bool $appendNewline
     */
    public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = \true)
    {
        $this->batchMode = $batchMode;
        $this->appendNewline = $appendNewline;
    }
    /**
     * The batch mode option configures the formatting style for
     * multiple records. By default, multiple records will be
     * formatted as a JSON-encoded array. However, for
     * compatibility with some API endpoints, alternative styles
     * are available.
     *
     * @return int
     */
    public function getBatchMode()
    {
        return $this->batchMode;
    }
    /**
     * True if newlines are appended to every formatted record
     *
     * @return bool
     */
    public function isAppendingNewlines()
    {
        return $this->appendNewline;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        return $this->toJson($this->normalize($record), \true) . ($this->appendNewline ? "\n" : '');
    }
    /**
     * {@inheritdoc}
     */
    public function formatBatch(array $records)
    {
        switch ($this->batchMode) {
            case static::BATCH_MODE_NEWLINES:
                return $this->formatBatchNewlines($records);
            case static::BATCH_MODE_JSON:
            default:
                return $this->formatBatchJson($records);
        }
    }
    /**
     * @param bool $include
     */
    public function includeStacktraces($include = \true)
    {
        $this->includeStacktraces = $include;
    }
    /**
     * Return a JSON-encoded array of records.
     *
     * @param  array  $records
     * @return string
     */
    protected function formatBatchJson(array $records)
    {
        return $this->toJson($this->normalize($records), \true);
    }
    /**
     * Use new lines to separate records instead of a
     * JSON-encoded array.
     *
     * @param  array  $records
     * @return string
     */
    protected function formatBatchNewlines(array $records)
    {
        $instance = $this;
        $oldNewline = $this->appendNewline;
        $this->appendNewline = \false;
        \array_walk($records, function (&$value, $key) use($instance) {
            $value = $instance->format($value);
        });
        $this->appendNewline = $oldNewline;
        return \implode("\n", $records);
    }
    /**
     * Normalizes given $data.
     *
     * @param mixed $data
     *
     * @return mixed
     */
    protected function normalize($data, $depth = 0)
    {
        if ($depth > 9) {
            return 'Over 9 levels deep, aborting normalization';
        }
        if (\is_array($data)) {
            $normalized = array();
            $count = 1;
            foreach ($data as $key => $value) {
                if ($count++ > 1000) {
                    $normalized['...'] = 'Over 1000 items (' . \count($data) . ' total), aborting normalization';
                    break;
                }
                $normalized[$key] = $this->normalize($value, $depth + 1);
            }
            return $normalized;
        }
        if ($data instanceof Exception || $data instanceof Throwable) {
            return $this->normalizeException($data);
        }
        if (\is_resource($data)) {
            return parent::normalize($data);
        }
        return $data;
    }
    /**
     * Normalizes given exception with or without its own stack trace based on
     * `includeStacktraces` property.
     *
     * @param Exception|Throwable $e
     *
     * @return array
     */
    protected function normalizeException($e)
    {
        // TODO 2.0 only check for Throwable
        if (!$e instanceof Exception && !$e instanceof Throwable) {
            throw new \InvalidArgumentException('Exception/Throwable expected, got ' . \gettype($e) . ' / ' . Utils::getClass($e));
        }
        $data = array('class' => Utils::getClass($e), 'message' => $e->getMessage(), 'code' => (int) $e->getCode(), 'file' => $e->getFile() . ':' . $e->getLine());
        if ($this->includeStacktraces) {
            $trace = $e->getTrace();
            foreach ($trace as $frame) {
                if (isset($frame['file'])) {
                    $data['trace'][] = $frame['file'] . ':' . $frame['line'];
                }
            }
        }
        if ($previous = $e->getPrevious()) {
            $data['previous'] = $this->normalizeException($previous);
        }
        return $data;
    }
}
Formatter/FormatterInterface.php000066600000001437151136154450013022 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

/**
 * Interface for formatters
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
interface FormatterInterface
{
    /**
     * Formats a log record.
     *
     * @param  array $record A record to format
     * @return mixed The formatted record
     */
    public function format(array $record);
    /**
     * Formats a set of log records.
     *
     * @param  array $records A set of records to format
     * @return mixed The formatted set of records
     */
    public function formatBatch(array $records);
}
Formatter/ElasticaFormatter.php000066600000003477151136154450012655 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Elastica\Document;
/**
 * Format a log message into an Elastica Document
 *
 * @author Jelle Vink <jelle.vink@gmail.com>
 */
class ElasticaFormatter extends NormalizerFormatter
{
    /**
     * @var string Elastic search index name
     */
    protected $index;
    /**
     * @var string Elastic search document type
     */
    protected $type;
    /**
     * @param string $index Elastic Search index name
     * @param string $type  Elastic Search document type
     */
    public function __construct($index, $type)
    {
        // elasticsearch requires a ISO 8601 format date with optional millisecond precision.
        parent::__construct('Y-m-d\\TH:i:s.uP');
        $this->index = $index;
        $this->type = $type;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        $record = parent::format($record);
        return $this->getDocument($record);
    }
    /**
     * Getter index
     * @return string
     */
    public function getIndex()
    {
        return $this->index;
    }
    /**
     * Getter type
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }
    /**
     * Convert a log message into an Elastica Document
     *
     * @param  array    $record Log message
     * @return Document
     */
    protected function getDocument($record)
    {
        $document = new Document();
        $document->setData($record);
        $document->setType($this->type);
        $document->setIndex($this->index);
        return $document;
    }
}
Formatter/ChromePHPFormatter.php000066600000003574151136154450012713 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

use AIOSEO\Vendor\Monolog\Logger;
/**
 * Formats a log message according to the ChromePHP array format
 *
 * @author Christophe Coevoet <stof@notk.org>
 */
class ChromePHPFormatter implements FormatterInterface
{
    /**
     * Translates Monolog log levels to Wildfire levels.
     */
    private $logLevels = array(Logger::DEBUG => 'log', Logger::INFO => 'info', Logger::NOTICE => 'info', Logger::WARNING => 'warn', Logger::ERROR => 'error', Logger::CRITICAL => 'error', Logger::ALERT => 'error', Logger::EMERGENCY => 'error');
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        // Retrieve the line and file if set and remove them from the formatted extra
        $backtrace = 'unknown';
        if (isset($record['extra']['file'], $record['extra']['line'])) {
            $backtrace = $record['extra']['file'] . ' : ' . $record['extra']['line'];
            unset($record['extra']['file'], $record['extra']['line']);
        }
        $message = array('message' => $record['message']);
        if ($record['context']) {
            $message['context'] = $record['context'];
        }
        if ($record['extra']) {
            $message['extra'] = $record['extra'];
        }
        if (\count($message) === 1) {
            $message = \reset($message);
        }
        return array($record['channel'], $message, $backtrace, $this->logLevels[$record['level']]);
    }
    public function formatBatch(array $records)
    {
        $formatted = array();
        foreach ($records as $record) {
            $formatted[] = $this->format($record);
        }
        return $formatted;
    }
}
Formatter/FlowdockFormatter.php000066600000004475151136154450012677 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

/**
 * formats the record to be used in the FlowdockHandler
 *
 * @author Dominik Liebler <liebler.dominik@gmail.com>
 */
class FlowdockFormatter implements FormatterInterface
{
    /**
     * @var string
     */
    private $source;
    /**
     * @var string
     */
    private $sourceEmail;
    /**
     * @param string $source
     * @param string $sourceEmail
     */
    public function __construct($source, $sourceEmail)
    {
        $this->source = $source;
        $this->sourceEmail = $sourceEmail;
    }
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        $tags = array('#logs', '#' . \strtolower($record['level_name']), '#' . $record['channel']);
        foreach ($record['extra'] as $value) {
            $tags[] = '#' . $value;
        }
        $subject = \sprintf('in %s: %s - %s', $this->source, $record['level_name'], $this->getShortMessage($record['message']));
        $record['flowdock'] = array('source' => $this->source, 'from_address' => $this->sourceEmail, 'subject' => $subject, 'content' => $record['message'], 'tags' => $tags, 'project' => $this->source);
        return $record;
    }
    /**
     * {@inheritdoc}
     */
    public function formatBatch(array $records)
    {
        $formatted = array();
        foreach ($records as $record) {
            $formatted[] = $this->format($record);
        }
        return $formatted;
    }
    /**
     * @param string $message
     *
     * @return string
     */
    public function getShortMessage($message)
    {
        static $hasMbString;
        if (null === $hasMbString) {
            $hasMbString = \function_exists('mb_strlen');
        }
        $maxLength = 45;
        if ($hasMbString) {
            if (\mb_strlen($message, 'UTF-8') > $maxLength) {
                $message = \mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...';
            }
        } else {
            if (\strlen($message) > $maxLength) {
                $message = \substr($message, 0, $maxLength - 4) . ' ...';
            }
        }
        return $message;
    }
}
Formatter/ScalarFormatter.php000066600000002034151136154450012321 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog\Formatter;

/**
 * Formats data into an associative array of scalar values.
 * Objects and arrays will be JSON encoded.
 *
 * @author Andrew Lawson <adlawson@gmail.com>
 */
class ScalarFormatter extends NormalizerFormatter
{
    /**
     * {@inheritdoc}
     */
    public function format(array $record)
    {
        foreach ($record as $key => $value) {
            $record[$key] = $this->normalizeValue($value);
        }
        return $record;
    }
    /**
     * @param  mixed $value
     * @return mixed
     */
    protected function normalizeValue($value)
    {
        $normalized = $this->normalize($value);
        if (\is_array($normalized) || \is_object($normalized)) {
            return $this->toJson($normalized, \true);
        }
        return $normalized;
    }
}
Registry.php000066600000007702151136154450007104 0ustar00<?php

/*
 * This file is part of the Monolog package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace AIOSEO\Vendor\Monolog;

use InvalidArgumentException;
/**
 * Monolog log registry
 *
 * Allows to get `Logger` instances in the global scope
 * via static method calls on this class.
 *
 * <code>
 * $application = new Monolog\Logger('application');
 * $api = new Monolog\Logger('api');
 *
 * Monolog\Registry::addLogger($application);
 * Monolog\Registry::addLogger($api);
 *
 * function testLogger()
 * {
 *     Monolog\Registry::api()->addError('Sent to $api Logger instance');
 *     Monolog\Registry::application()->addError('Sent to $application Logger instance');
 * }
 * </code>
 *
 * @author Tomas Tatarko <tomas@tatarko.sk>
 */
class Registry
{
    /**
     * List of all loggers in the registry (by named indexes)
     *
     * @var Logger[]
     */
    private static $loggers = array();
    /**
     * Adds new logging channel to the registry
     *
     * @param  Logger                    $logger    Instance of the logging channel
     * @param  string|null               $name      Name of the logging channel ($logger->getName() by default)
     * @param  bool                      $overwrite Overwrite instance in the registry if the given name already exists?
     * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists
     */
    public static function addLogger(Logger $logger, $name = null, $overwrite = \false)
    {
        $name = $name ?: $logger->getName();
        if (isset(self::$loggers[$name]) && !$overwrite) {
            throw new InvalidArgumentException('Logger with the given name already exists');
        }
        self::$loggers[$name] = $logger;
    }
    /**
     * Checks if such logging channel exists by name or instance
     *
     * @param string|Logger $logger Name or logger instance
     */
    public static function hasLogger($logger)
    {
        if ($logger instanceof Logger) {
            $index = \array_search($logger, self::$loggers, \true);
            return \false !== $index;
        } else {
            return isset(self::$loggers[$logger]);
        }
    }
    /**
     * Removes instance from registry by name or instance
     *
     * @param string|Logger $logger Name or logger instance
     */
    public static function removeLogger($logger)
    {
        if ($logger instanceof Logger) {
            if (\false !== ($idx = \array_search($logger, self::$loggers, \true))) {
                unset(self::$loggers[$idx]);
            }
        } else {
            unset(self::$loggers[$logger]);
        }
    }
    /**
     * Clears the registry
     */
    public static function clear()
    {
        self::$loggers = array();
    }
    /**
     * Gets Logger instance from the registry
     *
     * @param  string                    $name Name of the requested Logger instance
     * @throws \InvalidArgumentException If named Logger instance is not in the registry
     * @return Logger                    Requested instance of Logger
     */
    public static function getInstance($name)
    {
        if (!isset(self::$loggers[$name])) {
            throw new InvalidArgumentException(\sprintf('Requested "%s" logger instance is not in the registry', $name));
        }
        return self::$loggers[$name];
    }
    /**
     * Gets Logger instance from the registry via static method call
     *
     * @param  string                    $name      Name of the requested Logger instance
     * @param  array                     $arguments Arguments passed to static method call
     * @throws \InvalidArgumentException If named Logger instance is not in the registry
     * @return Logger                    Requested instance of Logger
     */
    public static function __callStatic($name, $arguments)
    {
        return self::getInstance($name);
    }
}