更新vendor

修正生成sitemap
This commit is contained in:
yumo 2023-05-05 11:10:57 +08:00
parent c7deee9ae9
commit ccec51ad88
201 changed files with 2782 additions and 1156 deletions

View File

@ -116,6 +116,8 @@ abstract class BaseController
$url = $_SERVER["HTTP_REFERER"]; $url = $_SERVER["HTTP_REFERER"];
} elseif ($url) { } elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url); $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url);
}else{
$url = app('route')->buildUrl("/");
} }
$result = [ $result = [
@ -152,7 +154,6 @@ abstract class BaseController
} elseif ($url) { } elseif ($url) {
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url); $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : $this->app->route->buildUrl($url);
} }
$result = [ $result = [
'code' => 0, 'code' => 0,
'msg' => $msg, 'msg' => $msg,
@ -160,7 +161,6 @@ abstract class BaseController
'url' => $url, 'url' => $url,
'wait' => $wait, 'wait' => $wait,
]; ];
$type = $this->getResponseType(); $type = $this->getResponseType();
if ($type == 'html') { if ($type == 'html') {
$response = view(config('app.dispatch_success_tmpl'), $result); $response = view(config('app.dispatch_success_tmpl'), $result);

View File

@ -15,6 +15,7 @@ use Exception;
use think\db\exception\DataNotFoundException; use think\db\exception\DataNotFoundException;
use think\db\exception\DbException; use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException; use think\db\exception\ModelNotFoundException;
use think\facade\Request;
class Index extends AuthController class Index extends AuthController
{ {
@ -82,11 +83,9 @@ class Index extends AuthController
*/ */
public function sitemap() public function sitemap()
{ {
//获取协议
$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ?
"https://" : "http://";
//获取域名 //获取域名
$domain = $protocol . $_SERVER['HTTP_HOST']; $domain = Request::domain();
//获取页码 //获取页码
$page = input('page/d'); $page = input('page/d');
if (!$page) { if (!$page) {
@ -114,10 +113,9 @@ class Index extends AuthController
->where('status', 1)->where('status', 1) ->where('status', 1)->where('status', 1)
->page($page, $pagesize) ->page($page, $pagesize)
->order('id desc')->select(); ->order('id desc')->select();
foreach ($categoryInfo as $v) { foreach ($categoryInfo as $v) {
$str .= '<url>'; $str .= '<url>';
$str .= '<loc>' . $domain . url('article/lists?id=' . $v['id']) . '</loc>'; $str .= '<loc>' . url('index/article/lists',["id"=>$v['id']],".html",$domain) . '</loc>';
$str .= '<lastmod>' . $v['create_time'] . '</lastmod>'; $str .= '<lastmod>' . $v['create_time'] . '</lastmod>';
$str .= '<changefreq>always</changefreq>'; $str .= '<changefreq>always</changefreq>';
$str .= '<priority>0.8</priority>'; $str .= '<priority>0.8</priority>';
@ -132,7 +130,7 @@ class Index extends AuthController
foreach ($documentInfo as $v) { foreach ($documentInfo as $v) {
$str .= '<url>'; $str .= '<url>';
$str .= '<loc>' . $domain . url('article/detail?id=' . $v['id']) . $v['id'] . '</loc>'; $str .= '<loc>' . url('/index/article/detail',["id"=>$v['id']],".html",$domain) . '</loc>';
$str .= '<lastmod>' . $v['create_time'] . '</lastmod>'; $str .= '<lastmod>' . $v['create_time'] . '</lastmod>';
$str .= '<changefreq>monthly</changefreq>'; $str .= '<changefreq>monthly</changefreq>';
$str .= '<priority>0.6</priority>'; $str .= '<priority>0.6</priority>';
@ -140,17 +138,13 @@ class Index extends AuthController
} }
if (count($categoryInfo) < $pagesize && count($documentInfo) < $pagesize) { if (count($categoryInfo) < $pagesize && count($documentInfo) < $pagesize) {
$str .= '</urlset>'; $str .= '</urlset>';
if (!(file_put_contents('sitemap.xml', $str, FILE_APPEND | LOCK_EX))) { return (!(file_put_contents('sitemap.xml', $str, FILE_APPEND | LOCK_EX))) ?
$this->error('站点地图更新失败!',"/admin/"); $this->failedNotice("站点地图更新失败!", "/admin/") :
} else { $this->successfulNotice("站点地图全部更新完成!", "/admin/");
$this->success('站点地图全部更新完成!', "/admin/");
}
} }
//写入 //写入
if (!(file_put_contents('sitemap.xml', $str, FILE_APPEND | LOCK_EX))) { return (!(file_put_contents('sitemap.xml', $str, FILE_APPEND | LOCK_EX))) ?
$this->error('站点地图更新失败!'); $this->failedNotice("站点地图更新失败!", "/admin/") :
} else { $this->successfulNotice('站点地图正在生成,请稍后(' . $page . '...', 'sitemap?page=' . ($page + 1));
$this->success('站点地图正在生成,请稍后(' . $page . '...', 'sitemap?page=' . ($page + 1));
}
} }
} }

View File

@ -38,9 +38,10 @@
<aside class="lyear-layout-sidebar"> <aside class="lyear-layout-sidebar">
<!-- logo --> <!-- logo -->
<div id="logo" class="sidebar-header"> <div id="logo" class="sidebar-header">
<a href="/admin/index/index.html"><img src="/static/admin/img/logo-sidebar.png" <a href="/admin/index/index.html">
title="{:system_config('title')}后台管理系统" <img src="/static/admin/img/logo-sidebar.png" title="{:system_config('title')}后台管理系统"
alt="{:system_config('title')}后台管理系统"/></a> alt="{:system_config('title')}后台管理系统"/>
</a>
</div> </div>
<div class="lyear-layout-sidebar-scroll"> <div class="lyear-layout-sidebar-scroll">
<nav class="sidebar-main"> <nav class="sidebar-main">

View File

@ -69,6 +69,22 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header"><h4>常用功能</h4></div>
<div class="card-body">
<div class="row">
<div class="example-box">
<div class="col-sm-3 col-md-2">
<a class="btn btn-primary btn-w-md" href="{:url('index/sitemap')}" type="button">网站地图</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="card"> <div class="card">

17
vendor/autoload.php vendored
View File

@ -3,8 +3,21 @@
// autoload.php @generated by Composer // autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) { if (PHP_VERSION_ID < 50600) {
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; if (!headers_sent()) {
exit(1); header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
} }
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';

View File

@ -42,6 +42,9 @@ namespace Composer\Autoload;
*/ */
class ClassLoader class ClassLoader
{ {
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */ /** @var ?string */
private $vendorDir; private $vendorDir;
@ -106,6 +109,7 @@ class ClassLoader
public function __construct($vendorDir = null) public function __construct($vendorDir = null)
{ {
$this->vendorDir = $vendorDir; $this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
} }
/** /**
@ -425,7 +429,8 @@ class ClassLoader
public function loadClass($class) public function loadClass($class)
{ {
if ($file = $this->findFile($class)) { if ($file = $this->findFile($class)) {
includeFile($file); $includeFile = self::$includeFile;
$includeFile($file);
return true; return true;
} }
@ -555,18 +560,26 @@ class ClassLoader
return false; return false;
} }
}
/** /**
* Scope isolated include. * @return void
* */
* Prevents access to $this/self from included files. private static function initializeIncludeClosure()
* {
* @param string $file if (self::$includeFile !== null) {
* @return void return;
* @private }
*/
function includeFile($file) /**
{ * Scope isolated include.
include $file; *
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
} }

View File

@ -10,7 +10,7 @@ return array(
'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'), 'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-filesystem/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'), 'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-filesystem/src', $vendorDir . '/topthink/think-template/src'),
'mailer\\' => array($vendorDir . '/yzh52521/think-mail/src/mailer'), 'mailer\\' => array($vendorDir . '/yzh52521/think-mail/src/mailer'),
'liliuwei\\social\\' => array($vendorDir . '/liliuwei/thinkphp-social/src'), 'liliuwei\\social\\' => array($vendorDir . '/liliuwei/thinkphp-social/src'),
'liliuwei\\sitemap\\' => array($vendorDir . '/liliuwei/php-sitemap/src'), 'liliuwei\\sitemap\\' => array($vendorDir . '/liliuwei/php-sitemap/src'),
@ -39,6 +39,7 @@ return array(
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'FormBuilder\\' => array($vendorDir . '/xaboy/form-builder/src'), 'FormBuilder\\' => array($vendorDir . '/xaboy/form-builder/src'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'), 'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'), 'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/src'),
'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'), 'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'),
); );

View File

@ -33,25 +33,18 @@ class ComposerAutoloaderInit4b57298e8d0e895486f3307a354a7e1a
$loader->register(true); $loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a::$files; $filesToLoad = \Composer\Autoload\ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a::$files;
foreach ($includeFiles as $fileIdentifier => $file) { $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
composerRequire4b57298e8d0e895486f3307a354a7e1a($fileIdentifier, $file); if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
} }
return $loader; return $loader;
} }
} }
/**
* @param string $fileIdentifier
* @param string $file
* @return void
*/
function composerRequire4b57298e8d0e895486f3307a354a7e1a($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}

View File

@ -82,6 +82,7 @@ class ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a
), ),
'D' => 'D' =>
array ( array (
'Doctrine\\Deprecations\\' => 22,
'Doctrine\\Common\\Lexer\\' => 22, 'Doctrine\\Common\\Lexer\\' => 22,
'Doctrine\\Common\\Annotations\\' => 28, 'Doctrine\\Common\\Annotations\\' => 28,
), ),
@ -106,10 +107,10 @@ class ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a
), ),
'think\\' => 'think\\' =>
array ( array (
0 => __DIR__ . '/..' . '/topthink/framework/src/think', 0 => __DIR__ . '/..' . '/topthink/think-helper/src',
1 => __DIR__ . '/..' . '/topthink/think-filesystem/src', 1 => __DIR__ . '/..' . '/topthink/think-orm/src',
2 => __DIR__ . '/..' . '/topthink/think-helper/src', 2 => __DIR__ . '/..' . '/topthink/framework/src/think',
3 => __DIR__ . '/..' . '/topthink/think-orm/src', 3 => __DIR__ . '/..' . '/topthink/think-filesystem/src',
4 => __DIR__ . '/..' . '/topthink/think-template/src', 4 => __DIR__ . '/..' . '/topthink/think-template/src',
), ),
'mailer\\' => 'mailer\\' =>
@ -224,9 +225,13 @@ class ComposerStaticInit4b57298e8d0e895486f3307a354a7e1a
array ( array (
0 => __DIR__ . '/..' . '/egulias/email-validator/src', 0 => __DIR__ . '/..' . '/egulias/email-validator/src',
), ),
'Doctrine\\Deprecations\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations',
),
'Doctrine\\Common\\Lexer\\' => 'Doctrine\\Common\\Lexer\\' =>
array ( array (
0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer', 0 => __DIR__ . '/..' . '/doctrine/lexer/src',
), ),
'Doctrine\\Common\\Annotations\\' => 'Doctrine\\Common\\Annotations\\' =>
array ( array (

View File

@ -2,17 +2,17 @@
"packages": [ "packages": [
{ {
"name": "doctrine/annotations", "name": "doctrine/annotations",
"version": "1.13.3", "version": "1.14.3",
"version_normalized": "1.13.3.0", "version_normalized": "1.14.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/annotations.git", "url": "https://github.com/doctrine/annotations.git",
"reference": "648b0343343565c4a056bfc8392201385e8d89f0" "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
"reference": "648b0343343565c4a056bfc8392201385e8d89f0", "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -22,20 +22,23 @@
] ]
}, },
"require": { "require": {
"doctrine/lexer": "1.*", "doctrine/lexer": "^1 || ^2",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"php": "^7.1 || ^8.0", "php": "^7.1 || ^8.0",
"psr/cache": "^1 || ^2 || ^3" "psr/cache": "^1 || ^2 || ^3"
}, },
"require-dev": { "require-dev": {
"doctrine/cache": "^1.11 || ^2.0", "doctrine/cache": "^1.11 || ^2.0",
"doctrine/coding-standard": "^6.0 || ^8.1", "doctrine/coding-standard": "^9 || ^10",
"phpstan/phpstan": "^1.4.10 || ^1.8.0", "phpstan/phpstan": "~1.4.10 || ^1.8.0",
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"symfony/cache": "^4.4 || ^5.2", "symfony/cache": "^4.4 || ^5.4 || ^6",
"vimeo/psalm": "^4.10" "vimeo/psalm": "^4.10"
}, },
"time": "2022-07-02T10:48:51+00:00", "suggest": {
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
},
"time": "2023-02-01T09:20:38+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -78,23 +81,23 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/annotations/issues", "issues": "https://github.com/doctrine/annotations/issues",
"source": "https://github.com/doctrine/annotations/tree/1.13.3" "source": "https://github.com/doctrine/annotations/tree/1.14.3"
}, },
"install-path": "../doctrine/annotations" "install-path": "../doctrine/annotations"
}, },
{ {
"name": "doctrine/lexer", "name": "doctrine/deprecations",
"version": "1.2.3", "version": "v1.0.0",
"version_normalized": "1.2.3.0", "version_normalized": "1.0.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/lexer.git", "url": "https://github.com/doctrine/deprecations.git",
"reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -104,20 +107,74 @@
] ]
}, },
"require": { "require": {
"php": "^7.1 || ^8.0" "php": "^7.1|^8.0"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^9.0", "doctrine/coding-standard": "^9",
"phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5|^8.5|^9.5",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/log": "^1|^2|^3"
"vimeo/psalm": "^4.11"
}, },
"time": "2022-02-28T11:07:21+00:00", "suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"time": "2022-05-02T15:47:09+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
"source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
},
"install-path": "../doctrine/deprecations"
},
{
"name": "doctrine/lexer",
"version": "2.1.0",
"version_normalized": "2.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
"reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"doctrine/deprecations": "^1.0",
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^9 || ^10",
"phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"psalm/plugin-phpunit": "^0.18.3",
"vimeo/psalm": "^4.11 || ^5.0"
},
"time": "2022-12-14T08:49:07+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Lexer\\": "src"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -149,7 +206,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/lexer/issues", "issues": "https://github.com/doctrine/lexer/issues",
"source": "https://github.com/doctrine/lexer/tree/1.2.3" "source": "https://github.com/doctrine/lexer/tree/2.1.0"
}, },
"funding": [ "funding": [
{ {
@ -169,17 +226,17 @@
}, },
{ {
"name": "egulias/email-validator", "name": "egulias/email-validator",
"version": "3.2.1", "version": "3.2.5",
"version_normalized": "3.2.1.0", "version_normalized": "3.2.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/egulias/EmailValidator.git", "url": "https://github.com/egulias/EmailValidator.git",
"reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715" "reference": "b531a2311709443320c786feb4519cfaf94af796"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f88dcf4b14af14a98ad96b14b2b317969eab6715", "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b531a2311709443320c786feb4519cfaf94af796",
"reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715", "reference": "b531a2311709443320c786feb4519cfaf94af796",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -189,19 +246,18 @@
] ]
}, },
"require": { "require": {
"doctrine/lexer": "^1.2", "doctrine/lexer": "^1.2|^2",
"php": ">=7.2", "php": ">=7.2",
"symfony/polyfill-intl-idn": "^1.15" "symfony/polyfill-intl-idn": "^1.15"
}, },
"require-dev": { "require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^8.5.8|^9.3.3", "phpunit/phpunit": "^8.5.8|^9.3.3",
"vimeo/psalm": "^4" "vimeo/psalm": "^4"
}, },
"suggest": { "suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
}, },
"time": "2022-06-18T20:57:19+00:00", "time": "2023-01-02T17:26:14+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -234,7 +290,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/egulias/EmailValidator/issues", "issues": "https://github.com/egulias/EmailValidator/issues",
"source": "https://github.com/egulias/EmailValidator/tree/3.2.1" "source": "https://github.com/egulias/EmailValidator/tree/3.2.5"
}, },
"funding": [ "funding": [
{ {
@ -544,17 +600,17 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.6.4", "version": "v6.7.1",
"version_normalized": "6.6.4.0", "version_normalized": "6.7.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" "reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/49cd7ea3d2563f028d7811f06864a53b1f15ff55",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", "reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -570,24 +626,26 @@
"php": ">=5.5.0" "php": ">=5.5.0"
}, },
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6.2", "squizlabs/php_codesniffer": "^3.7.1",
"yoast/phpunit-polyfills": "^1.0.0" "yoast/phpunit-polyfills": "^1.0.4"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
}, },
"time": "2022-08-22T09:22:00+00:00", "time": "2022-12-08T13:30:06+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -619,7 +677,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.7.1"
}, },
"funding": [ "funding": [
{ {
@ -805,17 +863,17 @@
}, },
{ {
"name": "psr/http-message", "name": "psr/http-message",
"version": "1.0.1", "version": "1.1",
"version_normalized": "1.0.1.0", "version_normalized": "1.1.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/http-message.git", "url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -825,13 +883,13 @@
] ]
}, },
"require": { "require": {
"php": ">=5.3.0" "php": "^7.2 || ^8.0"
}, },
"time": "2016-08-06T14:39:51+00:00", "time": "2023-04-04T09:50:52+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.0.x-dev" "dev-master": "1.1.x-dev"
} }
}, },
"installation-source": "dist", "installation-source": "dist",
@ -861,7 +919,7 @@
"response" "response"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/http-message/tree/master" "source": "https://github.com/php-fig/http-message/tree/1.1"
}, },
"install-path": "../psr/http-message" "install-path": "../psr/http-message"
}, },
@ -1121,17 +1179,17 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v5.4.9", "version": "v5.4.22",
"version_normalized": "5.4.9.0", "version_normalized": "5.4.22.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df20e45d56da29a4b1d8259dd6e950acbf1b13f",
"reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -1167,7 +1225,7 @@
"symfony/dependency-injection": "", "symfony/dependency-injection": "",
"symfony/http-kernel": "" "symfony/http-kernel": ""
}, },
"time": "2022-05-05T16:45:39+00:00", "time": "2023-03-17T11:31:58+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1195,7 +1253,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.22"
}, },
"funding": [ "funding": [
{ {
@ -1303,17 +1361,17 @@
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v5.4.15", "version": "v5.4.23",
"version_normalized": "5.4.15.0", "version_normalized": "5.4.23.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "75bd663ff2db90141bfb733682459d5bbe9e29c3" "reference": "af9fbb378f5f956c8f29d4886644c84c193780ac"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/75bd663ff2db90141bfb733682459d5bbe9e29c3", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/af9fbb378f5f956c8f29d4886644c84c193780ac",
"reference": "75bd663ff2db90141bfb733682459d5bbe9e29c3", "reference": "af9fbb378f5f956c8f29d4886644c84c193780ac",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -1340,7 +1398,7 @@
"suggest": { "suggest": {
"symfony/mime": "To use the file extension guesser" "symfony/mime": "To use the file extension guesser"
}, },
"time": "2022-10-12T09:43:19+00:00", "time": "2023-04-18T06:30:11+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1368,7 +1426,7 @@
"description": "Defines an object-oriented layer for the HTTP specification", "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-foundation/tree/v5.4.15" "source": "https://github.com/symfony/http-foundation/tree/v5.4.23"
}, },
"funding": [ "funding": [
{ {
@ -1388,17 +1446,17 @@
}, },
{ {
"name": "symfony/mailer", "name": "symfony/mailer",
"version": "v5.4.15", "version": "v5.4.22",
"version_normalized": "5.4.15.0", "version_normalized": "5.4.22.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mailer.git", "url": "https://github.com/symfony/mailer.git",
"reference": "926f4deddb60d40024e6058fd8f94e70e4024930" "reference": "6330cd465dfd8b7a07515757a1c37069075f7b0b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/926f4deddb60d40024e6058fd8f94e70e4024930", "url": "https://api.github.com/repos/symfony/mailer/zipball/6330cd465dfd8b7a07515757a1c37069075f7b0b",
"reference": "926f4deddb60d40024e6058fd8f94e70e4024930", "reference": "6330cd465dfd8b7a07515757a1c37069075f7b0b",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -1408,7 +1466,7 @@
] ]
}, },
"require": { "require": {
"egulias/email-validator": "^2.1.10|^3", "egulias/email-validator": "^2.1.10|^3|^4",
"php": ">=7.2.5", "php": ">=7.2.5",
"psr/event-dispatcher": "^1", "psr/event-dispatcher": "^1",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
@ -1422,10 +1480,10 @@
"symfony/http-kernel": "<4.4" "symfony/http-kernel": "<4.4"
}, },
"require-dev": { "require-dev": {
"symfony/http-client-contracts": "^1.1|^2|^3", "symfony/http-client": "^4.4|^5.0|^6.0",
"symfony/messenger": "^4.4|^5.0|^6.0" "symfony/messenger": "^4.4|^5.0|^6.0"
}, },
"time": "2022-10-27T07:55:40+00:00", "time": "2023-03-10T10:15:32+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1453,7 +1511,7 @@
"description": "Helps sending emails", "description": "Helps sending emails",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/mailer/tree/v5.4.15" "source": "https://github.com/symfony/mailer/tree/v5.4.22"
}, },
"funding": [ "funding": [
{ {
@ -1473,17 +1531,17 @@
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v5.4.14", "version": "v5.4.23",
"version_normalized": "5.4.14.0", "version_normalized": "5.4.23.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4" "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", "url": "https://api.github.com/repos/symfony/mime/zipball/ae0a1032a450a3abf305ee44fc55ed423fbf16e3",
"reference": "1c118b253bb3495d81e95a6e3ec6c2766a98a0c4", "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -1507,14 +1565,14 @@
"symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6" "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6"
}, },
"require-dev": { "require-dev": {
"egulias/email-validator": "^2.1.10|^3.1", "egulias/email-validator": "^2.1.10|^3.1|^4",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
"symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0",
"symfony/property-access": "^4.4|^5.1|^6.0", "symfony/property-access": "^4.4|^5.1|^6.0",
"symfony/property-info": "^4.4|^5.1|^6.0", "symfony/property-info": "^4.4|^5.1|^6.0",
"symfony/serializer": "^5.4.14|~6.0.14|^6.1.6" "symfony/serializer": "^5.4.14|~6.0.14|^6.1.6"
}, },
"time": "2022-10-07T08:01:20+00:00", "time": "2023-04-19T09:49:13+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1546,7 +1604,7 @@
"mime-type" "mime-type"
], ],
"support": { "support": {
"source": "https://github.com/symfony/mime/tree/v5.4.14" "source": "https://github.com/symfony/mime/tree/v5.4.23"
}, },
"funding": [ "funding": [
{ {
@ -2214,17 +2272,17 @@
}, },
{ {
"name": "topthink/framework", "name": "topthink/framework",
"version": "v6.1.1", "version": "v6.1.2",
"version_normalized": "6.1.1.0", "version_normalized": "6.1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/framework.git", "url": "https://github.com/top-think/framework.git",
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210" "reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/framework/zipball/2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", "url": "https://api.github.com/repos/top-think/framework/zipball/67235be5b919aaaf1de5aed9839f65d8e766aca3",
"reference": "2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210", "reference": "67235be5b919aaaf1de5aed9839f65d8e766aca3",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2242,7 +2300,7 @@
"psr/log": "~1.0", "psr/log": "~1.0",
"psr/simple-cache": "^1.0", "psr/simple-cache": "^1.0",
"topthink/think-helper": "^3.1.1", "topthink/think-helper": "^3.1.1",
"topthink/think-orm": "^2.0" "topthink/think-orm": "^2.0|^3.0"
}, },
"require-dev": { "require-dev": {
"guzzlehttp/psr7": "^2.1.0", "guzzlehttp/psr7": "^2.1.0",
@ -2250,7 +2308,7 @@
"mockery/mockery": "^1.2", "mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.0" "phpunit/phpunit": "^7.0"
}, },
"time": "2022-10-26T03:48:53+00:00", "time": "2023-02-08T02:24:01+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -2282,23 +2340,23 @@
], ],
"support": { "support": {
"issues": "https://github.com/top-think/framework/issues", "issues": "https://github.com/top-think/framework/issues",
"source": "https://github.com/top-think/framework/tree/v6.1.1" "source": "https://github.com/top-think/framework/tree/v6.1.2"
}, },
"install-path": "../topthink/framework" "install-path": "../topthink/framework"
}, },
{ {
"name": "topthink/think-captcha", "name": "topthink/think-captcha",
"version": "v3.0.8", "version": "v3.0.9",
"version_normalized": "3.0.8.0", "version_normalized": "3.0.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-captcha.git", "url": "https://github.com/top-think/think-captcha.git",
"reference": "52fba122c953995bec3013c635025172491ae299" "reference": "b1ef360670578214edeebcf824aaf6ab7ee0528b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-captcha/zipball/52fba122c953995bec3013c635025172491ae299", "url": "https://api.github.com/repos/top-think/think-captcha/zipball/b1ef360670578214edeebcf824aaf6ab7ee0528b",
"reference": "52fba122c953995bec3013c635025172491ae299", "reference": "b1ef360670578214edeebcf824aaf6ab7ee0528b",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2308,9 +2366,9 @@
] ]
}, },
"require": { "require": {
"topthink/framework": "^6.0" "topthink/framework": "^6.0|^8.0"
}, },
"time": "2022-10-26T07:59:42+00:00", "time": "2023-04-27T07:18:40+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {
@ -2344,23 +2402,23 @@
"description": "captcha package for thinkphp", "description": "captcha package for thinkphp",
"support": { "support": {
"issues": "https://github.com/top-think/think-captcha/issues", "issues": "https://github.com/top-think/think-captcha/issues",
"source": "https://github.com/top-think/think-captcha/tree/v3.0.8" "source": "https://github.com/top-think/think-captcha/tree/v3.0.9"
}, },
"install-path": "../topthink/think-captcha" "install-path": "../topthink/think-captcha"
}, },
{ {
"name": "topthink/think-filesystem", "name": "topthink/think-filesystem",
"version": "v2.0.0", "version": "v2.0.2",
"version_normalized": "2.0.0.0", "version_normalized": "2.0.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-filesystem.git", "url": "https://github.com/top-think/think-filesystem.git",
"reference": "63e525fd74f451b2df1df060c3194e9b6e724730" "reference": "c08503232fcae0c3c7fefae5e6b5c841ffe09f2f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-filesystem/zipball/63e525fd74f451b2df1df060c3194e9b6e724730", "url": "https://api.github.com/repos/top-think/think-filesystem/zipball/c08503232fcae0c3c7fefae5e6b5c841ffe09f2f",
"reference": "63e525fd74f451b2df1df060c3194e9b6e724730", "reference": "c08503232fcae0c3c7fefae5e6b5c841ffe09f2f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2371,14 +2429,14 @@
}, },
"require": { "require": {
"league/flysystem": "^2.0", "league/flysystem": "^2.0",
"topthink/framework": "^6.1" "topthink/framework": "^6.1|^8.0"
}, },
"require-dev": { "require-dev": {
"mikey179/vfsstream": "^1.6", "mikey179/vfsstream": "^1.6",
"mockery/mockery": "^1.2", "mockery/mockery": "^1.2",
"phpunit/phpunit": "^8.0" "phpunit/phpunit": "^8.0"
}, },
"time": "2022-10-26T04:51:41+00:00", "time": "2023-02-08T01:23:42+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -2399,7 +2457,7 @@
"description": "The ThinkPHP6.1 Filesystem Package", "description": "The ThinkPHP6.1 Filesystem Package",
"support": { "support": {
"issues": "https://github.com/top-think/think-filesystem/issues", "issues": "https://github.com/top-think/think-filesystem/issues",
"source": "https://github.com/top-think/think-filesystem/tree/v2.0.0" "source": "https://github.com/top-think/think-filesystem/tree/v2.0.2"
}, },
"install-path": "../topthink/think-filesystem" "install-path": "../topthink/think-filesystem"
}, },
@ -2514,17 +2572,17 @@
}, },
{ {
"name": "topthink/think-multi-app", "name": "topthink/think-multi-app",
"version": "v1.0.15", "version": "v1.0.16",
"version_normalized": "1.0.15.0", "version_normalized": "1.0.16.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-multi-app.git", "url": "https://github.com/top-think/think-multi-app.git",
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97" "reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-multi-app/zipball/387e0dac059c20f92cac5da41a871e10829c1c97", "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/07b9183855150455e1f76f8cbe9d77d6d1bc399f",
"reference": "387e0dac059c20f92cac5da41a871e10829c1c97", "reference": "07b9183855150455e1f76f8cbe9d77d6d1bc399f",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2535,9 +2593,9 @@
}, },
"require": { "require": {
"php": ">=7.1.0", "php": ">=7.1.0",
"topthink/framework": "^6.0" "topthink/framework": "^6.0|^8.0"
}, },
"time": "2022-10-26T08:03:06+00:00", "time": "2023-02-07T08:40:09+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {
@ -2565,23 +2623,23 @@
"description": "thinkphp6 multi app support", "description": "thinkphp6 multi app support",
"support": { "support": {
"issues": "https://github.com/top-think/think-multi-app/issues", "issues": "https://github.com/top-think/think-multi-app/issues",
"source": "https://github.com/top-think/think-multi-app/tree/v1.0.15" "source": "https://github.com/top-think/think-multi-app/tree/v1.0.16"
}, },
"install-path": "../topthink/think-multi-app" "install-path": "../topthink/think-multi-app"
}, },
{ {
"name": "topthink/think-orm", "name": "topthink/think-orm",
"version": "v2.0.54", "version": "v2.0.61",
"version_normalized": "2.0.54.0", "version_normalized": "2.0.61.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-orm.git", "url": "https://github.com/top-think/think-orm.git",
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e" "reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-orm/zipball/97b061b47616301ff29fbd4c35ed9184e1162e4e", "url": "https://api.github.com/repos/top-think/think-orm/zipball/10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e", "reference": "10528ebf4a5106b19c3bac9c6deae7a67ff49de6",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2601,7 +2659,7 @@
"require-dev": { "require-dev": {
"phpunit/phpunit": "^7|^8|^9.5" "phpunit/phpunit": "^7|^8|^9.5"
}, },
"time": "2022-07-05T05:25:51+00:00", "time": "2023-04-20T14:27:51+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -2629,23 +2687,23 @@
], ],
"support": { "support": {
"issues": "https://github.com/top-think/think-orm/issues", "issues": "https://github.com/top-think/think-orm/issues",
"source": "https://github.com/top-think/think-orm/tree/v2.0.54" "source": "https://github.com/top-think/think-orm/tree/v2.0.61"
}, },
"install-path": "../topthink/think-orm" "install-path": "../topthink/think-orm"
}, },
{ {
"name": "topthink/think-template", "name": "topthink/think-template",
"version": "v2.0.8", "version": "v2.0.9",
"version_normalized": "2.0.8.0", "version_normalized": "2.0.9.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/top-think/think-template.git", "url": "https://github.com/top-think/think-template.git",
"reference": "abfc293f74f9ef5127b5c416310a01fe42e59368" "reference": "6d25642ae0e306166742fd7073dc7a159e18073c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-template/zipball/abfc293f74f9ef5127b5c416310a01fe42e59368", "url": "https://api.github.com/repos/top-think/think-template/zipball/6d25642ae0e306166742fd7073dc7a159e18073c",
"reference": "abfc293f74f9ef5127b5c416310a01fe42e59368", "reference": "6d25642ae0e306166742fd7073dc7a159e18073c",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -2658,7 +2716,7 @@
"php": ">=7.1.0", "php": ">=7.1.0",
"psr/simple-cache": "^1.0" "psr/simple-cache": "^1.0"
}, },
"time": "2020-12-10T07:52:03+00:00", "time": "2023-02-14T10:50:39+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -2679,7 +2737,7 @@
"description": "the php template engine", "description": "the php template engine",
"support": { "support": {
"issues": "https://github.com/top-think/think-template/issues", "issues": "https://github.com/top-think/think-template/issues",
"source": "https://github.com/top-think/think-template/tree/v2.0.8" "source": "https://github.com/top-think/think-template/tree/v2.0.9"
}, },
"install-path": "../topthink/think-template" "install-path": "../topthink/think-template"
}, },

View File

@ -3,7 +3,7 @@
'name' => 'topthink/think', 'name' => 'topthink/think',
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => 'e3cf01d01f242927ac3fd497b0cbc88fad1c9df2', 'reference' => 'c7deee9ae9a946ac4af3f530791f720402b7692d',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -11,27 +11,36 @@
), ),
'versions' => array( 'versions' => array(
'doctrine/annotations' => array( 'doctrine/annotations' => array(
'pretty_version' => '1.13.3', 'pretty_version' => '1.14.3',
'version' => '1.13.3.0', 'version' => '1.14.3.0',
'reference' => '648b0343343565c4a056bfc8392201385e8d89f0', 'reference' => 'fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/annotations', 'install_path' => __DIR__ . '/../doctrine/annotations',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'doctrine/deprecations' => array(
'pretty_version' => 'v1.0.0',
'version' => '1.0.0.0',
'reference' => '0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/deprecations',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/lexer' => array( 'doctrine/lexer' => array(
'pretty_version' => '1.2.3', 'pretty_version' => '2.1.0',
'version' => '1.2.3.0', 'version' => '2.1.0.0',
'reference' => 'c268e882d4dbdd85e36e4ad69e02dc284f89d229', 'reference' => '39ab8fcf5a51ce4b85ca97c7a7d033eb12831124',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/lexer', 'install_path' => __DIR__ . '/../doctrine/lexer',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'egulias/email-validator' => array( 'egulias/email-validator' => array(
'pretty_version' => '3.2.1', 'pretty_version' => '3.2.5',
'version' => '3.2.1.0', 'version' => '3.2.5.0',
'reference' => 'f88dcf4b14af14a98ad96b14b2b317969eab6715', 'reference' => 'b531a2311709443320c786feb4519cfaf94af796',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../egulias/email-validator', 'install_path' => __DIR__ . '/../egulias/email-validator',
'aliases' => array(), 'aliases' => array(),
@ -74,9 +83,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'phpmailer/phpmailer' => array( 'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.6.4', 'pretty_version' => 'v6.7.1',
'version' => '6.6.4.0', 'version' => '6.7.1.0',
'reference' => 'a94fdebaea6bd17f51be0c2373ab80d3d681269b', 'reference' => '49cd7ea3d2563f028d7811f06864a53b1f15ff55',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer', 'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(), 'aliases' => array(),
@ -116,9 +125,9 @@
), ),
), ),
'psr/http-message' => array( 'psr/http-message' => array(
'pretty_version' => '1.0.1', 'pretty_version' => '1.1',
'version' => '1.0.1.0', 'version' => '1.1.0.0',
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message', 'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(), 'aliases' => array(),
@ -161,9 +170,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/event-dispatcher' => array( 'symfony/event-dispatcher' => array(
'pretty_version' => 'v5.4.9', 'pretty_version' => 'v5.4.22',
'version' => '5.4.9.0', 'version' => '5.4.22.0',
'reference' => '8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc', 'reference' => '1df20e45d56da29a4b1d8259dd6e950acbf1b13f',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(), 'aliases' => array(),
@ -185,27 +194,27 @@
), ),
), ),
'symfony/http-foundation' => array( 'symfony/http-foundation' => array(
'pretty_version' => 'v5.4.15', 'pretty_version' => 'v5.4.23',
'version' => '5.4.15.0', 'version' => '5.4.23.0',
'reference' => '75bd663ff2db90141bfb733682459d5bbe9e29c3', 'reference' => 'af9fbb378f5f956c8f29d4886644c84c193780ac',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation', 'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/mailer' => array( 'symfony/mailer' => array(
'pretty_version' => 'v5.4.15', 'pretty_version' => 'v5.4.22',
'version' => '5.4.15.0', 'version' => '5.4.22.0',
'reference' => '926f4deddb60d40024e6058fd8f94e70e4024930', 'reference' => '6330cd465dfd8b7a07515757a1c37069075f7b0b',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mailer', 'install_path' => __DIR__ . '/../symfony/mailer',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'symfony/mime' => array( 'symfony/mime' => array(
'pretty_version' => 'v5.4.14', 'pretty_version' => 'v5.4.23',
'version' => '5.4.14.0', 'version' => '5.4.23.0',
'reference' => '1c118b253bb3495d81e95a6e3ec6c2766a98a0c4', 'reference' => 'ae0a1032a450a3abf305ee44fc55ed423fbf16e3',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mime', 'install_path' => __DIR__ . '/../symfony/mime',
'aliases' => array(), 'aliases' => array(),
@ -275,9 +284,9 @@
'dev_requirement' => true, 'dev_requirement' => true,
), ),
'topthink/framework' => array( 'topthink/framework' => array(
'pretty_version' => 'v6.1.1', 'pretty_version' => 'v6.1.2',
'version' => '6.1.1.0', 'version' => '6.1.2.0',
'reference' => '2cb56f3e6f3c479fe90ea5f28d38d3b5ef6c4210', 'reference' => '67235be5b919aaaf1de5aed9839f65d8e766aca3',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/framework', 'install_path' => __DIR__ . '/../topthink/framework',
'aliases' => array(), 'aliases' => array(),
@ -286,25 +295,25 @@
'topthink/think' => array( 'topthink/think' => array(
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => 'e3cf01d01f242927ac3fd497b0cbc88fad1c9df2', 'reference' => 'c7deee9ae9a946ac4af3f530791f720402b7692d',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-captcha' => array( 'topthink/think-captcha' => array(
'pretty_version' => 'v3.0.8', 'pretty_version' => 'v3.0.9',
'version' => '3.0.8.0', 'version' => '3.0.9.0',
'reference' => '52fba122c953995bec3013c635025172491ae299', 'reference' => 'b1ef360670578214edeebcf824aaf6ab7ee0528b',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-captcha', 'install_path' => __DIR__ . '/../topthink/think-captcha',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-filesystem' => array( 'topthink/think-filesystem' => array(
'pretty_version' => 'v2.0.0', 'pretty_version' => 'v2.0.2',
'version' => '2.0.0.0', 'version' => '2.0.2.0',
'reference' => '63e525fd74f451b2df1df060c3194e9b6e724730', 'reference' => 'c08503232fcae0c3c7fefae5e6b5c841ffe09f2f',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-filesystem', 'install_path' => __DIR__ . '/../topthink/think-filesystem',
'aliases' => array(), 'aliases' => array(),
@ -329,27 +338,27 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-multi-app' => array( 'topthink/think-multi-app' => array(
'pretty_version' => 'v1.0.15', 'pretty_version' => 'v1.0.16',
'version' => '1.0.15.0', 'version' => '1.0.16.0',
'reference' => '387e0dac059c20f92cac5da41a871e10829c1c97', 'reference' => '07b9183855150455e1f76f8cbe9d77d6d1bc399f',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-multi-app', 'install_path' => __DIR__ . '/../topthink/think-multi-app',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-orm' => array( 'topthink/think-orm' => array(
'pretty_version' => 'v2.0.54', 'pretty_version' => 'v2.0.61',
'version' => '2.0.54.0', 'version' => '2.0.61.0',
'reference' => '97b061b47616301ff29fbd4c35ed9184e1162e4e', 'reference' => '10528ebf4a5106b19c3bac9c6deae7a67ff49de6',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-orm', 'install_path' => __DIR__ . '/../topthink/think-orm',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think-template' => array( 'topthink/think-template' => array(
'pretty_version' => 'v2.0.8', 'pretty_version' => 'v2.0.9',
'version' => '2.0.8.0', 'version' => '2.0.9.0',
'reference' => 'abfc293f74f9ef5127b5c416310a01fe42e59368', 'reference' => '6d25642ae0e306166742fd7073dc7a159e18073c',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../topthink/think-template', 'install_path' => __DIR__ . '/../topthink/think-template',
'aliases' => array(), 'aliases' => array(),

View File

@ -1,3 +1,9 @@
⚠️ PHP 8 introduced
[attributes](https://www.php.net/manual/en/language.attributes.overview.php),
which are a native replacement for annotations. As such, this library is
considered feature complete, and should receive exclusively bugfixes and
security fixes.
# Doctrine Annotations # Doctrine Annotations
[![Build Status](https://github.com/doctrine/annotations/workflows/Continuous%20Integration/badge.svg?label=build)](https://github.com/doctrine/persistence/actions) [![Build Status](https://github.com/doctrine/annotations/workflows/Continuous%20Integration/badge.svg?label=build)](https://github.com/doctrine/persistence/actions)

View File

@ -34,17 +34,20 @@
"require": { "require": {
"php": "^7.1 || ^8.0", "php": "^7.1 || ^8.0",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"doctrine/lexer": "1.*", "doctrine/lexer": "^1 || ^2",
"psr/cache": "^1 || ^2 || ^3" "psr/cache": "^1 || ^2 || ^3"
}, },
"require-dev": { "require-dev": {
"doctrine/cache": "^1.11 || ^2.0", "doctrine/cache": "^1.11 || ^2.0",
"doctrine/coding-standard": "^6.0 || ^8.1", "doctrine/coding-standard": "^9 || ^10",
"phpstan/phpstan": "^1.4.10 || ^1.8.0", "phpstan/phpstan": "~1.4.10 || ^1.8.0",
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"symfony/cache": "^4.4 || ^5.2", "symfony/cache": "^4.4 || ^5.4 || ^6",
"vimeo/psalm": "^4.10" "vimeo/psalm": "^4.10"
}, },
"suggest": {
"php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"

View File

@ -69,7 +69,7 @@ When using the ``@NamedArgumentConstructor`` tag, the first argument of the
constructor is considered as the default one. constructor is considered as the default one.
Usage with the ``@NamedArgumentContrustor`` tag Usage with the ``@NamedArgumentConstructor`` tag
.. code-block:: php .. code-block:: php

View File

@ -1,3 +1,12 @@
Deprecation notice
==================
PHP 8 introduced `attributes
<https://www.php.net/manual/en/language.attributes.overview.php>`_,
which are a native replacement for annotations. As such, this library is
considered feature complete, and should receive exclusively bugfixes and
security fixes.
Introduction Introduction
============ ============

View File

@ -18,9 +18,7 @@ class Annotation
*/ */
public $value; public $value;
/** /** @param array<string, mixed> $data Key-value for properties to be defined in this class. */
* @param array<string, mixed> $data Key-value for properties to be defined in this class.
*/
final public function __construct(array $data) final public function __construct(array $data)
{ {
foreach ($data as $key => $value) { foreach ($data as $key => $value) {

View File

@ -34,9 +34,9 @@ final class Enum
public $literal; public $literal;
/** /**
* @throws InvalidArgumentException
*
* @phpstan-param array{literal?: mixed[], value: list<scalar>} $values * @phpstan-param array{literal?: mixed[], value: list<scalar>} $values
*
* @throws InvalidArgumentException
*/ */
public function __construct(array $values) public function __construct(array $values)
{ {

View File

@ -21,9 +21,9 @@ final class IgnoreAnnotation
public $names; public $names;
/** /**
* @throws RuntimeException
*
* @phpstan-param array{value: string|list<string>} $values * @phpstan-param array{value: string|list<string>} $values
*
* @throws RuntimeException
*/ */
public function __construct(array $values) public function __construct(array $values)
{ {

View File

@ -56,9 +56,9 @@ final class Target
public $literal; public $literal;
/** /**
* @throws InvalidArgumentException
*
* @phpstan-param array{value?: string|list<string>} $values * @phpstan-param array{value?: string|list<string>} $values
*
* @throws InvalidArgumentException
*/ */
public function __construct(array $values) public function __construct(array $values)
{ {

View File

@ -133,10 +133,9 @@ class AnnotationException extends Exception
* @param string $annotationName * @param string $annotationName
* @param string $context * @param string $context
* @param mixed $given * @param mixed $given
* @phpstan-param list<string> $available
* *
* @return AnnotationException * @return AnnotationException
*
* @phpstan-param list<string> $available
*/ */
public static function enumeratorError($attributeName, $annotationName, $context, $available, $given) public static function enumeratorError($attributeName, $annotationName, $context, $available, $given)
{ {
@ -150,9 +149,7 @@ class AnnotationException extends Exception
)); ));
} }
/** /** @return AnnotationException */
* @return AnnotationException
*/
public static function optimizerPlusSaveComments() public static function optimizerPlusSaveComments()
{ {
return new self( return new self(
@ -160,9 +157,7 @@ class AnnotationException extends Exception
); );
} }
/** /** @return AnnotationException */
* @return AnnotationException
*/
public static function optimizerPlusLoadComments() public static function optimizerPlusLoadComments()
{ {
return new self( return new self(

View File

@ -38,9 +38,7 @@ final class CachedReader implements Reader
/** @var int[] */ /** @var int[] */
private $loadedFilemtimes = []; private $loadedFilemtimes = [];
/** /** @param bool $debug */
* @param bool $debug
*/
public function __construct(Reader $reader, Cache $cache, $debug = false) public function __construct(Reader $reader, Cache $cache, $debug = false)
{ {
$this->delegate = $reader; $this->delegate = $reader;

View File

@ -15,6 +15,8 @@ use function substr;
/** /**
* Simple lexer for docblock annotations. * Simple lexer for docblock annotations.
*
* @template-extends AbstractLexer<DocLexer::T_*, string>
*/ */
final class DocLexer extends AbstractLexer final class DocLexer extends AbstractLexer
{ {
@ -39,7 +41,7 @@ final class DocLexer extends AbstractLexer
public const T_COLON = 112; public const T_COLON = 112;
public const T_MINUS = 113; public const T_MINUS = 113;
/** @var array<string, int> */ /** @var array<string, self::T*> */
protected $noCase = [ protected $noCase = [
'@' => self::T_AT, '@' => self::T_AT,
',' => self::T_COMMA, ',' => self::T_COMMA,
@ -53,7 +55,7 @@ final class DocLexer extends AbstractLexer
'\\' => self::T_NAMESPACE_SEPARATOR, '\\' => self::T_NAMESPACE_SEPARATOR,
]; ];
/** @var array<string, int> */ /** @var array<string, self::T*> */
protected $withCase = [ protected $withCase = [
'true' => self::T_TRUE, 'true' => self::T_TRUE,
'false' => self::T_FALSE, 'false' => self::T_FALSE,
@ -126,4 +128,16 @@ final class DocLexer extends AbstractLexer
return $type; return $type;
} }
/** @return array{value: int|string, type:self::T_*|null, position:int} */
public function peek(): ?array
{
$token = parent::peek();
if ($token === null) {
return null;
}
return (array) $token;
}
} }

View File

@ -357,10 +357,10 @@ final class DocParser
* @param string $input The docblock string to parse. * @param string $input The docblock string to parse.
* @param string $context The parsing context. * @param string $context The parsing context.
* *
* @phpstan-return list<object> Array of annotations. If no annotations are found, an empty array is returned.
*
* @throws AnnotationException * @throws AnnotationException
* @throws ReflectionException * @throws ReflectionException
*
* @phpstan-return list<object> Array of annotations. If no annotations are found, an empty array is returned.
*/ */
public function parse($input, $context = '') public function parse($input, $context = '')
{ {
@ -426,9 +426,9 @@ final class DocParser
* If any of them matches, this method updates the lookahead token; otherwise * If any of them matches, this method updates the lookahead token; otherwise
* a syntax error is raised. * a syntax error is raised.
* *
* @throws AnnotationException
*
* @phpstan-param list<mixed[]> $tokens * @phpstan-param list<mixed[]> $tokens
*
* @throws AnnotationException
*/ */
private function matchAny(array $tokens): bool private function matchAny(array $tokens): bool
{ {
@ -613,6 +613,10 @@ final class DocParser
$metadata['default_property'] = reset($metadata['properties']); $metadata['default_property'] = reset($metadata['properties']);
} elseif ($metadata['has_named_argument_constructor']) { } elseif ($metadata['has_named_argument_constructor']) {
foreach ($constructor->getParameters() as $parameter) { foreach ($constructor->getParameters() as $parameter) {
if ($parameter->isVariadic()) {
break;
}
$metadata['constructor_args'][$parameter->getName()] = [ $metadata['constructor_args'][$parameter->getName()] = [
'position' => $parameter->getPosition(), 'position' => $parameter->getPosition(),
'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null, 'default' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
@ -674,10 +678,10 @@ final class DocParser
/** /**
* Annotations ::= Annotation {[ "*" ]* [Annotation]}* * Annotations ::= Annotation {[ "*" ]* [Annotation]}*
* *
* @phpstan-return list<object>
*
* @throws AnnotationException * @throws AnnotationException
* @throws ReflectionException * @throws ReflectionException
*
* @phpstan-return list<object>
*/ */
private function Annotations(): array private function Annotations(): array
{ {
@ -942,6 +946,23 @@ EXCEPTION
if (self::$annotationMetadata[$name]['has_named_argument_constructor']) { if (self::$annotationMetadata[$name]['has_named_argument_constructor']) {
if (PHP_VERSION_ID >= 80000) { if (PHP_VERSION_ID >= 80000) {
foreach ($values as $property => $value) {
if (! isset(self::$annotationMetadata[$name]['constructor_args'][$property])) {
throw AnnotationException::creationError(sprintf(
<<<'EXCEPTION'
The annotation @%s declared on %s does not have a property named "%s"
that can be set through its named arguments constructor.
Available named arguments: %s
EXCEPTION
,
$originalName,
$this->context,
$property,
implode(', ', array_keys(self::$annotationMetadata[$name]['constructor_args']))
));
}
}
return $this->instantiateAnnotiation($originalName, $this->context, $name, $values); return $this->instantiateAnnotiation($originalName, $this->context, $name, $values);
} }
@ -1166,9 +1187,7 @@ EXCEPTION
return $this->getClassConstantPositionInIdentifier($identifier) === strlen($identifier) - strlen('::class'); return $this->getClassConstantPositionInIdentifier($identifier) === strlen($identifier) - strlen('::class');
} }
/** /** @return int|false */
* @return int|false
*/
private function getClassConstantPositionInIdentifier(string $identifier) private function getClassConstantPositionInIdentifier(string $identifier)
{ {
return stripos($identifier, '::class'); return stripos($identifier, '::class');
@ -1357,10 +1376,10 @@ EXCEPTION
* KeyValuePair ::= Key ("=" | ":") PlainValue | Constant * KeyValuePair ::= Key ("=" | ":") PlainValue | Constant
* Key ::= string | integer | Constant * Key ::= string | integer | Constant
* *
* @phpstan-return array{mixed, mixed}
*
* @throws AnnotationException * @throws AnnotationException
* @throws ReflectionException * @throws ReflectionException
*
* @phpstan-return array{mixed, mixed}
*/ */
private function ArrayEntry(): array private function ArrayEntry(): array
{ {

View File

@ -46,9 +46,7 @@ class TokenParser
*/ */
private $pointer = 0; private $pointer = 0;
/** /** @param string $contents */
* @param string $contents
*/
public function __construct($contents) public function __construct($contents)
{ {
$this->tokens = token_get_all($contents); $this->tokens = token_get_all($contents);

19
vendor/doctrine/deprecations/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2020-2021 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

154
vendor/doctrine/deprecations/README.md vendored Normal file
View File

@ -0,0 +1,154 @@
# Doctrine Deprecations
A small (side-effect free by default) layer on top of
`trigger_error(E_USER_DEPRECATED)` or PSR-3 logging.
- no side-effects by default, making it a perfect fit for libraries that don't know how the error handler works they operate under
- options to avoid having to rely on error handlers global state by using PSR-3 logging
- deduplicate deprecation messages to avoid excessive triggering and reduce overhead
We recommend to collect Deprecations using a PSR logger instead of relying on
the global error handler.
## Usage from consumer perspective:
Enable Doctrine deprecations to be sent to a PSR3 logger:
```php
\Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
```
Enable Doctrine deprecations to be sent as `@trigger_error($message, E_USER_DEPRECATED)`
messages.
```php
\Doctrine\Deprecations\Deprecation::enableWithTriggerError();
```
If you only want to enable deprecation tracking, without logging or calling `trigger_error` then call:
```php
\Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
```
Tracking is enabled with all three modes and provides access to all triggered
deprecations and their individual count:
```php
$deprecations = \Doctrine\Deprecations\Deprecation::getTriggeredDeprecations();
foreach ($deprecations as $identifier => $count) {
echo $identifier . " was triggered " . $count . " times\n";
}
```
### Suppressing Specific Deprecations
Disable triggering about specific deprecations:
```php
\Doctrine\Deprecations\Deprecation::ignoreDeprecations("https://link/to/deprecations-description-identifier");
```
Disable all deprecations from a package
```php
\Doctrine\Deprecations\Deprecation::ignorePackage("doctrine/orm");
```
### Other Operations
When used within PHPUnit or other tools that could collect multiple instances of the same deprecations
the deduplication can be disabled:
```php
\Doctrine\Deprecations\Deprecation::withoutDeduplication();
```
Disable deprecation tracking again:
```php
\Doctrine\Deprecations\Deprecation::disable();
```
## Usage from a library/producer perspective:
When you want to unconditionally trigger a deprecation even when called
from the library itself then the `trigger` method is the way to go:
```php
\Doctrine\Deprecations\Deprecation::trigger(
"doctrine/orm",
"https://link/to/deprecations-description",
"message"
);
```
If variable arguments are provided at the end, they are used with `sprintf` on
the message.
```php
\Doctrine\Deprecations\Deprecation::trigger(
"doctrine/orm",
"https://github.com/doctrine/orm/issue/1234",
"message %s %d",
"foo",
1234
);
```
When you want to trigger a deprecation only when it is called by a function
outside of the current package, but not trigger when the package itself is the cause,
then use:
```php
\Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside(
"doctrine/orm",
"https://link/to/deprecations-description",
"message"
);
```
Based on the issue link each deprecation message is only triggered once per
request.
A limited stacktrace is included in the deprecation message to find the
offending location.
Note: A producer/library should never call `Deprecation::enableWith` methods
and leave the decision how to handle deprecations to application and
frameworks.
## Usage in PHPUnit tests
There is a `VerifyDeprecations` trait that you can use to make assertions on
the occurrence of deprecations within a test.
```php
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
class MyTest extends TestCase
{
use VerifyDeprecations;
public function testSomethingDeprecation()
{
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
triggerTheCodeWithDeprecation();
}
public function testSomethingDeprecationFixed()
{
$this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
triggerTheCodeWithoutDeprecation();
}
}
```
## What is a deprecation identifier?
An identifier for deprecations is just a link to any resource, most often a
Github Issue or Pull Request explaining the deprecation and potentially its
alternative.

View File

@ -0,0 +1,32 @@
{
"name": "doctrine/deprecations",
"type": "library",
"description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
"homepage": "https://www.doctrine-project.org/",
"license": "MIT",
"require": {
"php": "^7.1|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^7.5|^8.5|^9.5",
"psr/log": "^1|^2|^3",
"doctrine/coding-standard": "^9"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"autoload": {
"psr-4": {"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"}
},
"autoload-dev": {
"psr-4": {
"DeprecationTests\\": "test_fixtures/src",
"Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo"
}
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

View File

@ -0,0 +1,266 @@
<?php
declare(strict_types=1);
namespace Doctrine\Deprecations;
use Psr\Log\LoggerInterface;
use function array_key_exists;
use function array_reduce;
use function debug_backtrace;
use function sprintf;
use function strpos;
use function strrpos;
use function substr;
use function trigger_error;
use const DEBUG_BACKTRACE_IGNORE_ARGS;
use const DIRECTORY_SEPARATOR;
use const E_USER_DEPRECATED;
/**
* Manages Deprecation logging in different ways.
*
* By default triggered exceptions are not logged.
*
* To enable different deprecation logging mechanisms you can call the
* following methods:
*
* - Minimal collection of deprecations via getTriggeredDeprecations()
* \Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
*
* - Uses @trigger_error with E_USER_DEPRECATED
* \Doctrine\Deprecations\Deprecation::enableWithTriggerError();
*
* - Sends deprecation messages via a PSR-3 logger
* \Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
*
* Packages that trigger deprecations should use the `trigger()` or
* `triggerIfCalledFromOutside()` methods.
*/
class Deprecation
{
private const TYPE_NONE = 0;
private const TYPE_TRACK_DEPRECATIONS = 1;
private const TYPE_TRIGGER_ERROR = 2;
private const TYPE_PSR_LOGGER = 4;
/** @var int */
private static $type = self::TYPE_NONE;
/** @var LoggerInterface|null */
private static $logger;
/** @var array<string,bool> */
private static $ignoredPackages = [];
/** @var array<string,int> */
private static $ignoredLinks = [];
/** @var bool */
private static $deduplication = true;
/**
* Trigger a deprecation for the given package and identfier.
*
* The link should point to a Github issue or Wiki entry detailing the
* deprecation. It is additionally used to de-duplicate the trigger of the
* same deprecation during a request.
*
* @param mixed $args
*/
public static function trigger(string $package, string $link, string $message, ...$args): void
{
if (self::$type === self::TYPE_NONE) {
return;
}
if (array_key_exists($link, self::$ignoredLinks)) {
self::$ignoredLinks[$link]++;
} else {
self::$ignoredLinks[$link] = 1;
}
if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) {
return;
}
if (isset(self::$ignoredPackages[$package])) {
return;
}
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$message = sprintf($message, ...$args);
self::delegateTriggerToBackend($message, $backtrace, $link, $package);
}
/**
* Trigger a deprecation for the given package and identifier when called from outside.
*
* "Outside" means we assume that $package is currently installed as a
* dependency and the caller is not a file in that package. When $package
* is installed as a root package then deprecations triggered from the
* tests folder are also considered "outside".
*
* This deprecation method assumes that you are using Composer to install
* the dependency and are using the default /vendor/ folder and not a
* Composer plugin to change the install location. The assumption is also
* that $package is the exact composer packge name.
*
* Compared to {@link trigger()} this method causes some overhead when
* deprecation tracking is enabled even during deduplication, because it
* needs to call {@link debug_backtrace()}
*
* @param mixed $args
*/
public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args): void
{
if (self::$type === self::TYPE_NONE) {
return;
}
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
// first check that the caller is not from a tests folder, in which case we always let deprecations pass
if (strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === false) {
$path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR;
if (strpos($backtrace[0]['file'], $path) === false) {
return;
}
if (strpos($backtrace[1]['file'], $path) !== false) {
return;
}
}
if (array_key_exists($link, self::$ignoredLinks)) {
self::$ignoredLinks[$link]++;
} else {
self::$ignoredLinks[$link] = 1;
}
if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) {
return;
}
if (isset(self::$ignoredPackages[$package])) {
return;
}
$message = sprintf($message, ...$args);
self::delegateTriggerToBackend($message, $backtrace, $link, $package);
}
/**
* @param array<mixed> $backtrace
*/
private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package): void
{
if ((self::$type & self::TYPE_PSR_LOGGER) > 0) {
$context = [
'file' => $backtrace[0]['file'],
'line' => $backtrace[0]['line'],
'package' => $package,
'link' => $link,
];
self::$logger->notice($message, $context);
}
if (! ((self::$type & self::TYPE_TRIGGER_ERROR) > 0)) {
return;
}
$message .= sprintf(
' (%s:%d called by %s:%d, %s, package %s)',
self::basename($backtrace[0]['file']),
$backtrace[0]['line'],
self::basename($backtrace[1]['file']),
$backtrace[1]['line'],
$link,
$package
);
@trigger_error($message, E_USER_DEPRECATED);
}
/**
* A non-local-aware version of PHPs basename function.
*/
private static function basename(string $filename): string
{
$pos = strrpos($filename, DIRECTORY_SEPARATOR);
if ($pos === false) {
return $filename;
}
return substr($filename, $pos + 1);
}
public static function enableTrackingDeprecations(): void
{
self::$type |= self::TYPE_TRACK_DEPRECATIONS;
}
public static function enableWithTriggerError(): void
{
self::$type |= self::TYPE_TRIGGER_ERROR;
}
public static function enableWithPsrLogger(LoggerInterface $logger): void
{
self::$type |= self::TYPE_PSR_LOGGER;
self::$logger = $logger;
}
public static function withoutDeduplication(): void
{
self::$deduplication = false;
}
public static function disable(): void
{
self::$type = self::TYPE_NONE;
self::$logger = null;
self::$deduplication = true;
foreach (self::$ignoredLinks as $link => $count) {
self::$ignoredLinks[$link] = 0;
}
}
public static function ignorePackage(string $packageName): void
{
self::$ignoredPackages[$packageName] = true;
}
public static function ignoreDeprecations(string ...$links): void
{
foreach ($links as $link) {
self::$ignoredLinks[$link] = 0;
}
}
public static function getUniqueTriggeredDeprecationsCount(): int
{
return array_reduce(self::$ignoredLinks, static function (int $carry, int $count) {
return $carry + $count;
}, 0);
}
/**
* Returns each triggered deprecation link identifier and the amount of occurrences.
*
* @return array<string,int>
*/
public static function getTriggeredDeprecations(): array
{
return self::$ignoredLinks;
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Doctrine\Deprecations\PHPUnit;
use Doctrine\Deprecations\Deprecation;
use function sprintf;
trait VerifyDeprecations
{
/** @var array<string,int> */
private $doctrineDeprecationsExpectations = [];
/** @var array<string,int> */
private $doctrineNoDeprecationsExpectations = [];
public function expectDeprecationWithIdentifier(string $identifier): void
{
$this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
}
public function expectNoDeprecationWithIdentifier(string $identifier): void
{
$this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
}
/**
* @before
*/
public function enableDeprecationTracking(): void
{
Deprecation::enableTrackingDeprecations();
}
/**
* @after
*/
public function verifyDeprecationsAreTriggered(): void
{
foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) {
$actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
$this->assertTrue(
$actualCount > $expectation,
sprintf(
"Expected deprecation with identifier '%s' was not triggered by code executed in test.",
$identifier
)
);
}
foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) {
$actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
$this->assertTrue(
$actualCount === $expectation,
sprintf(
"Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.",
$identifier
)
);
}
}
}

22
vendor/doctrine/deprecations/phpcs.xml vendored Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<ruleset>
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
<arg name="cache" value=".phpcs-cache"/>
<arg name="colors"/>
<!-- Ignore warnings, show progress of the run and show sniff names -->
<arg value="nps"/>
<config name="php_version" value="70100"/>
<!-- Directories to be checked -->
<file>lib</file>
<file>tests</file>
<!-- Include full Doctrine Coding Standard -->
<rule ref="Doctrine">
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint" />
</rule>
</ruleset>

14
vendor/doctrine/lexer/UPGRADE.md vendored Normal file
View File

@ -0,0 +1,14 @@
Note about upgrading: Doctrine uses static and runtime mechanisms to raise
awareness about deprecated code.
- Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or
Static Analysis tools (like Psalm, phpstan)
- Use of our low-overhead runtime deprecation API, details:
https://github.com/doctrine/deprecations/
# Upgrade to 2.0.0
`AbstractLexer::glimpse()` and `AbstractLexer::peek()` now return
instances of `Doctrine\Common\Lexer\Token`, which is an array-like class
Using it as an array is deprecated in favor of using properties of that class.
Using `count()` on it is deprecated with no replacement.

View File

@ -1,7 +1,8 @@
{ {
"name": "doctrine/lexer", "name": "doctrine/lexer",
"type": "library",
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
"license": "MIT",
"type": "library",
"keywords": [ "keywords": [
"php", "php",
"parser", "parser",
@ -9,27 +10,41 @@
"annotations", "annotations",
"docblock" "docblock"
], ],
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"license": "MIT",
"authors": [ "authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, {
{"name": "Roman Borschel", "email": "roman@code-factory.org"}, "name": "Guilherme Blanco",
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} "email": "guilhermeblanco@gmail.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
], ],
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
"require": { "require": {
"php": "^7.1 || ^8.0" "php": "^7.1 || ^8.0",
"doctrine/deprecations": "^1.0"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^9.0", "doctrine/coding-standard": "^9 || ^10",
"phpstan/phpstan": "^1.3", "phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"vimeo/psalm": "^4.11" "psalm/plugin-phpunit": "^0.18.3",
"vimeo/psalm": "^4.11 || ^5.0"
}, },
"autoload": { "autoload": {
"psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" } "psr-4": {
"Doctrine\\Common\\Lexer\\": "src"
}
}, },
"autoload-dev": { "autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine" } "psr-4": {
"Doctrine\\Tests\\Common\\Lexer\\": "tests"
}
}, },
"config": { "config": {
"allow-plugins": { "allow-plugins": {

View File

@ -1,15 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="5"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="lib/Doctrine/Common/Lexer" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@ -5,9 +5,10 @@ declare(strict_types=1);
namespace Doctrine\Common\Lexer; namespace Doctrine\Common\Lexer;
use ReflectionClass; use ReflectionClass;
use UnitEnum;
use function get_class;
use function implode; use function implode;
use function in_array;
use function preg_split; use function preg_split;
use function sprintf; use function sprintf;
use function substr; use function substr;
@ -19,7 +20,8 @@ use const PREG_SPLIT_OFFSET_CAPTURE;
/** /**
* Base class for writing simple lexers, i.e. for creating small DSLs. * Base class for writing simple lexers, i.e. for creating small DSLs.
* *
* @psalm-type Token = array{value: int|string, type:string|int|null, position:int} * @template T of UnitEnum|string|int
* @template V of string|int
*/ */
abstract class AbstractLexer abstract class AbstractLexer
{ {
@ -33,14 +35,7 @@ abstract class AbstractLexer
/** /**
* Array of scanned tokens. * Array of scanned tokens.
* *
* Each token is an associative array containing three items: * @var list<Token<T, V>>
* - 'value' : the string value of the token in the input string
* - 'type' : the type of the token (identifier, numeric, string, input
* parameter, none)
* - 'position' : the position of the token in the input string
*
* @var mixed[][]
* @psalm-var list<Token>
*/ */
private $tokens = []; private $tokens = [];
@ -62,7 +57,7 @@ abstract class AbstractLexer
* The next token in the input. * The next token in the input.
* *
* @var mixed[]|null * @var mixed[]|null
* @psalm-var Token|null * @psalm-var Token<T, V>|null
*/ */
public $lookahead; public $lookahead;
@ -70,7 +65,7 @@ abstract class AbstractLexer
* The last matched/seen token. * The last matched/seen token.
* *
* @var mixed[]|null * @var mixed[]|null
* @psalm-var Token|null * @psalm-var Token<T, V>|null
*/ */
public $token; public $token;
@ -150,31 +145,37 @@ abstract class AbstractLexer
/** /**
* Checks whether a given token matches the current lookahead. * Checks whether a given token matches the current lookahead.
* *
* @param int|string $type * @param T $type
* *
* @return bool * @return bool
*
* @psalm-assert-if-true !=null $this->lookahead
*/ */
public function isNextToken($type) public function isNextToken($type)
{ {
return $this->lookahead !== null && $this->lookahead['type'] === $type; return $this->lookahead !== null && $this->lookahead->isA($type);
} }
/** /**
* Checks whether any of the given tokens matches the current lookahead. * Checks whether any of the given tokens matches the current lookahead.
* *
* @param list<int|string> $types * @param list<T> $types
* *
* @return bool * @return bool
*
* @psalm-assert-if-true !=null $this->lookahead
*/ */
public function isNextTokenAny(array $types) public function isNextTokenAny(array $types)
{ {
return $this->lookahead !== null && in_array($this->lookahead['type'], $types, true); return $this->lookahead !== null && $this->lookahead->isA(...$types);
} }
/** /**
* Moves to the next token in the input string. * Moves to the next token in the input string.
* *
* @return bool * @return bool
*
* @psalm-assert-if-true !null $this->lookahead
*/ */
public function moveNext() public function moveNext()
{ {
@ -189,13 +190,13 @@ abstract class AbstractLexer
/** /**
* Tells the lexer to skip input tokens until it sees a token with the given value. * Tells the lexer to skip input tokens until it sees a token with the given value.
* *
* @param string $type The token type to skip until. * @param T $type The token type to skip until.
* *
* @return void * @return void
*/ */
public function skipUntil($type) public function skipUntil($type)
{ {
while ($this->lookahead !== null && $this->lookahead['type'] !== $type) { while ($this->lookahead !== null && ! $this->lookahead->isA($type)) {
$this->moveNext(); $this->moveNext();
} }
} }
@ -203,7 +204,7 @@ abstract class AbstractLexer
/** /**
* Checks if given value is identical to the given token. * Checks if given value is identical to the given token.
* *
* @param mixed $value * @param string $value
* @param int|string $token * @param int|string $token
* *
* @return bool * @return bool
@ -217,7 +218,7 @@ abstract class AbstractLexer
* Moves the lookahead token forward. * Moves the lookahead token forward.
* *
* @return mixed[]|null The next token or NULL if there are no more tokens ahead. * @return mixed[]|null The next token or NULL if there are no more tokens ahead.
* @psalm-return Token|null * @psalm-return Token<T, V>|null
*/ */
public function peek() public function peek()
{ {
@ -232,7 +233,7 @@ abstract class AbstractLexer
* Peeks at the next token, returns it and immediately resets the peek. * Peeks at the next token, returns it and immediately resets the peek.
* *
* @return mixed[]|null The next token or NULL if there are no more tokens ahead. * @return mixed[]|null The next token or NULL if there are no more tokens ahead.
* @psalm-return Token|null * @psalm-return Token<T, V>|null
*/ */
public function glimpse() public function glimpse()
{ {
@ -270,26 +271,32 @@ abstract class AbstractLexer
foreach ($matches as $match) { foreach ($matches as $match) {
// Must remain before 'value' assignment since it can change content // Must remain before 'value' assignment since it can change content
$type = $this->getType($match[0]); $firstMatch = $match[0];
$type = $this->getType($firstMatch);
$this->tokens[] = [ $this->tokens[] = new Token(
'value' => $match[0], $firstMatch,
'type' => $type, $type,
'position' => $match[1], $match[1]
]; );
} }
} }
/** /**
* Gets the literal for a given token. * Gets the literal for a given token.
* *
* @param int|string $token * @param T $token
* *
* @return int|string * @return int|string
*/ */
public function getLiteral($token) public function getLiteral($token)
{ {
if ($token instanceof UnitEnum) {
return get_class($token) . '::' . $token->name;
}
$className = static::class; $className = static::class;
$reflClass = new ReflectionClass($className); $reflClass = new ReflectionClass($className);
$constants = $reflClass->getConstants(); $constants = $reflClass->getConstants();
@ -331,7 +338,9 @@ abstract class AbstractLexer
* *
* @param string $value * @param string $value
* *
* @return int|string|null * @return T|null
*
* @param-out V $value
*/ */
abstract protected function getType(&$value); abstract protected function getType(&$value);
} }

145
vendor/doctrine/lexer/src/Token.php vendored Normal file
View File

@ -0,0 +1,145 @@
<?php
declare(strict_types=1);
namespace Doctrine\Common\Lexer;
use ArrayAccess;
use Doctrine\Deprecations\Deprecation;
use ReturnTypeWillChange;
use UnitEnum;
use function in_array;
/**
* @template T of UnitEnum|string|int
* @template V of string|int
* @implements ArrayAccess<string,mixed>
*/
final class Token implements ArrayAccess
{
/**
* The string value of the token in the input string
*
* @readonly
* @var V
*/
public $value;
/**
* The type of the token (identifier, numeric, string, input parameter, none)
*
* @readonly
* @var T|null
*/
public $type;
/**
* The position of the token in the input string
*
* @readonly
* @var int
*/
public $position;
/**
* @param V $value
* @param T|null $type
*/
public function __construct($value, $type, int $position)
{
$this->value = $value;
$this->type = $type;
$this->position = $position;
}
/** @param T ...$types */
public function isA(...$types): bool
{
return in_array($this->type, $types, true);
}
/**
* @deprecated Use the value, type or position property instead
* {@inheritDoc}
*/
public function offsetExists($offset): bool
{
Deprecation::trigger(
'doctrine/lexer',
'https://github.com/doctrine/lexer/pull/79',
'Accessing %s properties via ArrayAccess is deprecated, use the value, type or position property instead',
self::class
);
return in_array($offset, ['value', 'type', 'position'], true);
}
/**
* @deprecated Use the value, type or position property instead
* {@inheritDoc}
*
* @param O $offset
*
* @return mixed
* @psalm-return (
* O is 'value'
* ? V
* : (
* O is 'type'
* ? T|null
* : (
* O is 'position'
* ? int
* : mixed
* )
* )
* )
*
* @template O of array-key
*/
#[ReturnTypeWillChange]
public function offsetGet($offset)
{
Deprecation::trigger(
'doctrine/lexer',
'https://github.com/doctrine/lexer/pull/79',
'Accessing %s properties via ArrayAccess is deprecated, use the value, type or position property instead',
self::class
);
return $this->$offset;
}
/**
* @deprecated no replacement planned
* {@inheritDoc}
*/
public function offsetSet($offset, $value): void
{
Deprecation::trigger(
'doctrine/lexer',
'https://github.com/doctrine/lexer/pull/79',
'Setting %s properties via ArrayAccess is deprecated',
self::class
);
$this->$offset = $value;
}
/**
* @deprecated no replacement planned
* {@inheritDoc}
*/
public function offsetUnset($offset): void
{
Deprecation::trigger(
'doctrine/lexer',
'https://github.com/doctrine/lexer/pull/79',
'Setting %s properties via ArrayAccess is deprecated',
self::class
);
$this->$offset = null;
}
}

View File

@ -5,7 +5,7 @@
* Access to local part and domain part from EmailParser * Access to local part and domain part from EmailParser
* Validations outside of the scope of the RFC will be considered "extra" validations, thus opening the door for adding new; will live in their own folder "extra" (as requested in #248, #195, #183). * Validations outside of the scope of the RFC will be considered "extra" validations, thus opening the door for adding new; will live in their own folder "extra" (as requested in #248, #195, #183).
## Breacking changes ## Breaking changes
* PHP version upgraded to match Symfony's (as of 12/2020). * PHP version upgraded to match Symfony's (as of 12/2020).
* DNSCheckValidation now fails for missing MX records. While the RFC argues that the existence of only A records to be valid, starting in v3 they will be considered invalid. * DNSCheckValidation now fails for missing MX records. While the RFC argues that the existence of only A records to be valid, starting in v3 they will be considered invalid.

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2021 Eduardo Gulias Davis Copyright (c) 2013-2022 Eduardo Gulias Davis
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -14,11 +14,10 @@
}, },
"require": { "require": {
"php": ">=7.2", "php": ">=7.2",
"doctrine/lexer": "^1.2", "doctrine/lexer": "^1.2|^2",
"symfony/polyfill-intl-idn": "^1.15" "symfony/polyfill-intl-idn": "^1.15"
}, },
"require-dev": { "require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^8.5.8|^9.3.3", "phpunit/phpunit": "^8.5.8|^9.3.3",
"vimeo/psalm": "^4" "vimeo/psalm": "^4"
}, },

View File

@ -3,58 +3,62 @@
namespace Egulias\EmailValidator; namespace Egulias\EmailValidator;
use Doctrine\Common\Lexer\AbstractLexer; use Doctrine\Common\Lexer\AbstractLexer;
use Doctrine\Common\Lexer\Token;
/**
* @extends AbstractLexer<int, string>
*/
class EmailLexer extends AbstractLexer class EmailLexer extends AbstractLexer
{ {
//ASCII values //ASCII values
const S_EMPTY = null; public const S_EMPTY = null;
const C_NUL = 0; public const C_NUL = 0;
const S_HTAB = 9; public const S_HTAB = 9;
const S_LF = 10; public const S_LF = 10;
const S_CR = 13; public const S_CR = 13;
const S_SP = 32; public const S_SP = 32;
const EXCLAMATION = 33; public const EXCLAMATION = 33;
const S_DQUOTE = 34; public const S_DQUOTE = 34;
const NUMBER_SIGN = 35; public const NUMBER_SIGN = 35;
const DOLLAR = 36; public const DOLLAR = 36;
const PERCENTAGE = 37; public const PERCENTAGE = 37;
const AMPERSAND = 38; public const AMPERSAND = 38;
const S_SQUOTE = 39; public const S_SQUOTE = 39;
const S_OPENPARENTHESIS = 40; public const S_OPENPARENTHESIS = 40;
const S_CLOSEPARENTHESIS = 41; public const S_CLOSEPARENTHESIS = 41;
const ASTERISK = 42; public const ASTERISK = 42;
const S_PLUS = 43; public const S_PLUS = 43;
const S_COMMA = 44; public const S_COMMA = 44;
const S_HYPHEN = 45; public const S_HYPHEN = 45;
const S_DOT = 46; public const S_DOT = 46;
const S_SLASH = 47; public const S_SLASH = 47;
const S_COLON = 58; public const S_COLON = 58;
const S_SEMICOLON = 59; public const S_SEMICOLON = 59;
const S_LOWERTHAN = 60; public const S_LOWERTHAN = 60;
const S_EQUAL = 61; public const S_EQUAL = 61;
const S_GREATERTHAN = 62; public const S_GREATERTHAN = 62;
const QUESTIONMARK = 63; public const QUESTIONMARK = 63;
const S_AT = 64; public const S_AT = 64;
const S_OPENBRACKET = 91; public const S_OPENBRACKET = 91;
const S_BACKSLASH = 92; public const S_BACKSLASH = 92;
const S_CLOSEBRACKET = 93; public const S_CLOSEBRACKET = 93;
const CARET = 94; public const CARET = 94;
const S_UNDERSCORE = 95; public const S_UNDERSCORE = 95;
const S_BACKTICK = 96; public const S_BACKTICK = 96;
const S_OPENCURLYBRACES = 123; public const S_OPENCURLYBRACES = 123;
const S_PIPE = 124; public const S_PIPE = 124;
const S_CLOSECURLYBRACES = 125; public const S_CLOSECURLYBRACES = 125;
const S_TILDE = 126; public const S_TILDE = 126;
const C_DEL = 127; public const C_DEL = 127;
const INVERT_QUESTIONMARK= 168; public const INVERT_QUESTIONMARK= 168;
const INVERT_EXCLAMATION = 173; public const INVERT_EXCLAMATION = 173;
const GENERIC = 300; public const GENERIC = 300;
const S_IPV6TAG = 301; public const S_IPV6TAG = 301;
const INVALID = 302; public const INVALID = 302;
const CRLF = 1310; public const CRLF = 1310;
const S_DOUBLECOLON = 5858; public const S_DOUBLECOLON = 5858;
const ASCII_INVALID_FROM = 127; public const ASCII_INVALID_FROM = 127;
const ASCII_INVALID_TO = 199; public const ASCII_INVALID_TO = 199;
/** /**
* US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3) * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
@ -107,11 +111,11 @@ class EmailLexer extends AbstractLexer
'¡' => self::INVERT_EXCLAMATION, '¡' => self::INVERT_EXCLAMATION,
]; ];
const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu"; public const INVALID_CHARS_REGEX = "/[^\p{S}\p{C}\p{Cc}]+/iu";
const VALID_UTF8_REGEX = '/\p{Cc}+/u'; public const VALID_UTF8_REGEX = '/\p{Cc}+/u';
const CATCHABLE_PATTERNS = [ public const CATCHABLE_PATTERNS = [
'[a-zA-Z]+[46]?', //ASCII and domain literal '[a-zA-Z]+[46]?', //ASCII and domain literal
'[^\x00-\x7F]', //UTF-8 '[^\x00-\x7F]', //UTF-8
'[0-9]+', '[0-9]+',
@ -121,11 +125,11 @@ class EmailLexer extends AbstractLexer
'.', '.',
]; ];
const NON_CATCHABLE_PATTERNS = [ public const NON_CATCHABLE_PATTERNS = [
'[\xA0-\xff]+', '[\xA0-\xff]+',
]; ];
const MODIFIERS = 'iu'; public const MODIFIERS = 'iu';
/** @var bool */ /** @var bool */
protected $hasInvalidTokens = false; protected $hasInvalidTokens = false;
@ -140,18 +144,20 @@ class EmailLexer extends AbstractLexer
/** /**
* The last matched/seen token. * The last matched/seen token.
* *
* @var array * @var array|Token
* *
* @psalm-suppress NonInvariantDocblockPropertyType * @psalm-suppress NonInvariantDocblockPropertyType
* @psalm-var array{value:string, type:null|int, position:int} * @psalm-var array{value:string, type:null|int, position:int}|Token<int, string>
* @psalm-suppress NonInvariantDocblockPropertyType
*/ */
public $token; public $token;
/** /**
* The next token in the input. * The next token in the input.
* *
* @var array{position: int, type: int|null|string, value: int|string}|null * @var array|Token|null
*
* @psalm-suppress NonInvariantDocblockPropertyType
* @psalm-var array{position: int, type: int|null|string, value: int|string}|Token<int, string>|null
*/ */
public $lookahead; public $lookahead;
@ -210,7 +216,9 @@ class EmailLexer extends AbstractLexer
$this->accumulator .= $this->token['value']; $this->accumulator .= $this->token['value'];
} }
$this->previous = $this->token; $this->previous = $this->token instanceof Token
? ['value' => $this->token->value, 'type' => $this->token->type, 'position' => $this->token->position]
: $this->token;
if($this->lookahead === null) { if($this->lookahead === null) {
$this->lookahead = self::$nullToken; $this->lookahead = self::$nullToken;

View File

@ -2,7 +2,6 @@
namespace Egulias\EmailValidator; namespace Egulias\EmailValidator;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\Result; use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\LocalPart; use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Parser\DomainPart; use Egulias\EmailValidator\Parser\DomainPart;
@ -13,7 +12,7 @@ use Egulias\EmailValidator\Result\Reason\NoLocalPart;
class EmailParser extends Parser class EmailParser extends Parser
{ {
const EMAIL_MAX_LENGTH = 254; public const EMAIL_MAX_LENGTH = 254;
/** /**
* @var string * @var string

View File

@ -2,7 +2,6 @@
namespace Egulias\EmailValidator; namespace Egulias\EmailValidator;
use Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Result\Result; use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\IDLeftPart; use Egulias\EmailValidator\Parser\IDLeftPart;
use Egulias\EmailValidator\Parser\IDRightPart; use Egulias\EmailValidator\Parser\IDRightPart;
@ -14,7 +13,7 @@ use Egulias\EmailValidator\Result\Reason\NoLocalPart;
class MessageIDParser extends Parser class MessageIDParser extends Parser
{ {
const EMAILID_MAX_LENGTH = 254; public const EMAILID_MAX_LENGTH = 254;
/** /**
* @var string * @var string
@ -89,4 +88,4 @@ class MessageIDParser extends Parser
$this->warnings[EmailTooLong::CODE] = new EmailTooLong(); $this->warnings[EmailTooLong::CODE] = new EmailTooLong();
} }
} }
} }

View File

@ -59,7 +59,8 @@ class Comment extends PartParser
if($this->openedParenthesis >= 1) { if($this->openedParenthesis >= 1) {
return new InvalidEmail(new UnclosedComment(), $this->lexer->token['value']); return new InvalidEmail(new UnclosedComment(), $this->lexer->token['value']);
} else if ($this->openedParenthesis < 0) { }
if ($this->openedParenthesis < 0) {
return new InvalidEmail(new UnOpenedComment(), $this->lexer->token['value']); return new InvalidEmail(new UnOpenedComment(), $this->lexer->token['value']);
} }
@ -100,4 +101,4 @@ class Comment extends PartParser
return true; return true;
} }
} }
} }

View File

@ -15,4 +15,4 @@ interface CommentStrategy
public function endOfLoopValidations(EmailLexer $lexer) : Result; public function endOfLoopValidations(EmailLexer $lexer) : Result;
public function getWarnings() : array; public function getWarnings() : array;
} }

View File

@ -34,4 +34,4 @@ class DomainComment implements CommentStrategy
{ {
return []; return [];
} }
} }

View File

@ -34,4 +34,4 @@ class LocalComment implements CommentStrategy
{ {
return $this->warnings; return $this->warnings;
} }
} }

View File

@ -22,9 +22,9 @@ use Egulias\EmailValidator\Warning\DomainLiteral as WarningDomainLiteral;
class DomainLiteral extends PartParser class DomainLiteral extends PartParser
{ {
const IPV4_REGEX = '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/'; public const IPV4_REGEX = '/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
const OBSOLETE_WARNINGS = [ public const OBSOLETE_WARNINGS = [
EmailLexer::INVALID, EmailLexer::INVALID,
EmailLexer::C_DEL, EmailLexer::C_DEL,
EmailLexer::S_LF, EmailLexer::S_LF,
@ -208,4 +208,4 @@ class DomainLiteral extends PartParser
} }
} }
} }

View File

@ -2,6 +2,7 @@
namespace Egulias\EmailValidator\Parser; namespace Egulias\EmailValidator\Parser;
use Doctrine\Common\Lexer\Token;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Warning\TLD; use Egulias\EmailValidator\Warning\TLD;
use Egulias\EmailValidator\Result\Result; use Egulias\EmailValidator\Result\Result;
@ -24,8 +25,8 @@ use Egulias\EmailValidator\Parser\DomainLiteral as DomainLiteralParser;
class DomainPart extends PartParser class DomainPart extends PartParser
{ {
const DOMAIN_MAX_LENGTH = 253; public const DOMAIN_MAX_LENGTH = 253;
const LABEL_MAX_LENGTH = 63; public const LABEL_MAX_LENGTH = 63;
/** /**
* @var string * @var string
@ -212,7 +213,10 @@ class DomainPart extends PartParser
return new ValidEmail(); return new ValidEmail();
} }
private function checkNotAllowedChars(array $token) : Result /**
* @psalm-param array|Token<int, string> $token
*/
private function checkNotAllowedChars($token) : Result
{ {
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true]; $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
if (isset($notAllowed[$token['type']])) { if (isset($notAllowed[$token['type']])) {

View File

@ -2,7 +2,6 @@
namespace Egulias\EmailValidator\Parser; namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Parser\Parser;
use Egulias\EmailValidator\Result\ValidEmail; use Egulias\EmailValidator\Result\ValidEmail;
use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Warning\CFWSWithFWS; use Egulias\EmailValidator\Warning\CFWSWithFWS;
@ -85,4 +84,4 @@ class DoubleQuote extends PartParser
return new ValidEmail(); return new ValidEmail();
} }
} }

View File

@ -15,7 +15,7 @@ use Egulias\EmailValidator\Result\ValidEmail;
class FoldingWhiteSpace extends PartParser class FoldingWhiteSpace extends PartParser
{ {
const FWS_TYPES = [ public const FWS_TYPES = [
EmailLexer::S_SP, EmailLexer::S_SP,
EmailLexer::S_HTAB, EmailLexer::S_HTAB,
EmailLexer::S_CR, EmailLexer::S_CR,
@ -83,4 +83,4 @@ class FoldingWhiteSpace extends PartParser
return in_array($this->lexer->token['type'], self::FWS_TYPES); return in_array($this->lexer->token['type'], self::FWS_TYPES);
} }
} }

View File

@ -3,7 +3,6 @@
namespace Egulias\EmailValidator\Parser; namespace Egulias\EmailValidator\Parser;
use Egulias\EmailValidator\Result\Result; use Egulias\EmailValidator\Result\Result;
use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\CommentsInIDRight; use Egulias\EmailValidator\Result\Reason\CommentsInIDRight;
@ -13,4 +12,4 @@ class IDLeftPart extends LocalPart
{ {
return new InvalidEmail(new CommentsInIDRight(), $this->lexer->token['value']); return new InvalidEmail(new CommentsInIDRight(), $this->lexer->token['value']);
} }
} }

View File

@ -26,4 +26,4 @@ class IDRightPart extends DomainPart
} }
return new ValidEmail(); return new ValidEmail();
} }
} }

View File

@ -15,7 +15,7 @@ use Egulias\EmailValidator\Parser\CommentStrategy\LocalComment;
class LocalPart extends PartParser class LocalPart extends PartParser
{ {
const INVALID_TOKENS = [ public const INVALID_TOKENS = [
EmailLexer::S_COMMA => EmailLexer::S_COMMA, EmailLexer::S_COMMA => EmailLexer::S_COMMA,
EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET, EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET,
EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET, EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET,
@ -162,4 +162,4 @@ class LocalPart extends PartParser
return new ValidEmail(); return new ValidEmail();
} }
} }

View File

@ -60,4 +60,4 @@ abstract class PartParser
&& &&
$this->lexer->token['type'] !== EmailLexer::GENERIC; $this->lexer->token['type'] !== EmailLexer::GENERIC;
} }
} }

View File

@ -6,7 +6,7 @@ use Egulias\EmailValidator\Result\Reason\Reason;
class InvalidEmail implements Result class InvalidEmail implements Result
{ {
private $token; private $token;
/** /**
* @var Reason * @var Reason
*/ */
@ -43,4 +43,4 @@ class InvalidEmail implements Result
return $this->reason; return $this->reason;
} }
} }

View File

@ -13,4 +13,4 @@ class AtextAfterCFWS implements Reason
{ {
return 'ATEXT found after CFWS'; return 'ATEXT found after CFWS';
} }
} }

View File

@ -4,8 +4,8 @@ namespace Egulias\EmailValidator\Result\Reason;
class CRLFAtTheEnd implements Reason class CRLFAtTheEnd implements Reason
{ {
const CODE = 149; public const CODE = 149;
const REASON = "CRLF at the end"; public const REASON = "CRLF at the end";
public function code() : int public function code() : int
{ {

View File

@ -13,4 +13,4 @@ class CharNotAllowed implements Reason
{ {
return "Character not allowed"; return "Character not allowed";
} }
} }

View File

@ -13,4 +13,4 @@ class CommaInDomain implements Reason
{ {
return "Comma ',' is not allowed in domain part"; return "Comma ',' is not allowed in domain part";
} }
} }

View File

@ -13,4 +13,4 @@ class CommentsInIDRight implements Reason
{ {
return 'Comments are not allowed in IDRight for message-id'; return 'Comments are not allowed in IDRight for message-id';
} }
} }

View File

@ -10,4 +10,4 @@ abstract class DetailedReason implements Reason
{ {
$this->detailedDescription = $details; $this->detailedDescription = $details;
} }
} }

View File

@ -13,4 +13,4 @@ class DomainAcceptsNoMail implements Reason
{ {
return 'Domain accepts no mail (Null MX, RFC7505)'; return 'Domain accepts no mail (Null MX, RFC7505)';
} }
} }

View File

@ -23,4 +23,4 @@ class ExceptionFound implements Reason
{ {
return $this->exception->getMessage(); return $this->exception->getMessage();
} }
} }

View File

@ -13,4 +13,4 @@ class ExpectingDomainLiteralClose implements Reason
{ {
return "Closing bracket ']' for domain literal not found"; return "Closing bracket ']' for domain literal not found";
} }
} }

View File

@ -13,4 +13,4 @@ class LocalOrReservedDomain implements Reason
{ {
return 'Local, mDNS or reserved domain (RFC2606, RFC6762)'; return 'Local, mDNS or reserved domain (RFC2606, RFC6762)';
} }
} }

View File

@ -13,4 +13,4 @@ class NoDNSRecord implements Reason
{ {
return 'No MX or A DSN record was found for this email'; return 'No MX or A DSN record was found for this email';
} }
} }

View File

@ -13,4 +13,4 @@ interface Reason
* Short description of the result, human readable. * Short description of the result, human readable.
*/ */
public function description() : string; public function description() : string;
} }

View File

@ -13,4 +13,4 @@ class UnOpenedComment implements Reason
{ {
return 'Missing opening comment parentheses - https://tools.ietf.org/html/rfc5322#section-3.2.2'; return 'Missing opening comment parentheses - https://tools.ietf.org/html/rfc5322#section-3.2.2';
} }
} }

View File

@ -23,4 +23,4 @@ class UnusualElements implements Reason
{ {
return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element; return 'Unusual element found, wourld render invalid in majority of cases. Element found: ' . $this->element;
} }
} }

View File

@ -24,4 +24,4 @@ interface Result
* Code for user land to act upon. * Code for user land to act upon.
*/ */
public function code() : int; public function code() : int;
} }

View File

@ -1,7 +1,6 @@
<?php <?php
namespace Egulias\EmailValidator\Result; namespace Egulias\EmailValidator\Result;
use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\SpoofEmail as ReasonSpoofEmail; use Egulias\EmailValidator\Result\Reason\SpoofEmail as ReasonSpoofEmail;
class SpoofEmail extends InvalidEmail class SpoofEmail extends InvalidEmail
@ -11,4 +10,4 @@ class SpoofEmail extends InvalidEmail
$this->reason = new ReasonSpoofEmail(); $this->reason = new ReasonSpoofEmail();
parent::__construct($this->reason, ''); parent::__construct($this->reason, '');
} }
} }

View File

@ -24,4 +24,4 @@ class ValidEmail implements Result
return 0; return 0;
} }
} }

View File

@ -2,7 +2,6 @@
namespace Egulias\EmailValidator\Validation; namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\Validation\DNSGetRecordWrapper;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Result\InvalidEmail; use Egulias\EmailValidator\Result\InvalidEmail;
use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail; use Egulias\EmailValidator\Result\Reason\DomainAcceptsNoMail;
@ -22,7 +21,7 @@ class DNSCheckValidation implements EmailValidation
* Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2), * Reserved Top Level DNS Names (https://tools.ietf.org/html/rfc2606#section-2),
* mDNS and private DNS Namespaces (https://tools.ietf.org/html/rfc6762#appendix-G) * mDNS and private DNS Namespaces (https://tools.ietf.org/html/rfc6762#appendix-G)
*/ */
const RESERVED_DNS_TOP_LEVEL_NAMES = [ public const RESERVED_DNS_TOP_LEVEL_NAMES = [
// Reserved Top Level DNS Names // Reserved Top Level DNS Names
'test', 'test',
'example', 'example',
@ -61,7 +60,7 @@ class DNSCheckValidation implements EmailValidation
*/ */
private $dnsGetRecord; private $dnsGetRecord;
public function __construct(DNSGetRecordWrapper $dnsGetRecord = null) public function __construct(?DNSGetRecordWrapper $dnsGetRecord = null)
{ {
if (!function_exists('idn_to_ascii')) { if (!function_exists('idn_to_ascii')) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__)); throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
@ -189,4 +188,4 @@ class DNSCheckValidation implements EmailValidation
return true; return true;
} }
} }

View File

@ -25,4 +25,4 @@ class DNSGetRecordWrapper
restore_error_handler(); restore_error_handler();
} }
} }
} }

View File

@ -32,4 +32,4 @@ class DNSRecords
} }
} }

View File

@ -9,7 +9,7 @@ class EmptyValidationList extends \InvalidArgumentException
/** /**
* @param int $code * @param int $code
*/ */
public function __construct($code = 0, Exception $previous = null) public function __construct($code = 0, ?Exception $previous = null)
{ {
parent::__construct("Empty validation list is not allowed", $code, $previous); parent::__construct("Empty validation list is not allowed", $code, $previous);
} }

View File

@ -13,13 +13,13 @@ class MultipleValidationWithAnd implements EmailValidation
* If one of validations fails, the remaining validations will be skipped. * If one of validations fails, the remaining validations will be skipped.
* This means MultipleErrors will only contain a single error, the first found. * This means MultipleErrors will only contain a single error, the first found.
*/ */
const STOP_ON_ERROR = 0; public const STOP_ON_ERROR = 0;
/** /**
* All of validations will be invoked even if one of them got failure. * All of validations will be invoked even if one of them got failure.
* So MultipleErrors will contain all causes. * So MultipleErrors will contain all causes.
*/ */
const ALLOW_ALL_ERRORS = 1; public const ALLOW_ALL_ERRORS = 1;
/** /**
* @var EmailValidation[] * @var EmailValidation[]

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class AddressLiteral extends Warning class AddressLiteral extends Warning
{ {
const CODE = 12; public const CODE = 12;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class CFWSNearAt extends Warning class CFWSNearAt extends Warning
{ {
const CODE = 49; public const CODE = 49;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class CFWSWithFWS extends Warning class CFWSWithFWS extends Warning
{ {
const CODE = 18; public const CODE = 18;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class Comment extends Warning class Comment extends Warning
{ {
const CODE = 17; public const CODE = 17;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class DeprecatedComment extends Warning class DeprecatedComment extends Warning
{ {
const CODE = 37; public const CODE = 37;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class DomainLiteral extends Warning class DomainLiteral extends Warning
{ {
const CODE = 70; public const CODE = 70;
public function __construct() public function __construct()
{ {

View File

@ -6,7 +6,7 @@ use Egulias\EmailValidator\EmailParser;
class EmailTooLong extends Warning class EmailTooLong extends Warning
{ {
const CODE = 66; public const CODE = 66;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6BadChar extends Warning class IPV6BadChar extends Warning
{ {
const CODE = 74; public const CODE = 74;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6ColonEnd extends Warning class IPV6ColonEnd extends Warning
{ {
const CODE = 77; public const CODE = 77;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6ColonStart extends Warning class IPV6ColonStart extends Warning
{ {
const CODE = 76; public const CODE = 76;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6Deprecated extends Warning class IPV6Deprecated extends Warning
{ {
const CODE = 13; public const CODE = 13;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6DoubleColon extends Warning class IPV6DoubleColon extends Warning
{ {
const CODE = 73; public const CODE = 73;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6GroupCount extends Warning class IPV6GroupCount extends Warning
{ {
const CODE = 72; public const CODE = 72;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class IPV6MaxGroups extends Warning class IPV6MaxGroups extends Warning
{ {
const CODE = 75; public const CODE = 75;
public function __construct() public function __construct()
{ {

View File

@ -4,8 +4,8 @@ namespace Egulias\EmailValidator\Warning;
class LocalTooLong extends Warning class LocalTooLong extends Warning
{ {
const CODE = 64; public const CODE = 64;
const LOCAL_PART_LENGTH = 64; public const LOCAL_PART_LENGTH = 64;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class NoDNSMXRecord extends Warning class NoDNSMXRecord extends Warning
{ {
const CODE = 6; public const CODE = 6;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class ObsoleteDTEXT extends Warning class ObsoleteDTEXT extends Warning
{ {
const CODE = 71; public const CODE = 71;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class QuotedPart extends Warning class QuotedPart extends Warning
{ {
const CODE = 36; public const CODE = 36;
/** /**
* @param scalar $prevToken * @param scalar $prevToken

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class QuotedString extends Warning class QuotedString extends Warning
{ {
const CODE = 11; public const CODE = 11;
/** /**
* @param scalar $prevToken * @param scalar $prevToken

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
class TLD extends Warning class TLD extends Warning
{ {
const CODE = 9; public const CODE = 9;
public function __construct() public function __construct()
{ {

View File

@ -4,7 +4,7 @@ namespace Egulias\EmailValidator\Warning;
abstract class Warning abstract class Warning
{ {
const CODE = 0; public const CODE = 0;
/** /**
* @var string * @var string

View File

@ -16,7 +16,7 @@
- Probably the world's most popular code for sending email from PHP! - Probably the world's most popular code for sending email from PHP!
- Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more - Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more
- Integrated SMTP support send without a local mail server - Integrated SMTP support send without a local mail server
- Send emails with multiple To, CC, BCC and Reply-to addresses - Send emails with multiple To, CC, BCC, and Reply-to addresses
- Multipart/alternative emails for mail clients that do not read HTML email - Multipart/alternative emails for mail clients that do not read HTML email
- Add attachments, including inline - Add attachments, including inline
- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings - Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
@ -25,7 +25,7 @@
- Protects against header injection attacks - Protects against header injection attacks
- Error messages in over 50 languages! - Error messages in over 50 languages!
- DKIM and S/MIME signing support - DKIM and S/MIME signing support
- Compatible with PHP 5.5 and later, including PHP 8.1 - Compatible with PHP 5.5 and later, including PHP 8.2
- Namespaced to prevent name clashes - Namespaced to prevent name clashes
- Much more! - Much more!
@ -38,7 +38,7 @@ The PHP `mail()` function usually sends via a local mail server, typically front
*Please* don't be tempted to do it yourself if you don't use PHPMailer, there are many other excellent libraries that *Please* don't be tempted to do it yourself if you don't use PHPMailer, there are many other excellent libraries that
you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/) you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/)
, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail) etc. , [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
## License ## License
This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution. This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
@ -47,7 +47,7 @@ This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lg
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json ```json
"phpmailer/phpmailer": "^6.5" "phpmailer/phpmailer": "^6.7.1"
``` ```
or run or run
@ -136,14 +136,14 @@ try {
} }
``` ```
You'll find plenty to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder, which covers many common scenarios including sending through gmail, building contact forms, sending to mailing lists, and more. You'll find plenty to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder, which covers many common scenarios including sending through Gmail, building contact forms, sending to mailing lists, and more.
If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance. If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance.
That's it. You should now be ready to use PHPMailer! That's it. You should now be ready to use PHPMailer!
## Localization ## Localization
PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder, you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
```php ```php
//To load the French version //To load the French version
@ -178,9 +178,9 @@ Please disclose any vulnerabilities found responsibly report security issues
See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) and [PHPMailer's security advisories on GitHub](https://github.com/PHPMailer/PHPMailer/security). See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) and [PHPMailer's security advisories on GitHub](https://github.com/PHPMailer/PHPMailer/security).
## Contributing ## Contributing
Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues). Please submit bug reports, suggestions, and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).
We're particularly interested in fixing edge-cases, expanding test coverage and updating translations. We're particularly interested in fixing edge cases, expanding test coverage, and updating translations.
If you found a mistake in the docs, or want to add something, go ahead and amend the wiki anyone can edit it. If you found a mistake in the docs, or want to add something, go ahead and amend the wiki anyone can edit it.
@ -204,7 +204,7 @@ Donations are very welcome, whether in beer 🍺, T-shirts 👕, or cold, hard c
Available as part of the Tidelift Subscription. Available as part of the Tidelift Subscription.
The maintainers of PHPMailer and thousands of other packages are working with Tidelift to deliver commercial The maintainers of PHPMailer and thousands of other packages are working with Tidelift to deliver commercial
support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and support and maintenance for the open-source packages you use to build your applications. Save time, reduce risk, and
improve code health, while paying the maintainers of the exact packages you improve code health, while paying the maintainers of the exact packages you
use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-phpmailer?utm_source=packagist-phpmailer-phpmailer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-phpmailer-phpmailer?utm_source=packagist-phpmailer-phpmailer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
@ -222,9 +222,9 @@ See [changelog](changelog.md).
### What's changed since moving from SourceForge? ### What's changed since moving from SourceForge?
- Official successor to the SourceForge and Google Code projects. - Official successor to the SourceForge and Google Code projects.
- Test suite. - Test suite.
- Continuous integration with Github Actions. - Continuous integration with GitHub Actions.
- Composer support. - Composer support.
- Public development. - Public development.
- Additional languages and language strings. - Additional languages and language strings.
- CRAM-MD5 authentication support. - CRAM-MD5 authentication support.
- Preserves full repo history of authors, commits and branches from the original SourceForge project. - Preserves full repo history of authors, commits, and branches from the original SourceForge project.

View File

@ -1 +1 @@
6.6.4 6.7.1

View File

@ -37,21 +37,23 @@
"ext-hash": "*" "ext-hash": "*"
}, },
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6.2", "squizlabs/php_codesniffer": "^3.7.1",
"yoast/phpunit-polyfills": "^1.0.0" "yoast/phpunit-polyfills": "^1.0.4"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
}, },
"autoload": { "autoload": {

Some files were not shown because too many files have changed in this diff Show More