mirror of
https://github.com/ledccn/IYUUPlus.git
synced 2024-09-20 07:05:28 +00:00
add announce patcher for qBittorrent 4.4+
This commit is contained in:
parent
83a16b7eb6
commit
af3bca56b0
|
@ -28,7 +28,7 @@
|
|||
"workerman/webman-framework": "^1.0",
|
||||
"monolog/monolog": "^2.0",
|
||||
"vlucas/phpdotenv": "5.1.0",
|
||||
"rhilip/bencode": "^1.1",
|
||||
"rhilip/bencode": "^2.1",
|
||||
"workerman/crontab": "^1.0",
|
||||
"curl/curl": "^2.3",
|
||||
"ext-posix": "*",
|
||||
|
|
0
runtime/.gitignore
vendored
Normal file → Executable file
0
runtime/.gitignore
vendored
Normal file → Executable file
0
runtime/logs/.gitignore
vendored
Normal file → Executable file
0
runtime/logs/.gitignore
vendored
Normal file → Executable file
0
runtime/views/.gitignore
vendored
Normal file → Executable file
0
runtime/views/.gitignore
vendored
Normal file → Executable file
|
@ -4,6 +4,8 @@ namespace IYUU\Reseed;
|
|||
use app\domain\ConfigParser\Move as domainMove;
|
||||
use app\domain\Crontab as domainCrontab;
|
||||
use IYUU\Client\ClientException;
|
||||
use Rhilip\Bencode\Bencode;
|
||||
use Rhilip\Bencode\ParseException;
|
||||
|
||||
class MoveTorrent extends AutoReseed
|
||||
{
|
||||
|
@ -97,6 +99,13 @@ class MoveTorrent extends AutoReseed
|
|||
echo "clients_".$k." 全部转移成功,本次无需转移!".PHP_EOL.PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
$qBittorrent_version_lg_4_4 = false;
|
||||
if ($v['type'] == 'qBittorrent') {
|
||||
$arr = preg_split(ltrim(static::getRpc($k)->appVersion(), "v"), ".", 3, PREG_SPLIT_NO_EMPTY);
|
||||
if ($arr[0] > '4' && $arr[1] > 4) {
|
||||
$qBittorrent_version_lg_4_4 = true;
|
||||
}
|
||||
}
|
||||
//遍历当前客户端种子
|
||||
foreach ($infohash_Dir as $info_hash => $downloadDir) {
|
||||
// 调用路径过滤器、选择器
|
||||
|
@ -115,6 +124,8 @@ class MoveTorrent extends AutoReseed
|
|||
// 种子目录:脚本要能够读取到
|
||||
$path = self::$links[$k]['BT_backup'];
|
||||
$torrentPath = '';
|
||||
$fast_resumePath = '';
|
||||
$needPatchTorrent = $qBittorrent_version_lg_4_4;
|
||||
// 待删除种子
|
||||
$torrentDelete = '';
|
||||
// 获取种子文件的实际路径
|
||||
|
@ -135,17 +146,52 @@ class MoveTorrent extends AutoReseed
|
|||
die("clients_".$k." IYUUPlus内下载器未设置种子目录,无法完成转移!");
|
||||
}
|
||||
$torrentPath = $path .DS. $info_hash . '.torrent';
|
||||
$fast_resumePath = $path .DS. $info_hash . '.fastresume';
|
||||
$torrentDelete = $info_hash;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!is_file($torrentPath)) {
|
||||
if (!is_file($fast_resumePath)) {
|
||||
echo $help_msg;
|
||||
die("clients_" . $k . " 的`{$move[$info_hash]['name']}`,resume文件`{$fast_resumePath}`不存在,无法完成转移!");
|
||||
}
|
||||
echo $help_msg;
|
||||
die("clients_".$k." 的`{$move[$info_hash]['name']}`,种子文件`{$torrentPath}`不存在,无法完成转移!");
|
||||
}
|
||||
echo '存在种子:'.$torrentPath.PHP_EOL;
|
||||
$torrent = file_get_contents($torrentPath);
|
||||
$parsed_torrent = [];
|
||||
try {
|
||||
global $parsed_torrent;
|
||||
$parsed_torrent = Bencode::decode($torrent);
|
||||
if (empty($parsed_torrent['announce'])) {
|
||||
$needPatchTorrent = true;
|
||||
}
|
||||
} catch (ParseException $e) {}
|
||||
if ($needPatchTorrent) {
|
||||
echo '未发现tracker信息,尝试补充tracker信息...'.PHP_EOL;
|
||||
if (empty($parsed_torrent)) {
|
||||
die("clients_".$k." 的`{$move[$info_hash]['name']}`,种子文件`{$torrentPath}`解析失败,无法完成转移!");
|
||||
}
|
||||
if (empty($parsed_torrent['announce'])) {
|
||||
try {
|
||||
$parsed_fast_resume = Bencode::load($fast_resumePath);
|
||||
$trackers = $parsed_fast_resume['trackers'];
|
||||
if (count($trackers) > 0 && !empty($trackers[0])) {
|
||||
if (is_array($trackers[0]) && count($trackers[0]) > 0 && !empty($trackers[0][0])) {
|
||||
$parsed_torrent['announce'] = $trackers[0][0];
|
||||
}
|
||||
} else {
|
||||
die("clients_".$k." 的`{$move[$info_hash]['name']}`,resume文件`{$fast_resumePath}`不包含tracker地址,无法完成转移!");
|
||||
}
|
||||
} catch (ParseException $e) {
|
||||
die("clients_".$k." 的`{$move[$info_hash]['name']}`,resume文件`{$fast_resumePath}`解析失败`{$e->getMessage()}`,无法完成转移!");
|
||||
}
|
||||
}
|
||||
$torrent = Bencode::encode($parsed_torrent);
|
||||
}
|
||||
// 正式开始转移
|
||||
echo "种子已推送给下载器,正在转移做种...".PHP_EOL;
|
||||
|
||||
|
@ -166,7 +212,7 @@ class MoveTorrent extends AutoReseed
|
|||
/**
|
||||
* 转移成功的种子写日志
|
||||
*/
|
||||
$log = $info_hash.PHP_EOL.$torrentPath.PHP_EOL.$downloadDir.PHP_EOL.PHP_EOL;
|
||||
$log = $info_hash.PHP_EOL.$torrentPath.PHP_EOL.$downloadDir.PHP_EOL.PHP_EOL;
|
||||
if ($ret) {
|
||||
//转移成功时,删除做种,不删资源
|
||||
if (isset(self::$conf['delete_torrent']) && self::$conf['delete_torrent']) {
|
||||
|
@ -180,7 +226,7 @@ class MoveTorrent extends AutoReseed
|
|||
// 失败的种子
|
||||
static::wLog($log, 'MoveError'.$k);
|
||||
static::$wechatMsg['MoveError']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
|
@ -4,4 +4,4 @@
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97::getLoader();
|
||||
return ComposerAutoloaderInit4dfbd30c142d9169bdd5809ad6beb22e::getLoader();
|
||||
|
|
157
vendor/composer/ClassLoader.php
vendored
157
vendor/composer/ClassLoader.php
vendored
|
@ -37,57 +37,130 @@ namespace Composer\Autoload;
|
|||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
|
@ -102,9 +175,11 @@ class ClassLoader
|
|||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
|
@ -147,11 +222,13 @@ class ClassLoader
|
|||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
|
@ -195,8 +272,10 @@ class ClassLoader
|
|||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
|
@ -211,10 +290,12 @@ class ClassLoader
|
|||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
|
@ -234,6 +315,8 @@ class ClassLoader
|
|||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
|
@ -256,6 +339,8 @@ class ClassLoader
|
|||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
|
@ -276,6 +361,8 @@ class ClassLoader
|
|||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
|
@ -296,25 +383,44 @@ class ClassLoader
|
|||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
|
@ -323,6 +429,8 @@ class ClassLoader
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,6 +475,21 @@ class ClassLoader
|
|||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
|
@ -438,6 +561,10 @@ class ClassLoader
|
|||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
|
|
337
vendor/composer/InstalledVersions.php
vendored
Normal file
337
vendor/composer/InstalledVersions.php
vendored
Normal file
|
@ -0,0 +1,337 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* 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 Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
private static $installed;
|
||||
private static $canGetVendors;
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints($constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
2
vendor/composer/autoload_classmap.php
vendored
2
vendor/composer/autoload_classmap.php
vendored
|
@ -7,6 +7,8 @@ $baseDir = dirname($vendorDir);
|
|||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
|
|
4
vendor/composer/autoload_files.php
vendored
4
vendor/composer/autoload_files.php
vendored
|
@ -6,9 +6,9 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'da5b71a9ad8465d48da441e2f36823b6' => $baseDir . '/support/helpers.php',
|
||||
);
|
||||
|
|
5
vendor/composer/autoload_psr4.php
vendored
5
vendor/composer/autoload_psr4.php
vendored
|
@ -6,12 +6,17 @@ $vendorDir = dirname(dirname(__FILE__));
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'support\\' => array($vendorDir . '/workerman/webman-framework/src/support'),
|
||||
'Workerman\\Crontab\\' => array($vendorDir . '/workerman/crontab/src'),
|
||||
'Workerman\\' => array($vendorDir . '/workerman/workerman'),
|
||||
'Webman\\' => array($vendorDir . '/workerman/webman-framework/src'),
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
|
||||
'Support\\View\\' => array($vendorDir . '/workerman/webman-framework/src/support/view'),
|
||||
'Support\\Exception\\' => array($vendorDir . '/workerman/webman-framework/src/support/exception'),
|
||||
'Support\\Bootstrap\\' => array($vendorDir . '/workerman/webman-framework/src/support/bootstrap'),
|
||||
'Support\\' => array($vendorDir . '/workerman/webman-framework/src/support'),
|
||||
'Rhilip\\Bencode\\' => array($vendorDir . '/rhilip/bencode/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
|
|
20
vendor/composer/autoload_real.php
vendored
20
vendor/composer/autoload_real.php
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97
|
||||
class ComposerAutoloaderInit4dfbd30c142d9169bdd5809ad6beb22e
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -22,15 +22,17 @@ class ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97', 'loadClassLoader'));
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit4dfbd30c142d9169bdd5809ad6beb22e', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit4dfbd30c142d9169bdd5809ad6beb22e', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
|
@ -51,19 +53,19 @@ class ComposerAutoloaderInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::$files;
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire687dbaa10a29b36f43b2c9b7d90f4c97($fileIdentifier, $file);
|
||||
composerRequire4dfbd30c142d9169bdd5809ad6beb22e($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire687dbaa10a29b36f43b2c9b7d90f4c97($fileIdentifier, $file)
|
||||
function composerRequire4dfbd30c142d9169bdd5809ad6beb22e($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
|
44
vendor/composer/autoload_static.php
vendored
44
vendor/composer/autoload_static.php
vendored
|
@ -4,17 +4,21 @@
|
|||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
||||
class ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e
|
||||
{
|
||||
public static $files = array (
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'da5b71a9ad8465d48da441e2f36823b6' => __DIR__ . '/../..' . '/support/helpers.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
's' =>
|
||||
array (
|
||||
'support\\' => 8,
|
||||
),
|
||||
'W' =>
|
||||
array (
|
||||
'Workerman\\Crontab\\' => 18,
|
||||
|
@ -26,6 +30,10 @@ class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Polyfill\\Ctype\\' => 23,
|
||||
'Support\\View\\' => 13,
|
||||
'Support\\Exception\\' => 18,
|
||||
'Support\\Bootstrap\\' => 18,
|
||||
'Support\\' => 8,
|
||||
),
|
||||
'R' =>
|
||||
array (
|
||||
|
@ -61,6 +69,10 @@ class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'support\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support',
|
||||
),
|
||||
'Workerman\\Crontab\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/crontab/src',
|
||||
|
@ -85,6 +97,22 @@ class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
|
||||
),
|
||||
'Support\\View\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support/view',
|
||||
),
|
||||
'Support\\Exception\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support/exception',
|
||||
),
|
||||
'Support\\Bootstrap\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support/bootstrap',
|
||||
),
|
||||
'Support\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/workerman/webman-framework/src/support',
|
||||
),
|
||||
'Rhilip\\Bencode\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/rhilip/bencode/src',
|
||||
|
@ -139,6 +167,8 @@ class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
|
@ -147,10 +177,10 @@ class ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97
|
|||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::$prefixesPsr0;
|
||||
$loader->classMap = ComposerStaticInit687dbaa10a29b36f43b2c9b7d90f4c97::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::$prefixesPsr0;
|
||||
$loader->classMap = ComposerStaticInit4dfbd30c142d9169bdd5809ad6beb22e::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
|
2188
vendor/composer/installed.json
vendored
2188
vendor/composer/installed.json
vendored
File diff suppressed because it is too large
Load Diff
175
vendor/composer/installed.php
vendored
Normal file
175
vendor/composer/installed.php
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
<?php return array(
|
||||
'root' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'db7e63dc33f2ffe163b45bf7cf138e07c4edf4a3',
|
||||
'name' => 'workerman/webman',
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'curl/curl' => array(
|
||||
'pretty_version' => '2.3.3',
|
||||
'version' => '2.3.3.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../curl/curl',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ec22ad27dead47093f0944f5e651df4b12846f5a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'graham-campbell/result-type' => array(
|
||||
'pretty_version' => 'v1.0.4',
|
||||
'version' => '1.0.4.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../graham-campbell/result-type',
|
||||
'aliases' => array(),
|
||||
'reference' => '0690bde05318336c7221785f2a932467f98b64ca',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ledccn/bittorrentclient' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ledccn/bittorrentclient',
|
||||
'aliases' => array(
|
||||
0 => '9999999-dev',
|
||||
),
|
||||
'reference' => '9aead6a8750befb518adec30dd27dc92d3ec88fa',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'monolog/monolog' => array(
|
||||
'pretty_version' => '2.4.0',
|
||||
'version' => '2.4.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../monolog/monolog',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd7fd7450628561ba697b7097d86db72662f54aef',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nikic/fast-route' => array(
|
||||
'pretty_version' => 'v1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/fast-route',
|
||||
'aliases' => array(),
|
||||
'reference' => '181d480e08d9476e61381e04a71b34dc0432e812',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpoption/phpoption' => array(
|
||||
'pretty_version' => '1.8.1',
|
||||
'version' => '1.8.1.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpoption/phpoption',
|
||||
'aliases' => array(),
|
||||
'reference' => 'eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '2.0.2',
|
||||
'version' => '2.0.2.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/container',
|
||||
'aliases' => array(),
|
||||
'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log' => array(
|
||||
'pretty_version' => '1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '1.0.0 || 2.0.0 || 3.0.0',
|
||||
),
|
||||
),
|
||||
'rhilip/bencode' => array(
|
||||
'pretty_version' => 'v2.1.1',
|
||||
'version' => '2.1.1.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../rhilip/bencode',
|
||||
'aliases' => array(),
|
||||
'reference' => '38a445a04db54034a155b4a40985fec715b607bc',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.25.0',
|
||||
'version' => '1.25.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'reference' => '30885182c981ab175d4d034db0f6f469898070ab',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.25.0',
|
||||
'version' => '1.25.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'reference' => '0abb51d2f102e00a4eefcf46ba7fec406d245825',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.25.0',
|
||||
'version' => '1.25.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'reference' => '4407588e0d3f1f52efb65fbe92babe41f37fe50c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'vlucas/phpdotenv' => array(
|
||||
'pretty_version' => 'v5.1.0',
|
||||
'version' => '5.1.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../vlucas/phpdotenv',
|
||||
'aliases' => array(),
|
||||
'reference' => '448c76d7a9e30c341ff5bc367a923af74ae18467',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/crontab' => array(
|
||||
'pretty_version' => 'v1.0.3',
|
||||
'version' => '1.0.3.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/crontab',
|
||||
'aliases' => array(),
|
||||
'reference' => '2a2b9f8c2dbfa47ad16599a10f584dd09863bebd',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/webman' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'db7e63dc33f2ffe163b45bf7cf138e07c4edf4a3',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/webman-framework' => array(
|
||||
'pretty_version' => 'v1.3.9',
|
||||
'version' => '1.3.9.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/webman-framework',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ffadeae56857ef4d6029d4dff5f763013083ca35',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/workerman' => array(
|
||||
'pretty_version' => 'v4.0.33',
|
||||
'version' => '4.0.33.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/workerman',
|
||||
'aliases' => array(),
|
||||
'reference' => '7e7a95d38abf2a878438070aa8934029059d6866',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
26
vendor/composer/platform_check.php
vendored
Normal file
26
vendor/composer/platform_check.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70400)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
59
vendor/curl/curl/.github/workflows/tests.yml
vendored
Normal file
59
vendor/curl/curl/.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
name: Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
DEFAULT_COMPOSER_FLAGS: "--prefer-dist --no-interaction"
|
||||
CC_TEST_REPORTER_ID: 40d4890deed3bca8888c04ca67b9768edf11d7a089d2960977997791daea31f6
|
||||
jobs:
|
||||
phpunit:
|
||||
name: PHP ${{ matrix.php }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
|
||||
steps:
|
||||
## checkout the repoistory §
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build server image
|
||||
run: docker build . -t localserver
|
||||
working-directory: ./tests/server
|
||||
|
||||
- name: Run test server
|
||||
run: docker run -d -p 1234:80 localserver
|
||||
|
||||
## Install php
|
||||
- name: Install PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: curl, mbstring, imagick, gd
|
||||
ini-values: date.timezone='UTC'
|
||||
coverage: xdebug
|
||||
|
||||
## install composer
|
||||
- name: Install dependencies
|
||||
run: composer install $DEFAULT_COMPOSER_FLAGS
|
||||
|
||||
## run unit tests
|
||||
- name: PHP Unit tests for PHP
|
||||
run: vendor/bin/phpunit --verbose --configuration actions.phpunit.xml
|
||||
if: matrix.php == '8.0' || matrix.php == '7.4' || matrix.php == '7.3' || matrix.php == '7.2' || matrix.php == '7.0' || matrix.php == '5.6'
|
||||
|
||||
## unit test with coverage
|
||||
- name: PHP Unit tests for PHP 7.1
|
||||
run: vendor/bin/phpunit --verbose --coverage-clover=clover.xml --configuration actions.phpunit.xml
|
||||
if: matrix.php == '7.1'
|
||||
|
||||
## coverage
|
||||
- name: Code coverage
|
||||
run: |
|
||||
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||
chmod +x ./cc-test-reporter
|
||||
./cc-test-reporter after-build -t clover
|
||||
if: matrix.php == '7.1'
|
||||
continue-on-error: true # if is fork
|
33
vendor/curl/curl/CHANGELOG.md
vendored
Normal file
33
vendor/curl/curl/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# CHANGELOG
|
||||
|
||||
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 2.4.0 (in progress)
|
||||
|
||||
+ [#61](https://github.com/php-mod/curl/issues/61) Adjust user agent version to latest version.
|
||||
+ [#74](https://github.com/php-mod/curl/pull/75) Fixed PHPDoc Block, Added more Unit Tests.
|
||||
+ Added GitHub Actions Tests (from 5.6 - 8.0)
|
||||
|
||||
## 2.3.1 (21. January 2021)
|
||||
|
||||
+ Supports PHP8
|
||||
|
||||
## 2.3.0 (19. March 2019)
|
||||
|
||||
+ add asJson option (#67)
|
||||
|
||||
## 2.2.0 (4. December 2018)
|
||||
|
||||
+ Added some getters.
|
||||
|
||||
## 2.1.0 (17. November 2018)
|
||||
|
||||
+ CurlFile fix
|
||||
+ This is not tested, but we are facing the same problem with CurlFile Uploads (https://github.com/php-mod/curl/issues/46) - This *should* do the trick.
|
||||
+ Update README.md
|
||||
+ cs fix
|
||||
|
||||
## 2.0.0 (15. November 2018)
|
||||
|
||||
+ Drop php 5.3, 5.4 and 5.5 support.
|
||||
+ Use Gitlab CI instead of Travis CI.
|
7
vendor/curl/curl/README.md
vendored
7
vendor/curl/curl/README.md
vendored
|
@ -2,8 +2,14 @@
|
|||
|
||||
This library provides an object-oriented wrapper of the PHP cURL extension.
|
||||
|
||||
[![Maintainability](https://api.codeclimate.com/v1/badges/6c34bb31f3eb6df36c7d/maintainability)](https://codeclimate.com/github/php-mod/curl/maintainability)
|
||||
[![Test Coverage](https://api.codeclimate.com/v1/badges/6c34bb31f3eb6df36c7d/test_coverage)](https://codeclimate.com/github/php-mod/curl/test_coverage)
|
||||
[![Total Downloads](https://poser.pugx.org/curl/curl/downloads)](//packagist.org/packages/curl/curl)
|
||||
|
||||
If you have questions or problems with installation or usage [create an Issue](https://github.com/php-mod/curl/issues).
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
In order to install this library via composer run the following command in the console:
|
||||
|
@ -122,4 +128,5 @@ In order to test the library:
|
|||
1. Create a fork
|
||||
2. Clone the fork to your machine
|
||||
3. Install the depencies `composer install`
|
||||
4. Build and start the docker image (in `tests/server`) `docker build . -t curlserver` start `docker run -p 1234:80 curlserver`
|
||||
4. Run the unit tests `./vendor/bin/phpunit tests`
|
||||
|
|
23
vendor/curl/curl/actions.phpunit.xml
vendored
Normal file
23
vendor/curl/curl/actions.phpunit.xml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
verbose="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="PHP-MOD CURL">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
5
vendor/curl/curl/composer.json
vendored
5
vendor/curl/curl/composer.json
vendored
|
@ -21,12 +21,11 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6 | ^7.0",
|
||||
"php": "^5.6 | ^7.0 | ^8.0",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"squizlabs/php_codesniffer": "~2.1"
|
||||
"yoast/phpunit-polyfills": "^0.2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
|
|
24
vendor/curl/curl/phpunit.xml.dist
vendored
24
vendor/curl/curl/phpunit.xml.dist
vendored
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="true"
|
||||
verbose="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<php>
|
||||
<ini name="display_errors" value="on"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="PHP MP4Box Tests Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
</phpunit>
|
10
vendor/curl/curl/src/Curl/Curl.php
vendored
10
vendor/curl/curl/src/Curl/Curl.php
vendored
|
@ -66,7 +66,7 @@ class Curl
|
|||
/**
|
||||
* @var string The user agent name which is set when making a request
|
||||
*/
|
||||
const USER_AGENT = 'PHP Curl/1.9 (+https://github.com/php-mod/curl)';
|
||||
const USER_AGENT = 'PHP Curl/2.3 (+https://github.com/php-mod/curl)';
|
||||
|
||||
private $_cookies = array();
|
||||
|
||||
|
@ -217,7 +217,7 @@ class Curl
|
|||
$this->http_error = $this->isError();
|
||||
$this->error = $this->curl_error || $this->http_error;
|
||||
$this->error_code = $this->error ? ($this->curl_error ? $this->getErrorCode() : $this->getHttpStatus()) : 0;
|
||||
$this->request_headers = preg_split('/\r\n/', curl_getinfo($this->curl, CURLINFO_HEADER_OUT), null, PREG_SPLIT_NO_EMPTY);
|
||||
$this->request_headers = preg_split('/\r\n/', curl_getinfo($this->curl, CURLINFO_HEADER_OUT), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$this->http_error_message = $this->error ? (isset($this->response_headers['0']) ? $this->response_headers['0'] : '') : '';
|
||||
$this->error_message = $this->curl_error ? $this->getErrorMessage() : $this->http_error_message;
|
||||
|
||||
|
@ -318,7 +318,7 @@ class Curl
|
|||
* Make a post request with optional post data.
|
||||
*
|
||||
* @param string $url The url to make the post request
|
||||
* @param array $data Post data to pass to the url
|
||||
* @param array|object|string $data Post data to pass to the url
|
||||
* @param boolean $asJson Whether the data should be passed as json or not. {@insce 2.2.1}
|
||||
* @return self
|
||||
*/
|
||||
|
@ -715,8 +715,8 @@ class Curl
|
|||
foreach ($this->response_headers as $header) {
|
||||
$parts = explode(":", $header, 2);
|
||||
|
||||
$key = isset($parts[0]) ? $parts[0] : null;
|
||||
$value = isset($parts[1]) ? $parts[1] : null;
|
||||
$key = isset($parts[0]) ? $parts[0] : '';
|
||||
$value = isset($parts[1]) ? $parts[1] : '';
|
||||
|
||||
$headers[trim(strtolower($key))] = trim($value);
|
||||
}
|
||||
|
|
506
vendor/curl/curl/tests/CurlTest.php
vendored
506
vendor/curl/curl/tests/CurlTest.php
vendored
|
@ -2,276 +2,310 @@
|
|||
|
||||
namespace Curl;
|
||||
|
||||
class CurlTest extends \PHPUnit_Framework_TestCase
|
||||
use Yoast\PHPUnitPolyfills\TestCases\TestCase;
|
||||
|
||||
class CurlTest extends TestCase
|
||||
{
|
||||
const TEST_URL = 'http://localhost:1234';
|
||||
|
||||
const TEST_URL = 'http://server_test';
|
||||
/**
|
||||
*
|
||||
* @var Curl
|
||||
*/
|
||||
protected $curl;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Curl
|
||||
*/
|
||||
protected $curl;
|
||||
|
||||
function setUp() {
|
||||
$this->curl = new Curl();
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
}
|
||||
|
||||
function server($request_method, $data='') {
|
||||
$request_method = strtolower($request_method);
|
||||
$this->curl->$request_method(self::TEST_URL . '/server.php', $data);
|
||||
return $this->curl->response;
|
||||
}
|
||||
|
||||
public function testExtensionLoaded() {
|
||||
|
||||
$this->assertTrue(extension_loaded('curl'));
|
||||
}
|
||||
|
||||
public function testUserAgent() {
|
||||
|
||||
$this->curl->setUserAgent(Curl::USER_AGENT);
|
||||
$this->assertEquals(Curl::USER_AGENT, $this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_USER_AGENT',
|
||||
)));
|
||||
|
||||
}
|
||||
|
||||
public function testGet() {
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'GET');
|
||||
}
|
||||
|
||||
public function testPostRequestMethod() {
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'POST');
|
||||
}
|
||||
|
||||
public function testPostData() {
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'post',
|
||||
'key' => 'test',
|
||||
)) === 'post');
|
||||
}
|
||||
|
||||
public function testPostMultidimensionalData() {
|
||||
|
||||
$data = array(
|
||||
'key' => 'file',
|
||||
'file' => array(
|
||||
'wibble',
|
||||
'wubble',
|
||||
'wobble',
|
||||
),
|
||||
);
|
||||
|
||||
$this->curl->post(self::TEST_URL . '/post_multidimensional.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
'key=file&file%5B0%5D=wibble&file%5B1%5D=wubble&file%5B2%5D=wobble',
|
||||
$this->curl->response);
|
||||
|
||||
}
|
||||
|
||||
public function testPostFilePathUpload()
|
||||
public function set_up()
|
||||
{
|
||||
parent::set_up();
|
||||
$this->curl = new Curl();
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
|
||||
$this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, false);
|
||||
}
|
||||
|
||||
$file_path = $this->get_png();
|
||||
public function server($request_method, $data='')
|
||||
{
|
||||
$request_method = strtolower($request_method);
|
||||
$this->curl->$request_method(self::TEST_URL . '/server.php', $data);
|
||||
return $this->curl->response;
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'key' => 'image',
|
||||
'image' => '@' . $file_path,
|
||||
);
|
||||
public function testExtensionLoaded()
|
||||
{
|
||||
$this->assertTrue(extension_loaded('curl'));
|
||||
}
|
||||
|
||||
public function testUserAgent()
|
||||
{
|
||||
$this->curl->setUserAgent(Curl::USER_AGENT);
|
||||
$this->assertEquals(Curl::USER_AGENT, $this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_USER_AGENT',
|
||||
)));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'GET');
|
||||
}
|
||||
|
||||
public function testPostRequestMethod()
|
||||
{
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'POST');
|
||||
}
|
||||
|
||||
public function testPostData()
|
||||
{
|
||||
$this->assertTrue($this->server('POST', array(
|
||||
'test' => 'post',
|
||||
'key' => 'test',
|
||||
)) === 'post');
|
||||
}
|
||||
|
||||
public function testPostJsonData()
|
||||
{
|
||||
$resp = $this->curl->post(self::TEST_URL.'/server.php', ['foo' => 'bar'], true);
|
||||
|
||||
$this->assertTrue($resp->isSuccess());
|
||||
|
||||
$this->assertArrayHasKey('x-powered-by', $resp->getResponseHeaders());
|
||||
|
||||
// syntax error check
|
||||
$resp->reset();
|
||||
}
|
||||
|
||||
public function testPostMultidimensionalData()
|
||||
{
|
||||
$data = array(
|
||||
'key' => 'file',
|
||||
'file' => array(
|
||||
'wibble',
|
||||
'wubble',
|
||||
'wobble',
|
||||
),
|
||||
);
|
||||
|
||||
$this->curl->post(self::TEST_URL . '/post_multidimensional.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
'key=file&file%5B0%5D=wibble&file%5B1%5D=wubble&file%5B2%5D=wobble',
|
||||
$this->curl->response
|
||||
);
|
||||
}
|
||||
|
||||
public function testPostFilePathUpload()
|
||||
{
|
||||
$file_path = $this->get_png();
|
||||
|
||||
$data = array(
|
||||
'key' => 'image',
|
||||
'image' => '@' . $file_path,
|
||||
);
|
||||
|
||||
$this->curl->setOpt(CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$this->curl->post(self::TEST_URL . '/post_file_path_upload.php', $data);
|
||||
$this->curl->post(self::TEST_URL . '/post_file_path_upload.php', $data);
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'request_method' => 'POST',
|
||||
'key' => 'image',
|
||||
'mime_content_type' => 'ERROR', // Temp change the image response, but assuming this is not fixing the issue indeed.
|
||||
//'mime_content_type' => 'image/png'
|
||||
),
|
||||
json_decode($this->curl->response, true));
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'request_method' => 'POST',
|
||||
'key' => 'image',
|
||||
'mime_content_type' => 'ERROR', // Temp change the image response, but assuming this is not fixing the issue indeed.
|
||||
//'mime_content_type' => 'image/png'
|
||||
),
|
||||
json_decode($this->curl->response, true)
|
||||
);
|
||||
|
||||
unlink($file_path);
|
||||
}
|
||||
unlink($file_path);
|
||||
}
|
||||
|
||||
public function testPutRequestMethod() {
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'PUT');
|
||||
}
|
||||
public function testPutRequestMethod()
|
||||
{
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'PUT');
|
||||
}
|
||||
|
||||
public function testPutData() {
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'put',
|
||||
'key' => 'test',
|
||||
)) === 'put');
|
||||
}
|
||||
public function testPutData()
|
||||
{
|
||||
$this->assertTrue($this->server('PUT', array(
|
||||
'test' => 'put',
|
||||
'key' => 'test',
|
||||
)) === 'put');
|
||||
}
|
||||
|
||||
public function testPutFileHandle() {
|
||||
$png = $this->create_png();
|
||||
$tmp_file = $this->create_tmp_file($png);
|
||||
public function testPutFileHandle()
|
||||
{
|
||||
$png = $this->create_png();
|
||||
$tmp_file = $this->create_tmp_file($png);
|
||||
|
||||
$this->curl->setOpt(CURLOPT_PUT, TRUE);
|
||||
$this->curl->setOpt(CURLOPT_INFILE, $tmp_file);
|
||||
$this->curl->setOpt(CURLOPT_INFILESIZE, strlen($png));
|
||||
$this->curl->put(self::TEST_URL . '/server.php', array(
|
||||
'test' => 'put_file_handle',
|
||||
));
|
||||
$this->curl->setOpt(CURLOPT_PUT, true);
|
||||
$this->curl->setOpt(CURLOPT_INFILE, $tmp_file);
|
||||
$this->curl->setOpt(CURLOPT_INFILESIZE, strlen($png));
|
||||
$this->curl->put(self::TEST_URL . '/server.php', array(
|
||||
'test' => 'put_file_handle',
|
||||
));
|
||||
|
||||
fclose($tmp_file);
|
||||
fclose($tmp_file);
|
||||
|
||||
$this->assertTrue($this->curl->response === 'image/png');
|
||||
}
|
||||
$this->assertTrue($this->curl->response === 'image/png');
|
||||
}
|
||||
|
||||
public function testDelete() {
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'DELETE');
|
||||
public function testDelete()
|
||||
{
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'server',
|
||||
'key' => 'REQUEST_METHOD',
|
||||
)) === 'DELETE');
|
||||
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'delete',
|
||||
'key' => 'test',
|
||||
)) === 'delete');
|
||||
}
|
||||
$this->assertTrue($this->server('DELETE', array(
|
||||
'test' => 'delete',
|
||||
'key' => 'test',
|
||||
)) === 'delete');
|
||||
}
|
||||
|
||||
public function testBasicHttpAuth() {
|
||||
public function testBasicHttpAuth()
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data = array();
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
$this->assertEquals('canceled', $this->curl->response);
|
||||
|
||||
$this->assertEquals('canceled', $this->curl->response);
|
||||
$username = 'myusername';
|
||||
$password = 'mypassword';
|
||||
|
||||
$username = 'myusername';
|
||||
$password = 'mypassword';
|
||||
$this->curl->setBasicAuthentication($username, $password);
|
||||
|
||||
$this->curl->setBasicAuthentication($username, $password);
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
|
||||
$this->curl->get(self::TEST_URL . '/http_basic_auth.php', $data);
|
||||
$this->assertEquals(
|
||||
'{"username":"myusername","password":"mypassword"}',
|
||||
$this->curl->response
|
||||
);
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
'{"username":"myusername","password":"mypassword"}',
|
||||
$this->curl->response);
|
||||
}
|
||||
public function testReferrer()
|
||||
{
|
||||
$this->curl->setReferer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
|
||||
public function testDeprecatedReferrer()
|
||||
{
|
||||
$this->curl->setReferrer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
|
||||
public function testReferrer() {
|
||||
$this->curl->setReferer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
|
||||
public function testDeprecatedReferrer() {
|
||||
$this->curl->setReferrer('myreferrer');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_REFERER',
|
||||
)) === 'myreferrer');
|
||||
}
|
||||
public function testCookies()
|
||||
{
|
||||
$this->curl->setCookie('mycookie', 'yum');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'cookie',
|
||||
'key' => 'mycookie',
|
||||
)) === 'yum');
|
||||
}
|
||||
|
||||
public function testCookies() {
|
||||
$this->curl->setCookie('mycookie', 'yum');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'cookie',
|
||||
'key' => 'mycookie',
|
||||
)) === 'yum');
|
||||
}
|
||||
public function testError()
|
||||
{
|
||||
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$this->curl->get('http://1.2.3.4/');
|
||||
$this->assertTrue($this->curl->error === true);
|
||||
$this->assertTrue($this->curl->curl_error === true);
|
||||
$this->assertTrue($this->curl->curl_error_code === CURLE_OPERATION_TIMEOUTED);
|
||||
}
|
||||
|
||||
public function testError() {
|
||||
$this->curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$this->curl->get('http://1.2.3.4/');
|
||||
$this->assertTrue($this->curl->error === TRUE);
|
||||
$this->assertTrue($this->curl->curl_error === TRUE);
|
||||
$this->assertTrue($this->curl->curl_error_code === CURLE_OPERATION_TIMEOUTED);
|
||||
}
|
||||
public function testHeaders()
|
||||
{
|
||||
$this->curl->setHeader('Content-Type', 'application/json');
|
||||
$this->curl->setHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
$this->curl->setHeader('Accept', 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'CONTENT_TYPE',
|
||||
)) === 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_X_REQUESTED_WITH',
|
||||
)) === 'XMLHttpRequest');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_ACCEPT',
|
||||
)) === 'application/json');
|
||||
}
|
||||
|
||||
public function testHeaders() {
|
||||
$this->curl->setHeader('Content-Type', 'application/json');
|
||||
$this->curl->setHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
$this->curl->setHeader('Accept', 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'CONTENT_TYPE',
|
||||
)) === 'application/json');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_X_REQUESTED_WITH',
|
||||
)) === 'XMLHttpRequest');
|
||||
$this->assertTrue($this->server('GET', array(
|
||||
'test' => 'server',
|
||||
'key' => 'HTTP_ACCEPT',
|
||||
)) === 'application/json');
|
||||
}
|
||||
public function testHeadersWithContinue()
|
||||
{
|
||||
$headers = file(dirname(__FILE__) . '/data/response_headers_with_continue.txt');
|
||||
|
||||
$this->curl->response_headers = array();
|
||||
foreach ($headers as $header_line) {
|
||||
$this->curl->addResponseHeaderLine(null, $header_line);
|
||||
}
|
||||
|
||||
public function testHeadersWithContinue() {
|
||||
$headers = file(dirname(__FILE__) . '/data/response_headers_with_continue.txt');
|
||||
|
||||
$this->curl->response_headers = array();
|
||||
foreach($headers as $header_line) {
|
||||
$this->curl->addResponseHeaderLine(null, $header_line);
|
||||
}
|
||||
$expected_headers = array_values(array_filter(array_map(function ($l) {
|
||||
return trim($l, "\r\n");
|
||||
}, array_slice($headers, 1))));
|
||||
|
||||
$expected_headers = array_values(array_filter(array_map(function($l) { return trim($l, "\r\n"); }, array_slice($headers, 1))));
|
||||
$this->assertEquals($expected_headers, $this->curl->response_headers);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$curl = $this->getMockBuilder(get_class($this->curl))->getMock();
|
||||
$curl->expects($this->once())->method('reset')->with();
|
||||
// lets make small request
|
||||
$curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$curl->get('http://1.2.3.4/');
|
||||
$curl->reset();
|
||||
$this->assertFalse($curl->error);
|
||||
$this->assertSame(0, $curl->error_code);
|
||||
$this->assertNull($curl->error_message);
|
||||
$this->assertFalse($curl->curl_error);
|
||||
$this->assertSame(0, $curl->curl_error_code);
|
||||
$this->assertNull($curl->curl_error_message);
|
||||
$this->assertFalse($curl->http_error);
|
||||
$this->assertSame(0, $curl->http_status_code);
|
||||
$this->assertNull($curl->http_error_message);
|
||||
$this->assertNull($curl->request_headers);
|
||||
$this->assertEmpty($curl->response_headers);
|
||||
$this->assertNull($curl->response);
|
||||
}
|
||||
|
||||
$this->assertEquals($expected_headers, $this->curl->response_headers);
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$curl = $this->getMockBuilder(get_class($this->curl))->getMock();
|
||||
$curl->expects($this->once())->method('reset')->with();
|
||||
// lets make small request
|
||||
$curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
|
||||
$curl->get('http://1.2.3.4/');
|
||||
$curl->reset();
|
||||
$this->assertFalse($curl->error);
|
||||
$this->assertSame(0, $curl->error_code);
|
||||
$this->assertNull($curl->error_message);
|
||||
$this->assertFalse($curl->curl_error);
|
||||
$this->assertSame(0, $curl->curl_error_code);
|
||||
$this->assertNull($curl->curl_error_message);
|
||||
$this->assertFalse($curl->http_error);
|
||||
$this->assertSame(0, $curl->http_status_code);
|
||||
$this->assertNull($curl->http_error_message);
|
||||
$this->assertNull($curl->request_headers);
|
||||
$this->assertEmpty($curl->response_headers);
|
||||
$this->assertNull($curl->response);
|
||||
}
|
||||
public function create_png()
|
||||
{
|
||||
// PNG image data, 1 x 1, 1-bit colormap, non-interlaced
|
||||
ob_start();
|
||||
imagepng(imagecreatefromstring(base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7')));
|
||||
$raw_image = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $raw_image;
|
||||
}
|
||||
|
||||
function create_png() {
|
||||
// PNG image data, 1 x 1, 1-bit colormap, non-interlaced
|
||||
ob_start();
|
||||
imagepng(imagecreatefromstring(base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7')));
|
||||
$raw_image = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $raw_image;
|
||||
}
|
||||
public function create_tmp_file($data)
|
||||
{
|
||||
$tmp_file = tmpfile();
|
||||
fwrite($tmp_file, $data);
|
||||
rewind($tmp_file);
|
||||
return $tmp_file;
|
||||
}
|
||||
|
||||
function create_tmp_file($data) {
|
||||
$tmp_file = tmpfile();
|
||||
fwrite($tmp_file, $data);
|
||||
rewind($tmp_file);
|
||||
return $tmp_file;
|
||||
}
|
||||
|
||||
function get_png() {
|
||||
$tmp_filename = tempnam('/tmp', 'php-curl-class.');
|
||||
file_put_contents($tmp_filename, $this->create_png());
|
||||
return $tmp_filename;
|
||||
}
|
||||
public function get_png()
|
||||
{
|
||||
$tmp_filename = tempnam('/tmp', 'php-curl-class.');
|
||||
file_put_contents($tmp_filename, $this->create_png());
|
||||
return $tmp_filename;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ $commands = array(
|
|||
|
||||
// Run the commands for output
|
||||
$output = '';
|
||||
foreach($commands AS $command){
|
||||
// Run it
|
||||
foreach ($commands as $command) {
|
||||
// Run it
|
||||
$tmp = shell_exec($command);
|
||||
// Output
|
||||
// Output
|
||||
$output .= "<span style=\"color: #6BE234;\">\$</span> <span style=\"color: #729FCF;\">{$command}\n</span>";
|
||||
$output .= htmlentities(trim($tmp)) . "\n";
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
|
||||
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
header('WWW-Authenticate: Basic realm="My Realm"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'canceled';
|
||||
exit;
|
||||
header('WWW-Authenticate: Basic realm="My Realm"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'canceled';
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(array(
|
||||
'username' => $_SERVER['PHP_AUTH_USER'],
|
||||
'password' => $_SERVER['PHP_AUTH_PW'],
|
||||
));
|
||||
'username' => $_SERVER['PHP_AUTH_USER'],
|
||||
'password' => $_SERVER['PHP_AUTH_PW'],
|
||||
));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
$request_method = isset($_SERVER['REQUEST_METHOD']) ?
|
||||
$_SERVER['REQUEST_METHOD'] : '';
|
||||
$_SERVER['REQUEST_METHOD'] : '';
|
||||
|
||||
$data_values = $request_method === 'POST' ? $_POST : $_GET;
|
||||
|
||||
|
@ -12,10 +12,12 @@ $response = array();
|
|||
$response['request_method'] = $request_method;
|
||||
$response['key'] = $key;
|
||||
|
||||
if(isset($_FILES[$key])) {
|
||||
$response['mime_content_type'] = mime_content_type($_FILES[$key]['tmp_name']);
|
||||
if (isset($_FILES[$key])) {
|
||||
$response['mime_content_type'] = mime_content_type($_FILES[$key]['tmp_name']);
|
||||
} else {
|
||||
$response['mime_content_type'] = 'ERROR';
|
||||
$response['mime_content_type'] = 'ERROR';
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
header('Content-Type: application/json');
|
||||
|
||||
echo json_encode($response);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?php
|
||||
|
||||
$http_raw_post_data = file_get_contents('php://input');
|
||||
echo $http_raw_post_data;
|
||||
|
||||
header('Content-Type: text/plain');
|
||||
|
||||
echo $http_raw_post_data;
|
||||
|
|
|
@ -22,10 +22,10 @@ $data_mapping = array(
|
|||
'server' => '_SERVER',
|
||||
);
|
||||
|
||||
if(isset($data_mapping[$test])) {
|
||||
if (isset($data_mapping[$test])) {
|
||||
$data = ${$data_mapping[$test]};
|
||||
$value = isset($data[$key]) ? $data[$key] : '';
|
||||
echo $value;
|
||||
echo $value;
|
||||
} else {
|
||||
echo "Error.";
|
||||
}
|
||||
|
|
2
vendor/graham-campbell/result-type/LICENSE
vendored
2
vendor/graham-campbell/result-type/LICENSE
vendored
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 Graham Campbell <graham@alt-three.com>
|
||||
Copyright (c) 2020-2021 Graham Campbell <hello@gjcampbell.co.uk>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
18
vendor/graham-campbell/result-type/composer.json
vendored
18
vendor/graham-campbell/result-type/composer.json
vendored
|
@ -6,15 +6,16 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@alt-three.com"
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.0|^8.0",
|
||||
"phpoption/phpoption": "^1.7.3"
|
||||
"php": "^7.0 || ^8.0",
|
||||
"phpoption/phpoption": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.5|^7.5|^8.5|^9.0"
|
||||
"phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@ -28,12 +29,5 @@
|
|||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
/*
|
||||
* This file is part of Result Type.
|
||||
*
|
||||
* (c) Graham Campbell <graham@alt-three.com>
|
||||
* (c) Graham Campbell <hello@gjcampbell.co.uk>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
/*
|
||||
* This file is part of Result Type.
|
||||
*
|
||||
* (c) Graham Campbell <graham@alt-three.com>
|
||||
* (c) Graham Campbell <hello@gjcampbell.co.uk>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
|
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||
/*
|
||||
* This file is part of Result Type.
|
||||
*
|
||||
* (c) Graham Campbell <graham@alt-three.com>
|
||||
* (c) Graham Campbell <hello@gjcampbell.co.uk>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
|
2
vendor/ledccn/bittorrentclient/composer.json
vendored
2
vendor/ledccn/bittorrentclient/composer.json
vendored
|
@ -12,7 +12,7 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6 | ^7.0",
|
||||
"php": "^5.6|^7.0|^8.0",
|
||||
"curl/curl": "^2.3",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
|
|
69
vendor/monolog/monolog/CHANGELOG.md
vendored
69
vendor/monolog/monolog/CHANGELOG.md
vendored
|
@ -1,3 +1,64 @@
|
|||
### 2.4.0 (2022-03-14)
|
||||
|
||||
* Added `[Monolog\LogRecord](src/Monolog/LogRecord.php)` interface that can be used to type-hint records like `array|\Monolog\LogRecord $record` to be forward compatible with the upcoming Monolog 3 changes
|
||||
* Added `includeStacktraces` constructor params to LineFormatter & JsonFormatter (#1603)
|
||||
* Added `persistent`, `timeout`, `writingTimeout`, `connectionTimeout`, `chunkSize` constructor params to SocketHandler and derivatives (#1600)
|
||||
* Added `AsMonologProcessor` PHP attribute which can help autowiring / autoconfiguration of processors if frameworks / integrations decide to make use of it. This is useless when used purely with Monolog (#1637)
|
||||
* Added support for keeping native BSON types as is in MongoDBFormatter (#1620)
|
||||
* Added support for a `user_agent` key in WebProcessor, disabled by default but you can use it by configuring the $extraFields you want (#1613)
|
||||
* Added support for username/userIcon in SlackWebhookHandler (#1617)
|
||||
* Added extension points to BrowserConsoleHandler (#1593)
|
||||
* Added record message/context/extra info to exceptions thrown when a StreamHandler cannot open its stream to avoid completely losing the data logged (#1630)
|
||||
* Fixed error handler signature to accept a null $context which happens with internal PHP errors (#1614)
|
||||
* Fixed a few setter methods not returning `self` (#1609)
|
||||
* Fixed handling of records going over the max Telegram message length (#1616)
|
||||
|
||||
### 2.3.5 (2021-10-01)
|
||||
|
||||
* Fixed regression in StreamHandler since 2.3.3 on systems with the memory_limit set to >=20GB (#1592)
|
||||
|
||||
### 2.3.4 (2021-09-15)
|
||||
|
||||
* Fixed support for psr/log 3.x (#1589)
|
||||
|
||||
### 2.3.3 (2021-09-14)
|
||||
|
||||
* Fixed memory usage when using StreamHandler and calling stream_get_contents on the resource you passed to it (#1578, #1577)
|
||||
* Fixed support for psr/log 2.x (#1587)
|
||||
* Fixed some type annotations
|
||||
|
||||
### 2.3.2 (2021-07-23)
|
||||
|
||||
* Fixed compatibility with PHP 7.2 - 7.4 when experiencing PCRE errors (#1568)
|
||||
|
||||
### 2.3.1 (2021-07-14)
|
||||
|
||||
* Fixed Utils::getClass handling of anonymous classes not being fully compatible with PHP 8 (#1563)
|
||||
* Fixed some `@inheritDoc` annotations having the wrong case
|
||||
|
||||
### 2.3.0 (2021-07-05)
|
||||
|
||||
* Added a ton of PHPStan type annotations as well as type aliases on Monolog\Logger for Record, Level and LevelName that you can import (#1557)
|
||||
* Added ability to customize date format when using JsonFormatter (#1561)
|
||||
* Fixed FilterHandler not calling reset on its internal handler when reset() is called on it (#1531)
|
||||
* Fixed SyslogUdpHandler not setting the timezone correctly on DateTimeImmutable instances (#1540)
|
||||
* Fixed StreamHandler thread safety - chunk size set to 2GB now to avoid interlacing when doing concurrent writes (#1553)
|
||||
|
||||
### 2.2.0 (2020-12-14)
|
||||
|
||||
* Added JSON_PARTIAL_OUTPUT_ON_ERROR to default json encoding flags, to avoid dropping entire context data or even records due to an invalid subset of it somewhere
|
||||
* Added setDateFormat to NormalizerFormatter (and Line/Json formatters by extension) to allow changing this after object creation
|
||||
* Added RedisPubSubHandler to log records to a Redis channel using PUBLISH
|
||||
* Added support for Elastica 7, and deprecated the $type argument of ElasticaFormatter which is not in use anymore as of Elastica 7
|
||||
* Added support for millisecond write timeouts in SocketHandler, you can now pass floats to setWritingTimeout, e.g. 0.2 is 200ms
|
||||
* Added support for unix sockets in SyslogUdpHandler (set $port to 0 to make the $host a unix socket)
|
||||
* Added handleBatch support for TelegramBotHandler
|
||||
* Added RFC5424e extended date format including milliseconds to SyslogUdpHandler
|
||||
* Added support for configuring handlers with numeric level values in strings (coming from e.g. env vars)
|
||||
* Fixed Wildfire/FirePHP/ChromePHP handling of unicode characters
|
||||
* Fixed PHP 8 issues in SyslogUdpHandler
|
||||
* Fixed internal type error when mbstring is missing
|
||||
|
||||
### 2.1.1 (2020-07-23)
|
||||
|
||||
* Fixed removing of json encoding options
|
||||
|
@ -86,6 +147,14 @@
|
|||
* Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler
|
||||
* Fixed many minor issues in various handlers, and probably added a few regressions too
|
||||
|
||||
### 1.26.1 (2021-05-28)
|
||||
|
||||
* Fixed PHP 8.1 deprecation warning
|
||||
|
||||
### 1.26.0 (2020-12-14)
|
||||
|
||||
* Added $dateFormat and $removeUsedContextFields arguments to PsrLogMessageProcessor (backport from 2.x)
|
||||
|
||||
### 1.25.5 (2020-07-23)
|
||||
|
||||
* Fixed array access on null in RavenHandler
|
||||
|
|
13
vendor/monolog/monolog/README.md
vendored
13
vendor/monolog/monolog/README.md
vendored
|
@ -1,4 +1,4 @@
|
|||
# Monolog - Logging for PHP [![Build Status](https://travis-ci.org/Seldaek/monolog.svg?branch=master)](https://travis-ci.org/Seldaek/monolog)
|
||||
# Monolog - Logging for PHP [![Continuous Integration](https://github.com/Seldaek/monolog/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/Seldaek/monolog/actions)
|
||||
|
||||
[![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
|
||||
[![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
|
||||
|
@ -64,7 +64,11 @@ can also add your own there if you publish one.
|
|||
|
||||
### Requirements
|
||||
|
||||
- Monolog 2.x works with PHP 7.2 or above, use Monolog `^1.0` for PHP 5.3+ support.
|
||||
- Monolog `^2.0` works with PHP 7.2 or above, use Monolog `^1.25` for PHP 5.3+ support.
|
||||
|
||||
### Support
|
||||
|
||||
Monolog 1.x support is somewhat limited at this point and only important fixes will be done. You should migrate to Monolog 2 where possible to benefit from all the latest features and fixes.
|
||||
|
||||
### Submitting bugs and feature requests
|
||||
|
||||
|
@ -82,13 +86,16 @@ Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/mono
|
|||
- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
|
||||
- [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog.
|
||||
- [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog.
|
||||
- [Nette Framework](http://nette.org/en/) can be used with Monolog via [contributte/monolog](https://github.com/contributte/monolog) extension.
|
||||
- [Nette Framework](http://nette.org/en/) is usable with Monolog via the [contributte/monolog](https://github.com/contributte/monolog) or [orisai/nette-monolog](https://github.com/orisai/nette-monolog) extensions.
|
||||
- [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog.
|
||||
- [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog.
|
||||
- [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog.
|
||||
- [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins.
|
||||
- [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog.
|
||||
- [SilverStripe 4](https://www.silverstripe.org/) comes out of the box with Monolog.
|
||||
- [Drupal](https://www.drupal.org/) is usable with Monolog via the [monolog](https://www.drupal.org/project/monolog) module.
|
||||
- [Aimeos ecommerce framework](https://aimeos.org/) is usable with Monolog via the [ai-monolog](https://github.com/aimeos/ai-monolog) extension.
|
||||
- [Magento](https://magento.com/) comes out of the box with Monolog.
|
||||
|
||||
### Author
|
||||
|
||||
|
|
40
vendor/monolog/monolog/composer.json
vendored
40
vendor/monolog/monolog/composer.json
vendored
|
@ -2,34 +2,35 @@
|
|||
"name": "monolog/monolog",
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"keywords": ["log", "logging", "psr-3"],
|
||||
"homepage": "http://github.com/Seldaek/monolog",
|
||||
"homepage": "https://github.com/Seldaek/monolog",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
"homepage": "https://seld.be"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"psr/log": "^1.0.1"
|
||||
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"elasticsearch/elasticsearch": "^6.0",
|
||||
"elasticsearch/elasticsearch": "^7",
|
||||
"mongodb/mongodb": "^1.8",
|
||||
"graylog2/gelf-php": "^1.4.2",
|
||||
"php-amqplib/php-amqplib": "~2.4",
|
||||
"php-amqplib/php-amqplib": "~2.4 || ^3",
|
||||
"php-console/php-console": "^3.1.3",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.0",
|
||||
"phpspec/prophecy": "^1.6.1",
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"predis/predis": "^1.1",
|
||||
"rollbar/rollbar": "^1.3",
|
||||
"ruflin/elastica": ">=0.90 <3.0",
|
||||
"swiftmailer/swiftmailer": "^5.3|^6.0"
|
||||
"rollbar/rollbar": "^1.3 || ^2 || ^3",
|
||||
"ruflin/elastica": ">=0.90@dev",
|
||||
"swiftmailer/swiftmailer": "^5.3|^6.0",
|
||||
"phpstan/phpstan": "^0.12.91"
|
||||
},
|
||||
"suggest": {
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
|
@ -43,7 +44,10 @@
|
|||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||
"php-console/php-console": "Allow sending log messages to Google Chrome",
|
||||
"ext-mbstring": "Allow to work properly with unicode symbols"
|
||||
"ext-mbstring": "Allow to work properly with unicode symbols",
|
||||
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
|
||||
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
|
||||
"ext-openssl": "Required to send log messages using SSL"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {"Monolog\\": "src/Monolog"}
|
||||
|
@ -52,24 +56,20 @@
|
|||
"psr-4": {"Monolog\\": "tests/Monolog"}
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0.0"
|
||||
"psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
"dev-main": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"lint": [
|
||||
"parallel-lint . --exclude vendor"
|
||||
],
|
||||
"test": [
|
||||
"phpunit"
|
||||
]
|
||||
"test": "@php vendor/bin/phpunit",
|
||||
"phpstan": "@php vendor/bin/phpstan analyse"
|
||||
},
|
||||
"config": {
|
||||
"lock": false,
|
||||
"sort-packages": true,
|
||||
"platform-check": false
|
||||
},
|
||||
"lock": false
|
||||
}
|
||||
}
|
||||
|
|
36
vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php
vendored
Normal file
36
vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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 Monolog\Attribute;
|
||||
|
||||
/**
|
||||
* A reusable attribute to help configure a class or a method as a processor.
|
||||
*
|
||||
* Using it offers no guarantee: it needs to be leveraged by a Monolog third-party consumer.
|
||||
*
|
||||
* Using it with the Monolog library only has no effect at all: processors should still be turned into a callable if
|
||||
* needed and manually pushed to the loggers and to the processable handlers.
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||
class AsMonologProcessor
|
||||
{
|
||||
/**
|
||||
* @param string|null $channel The logging channel the processor should be pushed to.
|
||||
* @param string|null $handler The handler the processor should be pushed to.
|
||||
* @param string|null $method The method that processes the records (if the attribute is used at the class level).
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $channel = null,
|
||||
public ?string $handler = null,
|
||||
public ?string $method = null,
|
||||
) {
|
||||
}
|
||||
}
|
|
@ -25,19 +25,30 @@ use Psr\Log\LogLevel;
|
|||
*/
|
||||
class ErrorHandler
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
private $previousExceptionHandler;
|
||||
private $uncaughtExceptionLevelMap;
|
||||
/** @var ?callable */
|
||||
private $previousExceptionHandler = null;
|
||||
/** @var array<class-string, LogLevel::*> an array of class name to LogLevel::* constant mapping */
|
||||
private $uncaughtExceptionLevelMap = [];
|
||||
|
||||
private $previousErrorHandler;
|
||||
private $errorLevelMap;
|
||||
private $handleOnlyReportedErrors;
|
||||
/** @var callable|true|null */
|
||||
private $previousErrorHandler = null;
|
||||
/** @var array<int, LogLevel::*> an array of E_* constant to LogLevel::* constant mapping */
|
||||
private $errorLevelMap = [];
|
||||
/** @var bool */
|
||||
private $handleOnlyReportedErrors = true;
|
||||
|
||||
private $hasFatalErrorHandler;
|
||||
private $fatalLevel;
|
||||
private $reservedMemory;
|
||||
/** @var bool */
|
||||
private $hasFatalErrorHandler = false;
|
||||
/** @var LogLevel::* */
|
||||
private $fatalLevel = LogLevel::ALERT;
|
||||
/** @var ?string */
|
||||
private $reservedMemory = null;
|
||||
/** @var ?mixed */
|
||||
private $lastFatalTrace;
|
||||
/** @var int[] */
|
||||
private static $fatalErrors = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR];
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
|
@ -50,14 +61,15 @@ class ErrorHandler
|
|||
*
|
||||
* 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 array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
|
||||
* @param string|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @param LoggerInterface $logger
|
||||
* @param array<int, LogLevel::*>|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
|
||||
* @param array<class-string, LogLevel::*>|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
|
||||
* @param LogLevel::*|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @return ErrorHandler
|
||||
*/
|
||||
public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
$handler = new static($logger);
|
||||
if ($errorLevelMap !== false) {
|
||||
$handler->registerErrorHandler($errorLevelMap);
|
||||
|
@ -72,9 +84,15 @@ class ErrorHandler
|
|||
return $handler;
|
||||
}
|
||||
|
||||
public function registerExceptionHandler($levelMap = [], $callPrevious = true): self
|
||||
/**
|
||||
* @param array<class-string, LogLevel::*> $levelMap an array of class name to LogLevel::* constant mapping
|
||||
* @return $this
|
||||
*/
|
||||
public function registerExceptionHandler(array $levelMap = [], bool $callPrevious = true): self
|
||||
{
|
||||
$prev = set_exception_handler([$this, 'handleException']);
|
||||
$prev = set_exception_handler(function (\Throwable $e): void {
|
||||
$this->handleException($e);
|
||||
});
|
||||
$this->uncaughtExceptionLevelMap = $levelMap;
|
||||
foreach ($this->defaultExceptionLevelMap() as $class => $level) {
|
||||
if (!isset($this->uncaughtExceptionLevelMap[$class])) {
|
||||
|
@ -88,12 +106,18 @@ class ErrorHandler
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function registerErrorHandler(array $levelMap = [], $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true): self
|
||||
/**
|
||||
* @param array<int, LogLevel::*> $levelMap an array of E_* constant to LogLevel::* constant mapping
|
||||
* @return $this
|
||||
*/
|
||||
public function registerErrorHandler(array $levelMap = [], bool $callPrevious = true, int $errorTypes = -1, bool $handleOnlyReportedErrors = true): self
|
||||
{
|
||||
$prev = set_error_handler([$this, 'handleError'], $errorTypes);
|
||||
$this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
|
||||
if ($callPrevious) {
|
||||
$this->previousErrorHandler = $prev ?: true;
|
||||
} else {
|
||||
$this->previousErrorHandler = null;
|
||||
}
|
||||
|
||||
$this->handleOnlyReportedErrors = $handleOnlyReportedErrors;
|
||||
|
@ -102,20 +126,23 @@ class ErrorHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
|
||||
* @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done
|
||||
* @param LogLevel::*|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT
|
||||
* @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done
|
||||
*/
|
||||
public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self
|
||||
{
|
||||
register_shutdown_function([$this, 'handleFatalError']);
|
||||
|
||||
$this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
|
||||
$this->fatalLevel = $level;
|
||||
$this->fatalLevel = null === $level ? LogLevel::ALERT : $level;
|
||||
$this->hasFatalErrorHandler = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string, LogLevel::*>
|
||||
*/
|
||||
protected function defaultExceptionLevelMap(): array
|
||||
{
|
||||
return [
|
||||
|
@ -124,6 +151,9 @@ class ErrorHandler
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, LogLevel::*>
|
||||
*/
|
||||
protected function defaultErrorLevelMap(): array
|
||||
{
|
||||
return [
|
||||
|
@ -146,10 +176,9 @@ class ErrorHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param \Exception $e
|
||||
* @phpstan-return never
|
||||
*/
|
||||
public function handleException($e)
|
||||
private function handleException(\Throwable $e): void
|
||||
{
|
||||
$level = LogLevel::ERROR;
|
||||
foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) {
|
||||
|
@ -178,11 +207,13 @@ class ErrorHandler
|
|||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* @param mixed[] $context
|
||||
*/
|
||||
public function handleError($code, $message, $file = '', $line = 0, $context = [])
|
||||
public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool
|
||||
{
|
||||
if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
|
||||
|
@ -198,7 +229,7 @@ class ErrorHandler
|
|||
if ($this->previousErrorHandler === true) {
|
||||
return false;
|
||||
} elseif ($this->previousErrorHandler) {
|
||||
return ($this->previousErrorHandler)($code, $message, $file, $line, $context);
|
||||
return (bool) ($this->previousErrorHandler)($code, $message, $file, $line, $context);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -207,14 +238,14 @@ class ErrorHandler
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
public function handleFatalError()
|
||||
public function handleFatalError(): void
|
||||
{
|
||||
$this->reservedMemory = '';
|
||||
|
||||
$lastError = error_get_last();
|
||||
if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) {
|
||||
$this->logger->log(
|
||||
$this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel,
|
||||
$this->fatalLevel,
|
||||
'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
|
||||
['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace]
|
||||
);
|
||||
|
@ -227,6 +258,9 @@ class ErrorHandler
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
*/
|
||||
private static function codeToString($code): string
|
||||
{
|
||||
switch ($code) {
|
||||
|
|
|
@ -22,6 +22,8 @@ class ChromePHPFormatter implements FormatterInterface
|
|||
{
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*
|
||||
* @var array<int, 'log'|'info'|'warn'|'error'>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 'log',
|
||||
|
@ -35,7 +37,7 @@ class ChromePHPFormatter implements FormatterInterface
|
|||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
|
@ -66,7 +68,7 @@ class ChromePHPFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ use Elastica\Document;
|
|||
* Format a log message into an Elastica Document
|
||||
*
|
||||
* @author Jelle Vink <jelle.vink@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class ElasticaFormatter extends NormalizerFormatter
|
||||
{
|
||||
|
@ -26,15 +28,15 @@ class ElasticaFormatter extends NormalizerFormatter
|
|||
protected $index;
|
||||
|
||||
/**
|
||||
* @var string Elastic search document type
|
||||
* @var ?string Elastic search document type
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @param string $index Elastic Search index name
|
||||
* @param string $type Elastic Search document type
|
||||
* @param string $index Elastic Search index name
|
||||
* @param ?string $type Elastic Search document type, deprecated as of Elastica 7
|
||||
*/
|
||||
public function __construct(string $index, string $type)
|
||||
public function __construct(string $index, ?string $type)
|
||||
{
|
||||
// elasticsearch requires a ISO 8601 format date with optional millisecond precision.
|
||||
parent::__construct('Y-m-d\TH:i:s.uP');
|
||||
|
@ -44,7 +46,7 @@ class ElasticaFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
|
@ -58,21 +60,28 @@ class ElasticaFormatter extends NormalizerFormatter
|
|||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Elastica 7 type has no effect
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a log message into an Elastica Document
|
||||
* @param array $record
|
||||
* @return Document
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
protected function getDocument(array $record): Document
|
||||
{
|
||||
$document = new Document();
|
||||
$document->setData($record);
|
||||
$document->setType($this->type);
|
||||
if (method_exists($document, 'setType')) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$document->setType($this->type);
|
||||
}
|
||||
$document->setIndex($this->index);
|
||||
|
||||
return $document;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Monolog\Formatter;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
* Format a log message into an Elasticsearch record
|
||||
|
@ -37,14 +37,14 @@ class ElasticsearchFormatter extends NormalizerFormatter
|
|||
public function __construct(string $index, string $type)
|
||||
{
|
||||
// Elasticsearch requires an ISO 8601 format date with optional millisecond precision.
|
||||
parent::__construct(DateTime::ISO8601);
|
||||
parent::__construct(DateTimeInterface::ISO8601);
|
||||
|
||||
$this->index = $index;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
|
@ -76,8 +76,8 @@ class ElasticsearchFormatter extends NormalizerFormatter
|
|||
/**
|
||||
* Convert a log message into an Elasticsearch record
|
||||
*
|
||||
* @param array $record Log message
|
||||
* @return array
|
||||
* @param mixed[] $record Log message
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getDocument(array $record): array
|
||||
{
|
||||
|
|
|
@ -35,7 +35,9 @@ class FlowdockFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
|
@ -69,7 +71,9 @@ class FlowdockFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return mixed[][]
|
||||
*/
|
||||
public function formatBatch(array $records): array
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace Monolog\Formatter;
|
|||
* Interface for formatters
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
|
@ -23,6 +25,8 @@ interface FormatterInterface
|
|||
*
|
||||
* @param array $record A record to format
|
||||
* @return mixed The formatted record
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function format(array $record);
|
||||
|
||||
|
@ -31,6 +35,8 @@ interface FormatterInterface
|
|||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return mixed The formatted set of records
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
public function formatBatch(array $records);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ use Monolog\Utils;
|
|||
* @see http://docs.graylog.org/en/latest/pages/gelf.html
|
||||
*
|
||||
* @author Matt Lehner <mlehner@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class GelfMessageFormatter extends NormalizerFormatter
|
||||
{
|
||||
|
@ -47,6 +49,10 @@ class GelfMessageFormatter extends NormalizerFormatter
|
|||
|
||||
/**
|
||||
* Translates Monolog log levels to Graylog2 log priorities.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*
|
||||
* @phpstan-var array<Level, int>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 7,
|
||||
|
@ -61,9 +67,13 @@ class GelfMessageFormatter extends NormalizerFormatter
|
|||
|
||||
public function __construct(?string $systemName = null, ?string $extraPrefix = null, string $contextPrefix = 'ctxt_', ?int $maxLength = null)
|
||||
{
|
||||
if (!class_exists(Message::class)) {
|
||||
throw new \RuntimeException('Composer package graylog2/gelf-php is required to use Monolog\'s GelfMessageFormatter');
|
||||
}
|
||||
|
||||
parent::__construct('U.u');
|
||||
|
||||
$this->systemName = (is_null($systemName) || $systemName === '') ? gethostname() : $systemName;
|
||||
$this->systemName = (is_null($systemName) || $systemName === '') ? (string) gethostname() : $systemName;
|
||||
|
||||
$this->extraPrefix = is_null($extraPrefix) ? '' : $extraPrefix;
|
||||
$this->contextPrefix = $contextPrefix;
|
||||
|
@ -71,15 +81,18 @@ class GelfMessageFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record): Message
|
||||
{
|
||||
$context = $extra = [];
|
||||
if (isset($record['context'])) {
|
||||
$record['context'] = parent::format($record['context']);
|
||||
/** @var mixed[] $context */
|
||||
$context = parent::normalize($record['context']);
|
||||
}
|
||||
if (isset($record['extra'])) {
|
||||
$record['extra'] = parent::format($record['extra']);
|
||||
/** @var mixed[] $extra */
|
||||
$extra = parent::normalize($record['extra']);
|
||||
}
|
||||
|
||||
if (!isset($record['datetime'], $record['message'], $record['level'])) {
|
||||
|
@ -103,39 +116,40 @@ class GelfMessageFormatter extends NormalizerFormatter
|
|||
if (isset($record['channel'])) {
|
||||
$message->setFacility($record['channel']);
|
||||
}
|
||||
if (isset($record['extra']['line'])) {
|
||||
$message->setLine($record['extra']['line']);
|
||||
unset($record['extra']['line']);
|
||||
if (isset($extra['line'])) {
|
||||
$message->setLine($extra['line']);
|
||||
unset($extra['line']);
|
||||
}
|
||||
if (isset($record['extra']['file'])) {
|
||||
$message->setFile($record['extra']['file']);
|
||||
unset($record['extra']['file']);
|
||||
if (isset($extra['file'])) {
|
||||
$message->setFile($extra['file']);
|
||||
unset($extra['file']);
|
||||
}
|
||||
|
||||
foreach ($record['extra'] as $key => $val) {
|
||||
foreach ($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, Utils::substr($val, 0, $this->maxLength));
|
||||
$message->setAdditional($this->extraPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength));
|
||||
|
||||
continue;
|
||||
}
|
||||
$message->setAdditional($this->extraPrefix . $key, $val);
|
||||
}
|
||||
|
||||
foreach ($record['context'] as $key => $val) {
|
||||
foreach ($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, Utils::substr($val, 0, $this->maxLength));
|
||||
$message->setAdditional($this->contextPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength));
|
||||
|
||||
continue;
|
||||
}
|
||||
$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)) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (null === $message->getFile() && isset($context['exception']['file'])) {
|
||||
if (preg_match("/^(.+):([0-9]+)$/", $context['exception']['file'], $matches)) {
|
||||
$message->setFile($matches[1]);
|
||||
$message->setLine($matches[2]);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ class HtmlFormatter extends NormalizerFormatter
|
|||
{
|
||||
/**
|
||||
* Translates Monolog log levels to html color priorities.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $logLevels = [
|
||||
Logger::DEBUG => '#CCCCCC',
|
||||
|
@ -79,7 +81,6 @@ class HtmlFormatter extends NormalizerFormatter
|
|||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param array $record A record to format
|
||||
* @return string The formatted record
|
||||
*/
|
||||
public function format(array $record): string
|
||||
|
@ -113,7 +114,6 @@ class HtmlFormatter extends NormalizerFormatter
|
|||
/**
|
||||
* Formats a set of log records.
|
||||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return string The formatted set of records
|
||||
*/
|
||||
public function formatBatch(array $records): string
|
||||
|
@ -126,6 +126,9 @@ class HtmlFormatter extends NormalizerFormatter
|
|||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function convertToString($data): string
|
||||
{
|
||||
if (null === $data || is_scalar($data)) {
|
||||
|
|
|
@ -19,26 +19,34 @@ use Throwable;
|
|||
* This can be useful to log to databases or remote APIs
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class JsonFormatter extends NormalizerFormatter
|
||||
{
|
||||
public const BATCH_MODE_JSON = 1;
|
||||
public const BATCH_MODE_NEWLINES = 2;
|
||||
|
||||
/** @var self::BATCH_MODE_* */
|
||||
protected $batchMode;
|
||||
/** @var bool */
|
||||
protected $appendNewline;
|
||||
/** @var bool */
|
||||
protected $ignoreEmptyContextAndExtra;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
/** @var bool */
|
||||
protected $includeStacktraces = false;
|
||||
|
||||
public function __construct(int $batchMode = self::BATCH_MODE_JSON, bool $appendNewline = true, bool $ignoreEmptyContextAndExtra = false)
|
||||
/**
|
||||
* @param self::BATCH_MODE_* $batchMode
|
||||
*/
|
||||
public function __construct(int $batchMode = self::BATCH_MODE_JSON, bool $appendNewline = true, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false)
|
||||
{
|
||||
$this->batchMode = $batchMode;
|
||||
$this->appendNewline = $appendNewline;
|
||||
$this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
|
||||
$this->includeStacktraces = $includeStacktraces;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,9 +70,7 @@ class JsonFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @suppress PhanTypeComparisonToArray
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record): string
|
||||
{
|
||||
|
@ -89,7 +95,7 @@ class JsonFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function formatBatch(array $records): string
|
||||
{
|
||||
|
@ -103,13 +109,20 @@ class JsonFormatter extends NormalizerFormatter
|
|||
}
|
||||
}
|
||||
|
||||
public function includeStacktraces(bool $include = true)
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function includeStacktraces(bool $include = true): self
|
||||
{
|
||||
$this->includeStacktraces = $include;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON-encoded array of records.
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
protected function formatBatchJson(array $records): string
|
||||
{
|
||||
|
@ -119,6 +132,8 @@ class JsonFormatter extends NormalizerFormatter
|
|||
/**
|
||||
* Use new lines to separate records instead of a
|
||||
* JSON-encoded array.
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
protected function formatBatchNewlines(array $records): string
|
||||
{
|
||||
|
@ -163,6 +178,10 @@ class JsonFormatter extends NormalizerFormatter
|
|||
return $normalized;
|
||||
}
|
||||
|
||||
if ($data instanceof \DateTimeInterface) {
|
||||
return $this->formatDate($data);
|
||||
}
|
||||
|
||||
if ($data instanceof Throwable) {
|
||||
return $this->normalizeException($data, $depth);
|
||||
}
|
||||
|
@ -177,6 +196,8 @@ class JsonFormatter extends NormalizerFormatter
|
|||
/**
|
||||
* Normalizes given exception with or without its own stack trace based on
|
||||
* `includeStacktraces` property.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function normalizeException(Throwable $e, int $depth = 0): array
|
||||
{
|
||||
|
|
|
@ -25,9 +25,13 @@ class LineFormatter extends NormalizerFormatter
|
|||
{
|
||||
public const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
|
||||
|
||||
/** @var string */
|
||||
protected $format;
|
||||
/** @var bool */
|
||||
protected $allowInlineLineBreaks;
|
||||
/** @var bool */
|
||||
protected $ignoreEmptyContextAndExtra;
|
||||
/** @var bool */
|
||||
protected $includeStacktraces;
|
||||
|
||||
/**
|
||||
|
@ -36,34 +40,41 @@ class LineFormatter extends NormalizerFormatter
|
|||
* @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries
|
||||
* @param bool $ignoreEmptyContextAndExtra
|
||||
*/
|
||||
public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false)
|
||||
public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false)
|
||||
{
|
||||
$this->format = $format === null ? static::SIMPLE_FORMAT : $format;
|
||||
$this->allowInlineLineBreaks = $allowInlineLineBreaks;
|
||||
$this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
|
||||
$this->includeStacktraces($includeStacktraces);
|
||||
parent::__construct($dateFormat);
|
||||
}
|
||||
|
||||
public function includeStacktraces(bool $include = true)
|
||||
public function includeStacktraces(bool $include = true): self
|
||||
{
|
||||
$this->includeStacktraces = $include;
|
||||
if ($this->includeStacktraces) {
|
||||
$this->allowInlineLineBreaks = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allowInlineLineBreaks(bool $allow = true)
|
||||
public function allowInlineLineBreaks(bool $allow = true): self
|
||||
{
|
||||
$this->allowInlineLineBreaks = $allow;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function ignoreEmptyContextAndExtra(bool $ignore = true)
|
||||
public function ignoreEmptyContextAndExtra(bool $ignore = true): self
|
||||
{
|
||||
$this->ignoreEmptyContextAndExtra = $ignore;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record): string
|
||||
{
|
||||
|
@ -106,6 +117,10 @@ class LineFormatter extends NormalizerFormatter
|
|||
// remove leftover %extra.xxx% and %context.xxx% if any
|
||||
if (false !== strpos($output, '%')) {
|
||||
$output = preg_replace('/%(?:extra|context)\..+?%/', '', $output);
|
||||
if (null === $output) {
|
||||
$pcreErrorCode = preg_last_error();
|
||||
throw new \RuntimeException('Failed to run preg_replace: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
@ -121,14 +136,14 @@ class LineFormatter extends NormalizerFormatter
|
|||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function stringify($value): string
|
||||
{
|
||||
return $this->replaceNewlines($this->convertToString($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @suppress PhanParamSignatureMismatch
|
||||
*/
|
||||
protected function normalizeException(\Throwable $e, int $depth = 0): string
|
||||
{
|
||||
$str = $this->formatException($e);
|
||||
|
@ -142,6 +157,9 @@ class LineFormatter extends NormalizerFormatter
|
|||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
*/
|
||||
protected function convertToString($data): string
|
||||
{
|
||||
if (null === $data || is_bool($data)) {
|
||||
|
|
|
@ -52,14 +52,14 @@ class LogstashFormatter extends NormalizerFormatter
|
|||
// logstash requires a ISO 8601 format date with optional millisecond precision.
|
||||
parent::__construct('Y-m-d\TH:i:s.uP');
|
||||
|
||||
$this->systemName = $systemName === null ? gethostname() : $systemName;
|
||||
$this->systemName = $systemName === null ? (string) gethostname() : $systemName;
|
||||
$this->applicationName = $applicationName;
|
||||
$this->extraKey = $extraKey;
|
||||
$this->contextKey = $contextKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record): string
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Monolog\Formatter;
|
||||
|
||||
use MongoDB\BSON\Type;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
use Monolog\Utils;
|
||||
|
||||
|
@ -21,8 +22,11 @@ use Monolog\Utils;
|
|||
*/
|
||||
class MongoDBFormatter implements FormatterInterface
|
||||
{
|
||||
/** @var bool */
|
||||
private $exceptionTraceAsString;
|
||||
/** @var int */
|
||||
private $maxNestingLevel;
|
||||
/** @var bool */
|
||||
private $isLegacyMongoExt;
|
||||
|
||||
/**
|
||||
|
@ -34,53 +38,66 @@ class MongoDBFormatter implements FormatterInterface
|
|||
$this->maxNestingLevel = max($maxNestingLevel, 0);
|
||||
$this->exceptionTraceAsString = $exceptionTraceAsString;
|
||||
|
||||
$this->isLegacyMongoExt = version_compare(phpversion('mongodb'), '1.1.9', '<=');
|
||||
$this->isLegacyMongoExt = extension_loaded('mongodb') && version_compare((string) phpversion('mongodb'), '1.1.9', '<=');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
return $this->formatArray($record);
|
||||
/** @var mixed[] $res */
|
||||
$res = $this->formatArray($record);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return array<mixed[]>
|
||||
*/
|
||||
public function formatBatch(array $records): array
|
||||
{
|
||||
$formatted = [];
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $this->format($record);
|
||||
$formatted[$key] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string Array except when max nesting level is reached then a string "[...]"
|
||||
* @param mixed[] $array
|
||||
* @return mixed[]|string Array except when max nesting level is reached then a string "[...]"
|
||||
*/
|
||||
protected function formatArray(array $record, int $nestingLevel = 0)
|
||||
protected function formatArray(array $array, int $nestingLevel = 0)
|
||||
{
|
||||
if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) {
|
||||
foreach ($record as $name => $value) {
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
$record[$name] = $this->formatDate($value, $nestingLevel + 1);
|
||||
} elseif ($value instanceof \Throwable) {
|
||||
$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 = '[...]';
|
||||
if ($this->maxNestingLevel > 0 && $nestingLevel > $this->maxNestingLevel) {
|
||||
return '[...]';
|
||||
}
|
||||
|
||||
return $record;
|
||||
foreach ($array as $name => $value) {
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
$array[$name] = $this->formatDate($value, $nestingLevel + 1);
|
||||
} elseif ($value instanceof \Throwable) {
|
||||
$array[$name] = $this->formatException($value, $nestingLevel + 1);
|
||||
} elseif (is_array($value)) {
|
||||
$array[$name] = $this->formatArray($value, $nestingLevel + 1);
|
||||
} elseif (is_object($value) && !$value instanceof Type) {
|
||||
$array[$name] = $this->formatObject($value, $nestingLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed[]|string
|
||||
*/
|
||||
protected function formatObject($value, int $nestingLevel)
|
||||
{
|
||||
$objectVars = get_object_vars($value);
|
||||
|
@ -89,6 +106,9 @@ class MongoDBFormatter implements FormatterInterface
|
|||
return $this->formatArray($objectVars, $nestingLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|string
|
||||
*/
|
||||
protected function formatException(\Throwable $exception, int $nestingLevel)
|
||||
{
|
||||
$formattedException = [
|
||||
|
@ -118,7 +138,7 @@ class MongoDBFormatter implements FormatterInterface
|
|||
|
||||
private function getMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
|
||||
{
|
||||
return new UTCDateTime((int) (string) floor($value->format('U.u') * 1000));
|
||||
return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,12 +150,13 @@ class MongoDBFormatter implements FormatterInterface
|
|||
*/
|
||||
private function legacyGetMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
|
||||
{
|
||||
$milliseconds = floor($value->format('U.u') * 1000);
|
||||
$milliseconds = floor(((float) $value->format('U.u')) * 1000);
|
||||
|
||||
$milliseconds = (PHP_INT_SIZE == 8) //64-bit OS?
|
||||
? (int) $milliseconds
|
||||
: (string) $milliseconds;
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
return new UTCDateTime($milliseconds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,14 @@ class NormalizerFormatter implements FormatterInterface
|
|||
{
|
||||
public const SIMPLE_DATE = "Y-m-d\TH:i:sP";
|
||||
|
||||
/** @var string */
|
||||
protected $dateFormat;
|
||||
/** @var int */
|
||||
protected $maxNormalizeDepth = 9;
|
||||
/** @var int */
|
||||
protected $maxNormalizeItemCount = 1000;
|
||||
|
||||
/** @var int */
|
||||
private $jsonEncodeOptions = Utils::DEFAULT_JSON_FLAGS;
|
||||
|
||||
/**
|
||||
|
@ -42,7 +46,9 @@ class NormalizerFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param mixed[] $record
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
|
@ -50,7 +56,7 @@ class NormalizerFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
|
@ -61,6 +67,18 @@ class NormalizerFormatter implements FormatterInterface
|
|||
return $records;
|
||||
}
|
||||
|
||||
public function getDateFormat(): string
|
||||
{
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
public function setDateFormat(string $dateFormat): self
|
||||
{
|
||||
$this->dateFormat = $dateFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of normalization levels to go through
|
||||
*/
|
||||
|
@ -106,8 +124,8 @@ class NormalizerFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return int|bool|string|null|array
|
||||
* @param mixed $data
|
||||
* @return null|scalar|array<array|scalar|null>
|
||||
*/
|
||||
protected function normalize($data, int $depth = 0)
|
||||
{
|
||||
|
@ -154,17 +172,15 @@ class NormalizerFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
if ($data instanceof \JsonSerializable) {
|
||||
/** @var null|scalar|array<array|scalar|null> $value */
|
||||
$value = $data->jsonSerialize();
|
||||
} elseif (method_exists($data, '__toString')) {
|
||||
/** @var string $value */
|
||||
$value = $data->__toString();
|
||||
} else {
|
||||
// the rest is normalized by json encoding and decoding it
|
||||
$encoded = $this->toJson($data, true);
|
||||
if ($encoded === false) {
|
||||
$value = 'JSON_ERROR';
|
||||
} else {
|
||||
$value = json_decode($encoded, true);
|
||||
}
|
||||
/** @var null|scalar|array<array|scalar|null> $value */
|
||||
$value = json_decode($this->toJson($data, true), true);
|
||||
}
|
||||
|
||||
return [Utils::getClass($data) => $value];
|
||||
|
@ -178,7 +194,7 @@ class NormalizerFormatter implements FormatterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function normalizeException(Throwable $e, int $depth = 0)
|
||||
{
|
||||
|
@ -237,6 +253,9 @@ class NormalizerFormatter implements FormatterInterface
|
|||
return Utils::jsonEncode($data, $this->jsonEncodeOptions, $ignoreErrors);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function formatDate(\DateTimeInterface $date)
|
||||
{
|
||||
// in case the date format isn't custom then we defer to the custom DateTimeImmutable
|
||||
|
@ -248,13 +267,17 @@ class NormalizerFormatter implements FormatterInterface
|
|||
return $date->format($this->dateFormat);
|
||||
}
|
||||
|
||||
public function addJsonEncodeOption($option)
|
||||
public function addJsonEncodeOption(int $option): self
|
||||
{
|
||||
$this->jsonEncodeOptions |= $option;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeJsonEncodeOption($option)
|
||||
public function removeJsonEncodeOption(int $option): self
|
||||
{
|
||||
$this->jsonEncodeOptions &= ~$option;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,26 +20,29 @@ namespace Monolog\Formatter;
|
|||
class ScalarFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @phpstan-return array<string, scalar|null> $record
|
||||
*/
|
||||
public function format(array $record): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($record as $key => $value) {
|
||||
$record[$key] = $this->normalizeValue($value);
|
||||
$result[$key] = $this->normalizeValue($value);
|
||||
}
|
||||
|
||||
return $record;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
* @param mixed $value
|
||||
* @return scalar|null
|
||||
*/
|
||||
protected function normalizeValue($value)
|
||||
{
|
||||
$normalized = $this->normalize($value);
|
||||
|
||||
if (is_array($normalized) || is_object($normalized)) {
|
||||
if (is_array($normalized)) {
|
||||
return $this->toJson($normalized, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,15 @@ use Monolog\Logger;
|
|||
* @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
* @author Kirill chEbba Chebunin <iam@chebba.org>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class WildfireFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*
|
||||
* @var array<Level, string>
|
||||
*/
|
||||
private $logLevels = [
|
||||
Logger::DEBUG => 'LOG',
|
||||
|
@ -37,7 +41,20 @@ class WildfireFormatter extends NormalizerFormatter
|
|||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
|
||||
*/
|
||||
public function __construct(?string $dateFormat = null)
|
||||
{
|
||||
parent::__construct($dateFormat);
|
||||
|
||||
// http headers do not like non-ISO-8559-1 characters
|
||||
$this->removeJsonEncodeOption(JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(array $record): string
|
||||
{
|
||||
|
@ -52,6 +69,7 @@ class WildfireFormatter extends NormalizerFormatter
|
|||
unset($record['extra']['line']);
|
||||
}
|
||||
|
||||
/** @var mixed[] $record */
|
||||
$record = $this->normalize($record);
|
||||
$message = ['message' => $record['message']];
|
||||
$handleError = false;
|
||||
|
@ -96,7 +114,9 @@ class WildfireFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @phpstan-return never
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
|
@ -104,8 +124,9 @@ class WildfireFormatter extends NormalizerFormatter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @suppress PhanTypeMismatchReturn
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return null|scalar|array<array|scalar|null>|object
|
||||
*/
|
||||
protected function normalize($data, int $depth = 0)
|
||||
{
|
||||
|
|
|
@ -13,20 +13,31 @@ namespace Monolog\Handler;
|
|||
|
||||
use Monolog\Logger;
|
||||
use Monolog\ResettableInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Base Handler class providing basic level/bubble support
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
abstract class AbstractHandler extends Handler implements ResettableInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @phpstan-var Level
|
||||
*/
|
||||
protected $level = Logger::DEBUG;
|
||||
/** @var bool */
|
||||
protected $bubble = true;
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
@ -35,7 +46,7 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -45,7 +56,7 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
|||
/**
|
||||
* Sets minimum logging level at which this handler will be triggered.
|
||||
*
|
||||
* @param int|string $level Level or level name
|
||||
* @param Level|LevelName|LogLevel::* $level Level or level name
|
||||
* @return self
|
||||
*/
|
||||
public function setLevel($level): self
|
||||
|
@ -59,6 +70,8 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
|||
* Gets minimum logging level at which this handler will be triggered.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @phpstan-return Level
|
||||
*/
|
||||
public function getLevel(): int
|
||||
{
|
||||
|
@ -90,6 +103,9 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
|
|||
return $this->bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ namespace Monolog\Handler;
|
|||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-type FormattedRecord array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[], formatted: mixed}
|
||||
*/
|
||||
abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
|
||||
{
|
||||
|
@ -25,7 +30,7 @@ abstract class AbstractProcessingHandler extends AbstractHandler implements Proc
|
|||
use FormattableHandlerTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@ -34,6 +39,7 @@ abstract class AbstractProcessingHandler extends AbstractHandler implements Proc
|
|||
}
|
||||
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
|
||||
|
@ -46,9 +52,14 @@ abstract class AbstractProcessingHandler extends AbstractHandler implements Proc
|
|||
|
||||
/**
|
||||
* Writes the record down to the log of the implementing handler
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
abstract protected function write(array $record): void;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
|
|
|
@ -17,13 +17,18 @@ use Monolog\Formatter\LineFormatter;
|
|||
|
||||
/**
|
||||
* Common syslog functionality
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var int */
|
||||
protected $facility;
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to syslog log priorities.
|
||||
* @var array
|
||||
* @phpstan-var array<Level, int>
|
||||
*/
|
||||
protected $logLevels = [
|
||||
Logger::DEBUG => LOG_DEBUG,
|
||||
|
@ -38,6 +43,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
|||
|
||||
/**
|
||||
* List of valid log facility names.
|
||||
* @var array<string, int>
|
||||
*/
|
||||
protected $facilities = [
|
||||
'auth' => LOG_AUTH,
|
||||
|
@ -55,8 +61,6 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
|||
|
||||
/**
|
||||
* @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
|
||||
* @param string|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, bool $bubble = true)
|
||||
{
|
||||
|
@ -93,7 +97,7 @@ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
|
|
|
@ -18,6 +18,9 @@ use PhpAmqpLib\Message\AMQPMessage;
|
|||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use AMQPExchange;
|
||||
|
||||
/**
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class AmqpHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
|
@ -33,8 +36,6 @@ class AmqpHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
|
||||
* @param string|null $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only
|
||||
* @param string|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($exchange, ?string $exchangeName = null, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
@ -93,6 +94,7 @@ class AmqpHandler extends AbstractProcessingHandler
|
|||
continue;
|
||||
}
|
||||
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
$data = $this->getFormatter()->format($record);
|
||||
|
||||
|
@ -108,6 +110,8 @@ class AmqpHandler extends AbstractProcessingHandler
|
|||
|
||||
/**
|
||||
* Gets the routing key for the AMQP exchange
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
protected function getRoutingKey(array $record): string
|
||||
{
|
||||
|
|
|
@ -11,20 +11,35 @@
|
|||
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Utils;
|
||||
|
||||
use function count;
|
||||
use function headers_list;
|
||||
use function stripos;
|
||||
use function trigger_error;
|
||||
|
||||
use const E_USER_DEPRECATED;
|
||||
|
||||
/**
|
||||
* Handler sending logs to browser's javascript console with no browser extension required
|
||||
*
|
||||
* @author Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var bool */
|
||||
protected static $initialized = false;
|
||||
/** @var FormattedRecord[] */
|
||||
protected static $records = [];
|
||||
|
||||
protected const FORMAT_HTML = 'html';
|
||||
protected const FORMAT_JS = 'js';
|
||||
protected const FORMAT_UNKNOWN = 'unknown';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -61,14 +76,14 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
public static function send(): void
|
||||
{
|
||||
$format = static::getResponseFormat();
|
||||
if ($format === 'unknown') {
|
||||
if ($format === self::FORMAT_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (count(static::$records)) {
|
||||
if ($format === 'html') {
|
||||
if ($format === self::FORMAT_HTML) {
|
||||
static::writeOutput('<script>' . static::generateScript() . '</script>');
|
||||
} elseif ($format === 'js') {
|
||||
} elseif ($format === self::FORMAT_JS) {
|
||||
static::writeOutput(static::generateScript());
|
||||
}
|
||||
static::resetStatic();
|
||||
|
@ -121,25 +136,37 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
* If Content-Type is anything else -> unknown
|
||||
*
|
||||
* @return string One of 'js', 'html' or 'unknown'
|
||||
* @phpstan-return self::FORMAT_*
|
||||
*/
|
||||
protected static function getResponseFormat(): string
|
||||
{
|
||||
// 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 static::getResponseFormatFromContentType($header);
|
||||
}
|
||||
}
|
||||
|
||||
return 'html';
|
||||
return self::FORMAT_HTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string One of 'js', 'html' or 'unknown'
|
||||
* @phpstan-return self::FORMAT_*
|
||||
*/
|
||||
protected static function getResponseFormatFromContentType(string $contentType): string
|
||||
{
|
||||
// This handler only works with HTML and javascript outputs
|
||||
// text/javascript is obsolete in favour of application/javascript, but still used
|
||||
if (stripos($contentType, 'application/javascript') !== false || stripos($contentType, 'text/javascript') !== false) {
|
||||
return self::FORMAT_JS;
|
||||
}
|
||||
|
||||
if (stripos($contentType, 'text/html') !== false) {
|
||||
return self::FORMAT_HTML;
|
||||
}
|
||||
|
||||
return self::FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
private static function generateScript(): string
|
||||
|
@ -165,6 +192,9 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private static function handleStyles(string $formatted): array
|
||||
{
|
||||
$args = [];
|
||||
|
@ -190,7 +220,7 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
static $colors = ['blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'];
|
||||
static $labels = [];
|
||||
|
||||
return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function (array $m) use ($string, &$colors, &$labels) {
|
||||
$style = preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function (array $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])) {
|
||||
|
@ -203,8 +233,19 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
|
||||
return $m[1];
|
||||
}, $style);
|
||||
|
||||
if (null === $style) {
|
||||
$pcreErrorCode = preg_last_error();
|
||||
throw new \RuntimeException('Failed to run preg_replace_callback: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $dict
|
||||
* @return mixed[]
|
||||
*/
|
||||
private static function dump(string $title, array $dict): array
|
||||
{
|
||||
$script = [];
|
||||
|
@ -229,13 +270,22 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
|
|||
return '"' . addcslashes($arg, "\"\n\\") . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $args
|
||||
*/
|
||||
private static function call(...$args): string
|
||||
{
|
||||
$method = array_shift($args);
|
||||
if (!is_string($method)) {
|
||||
throw new \UnexpectedValueException('Expected the first arg to be a string, got: '.var_export($method, true));
|
||||
}
|
||||
|
||||
return static::call_array($method, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $args
|
||||
*/
|
||||
private static function call_array(string $method, array $args): string
|
||||
{
|
||||
return 'c.' . $method . '(' . implode(', ', $args) . ');';
|
||||
|
|
|
@ -22,23 +22,29 @@ use Monolog\Formatter\FormatterInterface;
|
|||
* sending one per log message.
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
|
||||
{
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
/** @var HandlerInterface */
|
||||
protected $handler;
|
||||
/** @var int */
|
||||
protected $bufferSize = 0;
|
||||
/** @var int */
|
||||
protected $bufferLimit;
|
||||
/** @var bool */
|
||||
protected $flushOnOverflow;
|
||||
/** @var Record[] */
|
||||
protected $buffer = [];
|
||||
/** @var bool */
|
||||
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 string|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, int $bufferLimit = 0, $level = Logger::DEBUG, bool $bubble = true, bool $flushOnOverflow = false)
|
||||
|
@ -50,7 +56,7 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@ -74,6 +80,7 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
|
||||
|
@ -101,7 +108,7 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
|
@ -133,20 +140,28 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
$this->handler->setFormatter($formatter);
|
||||
if ($this->handler instanceof FormattableHandlerInterface) {
|
||||
$this->handler->setFormatter($formatter);
|
||||
|
||||
return $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
return $this->handler->getFormatter();
|
||||
if ($this->handler instanceof FormattableHandlerInterface) {
|
||||
return $this->handler->getFormatter();
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ use Monolog\Utils;
|
|||
* This also works out of the box with Firefox 43+
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class ChromePHPHandler extends AbstractProcessingHandler
|
||||
{
|
||||
|
@ -42,6 +44,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}';
|
||||
|
||||
/** @var bool */
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
|
@ -53,18 +56,16 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected static $overflowed = false;
|
||||
|
||||
/** @var mixed[] */
|
||||
protected static $json = [
|
||||
'version' => self::VERSION,
|
||||
'columns' => ['label', 'log', 'backtrace', 'type'],
|
||||
'rows' => [],
|
||||
];
|
||||
|
||||
/** @var bool */
|
||||
protected static $sendHeaders = true;
|
||||
|
||||
/**
|
||||
* @param string|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, bool $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
@ -74,7 +75,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -88,7 +89,9 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
|||
if ($record['level'] < $this->level) {
|
||||
continue;
|
||||
}
|
||||
$messages[] = $this->processRecord($record);
|
||||
/** @var Record $message */
|
||||
$message = $this->processRecord($record);
|
||||
$messages[] = $message;
|
||||
}
|
||||
|
||||
if (!empty($messages)) {
|
||||
|
@ -145,7 +148,7 @@ class ChromePHPHandler extends AbstractProcessingHandler
|
|||
self::$json['request_uri'] = $_SERVER['REQUEST_URI'] ?? '';
|
||||
}
|
||||
|
||||
$json = Utils::jsonEncode(self::$json, null, true);
|
||||
$json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true);
|
||||
$data = base64_encode(utf8_encode($json));
|
||||
if (strlen($data) > 3 * 1024) {
|
||||
self::$overflowed = true;
|
||||
|
|
|
@ -22,8 +22,12 @@ use Monolog\Logger;
|
|||
*/
|
||||
class CouchDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var mixed[] */
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param mixed[] $options
|
||||
*/
|
||||
public function __construct(array $options = [], $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
$this->options = array_merge([
|
||||
|
|
|
@ -22,11 +22,17 @@ use Monolog\Utils;
|
|||
*/
|
||||
class CubeHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $udpConnection;
|
||||
private $httpConnection;
|
||||
/** @var resource|\Socket|null */
|
||||
private $udpConnection = null;
|
||||
/** @var resource|\CurlHandle|null */
|
||||
private $httpConnection = null;
|
||||
/** @var string */
|
||||
private $scheme;
|
||||
/** @var string */
|
||||
private $host;
|
||||
/** @var int */
|
||||
private $port;
|
||||
/** @var string[] */
|
||||
private $acceptedSchemes = ['http', 'udp'];
|
||||
|
||||
/**
|
||||
|
@ -40,7 +46,7 @@ class CubeHandler extends AbstractProcessingHandler
|
|||
{
|
||||
$urlInfo = parse_url($url);
|
||||
|
||||
if (!isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
|
||||
if ($urlInfo === false || !isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
|
||||
throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
|
||||
}
|
||||
|
||||
|
@ -53,7 +59,7 @@ class CubeHandler extends AbstractProcessingHandler
|
|||
|
||||
$this->scheme = $urlInfo['scheme'];
|
||||
$this->host = $urlInfo['host'];
|
||||
$this->port = $urlInfo['port'];
|
||||
$this->port = (int) $urlInfo['port'];
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
@ -70,11 +76,12 @@ class CubeHandler extends AbstractProcessingHandler
|
|||
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) {
|
||||
$udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
|
||||
if (false === $udpConnection) {
|
||||
throw new \LogicException('Unable to create a socket');
|
||||
}
|
||||
|
||||
$this->udpConnection = $udpConnection;
|
||||
if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
|
||||
throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
|
||||
}
|
||||
|
@ -92,18 +99,18 @@ class CubeHandler extends AbstractProcessingHandler
|
|||
throw new MissingExtensionException('The curl extension is required to use http URLs with the CubeHandler');
|
||||
}
|
||||
|
||||
$this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
|
||||
|
||||
if (!$this->httpConnection) {
|
||||
$httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
|
||||
if (false === $httpConnection) {
|
||||
throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
|
||||
}
|
||||
|
||||
$this->httpConnection = $httpConnection;
|
||||
curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@ -144,6 +151,10 @@ class CubeHandler extends AbstractProcessingHandler
|
|||
$this->connectHttp();
|
||||
}
|
||||
|
||||
if (null === $this->httpConnection) {
|
||||
throw new \LogicException('No connection could be established');
|
||||
}
|
||||
|
||||
curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
|
||||
curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace Monolog\Handler\Curl;
|
||||
|
||||
use CurlHandle;
|
||||
|
||||
/**
|
||||
* This class is marked as internal and it is not under the BC promise of the package.
|
||||
*
|
||||
|
@ -18,6 +20,7 @@ namespace Monolog\Handler\Curl;
|
|||
*/
|
||||
final class Util
|
||||
{
|
||||
/** @var array<int> */
|
||||
private static $retriableErrorCodes = [
|
||||
CURLE_COULDNT_RESOLVE_HOST,
|
||||
CURLE_COULDNT_CONNECT,
|
||||
|
@ -31,10 +34,10 @@ final class Util
|
|||
/**
|
||||
* Executes a CURL request with optional retries and exception on failure
|
||||
*
|
||||
* @param resource $ch curl handler
|
||||
* @param int $retries
|
||||
* @param bool $closeAfterDone
|
||||
* @return bool|string @see curl_exec
|
||||
* @param resource|CurlHandle $ch curl handler
|
||||
* @param int $retries
|
||||
* @param bool $closeAfterDone
|
||||
* @return bool|string @see curl_exec
|
||||
*/
|
||||
public static function execute($ch, int $retries = 5, bool $closeAfterDone = true)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Simple handler wrapper that deduplicates log records across multiple requests
|
||||
|
@ -32,6 +33,10 @@ use Monolog\Logger;
|
|||
* same way.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
class DeduplicationHandler extends BufferHandler
|
||||
{
|
||||
|
@ -41,7 +46,7 @@ class DeduplicationHandler extends BufferHandler
|
|||
protected $deduplicationStore;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @var Level
|
||||
*/
|
||||
protected $deduplicationLevel;
|
||||
|
||||
|
@ -61,6 +66,8 @@ class DeduplicationHandler extends BufferHandler
|
|||
* @param string|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
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $deduplicationLevel
|
||||
*/
|
||||
public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, int $time = 60, bool $bubble = true)
|
||||
{
|
||||
|
@ -100,6 +107,9 @@ class DeduplicationHandler extends BufferHandler
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function isDuplicate(array $record): bool
|
||||
{
|
||||
if (!file_exists($this->deduplicationStore)) {
|
||||
|
@ -166,6 +176,9 @@ class DeduplicationHandler extends BufferHandler
|
|||
$this->gc = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function appendRecord(array $record): void
|
||||
{
|
||||
file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND);
|
||||
|
|
|
@ -23,6 +23,7 @@ use Doctrine\CouchDB\CouchDBClient;
|
|||
*/
|
||||
class DoctrineCouchDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var CouchDBClient */
|
||||
private $client;
|
||||
|
||||
public function __construct(CouchDBClient $client, $level = Logger::DEBUG, bool $bubble = true)
|
||||
|
|
|
@ -48,11 +48,9 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected $marshaler;
|
||||
|
||||
/**
|
||||
* @param int|string $level
|
||||
*/
|
||||
public function __construct(DynamoDbClient $client, string $table, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) {
|
||||
$this->version = 3;
|
||||
$this->marshaler = new Marshaler;
|
||||
|
@ -67,7 +65,7 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@ -75,6 +73,7 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
|||
if ($this->version === 3) {
|
||||
$formatted = $this->marshaler->marshalItem($filtered);
|
||||
} else {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$formatted = $this->client->formatAttributes($filtered);
|
||||
}
|
||||
|
||||
|
@ -84,6 +83,10 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $record
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function filterEmptyFields(array $record): array
|
||||
{
|
||||
return array_filter($record, function ($value) {
|
||||
|
@ -92,7 +95,7 @@ class DynamoDbHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Monolog\Handler;
|
||||
|
||||
use Elastica\Document;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\ElasticaFormatter;
|
||||
use Monolog\Logger;
|
||||
|
@ -25,7 +26,7 @@ use Elastica\Exception\ExceptionInterface;
|
|||
* $client = new \Elastica\Client();
|
||||
* $options = array(
|
||||
* 'index' => 'elastic_index_name',
|
||||
* 'type' => 'elastic_doc_type',
|
||||
* 'type' => 'elastic_doc_type', Types have been removed in Elastica 7
|
||||
* );
|
||||
* $handler = new ElasticaHandler($client, $options);
|
||||
* $log = new Logger('application');
|
||||
|
@ -41,15 +42,13 @@ class ElasticaHandler extends AbstractProcessingHandler
|
|||
protected $client;
|
||||
|
||||
/**
|
||||
* @var array Handler config options
|
||||
* @var mixed[] Handler config options
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @param Client $client Elastica Client object
|
||||
* @param array $options Handler configuration
|
||||
* @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
|
||||
* @param Client $client Elastica Client object
|
||||
* @param mixed[] $options Handler configuration
|
||||
*/
|
||||
public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
@ -74,7 +73,7 @@ class ElasticaHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
|
@ -85,6 +84,9 @@ class ElasticaHandler extends AbstractProcessingHandler
|
|||
throw new \InvalidArgumentException('ElasticaHandler is only compatible with ElasticaFormatter');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
|
@ -99,7 +101,7 @@ class ElasticaHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -109,6 +111,9 @@ class ElasticaHandler extends AbstractProcessingHandler
|
|||
|
||||
/**
|
||||
* Use Elasticsearch bulk API to send list of documents
|
||||
*
|
||||
* @param Document[] $documents
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function bulkSend(array $documents): void
|
||||
|
|
|
@ -49,15 +49,13 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
protected $client;
|
||||
|
||||
/**
|
||||
* @var array Handler config options
|
||||
* @var mixed[] Handler config options
|
||||
*/
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @param Client $client Elasticsearch Client object
|
||||
* @param array $options Handler configuration
|
||||
* @param string|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 Client $client Elasticsearch Client object
|
||||
* @param mixed[] $options Handler configuration
|
||||
*/
|
||||
public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
@ -82,7 +80,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
|
@ -96,7 +94,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Getter options
|
||||
*
|
||||
* @return array
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
|
@ -112,7 +110,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -123,7 +121,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Use Elasticsearch bulk API to send list of documents
|
||||
*
|
||||
* @param array $records
|
||||
* @param array[] $records Records + _index/_type keys
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function bulkSend(array $records): void
|
||||
|
@ -162,7 +160,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* Only the first error is converted into an exception.
|
||||
*
|
||||
* @param array $responses returned by $this->client->bulk()
|
||||
* @param mixed[] $responses returned by $this->client->bulk()
|
||||
*/
|
||||
protected function createExceptionFromResponses(array $responses): ElasticsearchRuntimeException
|
||||
{
|
||||
|
@ -178,7 +176,7 @@ class ElasticsearchHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Creates elasticsearch exception from error array
|
||||
*
|
||||
* @param array $error
|
||||
* @param mixed[] $error
|
||||
*/
|
||||
protected function createExceptionFromError(array $error): ElasticsearchRuntimeException
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Monolog\Handler;
|
|||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Utils;
|
||||
|
||||
/**
|
||||
* Stores to PHP error_log() handler.
|
||||
|
@ -25,14 +26,14 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
|||
public const OPERATING_SYSTEM = 0;
|
||||
public const SAPI = 4;
|
||||
|
||||
/** @var int */
|
||||
protected $messageType;
|
||||
/** @var bool */
|
||||
protected $expandNewlines;
|
||||
|
||||
/**
|
||||
* @param int $messageType Says where the error should go.
|
||||
* @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
|
||||
* @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
|
||||
* @param int $messageType Says where the error should go.
|
||||
* @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
|
||||
*/
|
||||
public function __construct(int $messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, bool $bubble = true, bool $expandNewlines = false)
|
||||
{
|
||||
|
@ -49,7 +50,7 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array With all available types
|
||||
* @return int[] With all available types
|
||||
*/
|
||||
public static function getAvailableTypes(): array
|
||||
{
|
||||
|
@ -68,7 +69,7 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@ -79,6 +80,10 @@ class ErrorLogHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
$lines = preg_split('{[\r\n]+}', (string) $record['formatted']);
|
||||
if ($lines === false) {
|
||||
$pcreErrorCode = preg_last_error();
|
||||
throw new \RuntimeException('Failed to preg_split formatted string: ' . $pcreErrorCode . ' / '. Utils::pcreLastErrorMessage($pcreErrorCode));
|
||||
}
|
||||
foreach ($lines as $line) {
|
||||
error_log($line, $this->messageType);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,24 @@ namespace Monolog\Handler;
|
|||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Forwards records to at most one handler
|
||||
*
|
||||
* If a handler fails, the exception is suppressed and the record is forwarded to the next handler.
|
||||
*
|
||||
* As soon as one handler handles a record successfully, the handling stops there.
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class FallbackGroupHandler extends GroupHandler
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
foreach ($this->handlers as $handler) {
|
||||
|
@ -36,7 +46,7 @@ class FallbackGroupHandler extends GroupHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -45,6 +55,7 @@ class FallbackGroupHandler extends GroupHandler
|
|||
foreach ($records as $record) {
|
||||
$processed[] = $this->processRecord($record);
|
||||
}
|
||||
/** @var Record[] $records */
|
||||
$records = $processed;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Monolog\Handler;
|
|||
use Monolog\Logger;
|
||||
use Monolog\ResettableInterface;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Simple handler wrapper that filters records based on a list of levels
|
||||
|
@ -22,6 +23,10 @@ use Monolog\Formatter\FormatterInterface;
|
|||
*
|
||||
* @author Hennadiy Verkh
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
|
||||
{
|
||||
|
@ -30,7 +35,8 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
/**
|
||||
* Handler or factory callable($record, $this)
|
||||
*
|
||||
* @var callable|\Monolog\Handler\HandlerInterface
|
||||
* @var callable|HandlerInterface
|
||||
* @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
|
||||
|
@ -38,6 +44,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
* Minimum level for logs that are passed to handler
|
||||
*
|
||||
* @var int[]
|
||||
* @phpstan-var array<Level, int>
|
||||
*/
|
||||
protected $acceptedLevels;
|
||||
|
||||
|
@ -49,12 +56,15 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
protected $bubble;
|
||||
|
||||
/**
|
||||
* @psalm-param HandlerInterface|callable(?array, HandlerInterface): HandlerInterface $handler
|
||||
* @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
|
||||
*
|
||||
* @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|string $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
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $maxLevel
|
||||
*/
|
||||
public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, bool $bubble = true)
|
||||
{
|
||||
|
@ -67,6 +77,9 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return array<int, Level>
|
||||
*/
|
||||
public function getAcceptedLevels(): array
|
||||
{
|
||||
return array_flip($this->acceptedLevels);
|
||||
|
@ -75,6 +88,9 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
/**
|
||||
* @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
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $maxLevel
|
||||
*/
|
||||
public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY): self
|
||||
{
|
||||
|
@ -93,7 +109,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -101,7 +117,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@ -110,6 +126,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
|
||||
|
@ -119,7 +136,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -141,6 +158,8 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
* If the handler was provided as a factory callable, this will trigger the handler's instantiation.
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function getHandler(array $record = null)
|
||||
{
|
||||
|
@ -155,25 +174,39 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
$this->getHandler()->setFormatter($formatter);
|
||||
$handler = $this->getHandler();
|
||||
if ($handler instanceof FormattableHandlerInterface) {
|
||||
$handler->setFormatter($formatter);
|
||||
|
||||
return $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
return $this->getHandler()->getFormatter();
|
||||
$handler = $this->getHandler();
|
||||
if ($handler instanceof FormattableHandlerInterface) {
|
||||
return $handler->getFormatter();
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->resetProcessors();
|
||||
|
||||
if ($this->getHandler() instanceof ResettableInterface) {
|
||||
$this->getHandler()->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,15 @@ namespace Monolog\Handler\FingersCrossed;
|
|||
* Interface for activation strategies for the FingersCrossedHandler.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
interface ActivationStrategyInterface
|
||||
{
|
||||
/**
|
||||
* Returns whether the given record activates the handler.
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function isHandlerActivated(array $record): bool;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Monolog\Handler\FingersCrossed;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Channel and Error level based monolog activation strategy. Allows to trigger activation
|
||||
|
@ -32,22 +33,29 @@ use Monolog\Logger;
|
|||
* </code>
|
||||
*
|
||||
* @author Mike Meessen <netmikey@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class ChannelLevelActivationStrategy implements ActivationStrategyInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @var Level
|
||||
*/
|
||||
private $defaultActionLevel;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<string, Level>
|
||||
*/
|
||||
private $channelToActionLevel;
|
||||
|
||||
/**
|
||||
* @param int|string $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.
|
||||
* @param int|string $defaultActionLevel The default action level to be used if the record's category doesn't match any
|
||||
* @param array<string, int> $channelToActionLevel An array that maps channel names to action levels.
|
||||
*
|
||||
* @phpstan-param array<string, Level> $channelToActionLevel
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $defaultActionLevel
|
||||
*/
|
||||
public function __construct($defaultActionLevel, array $channelToActionLevel = [])
|
||||
{
|
||||
|
@ -55,6 +63,9 @@ class ChannelLevelActivationStrategy implements ActivationStrategyInterface
|
|||
$this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function isHandlerActivated(array $record): bool
|
||||
{
|
||||
if (isset($this->channelToActionLevel[$record['channel']])) {
|
||||
|
|
|
@ -12,21 +12,27 @@
|
|||
namespace Monolog\Handler\FingersCrossed;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Error level based activation strategy.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class ErrorLevelActivationStrategy implements ActivationStrategyInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @var Level
|
||||
*/
|
||||
private $actionLevel;
|
||||
|
||||
/**
|
||||
* @param int|string $actionLevel Level or name or value
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $actionLevel
|
||||
*/
|
||||
public function __construct($actionLevel)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
|
|||
use Monolog\Logger;
|
||||
use Monolog\ResettableInterface;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Buffers all records until a certain level is reached
|
||||
|
@ -32,22 +33,40 @@ use Monolog\Formatter\FormatterInterface;
|
|||
* Monolog\Handler\FingersCrossed\ namespace.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
|
||||
{
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
/**
|
||||
* @var callable|HandlerInterface
|
||||
* @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
|
||||
*/
|
||||
protected $handler;
|
||||
/** @var ActivationStrategyInterface */
|
||||
protected $activationStrategy;
|
||||
/** @var bool */
|
||||
protected $buffering = true;
|
||||
/** @var int */
|
||||
protected $bufferSize;
|
||||
/** @var Record[] */
|
||||
protected $buffer = [];
|
||||
/** @var bool */
|
||||
protected $stopBuffering;
|
||||
/**
|
||||
* @var ?int
|
||||
* @phpstan-var ?Level
|
||||
*/
|
||||
protected $passthruLevel;
|
||||
/** @var bool */
|
||||
protected $bubble;
|
||||
|
||||
/**
|
||||
* @psalm-param HandlerInterface|callable(?array, FingersCrossedHandler): HandlerInterface $handler
|
||||
* @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
|
||||
*
|
||||
* @param callable|HandlerInterface $handler Handler or factory callable($record|null, $fingersCrossedHandler).
|
||||
* @param int|string|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated
|
||||
|
@ -55,6 +74,9 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
* @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|string $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $passthruLevel
|
||||
* @phpstan-param Level|LevelName|LogLevel::*|ActivationStrategyInterface $activationStrategy
|
||||
*/
|
||||
public function __construct($handler, $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, $passthruLevel = null)
|
||||
{
|
||||
|
@ -83,7 +105,7 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -104,11 +126,12 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
|
||||
|
@ -128,13 +151,13 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
$this->flushBuffer();
|
||||
|
||||
$this->handler->close();
|
||||
$this->getHandler()->close();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
|
@ -170,7 +193,7 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
return $record['level'] >= $level;
|
||||
});
|
||||
if (count($this->buffer) > 0) {
|
||||
$this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer);
|
||||
$this->getHandler(end($this->buffer))->handleBatch($this->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +207,8 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
* If the handler was provided as a factory callable, this will trigger the handler's instantiation.
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function getHandler(array $record = null)
|
||||
{
|
||||
|
@ -198,20 +223,30 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
$this->getHandler()->setFormatter($formatter);
|
||||
$handler = $this->getHandler();
|
||||
if ($handler instanceof FormattableHandlerInterface) {
|
||||
$handler->setFormatter($formatter);
|
||||
|
||||
return $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
return $this->getHandler()->getFormatter();
|
||||
$handler = $this->getHandler();
|
||||
if ($handler instanceof FormattableHandlerInterface) {
|
||||
return $handler->getFormatter();
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ use Monolog\Formatter\FormatterInterface;
|
|||
* Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
|
||||
*
|
||||
* @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FirePHPHandler extends AbstractProcessingHandler
|
||||
{
|
||||
|
@ -45,6 +47,7 @@ class FirePHPHandler extends AbstractProcessingHandler
|
|||
|
||||
/**
|
||||
* Whether or not Wildfire vendor-specific headers have been generated & sent yet
|
||||
* @var bool
|
||||
*/
|
||||
protected static $initialized = false;
|
||||
|
||||
|
@ -54,14 +57,18 @@ class FirePHPHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected static $messageIndex = 1;
|
||||
|
||||
/** @var bool */
|
||||
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
|
||||
* @param array<int|string> $meta Wildfire Plugin, Protocol & Structure Indexes
|
||||
* @param string $message Log message
|
||||
*
|
||||
* @return array<string, string> Complete header string ready for the client as key and message as value
|
||||
*
|
||||
* @phpstan-return non-empty-array<string, string>
|
||||
*/
|
||||
protected function createHeader(array $meta, string $message): array
|
||||
{
|
||||
|
@ -73,7 +80,13 @@ class FirePHPHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Creates message header from record
|
||||
*
|
||||
* @return array<string, string>
|
||||
*
|
||||
* @phpstan-return non-empty-array<string, string>
|
||||
*
|
||||
* @see createHeader()
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
protected function createRecordHeader(array $record): array
|
||||
{
|
||||
|
@ -98,6 +111,8 @@ class FirePHPHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* @see createHeader()
|
||||
* @see sendHeader()
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function getInitHeaders(): array
|
||||
{
|
||||
|
@ -124,7 +139,6 @@ class FirePHPHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* @see sendHeader()
|
||||
* @see sendInitHeaders()
|
||||
* @param array $record
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
|
|
@ -22,6 +22,8 @@ use Monolog\Logger;
|
|||
*
|
||||
* @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation
|
||||
* @author Ando Roots <ando@sqroot.eu>
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FleepHookHandler extends SocketHandler
|
||||
{
|
||||
|
@ -41,12 +43,18 @@ class FleepHookHandler extends SocketHandler
|
|||
* see https://fleep.io/integrations/webhooks/
|
||||
*
|
||||
* @param string $token Webhook token
|
||||
* @param string|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(string $token, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
public function __construct(
|
||||
string $token,
|
||||
$level = Logger::DEBUG,
|
||||
bool $bubble = true,
|
||||
bool $persistent = false,
|
||||
float $timeout = 0.0,
|
||||
float $writingTimeout = 10.0,
|
||||
?float $connectionTimeout = null,
|
||||
?int $chunkSize = null
|
||||
) {
|
||||
if (!extension_loaded('openssl')) {
|
||||
throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler');
|
||||
}
|
||||
|
@ -54,7 +62,16 @@ class FleepHookHandler extends SocketHandler
|
|||
$this->token = $token;
|
||||
|
||||
$connectionString = 'ssl://' . static::FLEEP_HOST . ':443';
|
||||
parent::__construct($connectionString, $level, $bubble);
|
||||
parent::__construct(
|
||||
$connectionString,
|
||||
$level,
|
||||
$bubble,
|
||||
$persistent,
|
||||
$timeout,
|
||||
$writingTimeout,
|
||||
$connectionTimeout,
|
||||
$chunkSize
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,7 +96,7 @@ class FleepHookHandler extends SocketHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
|
@ -104,6 +121,8 @@ class FleepHookHandler extends SocketHandler
|
|||
|
||||
/**
|
||||
* Builds the body of API call
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
|
|
|
@ -26,6 +26,8 @@ use Monolog\Formatter\FormatterInterface;
|
|||
*
|
||||
* @author Dominik Liebler <liebler.dominik@gmail.com>
|
||||
* @see https://www.flowdock.com/api/push
|
||||
*
|
||||
* @phpstan-import-type FormattedRecord from AbstractProcessingHandler
|
||||
*/
|
||||
class FlowdockHandler extends SocketHandler
|
||||
{
|
||||
|
@ -35,23 +37,37 @@ class FlowdockHandler extends SocketHandler
|
|||
protected $apiToken;
|
||||
|
||||
/**
|
||||
* @param string|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(string $apiToken, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
public function __construct(
|
||||
string $apiToken,
|
||||
$level = Logger::DEBUG,
|
||||
bool $bubble = true,
|
||||
bool $persistent = false,
|
||||
float $timeout = 0.0,
|
||||
float $writingTimeout = 10.0,
|
||||
?float $connectionTimeout = null,
|
||||
?int $chunkSize = null
|
||||
) {
|
||||
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);
|
||||
parent::__construct(
|
||||
'ssl://api.flowdock.com:443',
|
||||
$level,
|
||||
$bubble,
|
||||
$persistent,
|
||||
$timeout,
|
||||
$writingTimeout,
|
||||
$connectionTimeout,
|
||||
$chunkSize
|
||||
);
|
||||
$this->apiToken = $apiToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
|
@ -71,9 +87,7 @@ class FlowdockHandler extends SocketHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $record
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
@ -83,7 +97,7 @@ class FlowdockHandler extends SocketHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
|
@ -94,6 +108,8 @@ class FlowdockHandler extends SocketHandler
|
|||
|
||||
/**
|
||||
* Builds the body of API call
|
||||
*
|
||||
* @phpstan-param FormattedRecord $record
|
||||
*/
|
||||
private function buildContent(array $record): string
|
||||
{
|
||||
|
|
|
@ -22,13 +22,12 @@ use Monolog\Formatter\LineFormatter;
|
|||
trait FormattableHandlerTrait
|
||||
{
|
||||
/**
|
||||
* @var FormatterInterface
|
||||
* @var ?FormatterInterface
|
||||
*/
|
||||
protected $formatter;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @suppress PhanTypeMismatchReturn
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
|
@ -38,7 +37,7 @@ trait FormattableHandlerTrait
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
|
|
|
@ -25,14 +25,12 @@ use Monolog\Formatter\FormatterInterface;
|
|||
class GelfHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
* @var PublisherInterface|null the publisher object that sends the message to the server
|
||||
* @var PublisherInterface the publisher object that sends the message to the server
|
||||
*/
|
||||
protected $publisher;
|
||||
|
||||
/**
|
||||
* @param PublisherInterface $publisher a publisher object
|
||||
* @param string|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 PublisherInterface $publisher a gelf publisher object
|
||||
*/
|
||||
public function __construct(PublisherInterface $publisher, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
@ -42,7 +40,7 @@ class GelfHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
|
|
|
@ -18,12 +18,16 @@ use Monolog\ResettableInterface;
|
|||
* Forwards records to multiple handlers
|
||||
*
|
||||
* @author Lenar Lõhmus <lenar@city.ee>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class GroupHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface
|
||||
{
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
/** @var HandlerInterface[] */
|
||||
protected $handlers;
|
||||
/** @var bool */
|
||||
protected $bubble;
|
||||
|
||||
/**
|
||||
|
@ -43,7 +47,7 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -57,11 +61,12 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
if ($this->processors) {
|
||||
/** @var Record $record */
|
||||
$record = $this->processRecord($record);
|
||||
}
|
||||
|
||||
|
@ -73,7 +78,7 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -82,6 +87,7 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
|||
foreach ($records as $record) {
|
||||
$processed[] = $this->processRecord($record);
|
||||
}
|
||||
/** @var Record[] $records */
|
||||
$records = $processed;
|
||||
}
|
||||
|
||||
|
@ -111,12 +117,14 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
foreach ($this->handlers as $handler) {
|
||||
$handler->setFormatter($formatter);
|
||||
if ($handler instanceof FormattableHandlerInterface) {
|
||||
$handler->setFormatter($formatter);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Monolog\Handler;
|
|||
abstract class Handler implements HandlerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ abstract class Handler implements HandlerInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace Monolog\Handler;
|
|||
* Interface that all Monolog Handlers must implement
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
*/
|
||||
interface HandlerInterface
|
||||
{
|
||||
|
@ -30,6 +33,8 @@ interface HandlerInterface
|
|||
* @param array $record Partial log record containing only a level key
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param array{level: Level} $record
|
||||
*/
|
||||
public function isHandling(array $record): bool;
|
||||
|
||||
|
@ -46,6 +51,8 @@ interface HandlerInterface
|
|||
* @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.
|
||||
*
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
public function handle(array $record): bool;
|
||||
|
||||
|
@ -53,6 +60,8 @@ interface HandlerInterface
|
|||
* Handles a set of records at once.
|
||||
*
|
||||
* @param array $records The records to handle (an array of record arrays)
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
public function handleBatch(array $records): void;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function pushProcessor(callable $callback): HandlerInterface
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function popProcessor(): callable
|
||||
{
|
||||
|
@ -102,19 +102,21 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
if ($this->handler instanceof FormattableHandlerInterface) {
|
||||
$this->handler->setFormatter($formatter);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
|
@ -128,7 +130,7 @@ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, F
|
|||
public function reset()
|
||||
{
|
||||
if ($this->handler instanceof ResettableInterface) {
|
||||
return $this->handler->reset();
|
||||
$this->handler->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,17 +27,21 @@ use Monolog\Utils;
|
|||
*/
|
||||
class IFTTTHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var string */
|
||||
private $eventName;
|
||||
/** @var string */
|
||||
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 string|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 $eventName The name of the IFTTT Maker event that should be triggered
|
||||
* @param string $secretKey A valid IFTTT secret key
|
||||
*/
|
||||
public function __construct(string $eventName, string $secretKey, $level = Logger::ERROR, bool $bubble = true)
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new MissingExtensionException('The curl extension is needed to use the IFTTTHandler');
|
||||
}
|
||||
|
||||
$this->eventName = $eventName;
|
||||
$this->secretKey = $secretKey;
|
||||
|
||||
|
@ -45,7 +49,7 @@ class IFTTTHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function write(array $record): void
|
||||
{
|
||||
|
|
|
@ -30,13 +30,21 @@ class InsightOpsHandler extends SocketHandler
|
|||
* @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 string|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(string $token, string $region = 'us', bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
public function __construct(
|
||||
string $token,
|
||||
string $region = 'us',
|
||||
bool $useSSL = true,
|
||||
$level = Logger::DEBUG,
|
||||
bool $bubble = true,
|
||||
bool $persistent = false,
|
||||
float $timeout = 0.0,
|
||||
float $writingTimeout = 10.0,
|
||||
?float $connectionTimeout = null,
|
||||
?int $chunkSize = null
|
||||
) {
|
||||
if ($useSSL && !extension_loaded('openssl')) {
|
||||
throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler');
|
||||
}
|
||||
|
@ -45,12 +53,21 @@ class InsightOpsHandler extends SocketHandler
|
|||
? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443'
|
||||
: $region . '.data.logs.insight.rapid7.com:80';
|
||||
|
||||
parent::__construct($endpoint, $level, $bubble);
|
||||
parent::__construct(
|
||||
$endpoint,
|
||||
$level,
|
||||
$bubble,
|
||||
$persistent,
|
||||
$timeout,
|
||||
$writingTimeout,
|
||||
$connectionTimeout,
|
||||
$chunkSize
|
||||
);
|
||||
$this->logToken = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
|
|
|
@ -26,25 +26,42 @@ class LogEntriesHandler extends SocketHandler
|
|||
/**
|
||||
* @param string $token Log token supplied by LogEntries
|
||||
* @param bool $useSSL Whether or not SSL encryption should be used.
|
||||
* @param string|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.
|
||||
* @param string $host Custom hostname to send the data to if needed
|
||||
*
|
||||
* @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
|
||||
*/
|
||||
public function __construct(string $token, bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true, string $host = 'data.logentries.com')
|
||||
{
|
||||
public function __construct(
|
||||
string $token,
|
||||
bool $useSSL = true,
|
||||
$level = Logger::DEBUG,
|
||||
bool $bubble = true,
|
||||
string $host = 'data.logentries.com',
|
||||
bool $persistent = false,
|
||||
float $timeout = 0.0,
|
||||
float $writingTimeout = 10.0,
|
||||
?float $connectionTimeout = null,
|
||||
?int $chunkSize = null
|
||||
) {
|
||||
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);
|
||||
parent::__construct(
|
||||
$endpoint,
|
||||
$level,
|
||||
$bubble,
|
||||
$persistent,
|
||||
$timeout,
|
||||
$writingTimeout,
|
||||
$connectionTimeout,
|
||||
$chunkSize
|
||||
);
|
||||
$this->logToken = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@ use Monolog\Logger;
|
|||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LogglyFormatter;
|
||||
use function array_key_exists;
|
||||
use CurlHandle;
|
||||
|
||||
/**
|
||||
* Sends errors to Loggly.
|
||||
|
@ -32,18 +33,18 @@ class LogglyHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Caches the curl handlers for every given endpoint.
|
||||
*
|
||||
* @var array
|
||||
* @var resource[]|CurlHandle[]
|
||||
*/
|
||||
protected $curlHandlers = [];
|
||||
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
/** @var string[] */
|
||||
protected $tag = [];
|
||||
|
||||
/**
|
||||
* @param string $token API token supplied by Loggly
|
||||
* @param string|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.
|
||||
* @param string $token API token supplied by Loggly
|
||||
*
|
||||
* @throws MissingExtensionException If the curl extension is missing
|
||||
*/
|
||||
|
@ -63,12 +64,12 @@ class LogglyHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return resource
|
||||
* @return resource|CurlHandle
|
||||
*/
|
||||
protected function getCurlHandler(string $endpoint)
|
||||
{
|
||||
if (!array_key_exists($endpoint, $this->curlHandlers)) {
|
||||
$this->curlHandlers[$endpoint] = $this->loadCurlHandler($endpoint);
|
||||
$this->curlHandlers[$endpoint] = $this->loadCurlHandle($endpoint);
|
||||
}
|
||||
|
||||
return $this->curlHandlers[$endpoint];
|
||||
|
@ -79,9 +80,9 @@ class LogglyHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return resource
|
||||
* @return resource|CurlHandle
|
||||
*/
|
||||
private function loadCurlHandler(string $endpoint)
|
||||
private function loadCurlHandle(string $endpoint)
|
||||
{
|
||||
$url = sprintf("https://%s/%s/%s/", static::HOST, $endpoint, $this->token);
|
||||
|
||||
|
|
|
@ -40,13 +40,22 @@ class LogmaticHandler extends SocketHandler
|
|||
* @param string $hostname Host name supplied by Logmatic.
|
||||
* @param string $appname Application name supplied by Logmatic.
|
||||
* @param bool $useSSL Whether or not SSL encryption should be used.
|
||||
* @param int|string $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(string $token, string $hostname = '', string $appname = '', bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
public function __construct(
|
||||
string $token,
|
||||
string $hostname = '',
|
||||
string $appname = '',
|
||||
bool $useSSL = true,
|
||||
$level = Logger::DEBUG,
|
||||
bool $bubble = true,
|
||||
bool $persistent = false,
|
||||
float $timeout = 0.0,
|
||||
float $writingTimeout = 10.0,
|
||||
?float $connectionTimeout = null,
|
||||
?int $chunkSize = null
|
||||
) {
|
||||
if ($useSSL && !extension_loaded('openssl')) {
|
||||
throw new MissingExtensionException('The OpenSSL PHP extension is required to use SSL encrypted connection for LogmaticHandler');
|
||||
}
|
||||
|
@ -54,7 +63,16 @@ class LogmaticHandler extends SocketHandler
|
|||
$endpoint = $useSSL ? 'ssl://api.logmatic.io:10515' : 'api.logmatic.io:10514';
|
||||
$endpoint .= '/v1/';
|
||||
|
||||
parent::__construct($endpoint, $level, $bubble);
|
||||
parent::__construct(
|
||||
$endpoint,
|
||||
$level,
|
||||
$bubble,
|
||||
$persistent,
|
||||
$timeout,
|
||||
$writingTimeout,
|
||||
$connectionTimeout,
|
||||
$chunkSize
|
||||
);
|
||||
|
||||
$this->logToken = $token;
|
||||
$this->hostname = $hostname;
|
||||
|
@ -62,7 +80,7 @@ class LogmaticHandler extends SocketHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function generateDataStream(array $record): string
|
||||
{
|
||||
|
@ -70,7 +88,7 @@ class LogmaticHandler extends SocketHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
|
|
|
@ -18,11 +18,13 @@ use Monolog\Formatter\HtmlFormatter;
|
|||
* Base class for all mail handlers
|
||||
*
|
||||
* @author Gyula Sallai
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
abstract class MailHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
|
@ -32,7 +34,9 @@ abstract class MailHandler extends AbstractProcessingHandler
|
|||
if ($record['level'] < $this->level) {
|
||||
continue;
|
||||
}
|
||||
$messages[] = $this->processRecord($record);
|
||||
/** @var Record $message */
|
||||
$message = $this->processRecord($record);
|
||||
$messages[] = $message;
|
||||
}
|
||||
|
||||
if (!empty($messages)) {
|
||||
|
@ -45,17 +49,23 @@ abstract class MailHandler extends AbstractProcessingHandler
|
|||
*
|
||||
* @param string $content formatted email body to be sent
|
||||
* @param array $records the array of log records that formed this content
|
||||
*
|
||||
* @phpstan-param Record[] $records
|
||||
*/
|
||||
abstract protected function send(string $content, array $records): void;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record): void
|
||||
{
|
||||
$this->send((string) $record['formatted'], [$record]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param non-empty-array<Record> $records
|
||||
* @phpstan-return Record
|
||||
*/
|
||||
protected function getHighestRecord(array $records): array
|
||||
{
|
||||
$highestRecord = null;
|
||||
|
@ -70,7 +80,7 @@ abstract class MailHandler extends AbstractProcessingHandler
|
|||
|
||||
protected function isHtmlBody(string $body): bool
|
||||
{
|
||||
return substr($body, 0, 1) === '<';
|
||||
return ($body[0] ?? null) === '<';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Monolog\Handler;
|
|||
|
||||
use Monolog\Logger;
|
||||
use Swift;
|
||||
use Swift_Message;
|
||||
|
||||
/**
|
||||
* MandrillHandler uses cURL to send the emails to the Mandrill API
|
||||
|
@ -21,25 +22,25 @@ use Swift;
|
|||
*/
|
||||
class MandrillHandler extends MailHandler
|
||||
{
|
||||
/** @var Swift_Message */
|
||||
protected $message;
|
||||
/** @var string */
|
||||
protected $apiKey;
|
||||
|
||||
/**
|
||||
* @psalm-param Swift_Message|callable(string, array): Swift_Message $message
|
||||
* @psalm-param Swift_Message|callable(): Swift_Message $message
|
||||
*
|
||||
* @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 string|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 $apiKey A valid Mandrill API key
|
||||
* @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
|
||||
*/
|
||||
public function __construct(string $apiKey, $message, $level = Logger::ERROR, bool $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
if (!$message instanceof \Swift_Message && is_callable($message)) {
|
||||
if (!$message instanceof Swift_Message && is_callable($message)) {
|
||||
$message = $message();
|
||||
}
|
||||
if (!$message instanceof \Swift_Message) {
|
||||
if (!$message instanceof Swift_Message) {
|
||||
throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
|
||||
}
|
||||
$this->message = $message;
|
||||
|
@ -47,7 +48,7 @@ class MandrillHandler extends MailHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function send(string $content, array $records): void
|
||||
{
|
||||
|
@ -58,9 +59,11 @@ class MandrillHandler extends MailHandler
|
|||
|
||||
$message = clone $this->message;
|
||||
$message->setBody($content, $mime);
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
|
||||
$message->setDate(new \DateTimeImmutable());
|
||||
} else {
|
||||
/** @phpstan-ignore-next-line */
|
||||
$message->setDate(time());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,11 @@ use Monolog\Formatter\MongoDBFormatter;
|
|||
*/
|
||||
class MongoDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var \MongoDB\Collection */
|
||||
private $collection;
|
||||
/** @var Client|Manager */
|
||||
private $manager;
|
||||
/** @var string */
|
||||
private $namespace;
|
||||
|
||||
/**
|
||||
|
@ -43,8 +46,6 @@ class MongoDBHandler extends AbstractProcessingHandler
|
|||
* @param Client|Manager $mongodb MongoDB library or driver client
|
||||
* @param string $database Database name
|
||||
* @param string $collection Collection name
|
||||
* @param string|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($mongodb, string $database, string $collection, $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class NativeMailerHandler extends MailHandler
|
|||
{
|
||||
/**
|
||||
* The email addresses to which the message will be sent
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $to;
|
||||
|
||||
|
@ -36,13 +36,13 @@ class NativeMailerHandler extends MailHandler
|
|||
|
||||
/**
|
||||
* Optional headers for the message
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $headers = [];
|
||||
|
||||
/**
|
||||
* Optional parameters for the message
|
||||
* @var array
|
||||
* @var string[]
|
||||
*/
|
||||
protected $parameters = [];
|
||||
|
||||
|
@ -65,12 +65,10 @@ class NativeMailerHandler extends MailHandler
|
|||
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 string|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
|
||||
* @param string|string[] $to The receiver of the mail
|
||||
* @param string $subject The subject of the mail
|
||||
* @param string $from The sender of the mail
|
||||
* @param int $maxColumnWidth The maximum column width that the message lines will have
|
||||
*/
|
||||
public function __construct($to, string $subject, string $from, $level = Logger::ERROR, bool $bubble = true, int $maxColumnWidth = 70)
|
||||
{
|
||||
|
@ -84,7 +82,7 @@ class NativeMailerHandler extends MailHandler
|
|||
/**
|
||||
* Add headers to the message
|
||||
*
|
||||
* @param string|array $headers Custom added headers
|
||||
* @param string|string[] $headers Custom added headers
|
||||
*/
|
||||
public function addHeader($headers): self
|
||||
{
|
||||
|
@ -101,7 +99,7 @@ class NativeMailerHandler extends MailHandler
|
|||
/**
|
||||
* Add parameters to the message
|
||||
*
|
||||
* @param string|array $parameters Custom added parameters
|
||||
* @param string|string[] $parameters Custom added parameters
|
||||
*/
|
||||
public function addParameter($parameters): self
|
||||
{
|
||||
|
@ -111,7 +109,7 @@ class NativeMailerHandler extends MailHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function send(string $content, array $records): void
|
||||
{
|
||||
|
|
|
@ -30,14 +30,14 @@ class NewRelicHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* Name of the New Relic application that will receive logs from this handler.
|
||||
*
|
||||
* @var string|null
|
||||
* @var ?string
|
||||
*/
|
||||
protected $appName;
|
||||
|
||||
/**
|
||||
* Name of the current transaction
|
||||
*
|
||||
* @var string|null
|
||||
* @var ?string
|
||||
*/
|
||||
protected $transactionName;
|
||||
|
||||
|
@ -52,8 +52,6 @@ class NewRelicHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param string|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|null $appName
|
||||
* @param bool $explodeArrays
|
||||
* @param string|null $transactionName
|
||||
|
@ -135,6 +133,8 @@ class NewRelicHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* 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 mixed[] $context
|
||||
*/
|
||||
protected function getAppName(array $context): ?string
|
||||
{
|
||||
|
@ -148,6 +148,8 @@ class NewRelicHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* 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 mixed[] $context
|
||||
*/
|
||||
protected function getTransactionName(array $context): ?string
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace Monolog\Handler;
|
|||
class NoopHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ class NoopHandler extends Handler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Blackhole
|
||||
|
@ -20,6 +21,9 @@ use Monolog\Logger;
|
|||
* to put on top of an existing stack to override it temporarily.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @phpstan-import-type Level from \Monolog\Logger
|
||||
* @phpstan-import-type LevelName from \Monolog\Logger
|
||||
*/
|
||||
class NullHandler extends Handler
|
||||
{
|
||||
|
@ -30,6 +34,8 @@ class NullHandler extends Handler
|
|||
|
||||
/**
|
||||
* @param string|int $level The minimum logging level at which this handler will be triggered
|
||||
*
|
||||
* @phpstan-param Level|LevelName|LogLevel::* $level
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG)
|
||||
{
|
||||
|
@ -37,7 +43,7 @@ class NullHandler extends Handler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
|
@ -45,7 +51,7 @@ class NullHandler extends Handler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
|
|
@ -61,8 +61,6 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
|
|||
/**
|
||||
* @param HandlerInterface $handler
|
||||
* @param int[] $thresholdMap Dictionary of logger level => threshold
|
||||
* @param int|string $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble
|
||||
*/
|
||||
public function __construct(
|
||||
HandlerInterface $handler,
|
||||
|
@ -87,10 +85,7 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
|
|||
* 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 Boolean 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.
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
|
@ -127,20 +122,28 @@ class OverflowHandler extends AbstractHandler implements FormattableHandlerInter
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter): HandlerInterface
|
||||
{
|
||||
$this->handler->setFormatter($formatter);
|
||||
if ($this->handler instanceof FormattableHandlerInterface) {
|
||||
$this->handler->setFormatter($formatter);
|
||||
|
||||
return $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFormatter(): FormatterInterface
|
||||
{
|
||||
return $this->handler->getFormatter();
|
||||
if ($this->handler instanceof FormattableHandlerInterface) {
|
||||
return $this->handler->getFormatter();
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,12 @@ use PhpConsole\Helper;
|
|||
* PC::debug($_SERVER); // PHP Console debugger for any type of vars
|
||||
*
|
||||
* @author Sergey Barbushin https://www.linkedin.com/in/barbushin
|
||||
*
|
||||
* @phpstan-import-type Record from \Monolog\Logger
|
||||
*/
|
||||
class PHPConsoleHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private $options = [
|
||||
'enabled' => true, // bool Is PHP Console server enabled
|
||||
'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with...
|
||||
|
@ -67,10 +70,8 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
private $connector;
|
||||
|
||||
/**
|
||||
* @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details
|
||||
* @param Connector|null $connector Instance of \PhpConsole\Connector class (optional)
|
||||
* @param string|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<string, mixed> $options See \Monolog\Handler\PHPConsoleHandler::$options for more details
|
||||
* @param Connector|null $connector Instance of \PhpConsole\Connector class (optional)
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct(array $options = [], ?Connector $connector = null, $level = Logger::DEBUG, bool $bubble = true)
|
||||
|
@ -83,6 +84,11 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
$this->connector = $this->initConnector($connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $options
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function initOptions(array $options): array
|
||||
{
|
||||
$wrongOptions = array_diff(array_keys($options), array_keys($this->options));
|
||||
|
@ -93,9 +99,6 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
return array_replace($this->options, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @suppress PhanTypeMismatchArgument
|
||||
*/
|
||||
private function initConnector(?Connector $connector = null): Connector
|
||||
{
|
||||
if (!$connector) {
|
||||
|
@ -156,6 +159,9 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
return $this->connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
|
@ -184,6 +190,9 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleDebugRecord(array $record): void
|
||||
{
|
||||
$tags = $this->getRecordTags($record);
|
||||
|
@ -194,11 +203,17 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
$this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleExceptionRecord(array $record): void
|
||||
{
|
||||
$this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
*/
|
||||
private function handleErrorRecord(array $record): void
|
||||
{
|
||||
$context = $record['context'];
|
||||
|
@ -212,6 +227,10 @@ class PHPConsoleHandler extends AbstractProcessingHandler
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param Record $record
|
||||
* @return string
|
||||
*/
|
||||
private function getRecordTags(array &$record)
|
||||
{
|
||||
$tags = null;
|
||||
|
|
|
@ -44,12 +44,12 @@ class ProcessHandler extends AbstractProcessingHandler
|
|||
private $cwd;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var resource[]
|
||||
*/
|
||||
private $pipes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array<int, string[]>
|
||||
*/
|
||||
protected const DESCRIPTOR_SPEC = [
|
||||
0 => ['pipe', 'r'], // STDIN is a pipe that the child will read from
|
||||
|
@ -60,8 +60,6 @@ class ProcessHandler extends AbstractProcessingHandler
|
|||
/**
|
||||
* @param string $command Command for the process to start. Absolute paths are recommended,
|
||||
* especially if you do not use the $cwd parameter.
|
||||
* @param string|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|null $cwd "Current working directory" (CWD) for the process to be executed in.
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -164,7 +162,7 @@ class ProcessHandler extends AbstractProcessingHandler
|
|||
*/
|
||||
protected function readProcessErrors(): string
|
||||
{
|
||||
return stream_get_contents($this->pipes[2]);
|
||||
return (string) stream_get_contents($this->pipes[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,7 +176,7 @@ class ProcessHandler extends AbstractProcessingHandler
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user