mirror of https://github.com/1099438829/apeblog
parent
c7deee9ae9
commit
ccec51ad88
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function initializeIncludeClosure()
|
||||||
|
{
|
||||||
|
if (self::$includeFile !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Scope isolated include.
|
* Scope isolated include.
|
||||||
*
|
*
|
||||||
* Prevents access to $this/self from included files.
|
* Prevents access to $this/self from included files.
|
||||||
*
|
*
|
||||||
* @param string $file
|
* @param string $file
|
||||||
* @return void
|
* @return void
|
||||||
* @private
|
|
||||||
*/
|
*/
|
||||||
function includeFile($file)
|
self::$includeFile = \Closure::bind(static function($file) {
|
||||||
{
|
|
||||||
include $file;
|
include $file;
|
||||||
|
}, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $loader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $fileIdentifier
|
|
||||||
* @param string $file
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function composerRequire4b57298e8d0e895486f3307a354a7e1a($fileIdentifier, $file)
|
|
||||||
{
|
|
||||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
|
|
||||||
require $file;
|
require $file;
|
||||||
}
|
}
|
||||||
|
}, null, null);
|
||||||
|
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||||
|
$requireFile($fileIdentifier, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $loader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
[](https://github.com/doctrine/persistence/actions)
|
[](https://github.com/doctrine/persistence/actions)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
66
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
vendored
Normal file
66
vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
vendored
Normal 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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": {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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']])) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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__));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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[]
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
6.6.4
|
6.7.1
|
||||||
|
|
@ -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": {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ use League\OAuth2\Client\Provider\Google;
|
||||||
use Hayageek\OAuth2\Client\Provider\Yahoo;
|
use Hayageek\OAuth2\Client\Provider\Yahoo;
|
||||||
//@see https://github.com/stevenmaguire/oauth2-microsoft
|
//@see https://github.com/stevenmaguire/oauth2-microsoft
|
||||||
use Stevenmaguire\OAuth2\Client\Provider\Microsoft;
|
use Stevenmaguire\OAuth2\Client\Provider\Microsoft;
|
||||||
|
//@see https://github.com/greew/oauth2-azure-provider
|
||||||
|
use Greew\OAuth2\Client\Provider\Azure;
|
||||||
|
|
||||||
if (!isset($_GET['code']) && !isset($_POST['provider'])) {
|
if (!isset($_GET['code']) && !isset($_POST['provider'])) {
|
||||||
?>
|
?>
|
||||||
|
|
@ -57,11 +59,14 @@ if (!isset($_GET['code']) && !isset($_POST['provider'])) {
|
||||||
<label for="providerYahoo">Yahoo</label><br>
|
<label for="providerYahoo">Yahoo</label><br>
|
||||||
<input type="radio" name="provider" value="Microsoft" id="providerMicrosoft">
|
<input type="radio" name="provider" value="Microsoft" id="providerMicrosoft">
|
||||||
<label for="providerMicrosoft">Microsoft</label><br>
|
<label for="providerMicrosoft">Microsoft</label><br>
|
||||||
|
<input type="radio" name="provider" value="Azure" id="providerAzure">
|
||||||
|
<label for="providerAzure">Azure</label><br>
|
||||||
<h1>Enter id and secret</h1>
|
<h1>Enter id and secret</h1>
|
||||||
<p>These details are obtained by setting up an app in your provider's developer console.
|
<p>These details are obtained by setting up an app in your provider's developer console.
|
||||||
</p>
|
</p>
|
||||||
<p>ClientId: <input type="text" name="clientId"><p>
|
<p>ClientId: <input type="text" name="clientId"><p>
|
||||||
<p>ClientSecret: <input type="text" name="clientSecret"></p>
|
<p>ClientSecret: <input type="text" name="clientSecret"></p>
|
||||||
|
<p>TenantID (only relevant for Azure): <input type="text" name="tenantId"></p>
|
||||||
<input type="submit" value="Continue">
|
<input type="submit" value="Continue">
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
|
@ -77,18 +82,22 @@ session_start();
|
||||||
$providerName = '';
|
$providerName = '';
|
||||||
$clientId = '';
|
$clientId = '';
|
||||||
$clientSecret = '';
|
$clientSecret = '';
|
||||||
|
$tenantId = '';
|
||||||
|
|
||||||
if (array_key_exists('provider', $_POST)) {
|
if (array_key_exists('provider', $_POST)) {
|
||||||
$providerName = $_POST['provider'];
|
$providerName = $_POST['provider'];
|
||||||
$clientId = $_POST['clientId'];
|
$clientId = $_POST['clientId'];
|
||||||
$clientSecret = $_POST['clientSecret'];
|
$clientSecret = $_POST['clientSecret'];
|
||||||
|
$tenantId = $_POST['tenantId'];
|
||||||
$_SESSION['provider'] = $providerName;
|
$_SESSION['provider'] = $providerName;
|
||||||
$_SESSION['clientId'] = $clientId;
|
$_SESSION['clientId'] = $clientId;
|
||||||
$_SESSION['clientSecret'] = $clientSecret;
|
$_SESSION['clientSecret'] = $clientSecret;
|
||||||
|
$_SESSION['tenantId'] = $tenantId;
|
||||||
} elseif (array_key_exists('provider', $_SESSION)) {
|
} elseif (array_key_exists('provider', $_SESSION)) {
|
||||||
$providerName = $_SESSION['provider'];
|
$providerName = $_SESSION['provider'];
|
||||||
$clientId = $_SESSION['clientId'];
|
$clientId = $_SESSION['clientId'];
|
||||||
$clientSecret = $_SESSION['clientSecret'];
|
$clientSecret = $_SESSION['clientSecret'];
|
||||||
|
$tenantId = $_SESSION['tenantId'];
|
||||||
}
|
}
|
||||||
|
|
||||||
//If you don't want to use the built-in form, set your client id and secret here
|
//If you don't want to use the built-in form, set your client id and secret here
|
||||||
|
|
@ -130,6 +139,17 @@ switch ($providerName) {
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
case 'Azure':
|
||||||
|
$params['tenantId'] = $tenantId;
|
||||||
|
|
||||||
|
$provider = new Azure($params);
|
||||||
|
$options = [
|
||||||
|
'scope' => [
|
||||||
|
'https://outlook.office.com/SMTP.Send',
|
||||||
|
'offline_access'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $provider) {
|
if (null === $provider) {
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,22 @@ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.
|
||||||
$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold';
|
$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold';
|
||||||
$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: ';
|
$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: ';
|
||||||
$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: ';
|
$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: ';
|
||||||
|
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
|
||||||
$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: ';
|
$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: ';
|
||||||
$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
|
$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
|
||||||
$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
|
$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
|
||||||
$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.';
|
$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.';
|
||||||
$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: ';
|
$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: ';
|
||||||
|
$PHPMAILER_LANG['invalid_header'] = 'Ugyldig header navn eller værdi';
|
||||||
|
$PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig hostentry: ';
|
||||||
|
$PHPMAILER_LANG['invalid_host'] = 'Ugyldig vært: ';
|
||||||
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
|
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
|
||||||
$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.';
|
$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.';
|
||||||
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: ';
|
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere fejlede: ';
|
||||||
$PHPMAILER_LANG['signing'] = 'Signeringsfejl: ';
|
$PHPMAILER_LANG['signing'] = 'Signeringsfejl: ';
|
||||||
|
$PHPMAILER_LANG['smtp_code'] = 'SMTP kode: ';
|
||||||
|
$PHPMAILER_LANG['smtp_code_ex'] = 'Yderligere SMTP info: ';
|
||||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
|
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
|
||||||
|
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
|
||||||
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
|
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
|
||||||
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
|
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
|
||||||
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
* Spanish PHPMailer language file: refer to English translation for definitive list
|
* Spanish PHPMailer language file: refer to English translation for definitive list
|
||||||
* @package PHPMailer
|
* @package PHPMailer
|
||||||
* @author Matt Sturdy <matt.sturdy@gmail.com>
|
* @author Matt Sturdy <matt.sturdy@gmail.com>
|
||||||
|
* @author Crystopher Glodzienski Cardoso <crystopher.glodzienski@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
|
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
|
||||||
|
|
@ -25,3 +26,6 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
|
||||||
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
|
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
|
||||||
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
|
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
|
||||||
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
|
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
|
||||||
|
$PHPMAILER_LANG['smtp_code'] = 'Código del servidor SMTP: ';
|
||||||
|
$PHPMAILER_LANG['smtp_code_ex'] = 'Información adicional del servidor SMTP: ';
|
||||||
|
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,18 @@ $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzi
|
||||||
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
|
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
|
||||||
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
|
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
|
||||||
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
|
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
|
||||||
$PHPMAILER_LANG['encoding'] = 'Nieznany sposób kodowania znaków: ';
|
$PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: ';
|
||||||
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
|
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
|
||||||
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
|
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
|
||||||
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
|
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
|
||||||
$PHPMAILER_LANG['from_failed'] = 'Następujący adres Nadawcy jest nieprawidłowy: ';
|
$PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: ';
|
||||||
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
|
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
|
||||||
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' .
|
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
|
||||||
'następujący adres Odbiorcy jest nieprawidłowy: ';
|
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.';
|
||||||
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
|
|
||||||
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
|
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
|
||||||
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
|
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: ';
|
||||||
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
|
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
|
||||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.';
|
$PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.';
|
||||||
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
|
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
|
||||||
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
|
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
|
||||||
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
|
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
|
||||||
|
|
|
||||||
|
|
@ -750,7 +750,7 @@ class PHPMailer
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const VERSION = '6.6.4';
|
const VERSION = '6.7.1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error severity: message only, continue processing.
|
* Error severity: message only, continue processing.
|
||||||
|
|
@ -858,7 +858,7 @@ class PHPMailer
|
||||||
private function mailPassthru($to, $subject, $body, $header, $params)
|
private function mailPassthru($to, $subject, $body, $header, $params)
|
||||||
{
|
{
|
||||||
//Check overloading of mail function to avoid double-encoding
|
//Check overloading of mail function to avoid double-encoding
|
||||||
if (ini_get('mbstring.func_overload') & 1) {
|
if ((int)ini_get('mbstring.func_overload') & 1) {
|
||||||
$subject = $this->secureHeader($subject);
|
$subject = $this->secureHeader($subject);
|
||||||
} else {
|
} else {
|
||||||
$subject = $this->encodeHeader($this->secureHeader($subject));
|
$subject = $this->encodeHeader($this->secureHeader($subject));
|
||||||
|
|
@ -1124,6 +1124,22 @@ class PHPMailer
|
||||||
return call_user_func_array([$this, 'addAnAddress'], $params);
|
return call_user_func_array([$this, 'addAnAddress'], $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the boundaries to use for delimiting MIME parts.
|
||||||
|
* If you override this, ensure you set all 3 boundaries to unique values.
|
||||||
|
* The default boundaries include a "=_" sequence which cannot occur in quoted-printable bodies,
|
||||||
|
* as suggested by https://www.rfc-editor.org/rfc/rfc2045#section-6.7
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setBoundaries()
|
||||||
|
{
|
||||||
|
$this->uniqueid = $this->generateId();
|
||||||
|
$this->boundary[1] = 'b1=_' . $this->uniqueid;
|
||||||
|
$this->boundary[2] = 'b2=_' . $this->uniqueid;
|
||||||
|
$this->boundary[3] = 'b3=_' . $this->uniqueid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an address to one of the recipient arrays or to the ReplyTo array.
|
* Add an address to one of the recipient arrays or to the ReplyTo array.
|
||||||
* Addresses that have been added already return false, but do not throw exceptions.
|
* Addresses that have been added already return false, but do not throw exceptions.
|
||||||
|
|
@ -1671,11 +1687,11 @@ class PHPMailer
|
||||||
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
|
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
|
||||||
}
|
}
|
||||||
} catch (Exception $exc) {
|
} catch (Exception $exc) {
|
||||||
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
|
|
||||||
$this->smtp->reset();
|
|
||||||
}
|
|
||||||
$this->setError($exc->getMessage());
|
$this->setError($exc->getMessage());
|
||||||
$this->edebug($exc->getMessage());
|
$this->edebug($exc->getMessage());
|
||||||
|
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
|
||||||
|
$this->smtp->reset();
|
||||||
|
}
|
||||||
if ($this->exceptions) {
|
if ($this->exceptions) {
|
||||||
throw $exc;
|
throw $exc;
|
||||||
}
|
}
|
||||||
|
|
@ -1863,7 +1879,7 @@ class PHPMailer
|
||||||
if (!static::isPermittedPath($path)) {
|
if (!static::isPermittedPath($path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$readable = file_exists($path);
|
$readable = is_file($path);
|
||||||
//If not a UNC path (expected to start with \\), check read permission, see #2069
|
//If not a UNC path (expected to start with \\), check read permission, see #2069
|
||||||
if (strpos($path, '\\\\') !== 0) {
|
if (strpos($path, '\\\\') !== 0) {
|
||||||
$readable = $readable && is_readable($path);
|
$readable = $readable && is_readable($path);
|
||||||
|
|
@ -2101,6 +2117,9 @@ class PHPMailer
|
||||||
$this->smtp->setDebugLevel($this->SMTPDebug);
|
$this->smtp->setDebugLevel($this->SMTPDebug);
|
||||||
$this->smtp->setDebugOutput($this->Debugoutput);
|
$this->smtp->setDebugOutput($this->Debugoutput);
|
||||||
$this->smtp->setVerp($this->do_verp);
|
$this->smtp->setVerp($this->do_verp);
|
||||||
|
if ($this->Host === null) {
|
||||||
|
$this->Host = 'localhost';
|
||||||
|
}
|
||||||
$hosts = explode(';', $this->Host);
|
$hosts = explode(';', $this->Host);
|
||||||
$lastexception = null;
|
$lastexception = null;
|
||||||
|
|
||||||
|
|
@ -2791,10 +2810,7 @@ class PHPMailer
|
||||||
{
|
{
|
||||||
$body = '';
|
$body = '';
|
||||||
//Create unique IDs and preset boundaries
|
//Create unique IDs and preset boundaries
|
||||||
$this->uniqueid = $this->generateId();
|
$this->setBoundaries();
|
||||||
$this->boundary[1] = 'b1_' . $this->uniqueid;
|
|
||||||
$this->boundary[2] = 'b2_' . $this->uniqueid;
|
|
||||||
$this->boundary[3] = 'b3_' . $this->uniqueid;
|
|
||||||
|
|
||||||
if ($this->sign_key_file) {
|
if ($this->sign_key_file) {
|
||||||
$body .= $this->getMailMIME() . static::$LE;
|
$body .= $this->getMailMIME() . static::$LE;
|
||||||
|
|
@ -2830,7 +2846,7 @@ class PHPMailer
|
||||||
$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
|
$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
|
||||||
}
|
}
|
||||||
//Use this as a preamble in all multipart message types
|
//Use this as a preamble in all multipart message types
|
||||||
$mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE;
|
$mimepre = '';
|
||||||
switch ($this->message_type) {
|
switch ($this->message_type) {
|
||||||
case 'inline':
|
case 'inline':
|
||||||
$body .= $mimepre;
|
$body .= $mimepre;
|
||||||
|
|
@ -3066,6 +3082,18 @@ class PHPMailer
|
||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the boundaries that this message will use
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getBoundaries()
|
||||||
|
{
|
||||||
|
if (empty($this->boundary)) {
|
||||||
|
$this->setBoundaries();
|
||||||
|
}
|
||||||
|
return $this->boundary;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the start of a message boundary.
|
* Return the start of a message boundary.
|
||||||
*
|
*
|
||||||
|
|
@ -4183,6 +4211,7 @@ class PHPMailer
|
||||||
* @param string $name Custom header name
|
* @param string $name Custom header name
|
||||||
* @param string|null $value Header value
|
* @param string|null $value Header value
|
||||||
*
|
*
|
||||||
|
* @return bool True if a header was set successfully
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function addCustomHeader($name, $value = null)
|
public function addCustomHeader($name, $value = null)
|
||||||
|
|
@ -4632,15 +4661,27 @@ class PHPMailer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove trailing breaks from a string.
|
* Remove trailing whitespace from a string.
|
||||||
|
*
|
||||||
|
* @param string $text
|
||||||
|
*
|
||||||
|
* @return string The text to remove whitespace from
|
||||||
|
*/
|
||||||
|
public static function stripTrailingWSP($text)
|
||||||
|
{
|
||||||
|
return rtrim($text, " \r\n\t");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip trailing line breaks from a string.
|
||||||
*
|
*
|
||||||
* @param string $text
|
* @param string $text
|
||||||
*
|
*
|
||||||
* @return string The text to remove breaks from
|
* @return string The text to remove breaks from
|
||||||
*/
|
*/
|
||||||
public static function stripTrailingWSP($text)
|
public static function stripTrailingBreaks($text)
|
||||||
{
|
{
|
||||||
return rtrim($text, " \r\n\t");
|
return rtrim($text, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -4806,7 +4847,7 @@ class PHPMailer
|
||||||
$body = static::normalizeBreaks($body, self::CRLF);
|
$body = static::normalizeBreaks($body, self::CRLF);
|
||||||
|
|
||||||
//Reduce multiple trailing line breaks to a single one
|
//Reduce multiple trailing line breaks to a single one
|
||||||
return static::stripTrailingWSP($body) . self::CRLF;
|
return static::stripTrailingBreaks($body) . self::CRLF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class POP3
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const VERSION = '6.6.4';
|
const VERSION = '6.7.1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default POP3 port number.
|
* Default POP3 port number.
|
||||||
|
|
@ -337,7 +337,12 @@ class POP3
|
||||||
*/
|
*/
|
||||||
public function disconnect()
|
public function disconnect()
|
||||||
{
|
{
|
||||||
$this->sendString('QUIT');
|
// If could not connect at all, no need to disconnect
|
||||||
|
if ($this->pop_conn === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendString('QUIT' . static::LE);
|
||||||
|
|
||||||
// RFC 1939 shows POP3 server sending a +OK response to the QUIT command.
|
// RFC 1939 shows POP3 server sending a +OK response to the QUIT command.
|
||||||
// Try to get it. Ignore any failures here.
|
// Try to get it. Ignore any failures here.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class SMTP
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const VERSION = '6.6.4';
|
const VERSION = '6.7.1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SMTP line break constant.
|
* SMTP line break constant.
|
||||||
|
|
@ -682,7 +682,6 @@ class SMTP
|
||||||
*/
|
*/
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
$this->setError('');
|
|
||||||
$this->server_caps = null;
|
$this->server_caps = null;
|
||||||
$this->helo_rply = null;
|
$this->helo_rply = null;
|
||||||
if (is_resource($this->smtp_conn)) {
|
if (is_resource($this->smtp_conn)) {
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,7 @@ interface that describes a HTTP message. See the specification for more details.
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
We'll certainly need some stuff in here.
|
Before reading the usage guide we recommend reading the PSR-7 interfaces method list:
|
||||||
|
|
||||||
|
* [`PSR-7 Interfaces Method List`](docs/PSR7-Interfaces.md)
|
||||||
|
* [`PSR-7 Usage Guide`](docs/PSR7-Usage.md)
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"php": "^7.2 || ^8.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.0.x-dev"
|
"dev-master": "1.1.x-dev"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Interfaces
|
||||||
|
|
||||||
|
The purpose of this list is to help in finding the methods when working with PSR-7. This can be considered as a cheatsheet for PSR-7 interfaces.
|
||||||
|
|
||||||
|
The interfaces defined in PSR-7 are the following:
|
||||||
|
|
||||||
|
| Class Name | Description |
|
||||||
|
|---|---|
|
||||||
|
| [Psr\Http\Message\MessageInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagemessageinterface) | Representation of a HTTP message |
|
||||||
|
| [Psr\Http\Message\RequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagerequestinterface) | Representation of an outgoing, client-side request. |
|
||||||
|
| [Psr\Http\Message\ServerRequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageserverrequestinterface) | Representation of an incoming, server-side HTTP request. |
|
||||||
|
| [Psr\Http\Message\ResponseInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageresponseinterface) | Representation of an outgoing, server-side response. |
|
||||||
|
| [Psr\Http\Message\StreamInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagestreaminterface) | Describes a data stream |
|
||||||
|
| [Psr\Http\Message\UriInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuriinterface) | Value object representing a URI. |
|
||||||
|
| [Psr\Http\Message\UploadedFileInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuploadedfileinterface) | Value object representing a file uploaded through an HTTP request. |
|
||||||
|
|
||||||
|
## `Psr\Http\Message\MessageInterface` Methods
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getProtocolVersion()` | Retrieve HTTP protocol version | 1.0 or 1.1 |
|
||||||
|
| `withProtocolVersion($version)` | Returns new message instance with given HTTP protocol version | |
|
||||||
|
| `getHeaders()` | Retrieve all HTTP Headers | [Request Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields), [Response Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields) |
|
||||||
|
| `hasHeader($name)` | Checks if HTTP Header with given name exists | |
|
||||||
|
| `getHeader($name)` | Retrieves a array with the values for a single header | |
|
||||||
|
| `getHeaderLine($name)` | Retrieves a comma-separated string of the values for a single header | |
|
||||||
|
| `withHeader($name, $value)` | Returns new message instance with given HTTP Header | if the header existed in the original instance, replaces the header value from the original message with the value provided when creating the new instance. |
|
||||||
|
| `withAddedHeader($name, $value)` | Returns new message instance with appended value to given header | If header already exists value will be appended, if not a new header will be created |
|
||||||
|
| `withoutHeader($name)` | Removes HTTP Header with given name| |
|
||||||
|
| `getBody()` | Retrieves the HTTP Message Body | Returns object implementing `StreamInterface`|
|
||||||
|
| `withBody(StreamInterface $body)` | Returns new message instance with given HTTP Message Body | |
|
||||||
|
|
||||||
|
|
||||||
|
## `Psr\Http\Message\RequestInterface` Methods
|
||||||
|
|
||||||
|
Same methods as `Psr\Http\Message\MessageInterface` + the following methods:
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getRequestTarget()` | Retrieves the message's request target | origin-form, absolute-form, authority-form, asterisk-form ([RFC7230](https://www.rfc-editor.org/rfc/rfc7230.txt)) |
|
||||||
|
| `withRequestTarget($requestTarget)` | Return a new message instance with the specific request-target | |
|
||||||
|
| `getMethod()` | Retrieves the HTTP method of the request. | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE (defined in [RFC7231](https://tools.ietf.org/html/rfc7231)), PATCH (defined in [RFC5789](https://tools.ietf.org/html/rfc5789)) |
|
||||||
|
| `withMethod($method)` | Returns a new message instance with the provided HTTP method | |
|
||||||
|
| `getUri()` | Retrieves the URI instance | |
|
||||||
|
| `withUri(UriInterface $uri, $preserveHost = false)` | Returns a new message instance with the provided URI | |
|
||||||
|
|
||||||
|
|
||||||
|
## `Psr\Http\Message\ServerRequestInterface` Methods
|
||||||
|
|
||||||
|
Same methods as `Psr\Http\Message\RequestInterface` + the following methods:
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getServerParams() ` | Retrieve server parameters | Typically derived from `$_SERVER` |
|
||||||
|
| `getCookieParams()` | Retrieves cookies sent by the client to the server. | Typically derived from `$_COOKIES` |
|
||||||
|
| `withCookieParams(array $cookies)` | Returns a new request instance with the specified cookies | |
|
||||||
|
| `withQueryParams(array $query)` | Returns a new request instance with the specified query string arguments | |
|
||||||
|
| `getUploadedFiles()` | Retrieve normalized file upload data | |
|
||||||
|
| `withUploadedFiles(array $uploadedFiles)` | Returns a new request instance with the specified uploaded files | |
|
||||||
|
| `getParsedBody()` | Retrieve any parameters provided in the request body | |
|
||||||
|
| `withParsedBody($data)` | Returns a new request instance with the specified body parameters | |
|
||||||
|
| `getAttributes()` | Retrieve attributes derived from the request | |
|
||||||
|
| `getAttribute($name, $default = null)` | Retrieve a single derived request attribute | |
|
||||||
|
| `withAttribute($name, $value)` | Returns a new request instance with the specified derived request attribute | |
|
||||||
|
| `withoutAttribute($name)` | Returns a new request instance that without the specified derived request attribute | |
|
||||||
|
|
||||||
|
## `Psr\Http\Message\ResponseInterface` Methods:
|
||||||
|
|
||||||
|
Same methods as `Psr\Http\Message\MessageInterface` + the following methods:
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getStatusCode()` | Gets the response status code. | |
|
||||||
|
| `withStatus($code, $reasonPhrase = '')` | Returns a new response instance with the specified status code and, optionally, reason phrase. | |
|
||||||
|
| `getReasonPhrase()` | Gets the response reason phrase associated with the status code. | |
|
||||||
|
|
||||||
|
## `Psr\Http\Message\StreamInterface` Methods
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `__toString()` | Reads all data from the stream into a string, from the beginning to end. | |
|
||||||
|
| `close()` | Closes the stream and any underlying resources. | |
|
||||||
|
| `detach()` | Separates any underlying resources from the stream. | |
|
||||||
|
| `getSize()` | Get the size of the stream if known. | |
|
||||||
|
| `eof()` | Returns true if the stream is at the end of the stream.| |
|
||||||
|
| `isSeekable()` | Returns whether or not the stream is seekable. | |
|
||||||
|
| `seek($offset, $whence = SEEK_SET)` | Seek to a position in the stream. | |
|
||||||
|
| `rewind()` | Seek to the beginning of the stream. | |
|
||||||
|
| `isWritable()` | Returns whether or not the stream is writable. | |
|
||||||
|
| `write($string)` | Write data to the stream. | |
|
||||||
|
| `isReadable()` | Returns whether or not the stream is readable. | |
|
||||||
|
| `read($length)` | Read data from the stream. | |
|
||||||
|
| `getContents()` | Returns the remaining contents in a string | |
|
||||||
|
| `getMetadata($key = null)()` | Get stream metadata as an associative array or retrieve a specific key. | |
|
||||||
|
|
||||||
|
## `Psr\Http\Message\UriInterface` Methods
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getScheme()` | Retrieve the scheme component of the URI. | |
|
||||||
|
| `getAuthority()` | Retrieve the authority component of the URI. | |
|
||||||
|
| `getUserInfo()` | Retrieve the user information component of the URI. | |
|
||||||
|
| `getHost()` | Retrieve the host component of the URI. | |
|
||||||
|
| `getPort()` | Retrieve the port component of the URI. | |
|
||||||
|
| `getPath()` | Retrieve the path component of the URI. | |
|
||||||
|
| `getQuery()` | Retrieve the query string of the URI. | |
|
||||||
|
| `getFragment()` | Retrieve the fragment component of the URI. | |
|
||||||
|
| `withScheme($scheme)` | Return an instance with the specified scheme. | |
|
||||||
|
| `withUserInfo($user, $password = null)` | Return an instance with the specified user information. | |
|
||||||
|
| `withHost($host)` | Return an instance with the specified host. | |
|
||||||
|
| `withPort($port)` | Return an instance with the specified port. | |
|
||||||
|
| `withPath($path)` | Return an instance with the specified path. | |
|
||||||
|
| `withQuery($query)` | Return an instance with the specified query string. | |
|
||||||
|
| `withFragment($fragment)` | Return an instance with the specified URI fragment. | |
|
||||||
|
| `__toString()` | Return the string representation as a URI reference. | |
|
||||||
|
|
||||||
|
## `Psr\Http\Message\UploadedFileInterface` Methods
|
||||||
|
|
||||||
|
| Method Name | Description | Notes |
|
||||||
|
|------------------------------------| ----------- | ----- |
|
||||||
|
| `getStream()` | Retrieve a stream representing the uploaded file. | |
|
||||||
|
| `moveTo($targetPath)` | Move the uploaded file to a new location. | |
|
||||||
|
| `getSize()` | Retrieve the file size. | |
|
||||||
|
| `getError()` | Retrieve the error associated with the uploaded file. | |
|
||||||
|
| `getClientFilename()` | Retrieve the filename sent by the client. | |
|
||||||
|
| `getClientMediaType()` | Retrieve the media type sent by the client. | |
|
||||||
|
|
||||||
|
> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`.
|
||||||
|
> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
### PSR-7 Usage
|
||||||
|
|
||||||
|
All PSR-7 applications comply with these interfaces
|
||||||
|
They were created to establish a standard between middleware implementations.
|
||||||
|
|
||||||
|
> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`.
|
||||||
|
> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered.
|
||||||
|
|
||||||
|
|
||||||
|
The following examples will illustrate how basic operations are done in PSR-7.
|
||||||
|
|
||||||
|
##### Examples
|
||||||
|
|
||||||
|
|
||||||
|
For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc)
|
||||||
|
All PSR-7 implementations should have the same behaviour.
|
||||||
|
|
||||||
|
The following will be assumed:
|
||||||
|
`$request` is an object of `Psr\Http\Message\RequestInterface` and
|
||||||
|
|
||||||
|
`$response` is an object implementing `Psr\Http\Message\RequestInterface`
|
||||||
|
|
||||||
|
|
||||||
|
### Working with HTTP Headers
|
||||||
|
|
||||||
|
#### Adding headers to response:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response->withHeader('My-Custom-Header', 'My Custom Message');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Appending values to headers
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response->withAddedHeader('My-Custom-Header', 'The second message');
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Checking if header exists:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$request->hasHeader('My-Custom-Header'); // will return false
|
||||||
|
$response->hasHeader('My-Custom-Header'); // will return true
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: My-Custom-Header was only added in the Response
|
||||||
|
|
||||||
|
#### Getting comma-separated values from a header (also applies to request)
|
||||||
|
|
||||||
|
```php
|
||||||
|
// getting value from request headers
|
||||||
|
$request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8"
|
||||||
|
// getting value from response headers
|
||||||
|
$response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Getting array of value from a header (also applies to request)
|
||||||
|
```php
|
||||||
|
// getting value from request headers
|
||||||
|
$request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"]
|
||||||
|
// getting value from response headers
|
||||||
|
$response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Removing headers from HTTP Messages
|
||||||
|
```php
|
||||||
|
// removing a header from Request, removing deprecated "Content-MD5" header
|
||||||
|
$request->withoutHeader('Content-MD5');
|
||||||
|
|
||||||
|
// removing a header from Response
|
||||||
|
// effect: the browser won't know the size of the stream
|
||||||
|
// the browser will download the stream till it ends
|
||||||
|
$response->withoutHeader('Content-Length');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Working with HTTP Message Body
|
||||||
|
|
||||||
|
When working with the PSR-7 there are two methods of implementation:
|
||||||
|
#### 1. Getting the body separately
|
||||||
|
|
||||||
|
> This method makes the body handling easier to understand and is useful when repeatedly calling body methods. (You only call `getBody()` once). Using this method mistakes like `$response->write()` are also prevented.
|
||||||
|
|
||||||
|
```php
|
||||||
|
$body = $response->getBody();
|
||||||
|
// operations on body, eg. read, write, seek
|
||||||
|
// ...
|
||||||
|
// replacing the old body
|
||||||
|
$response->withBody($body);
|
||||||
|
// this last statement is optional as we working with objects
|
||||||
|
// in this case the "new" body is same with the "old" one
|
||||||
|
// the $body variable has the same value as the one in $request, only the reference is passed
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Working directly on response
|
||||||
|
|
||||||
|
> This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response->getBody()->write('hello');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting the body contents
|
||||||
|
|
||||||
|
The following snippet gets the contents of a stream contents.
|
||||||
|
> Note: Streams must be rewinded, if content was written into streams, it will be ignored when calling `getContents()` because the stream pointer is set to the last character, which is `\0` - meaning end of stream.
|
||||||
|
```php
|
||||||
|
$body = $response->getBody();
|
||||||
|
$body->rewind(); // or $body->seek(0);
|
||||||
|
$bodyText = $body->getContents();
|
||||||
|
```
|
||||||
|
> Note: If `$body->seek(1)` is called before `$body->getContents()`, the first character will be ommited as the starting pointer is set to `1`, not `0`. This is why using `$body->rewind()` is recommended.
|
||||||
|
|
||||||
|
### Append to body
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response->getBody()->write('Hello'); // writing directly
|
||||||
|
$body = $request->getBody(); // which is a `StreamInterface`
|
||||||
|
$body->write('xxxxx');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Prepend to body
|
||||||
|
Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended.
|
||||||
|
The following example will explain the behaviour of streams.
|
||||||
|
|
||||||
|
```php
|
||||||
|
// assuming our response is initially empty
|
||||||
|
$body = $repsonse->getBody();
|
||||||
|
// writing the string "abcd"
|
||||||
|
$body->write('abcd');
|
||||||
|
|
||||||
|
// seeking to start of stream
|
||||||
|
$body->seek(0);
|
||||||
|
// writing 'ef'
|
||||||
|
$body->write('ef'); // at this point the stream contains "efcd"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Prepending by rewriting separately
|
||||||
|
|
||||||
|
```php
|
||||||
|
// assuming our response body stream only contains: "abcd"
|
||||||
|
$body = $response->getBody();
|
||||||
|
$body->rewind();
|
||||||
|
$contents = $body->getContents(); // abcd
|
||||||
|
// seeking the stream to beginning
|
||||||
|
$body->rewind();
|
||||||
|
$body->write('ef'); // stream contains "efcd"
|
||||||
|
$body->write($contents); // stream contains "efabcd"
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: `getContents()` seeks the stream while reading it, therefore if the second `rewind()` method call was not present the stream would have resulted in `abcdefabcd` because the `write()` method appends to stream if not preceeded by `rewind()` or `seek(0)`.
|
||||||
|
|
||||||
|
#### Prepending by using contents as a string
|
||||||
|
```php
|
||||||
|
$body = $response->getBody();
|
||||||
|
$body->rewind();
|
||||||
|
$contents = $body->getContents(); // efabcd
|
||||||
|
$contents = 'ef'.$contents;
|
||||||
|
$body->rewind();
|
||||||
|
$body->write($contents);
|
||||||
|
```
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,7 +40,7 @@ interface MessageInterface
|
||||||
* @param string $version HTTP protocol version
|
* @param string $version HTTP protocol version
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withProtocolVersion($version);
|
public function withProtocolVersion(string $version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all message header values.
|
* Retrieves all message header values.
|
||||||
|
|
@ -75,7 +77,7 @@ interface MessageInterface
|
||||||
* name using a case-insensitive string comparison. Returns false if
|
* name using a case-insensitive string comparison. Returns false if
|
||||||
* no matching header name is found in the message.
|
* no matching header name is found in the message.
|
||||||
*/
|
*/
|
||||||
public function hasHeader($name);
|
public function hasHeader(string $name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a message header value by the given case-insensitive name.
|
* Retrieves a message header value by the given case-insensitive name.
|
||||||
|
|
@ -91,7 +93,7 @@ interface MessageInterface
|
||||||
* header. If the header does not appear in the message, this method MUST
|
* header. If the header does not appear in the message, this method MUST
|
||||||
* return an empty array.
|
* return an empty array.
|
||||||
*/
|
*/
|
||||||
public function getHeader($name);
|
public function getHeader(string $name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a comma-separated string of the values for a single header.
|
* Retrieves a comma-separated string of the values for a single header.
|
||||||
|
|
@ -112,7 +114,7 @@ interface MessageInterface
|
||||||
* concatenated together using a comma. If the header does not appear in
|
* concatenated together using a comma. If the header does not appear in
|
||||||
* the message, this method MUST return an empty string.
|
* the message, this method MUST return an empty string.
|
||||||
*/
|
*/
|
||||||
public function getHeaderLine($name);
|
public function getHeaderLine(string $name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the provided value replacing the specified header.
|
* Return an instance with the provided value replacing the specified header.
|
||||||
|
|
@ -129,7 +131,7 @@ interface MessageInterface
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \InvalidArgumentException for invalid header names or values.
|
* @throws \InvalidArgumentException for invalid header names or values.
|
||||||
*/
|
*/
|
||||||
public function withHeader($name, $value);
|
public function withHeader(string $name, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified header appended with the given value.
|
* Return an instance with the specified header appended with the given value.
|
||||||
|
|
@ -147,7 +149,7 @@ interface MessageInterface
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \InvalidArgumentException for invalid header names or values.
|
* @throws \InvalidArgumentException for invalid header names or values.
|
||||||
*/
|
*/
|
||||||
public function withAddedHeader($name, $value);
|
public function withAddedHeader(string $name, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance without the specified header.
|
* Return an instance without the specified header.
|
||||||
|
|
@ -161,7 +163,7 @@ interface MessageInterface
|
||||||
* @param string $name Case-insensitive header field name to remove.
|
* @param string $name Case-insensitive header field name to remove.
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withoutHeader($name);
|
public function withoutHeader(string $name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the body of the message.
|
* Gets the body of the message.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,10 +57,10 @@ interface RequestInterface extends MessageInterface
|
||||||
*
|
*
|
||||||
* @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
|
* @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
|
||||||
* request-target forms allowed in request messages)
|
* request-target forms allowed in request messages)
|
||||||
* @param mixed $requestTarget
|
* @param string $requestTarget
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withRequestTarget($requestTarget);
|
public function withRequestTarget(string $requestTarget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the HTTP method of the request.
|
* Retrieves the HTTP method of the request.
|
||||||
|
|
@ -82,7 +84,7 @@ interface RequestInterface extends MessageInterface
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \InvalidArgumentException for invalid HTTP methods.
|
* @throws \InvalidArgumentException for invalid HTTP methods.
|
||||||
*/
|
*/
|
||||||
public function withMethod($method);
|
public function withMethod(string $method);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the URI instance.
|
* Retrieves the URI instance.
|
||||||
|
|
@ -125,5 +127,5 @@ interface RequestInterface extends MessageInterface
|
||||||
* @param bool $preserveHost Preserve the original state of the Host header.
|
* @param bool $preserveHost Preserve the original state of the Host header.
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withUri(UriInterface $uri, $preserveHost = false);
|
public function withUri(UriInterface $uri, bool $preserveHost = false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,7 +51,7 @@ interface ResponseInterface extends MessageInterface
|
||||||
* @return static
|
* @return static
|
||||||
* @throws \InvalidArgumentException For invalid status code arguments.
|
* @throws \InvalidArgumentException For invalid status code arguments.
|
||||||
*/
|
*/
|
||||||
public function withStatus($code, $reasonPhrase = '');
|
public function withStatus(int $code, string $reasonPhrase = '');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the response reason phrase associated with the status code.
|
* Gets the response reason phrase associated with the status code.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -224,7 +226,7 @@ interface ServerRequestInterface extends RequestInterface
|
||||||
* @param mixed $default Default value to return if the attribute does not exist.
|
* @param mixed $default Default value to return if the attribute does not exist.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getAttribute($name, $default = null);
|
public function getAttribute(string $name, $default = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified derived request attribute.
|
* Return an instance with the specified derived request attribute.
|
||||||
|
|
@ -241,7 +243,7 @@ interface ServerRequestInterface extends RequestInterface
|
||||||
* @param mixed $value The value of the attribute.
|
* @param mixed $value The value of the attribute.
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withAttribute($name, $value);
|
public function withAttribute(string $name, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance that removes the specified derived request attribute.
|
* Return an instance that removes the specified derived request attribute.
|
||||||
|
|
@ -257,5 +259,5 @@ interface ServerRequestInterface extends RequestInterface
|
||||||
* @param string $name The attribute name.
|
* @param string $name The attribute name.
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function withoutAttribute($name);
|
public function withoutAttribute(string $name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,7 +86,7 @@ interface StreamInterface
|
||||||
* SEEK_END: Set position to end-of-stream plus offset.
|
* SEEK_END: Set position to end-of-stream plus offset.
|
||||||
* @throws \RuntimeException on failure.
|
* @throws \RuntimeException on failure.
|
||||||
*/
|
*/
|
||||||
public function seek($offset, $whence = SEEK_SET);
|
public function seek(int $offset, int $whence = SEEK_SET);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seek to the beginning of the stream.
|
* Seek to the beginning of the stream.
|
||||||
|
|
@ -112,7 +114,7 @@ interface StreamInterface
|
||||||
* @return int Returns the number of bytes written to the stream.
|
* @return int Returns the number of bytes written to the stream.
|
||||||
* @throws \RuntimeException on failure.
|
* @throws \RuntimeException on failure.
|
||||||
*/
|
*/
|
||||||
public function write($string);
|
public function write(string $string);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the stream is readable.
|
* Returns whether or not the stream is readable.
|
||||||
|
|
@ -131,7 +133,7 @@ interface StreamInterface
|
||||||
* if no bytes are available.
|
* if no bytes are available.
|
||||||
* @throws \RuntimeException if an error occurs.
|
* @throws \RuntimeException if an error occurs.
|
||||||
*/
|
*/
|
||||||
public function read($length);
|
public function read(int $length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the remaining contents in a string
|
* Returns the remaining contents in a string
|
||||||
|
|
@ -149,10 +151,10 @@ interface StreamInterface
|
||||||
* stream_get_meta_data() function.
|
* stream_get_meta_data() function.
|
||||||
*
|
*
|
||||||
* @link http://php.net/manual/en/function.stream-get-meta-data.php
|
* @link http://php.net/manual/en/function.stream-get-meta-data.php
|
||||||
* @param string $key Specific metadata to retrieve.
|
* @param string|null $key Specific metadata to retrieve.
|
||||||
* @return array|mixed|null Returns an associative array if no key is
|
* @return array|mixed|null Returns an associative array if no key is
|
||||||
* provided. Returns a specific key value if a key is provided and the
|
* provided. Returns a specific key value if a key is provided and the
|
||||||
* value is found, or null if the key is not found.
|
* value is found, or null if the key is not found.
|
||||||
*/
|
*/
|
||||||
public function getMetadata($key = null);
|
public function getMetadata(?string $key = null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,7 +64,7 @@ interface UploadedFileInterface
|
||||||
* @throws \RuntimeException on any error during the move operation, or on
|
* @throws \RuntimeException on any error during the move operation, or on
|
||||||
* the second or subsequent call to the method.
|
* the second or subsequent call to the method.
|
||||||
*/
|
*/
|
||||||
public function moveTo($targetPath);
|
public function moveTo(string $targetPath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the file size.
|
* Retrieve the file size.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Psr\Http\Message;
|
namespace Psr\Http\Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -188,7 +191,7 @@ interface UriInterface
|
||||||
* @return static A new instance with the specified scheme.
|
* @return static A new instance with the specified scheme.
|
||||||
* @throws \InvalidArgumentException for invalid or unsupported schemes.
|
* @throws \InvalidArgumentException for invalid or unsupported schemes.
|
||||||
*/
|
*/
|
||||||
public function withScheme($scheme);
|
public function withScheme(string $scheme);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified user information.
|
* Return an instance with the specified user information.
|
||||||
|
|
@ -204,7 +207,7 @@ interface UriInterface
|
||||||
* @param null|string $password The password associated with $user.
|
* @param null|string $password The password associated with $user.
|
||||||
* @return static A new instance with the specified user information.
|
* @return static A new instance with the specified user information.
|
||||||
*/
|
*/
|
||||||
public function withUserInfo($user, $password = null);
|
public function withUserInfo(string $user, ?string $password = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified host.
|
* Return an instance with the specified host.
|
||||||
|
|
@ -218,7 +221,7 @@ interface UriInterface
|
||||||
* @return static A new instance with the specified host.
|
* @return static A new instance with the specified host.
|
||||||
* @throws \InvalidArgumentException for invalid hostnames.
|
* @throws \InvalidArgumentException for invalid hostnames.
|
||||||
*/
|
*/
|
||||||
public function withHost($host);
|
public function withHost(string $host);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified port.
|
* Return an instance with the specified port.
|
||||||
|
|
@ -237,7 +240,7 @@ interface UriInterface
|
||||||
* @return static A new instance with the specified port.
|
* @return static A new instance with the specified port.
|
||||||
* @throws \InvalidArgumentException for invalid ports.
|
* @throws \InvalidArgumentException for invalid ports.
|
||||||
*/
|
*/
|
||||||
public function withPort($port);
|
public function withPort(?int $port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified path.
|
* Return an instance with the specified path.
|
||||||
|
|
@ -261,7 +264,7 @@ interface UriInterface
|
||||||
* @return static A new instance with the specified path.
|
* @return static A new instance with the specified path.
|
||||||
* @throws \InvalidArgumentException for invalid paths.
|
* @throws \InvalidArgumentException for invalid paths.
|
||||||
*/
|
*/
|
||||||
public function withPath($path);
|
public function withPath(string $path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified query string.
|
* Return an instance with the specified query string.
|
||||||
|
|
@ -278,7 +281,7 @@ interface UriInterface
|
||||||
* @return static A new instance with the specified query string.
|
* @return static A new instance with the specified query string.
|
||||||
* @throws \InvalidArgumentException for invalid query strings.
|
* @throws \InvalidArgumentException for invalid query strings.
|
||||||
*/
|
*/
|
||||||
public function withQuery($query);
|
public function withQuery(string $query);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an instance with the specified URI fragment.
|
* Return an instance with the specified URI fragment.
|
||||||
|
|
@ -294,7 +297,7 @@ interface UriInterface
|
||||||
* @param string $fragment The fragment to use with the new instance.
|
* @param string $fragment The fragment to use with the new instance.
|
||||||
* @return static A new instance with the specified fragment.
|
* @return static A new instance with the specified fragment.
|
||||||
*/
|
*/
|
||||||
public function withFragment($fragment);
|
public function withFragment(string $fragment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the string representation as a URI reference.
|
* Return the string representation as a URI reference.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
// This file is automatically generated at:2022-11-26 23:54:39
|
// This file is automatically generated at:2023-05-05 09:47:16
|
||||||
declare (strict_types = 1);
|
declare (strict_types = 1);
|
||||||
return array (
|
return array (
|
||||||
0 => 'think\\captcha\\CaptchaService',
|
0 => 'think\\captcha\\CaptchaService',
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ final class WrappedListener
|
||||||
$r = new \ReflectionFunction($listener);
|
$r = new \ReflectionFunction($listener);
|
||||||
if (str_contains($r->name, '{closure}')) {
|
if (str_contains($r->name, '{closure}')) {
|
||||||
$this->pretty = $this->name = 'closure';
|
$this->pretty = $this->name = 'closure';
|
||||||
} elseif ($class = $r->getClosureScopeClass()) {
|
} elseif ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) {
|
||||||
$this->name = $class->name;
|
$this->name = $class->name;
|
||||||
$this->pretty = $this->name.'::'.$r->name;
|
$this->pretty = $this->name.'::'.$r->name;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -114,11 +114,13 @@ final class WrappedListener
|
||||||
|
|
||||||
$e = $this->stopwatch->start($this->name, 'event_listener');
|
$e = $this->stopwatch->start($this->name, 'event_listener');
|
||||||
|
|
||||||
|
try {
|
||||||
($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);
|
($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);
|
||||||
|
} finally {
|
||||||
if ($e->isStarted()) {
|
if ($e->isStarted()) {
|
||||||
$e->stop();
|
$e->stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
|
if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
|
||||||
$this->stoppedPropagation = true;
|
$this->stoppedPropagation = true;
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||||
|
|
||||||
$dispatcherDefinition = $globalDispatcherDefinition;
|
$dispatcherDefinition = $globalDispatcherDefinition;
|
||||||
if (isset($event['dispatcher'])) {
|
if (isset($event['dispatcher'])) {
|
||||||
$dispatcherDefinition = $container->getDefinition($event['dispatcher']);
|
$dispatcherDefinition = $container->findDefinition($event['dispatcher']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dispatcherDefinition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]);
|
$dispatcherDefinition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]);
|
||||||
|
|
@ -161,7 +161,7 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dispatcherDefinitions[$attributes['dispatcher']] = $container->getDefinition($attributes['dispatcher']);
|
$dispatcherDefinitions[$attributes['dispatcher']] = $container->findDefinition($attributes['dispatcher']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$dispatcherDefinitions) {
|
if (!$dispatcherDefinitions) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2004-2022 Fabien Potencier
|
Copyright (c) 2004-present Fabien Potencier
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class BinaryFileResponse extends Response
|
||||||
protected $offset = 0;
|
protected $offset = 0;
|
||||||
protected $maxlen = -1;
|
protected $maxlen = -1;
|
||||||
protected $deleteFileAfterSend = false;
|
protected $deleteFileAfterSend = false;
|
||||||
protected $chunkSize = 8 * 1024;
|
protected $chunkSize = 16 * 1024;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \SplFileInfo|string $file The file to stream
|
* @param \SplFileInfo|string $file The file to stream
|
||||||
|
|
@ -267,7 +267,7 @@ class BinaryFileResponse extends Response
|
||||||
$range = $request->headers->get('Range');
|
$range = $request->headers->get('Range');
|
||||||
|
|
||||||
if (str_starts_with($range, 'bytes=')) {
|
if (str_starts_with($range, 'bytes=')) {
|
||||||
[$start, $end] = explode('-', substr($range, 6), 2) + [0];
|
[$start, $end] = explode('-', substr($range, 6), 2) + [1 => 0];
|
||||||
|
|
||||||
$end = ('' === $end) ? $fileSize - 1 : (int) $end;
|
$end = ('' === $end) ? $fileSize - 1 : (int) $end;
|
||||||
|
|
||||||
|
|
@ -341,14 +341,21 @@ class BinaryFileResponse extends Response
|
||||||
|
|
||||||
$length = $this->maxlen;
|
$length = $this->maxlen;
|
||||||
while ($length && !feof($file)) {
|
while ($length && !feof($file)) {
|
||||||
$read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
|
$read = $length > $this->chunkSize || 0 > $length ? $this->chunkSize : $length;
|
||||||
$length -= $read;
|
|
||||||
|
|
||||||
stream_copy_to_stream($file, $out, $read);
|
if (false === $data = fread($file, $read)) {
|
||||||
|
|
||||||
if (connection_aborted()) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
while ('' !== $data) {
|
||||||
|
$read = fwrite($out, $data);
|
||||||
|
if (false === $read || connection_aborted()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0 < $length) {
|
||||||
|
$length -= $read;
|
||||||
|
}
|
||||||
|
$data = substr($data, $read);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose($out);
|
fclose($out);
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue