修复越权
This commit is contained in:
parent
9c83c4d0cd
commit
88275662c3
@ -557,9 +557,7 @@ class Addons extends AdminController
|
||||
$data = Request::only(['id','name','version','uid','price']);
|
||||
// $url = $this->getSystem()['api_url'].'/v1/createOrder';
|
||||
// $order = Api::urlPost($url,$data);
|
||||
|
||||
$response = HttpHelper::withHost()->post('/v1/createOrder', $data);
|
||||
|
||||
if ($response->ok()) {
|
||||
// $orderData = json_decode(json_encode($response->toJson()->data),TRUE);
|
||||
View::assign('orderData',$response->toArray()['data']);
|
||||
|
@ -66,7 +66,7 @@
|
||||
//上传头像
|
||||
upload.render({
|
||||
elem: '.upload-select'
|
||||
,url: 'uploads'
|
||||
,url: "{:url('Addons/uploads')}"
|
||||
,data: {type:'image'}
|
||||
,accept: 'images'
|
||||
,method: 'get'
|
||||
|
@ -68,7 +68,7 @@ class Article extends Model
|
||||
*/
|
||||
public function add(array $data)
|
||||
{
|
||||
$superAdmin = User::where('id',$data['user_id'])->value('auth');
|
||||
$superAdmin = User::where('id', $data['user_id'])->value('auth');
|
||||
// 超级管理员无需审核
|
||||
$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.posts_check');
|
||||
$msg = $data['status'] ? '发布成功' : '发布成功,请等待审核';
|
||||
|
@ -139,7 +139,7 @@ class User extends Model
|
||||
//重置密码
|
||||
public function respass($data)
|
||||
{ //halt($data);
|
||||
$user = $this->where('id',$data['uid'])->find();
|
||||
$user = $this->where('id', $data['uid'])->find();
|
||||
$salt = substr(md5($user['create_time']),-6);
|
||||
$data['password'] = substr_replace(md5($data['password']),$salt,0,6);
|
||||
$result = $user->save($data);
|
||||
@ -153,8 +153,7 @@ class User extends Model
|
||||
//更新设置
|
||||
public function setNew($data)
|
||||
{
|
||||
$userId = $data['user_id'];
|
||||
$user = User::where('id',$userId)->find();
|
||||
$user = User::where('id', session('user_id'))->find();
|
||||
$result = $user->allowField(['email','active','nickname','sex','city','area_id','sign'])->save($data);
|
||||
if($result){
|
||||
return 1;
|
||||
|
@ -241,7 +241,8 @@ class Article extends BaseController
|
||||
// 检验发帖是否开放
|
||||
if(config('taoler.config.is_post') == 0 ) return json(['code'=>-1,'msg'=>'抱歉,系统维护中,暂时禁止发帖!']);
|
||||
// 数据
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'content', 'upzip', 'keywords', 'description', 'captcha']);
|
||||
$data = Request::only(['cate_id', 'title', 'title_color', 'content', 'upzip', 'keywords', 'description', 'captcha']);
|
||||
$data['user_id'] = $this->uid;
|
||||
$tagId = input('tagid');
|
||||
|
||||
// 验证码
|
||||
@ -340,6 +341,7 @@ class Article extends BaseController
|
||||
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['id','cate_id','title','title_color','user_id','content','upzip','keywords','description','captcha']);
|
||||
$data['user_id'] = $this->uid;
|
||||
$tagId = input('tagid');
|
||||
|
||||
// 验证码
|
||||
|
@ -119,7 +119,8 @@ class User extends BaseController
|
||||
public function set()
|
||||
{
|
||||
if(Request::isAjax()){
|
||||
$data = Request::only(['user_id','email','nickname','sex','city','area_id','sign']);
|
||||
$data = Request::only(['email','nickname','sex','city','area_id','sign']);
|
||||
$data['user_id'] = $this->uid;
|
||||
// 过滤
|
||||
$sign = strtolower($data['sign']);
|
||||
if(strstr($sign, 'script')) return json(['code'=>-1,'msg'=>'包含有非法字符串script脚本']);
|
||||
|
84
composer.lock
generated
84
composer.lock
generated
@ -8,16 +8,16 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "2.0.7",
|
||||
"version": "2.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Bacon/BaconQrCode.git",
|
||||
"reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c"
|
||||
"reference": "8674e51bb65af933a5ffaf1c308a660387c35c22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/d70c840f68657ce49094b8d91f9ee0cc07fbf66c",
|
||||
"reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22",
|
||||
"reference": "8674e51bb65af933a5ffaf1c308a660387c35c22",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -62,9 +62,9 @@
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"support": {
|
||||
"issues": "https://github.com/Bacon/BaconQrCode/issues",
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/2.0.7"
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8"
|
||||
},
|
||||
"time": "2022-03-14T02:02:36+00:00"
|
||||
"time": "2022-12-07T17:46:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cache/adapter-common",
|
||||
@ -1488,16 +1488,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.6.4",
|
||||
"version": "v6.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
|
||||
"reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/49cd7ea3d2563f028d7811f06864a53b1f15ff55",
|
||||
"reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -1513,22 +1513,24 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.2",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.6.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.0"
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"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",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"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"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -1560,7 +1562,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"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": [
|
||||
{
|
||||
@ -1568,7 +1570,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-22T09:22:00+00:00"
|
||||
"time": "2022-12-08T13:30:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@ -2372,16 +2374,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.10",
|
||||
"version": "v5.4.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340"
|
||||
"reference": "2adac0a9b55f9fb40b983b790509581dc3db0fff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
|
||||
"reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/2adac0a9b55f9fb40b983b790509581dc3db0fff",
|
||||
"reference": "2adac0a9b55f9fb40b983b790509581dc3db0fff",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -2431,7 +2433,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.10"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.17"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2447,7 +2449,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-27T12:56:18+00:00"
|
||||
"time": "2022-12-22T10:10:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "taoser/think-addons",
|
||||
@ -3026,16 +3028,16 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.54",
|
||||
"version": "v2.0.56",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e"
|
||||
"reference": "75b8512736daaa056d511f42c15bed87c9f3605a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/97b061b47616301ff29fbd4c35ed9184e1162e4e",
|
||||
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/75b8512736daaa056d511f42c15bed87c9f3605a",
|
||||
"reference": "75b8512736daaa056d511f42c15bed87c9f3605a",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3081,9 +3083,9 @@
|
||||
],
|
||||
"support": {
|
||||
"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.56"
|
||||
},
|
||||
"time": "2022-07-05T05:25:51+00:00"
|
||||
"time": "2022-12-15T02:52:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-template",
|
||||
@ -3326,16 +3328,16 @@
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.1.4",
|
||||
"version": "v4.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "83e007acf936e2233ac92d7368b87716f2bae338"
|
||||
"reference": "16bcfc2c7574feea46cdadaaa8ae73f14d464b21"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/83e007acf936e2233ac92d7368b87716f2bae338",
|
||||
"reference": "83e007acf936e2233ac92d7368b87716f2bae338",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/16bcfc2c7574feea46cdadaaa8ae73f14d464b21",
|
||||
"reference": "16bcfc2c7574feea46cdadaaa8ae73f14d464b21",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3391,7 +3393,7 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-09T11:33:14+00:00"
|
||||
"time": "2022-12-14T11:58:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "yansongda/pay",
|
||||
@ -3545,16 +3547,16 @@
|
||||
},
|
||||
{
|
||||
"name": "yzh52521/easyhttp",
|
||||
"version": "v1.0.4",
|
||||
"version": "v1.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b"
|
||||
"reference": "a74fa5a1d4f701bd20e581b0731e885aac3daf9f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
|
||||
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/a74fa5a1d4f701bd20e581b0731e885aac3daf9f",
|
||||
"reference": "a74fa5a1d4f701bd20e581b0731e885aac3daf9f",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3597,9 +3599,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.4"
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.5"
|
||||
},
|
||||
"time": "2022-11-10T01:24:11+00:00"
|
||||
"time": "2022-12-05T12:18:34+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -16,7 +16,7 @@ return [
|
||||
// 应用名,此项不可更改
|
||||
'appname' => 'TaoLer',
|
||||
// 版本配置
|
||||
'version' => '2.1.1',
|
||||
'version' => '2.1.3',
|
||||
// 加盐
|
||||
'salt' => 'taoler',
|
||||
// 数据库备份目录
|
||||
|
@ -106,7 +106,7 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
||||
layer.close(index);
|
||||
layer.open({
|
||||
type: 2,
|
||||
area: ['50%', '65%'],
|
||||
area: ['55%', '75%'],
|
||||
fixed: false, //不固定
|
||||
maxmin: true,
|
||||
content: 'pay.html'+ "?id=" + data.id+ "&name=" + data.name + "&version=" + data.version + "&uid=" + userinfo.uid + "&price=" + data.price,
|
||||
|
6
vendor/bacon/bacon-qr-code/composer.json
vendored
6
vendor/bacon/bacon-qr-code/composer.json
vendored
@ -34,5 +34,11 @@
|
||||
"allow-plugins": {
|
||||
"ocramius/package-versions": true
|
||||
}
|
||||
},
|
||||
"archive": {
|
||||
"exclude": [
|
||||
"/test",
|
||||
"/phpunit.xml.dist"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
13
vendor/bacon/bacon-qr-code/phpunit.xml.dist
vendored
Normal file
13
vendor/bacon/bacon-qr-code/phpunit.xml.dist
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="BaconQrCode Tests">
|
||||
<directory>./test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
@ -89,6 +89,9 @@ final class CharacterSetEci extends AbstractEnum
|
||||
*/
|
||||
private static $nameToEci;
|
||||
|
||||
/**
|
||||
* @param int[] $values
|
||||
*/
|
||||
public function __construct(array $values, string ...$otherEncodingNames)
|
||||
{
|
||||
$this->values = $values;
|
||||
|
@ -62,7 +62,7 @@ class FormatInformation
|
||||
/**
|
||||
* Offset i holds the number of 1 bits in the binary representation of i.
|
||||
*
|
||||
* @var array
|
||||
* @var int[]
|
||||
*/
|
||||
private const BITS_SET_IN_HALF_BYTE = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
|
||||
|
||||
|
@ -42,6 +42,9 @@ final class Mode extends AbstractEnum
|
||||
*/
|
||||
private $bits;
|
||||
|
||||
/**
|
||||
* @param int[] $characterCountBitsForVersions
|
||||
*/
|
||||
protected function __construct(array $characterCountBitsForVersions, int $bits)
|
||||
{
|
||||
$this->characterCountBitsForVersions = $characterCountBitsForVersions;
|
||||
|
@ -37,7 +37,7 @@ final class Encoder
|
||||
/**
|
||||
* Codec cache.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string,ReedSolomonCodec>
|
||||
*/
|
||||
private static $codecs = [];
|
||||
|
||||
|
@ -334,7 +334,7 @@ final class SvgImageBackEnd implements ImageBackEndInterface
|
||||
$this->xmlWriter->writeAttribute('stop-color', $this->getColorString($startColor));
|
||||
|
||||
if ($startColor instanceof Alpha) {
|
||||
$this->xmlWriter->writeAttribute('stop-opacity', $startColor->getAlpha());
|
||||
$this->xmlWriter->writeAttribute('stop-opacity', (string) $startColor->getAlpha());
|
||||
}
|
||||
|
||||
$this->xmlWriter->endElement();
|
||||
@ -344,7 +344,7 @@ final class SvgImageBackEnd implements ImageBackEndInterface
|
||||
$this->xmlWriter->writeAttribute('stop-color', $this->getColorString($endColor));
|
||||
|
||||
if ($endColor instanceof Alpha) {
|
||||
$this->xmlWriter->writeAttribute('stop-opacity', $endColor->getAlpha());
|
||||
$this->xmlWriter->writeAttribute('stop-opacity', (string) $endColor->getAlpha());
|
||||
}
|
||||
|
||||
$this->xmlWriter->endElement();
|
||||
|
@ -41,7 +41,7 @@ final class EdgeIterator implements IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Edge[]
|
||||
* @return Traversable<Edge>
|
||||
*/
|
||||
public function getIterator() : Traversable
|
||||
{
|
||||
|
@ -136,7 +136,7 @@ final class EllipticArc implements OperationInterface
|
||||
/**
|
||||
* @return Curve[]
|
||||
*/
|
||||
private function createCurves(float $fromX, $fromY) : array
|
||||
private function createCurves(float $fromX, float $fromY) : array
|
||||
{
|
||||
$xAngle = deg2rad($this->xAxisAngle);
|
||||
list($centerX, $centerY, $radiusX, $radiusY, $startAngle, $deltaAngle) =
|
||||
|
@ -17,10 +17,16 @@ use BaconQrCode\Writer;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Spatie\Snapshots\MatchesSnapshots;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
*/
|
||||
final class ImagickRenderingTest extends TestCase
|
||||
{
|
||||
use MatchesSnapshots;
|
||||
|
||||
/**
|
||||
* @requires extension imagick
|
||||
*/
|
||||
public function testGenericQrCode() : void
|
||||
{
|
||||
$renderer = new ImageRenderer(
|
||||
@ -35,6 +41,9 @@ final class ImagickRenderingTest extends TestCase
|
||||
unlink($tempName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires extension imagick
|
||||
*/
|
||||
public function testIssue79() : void
|
||||
{
|
||||
$eye = SquareEye::instance();
|
||||
|
2
vendor/composer/autoload_psr4.php
vendored
2
vendor/composer/autoload_psr4.php
vendored
@ -14,7 +14,7 @@ return array(
|
||||
'think\\composer\\' => array($vendorDir . '/topthink/think-installer/src'),
|
||||
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
|
||||
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
|
||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
|
||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/think-orm/src'),
|
||||
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
|
||||
'taoser\\' => array($vendorDir . '/taoser/think-addons/src', $vendorDir . '/taoser/think-setarr/src'),
|
||||
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
|
||||
|
4
vendor/composer/autoload_static.php
vendored
4
vendor/composer/autoload_static.php
vendored
@ -182,8 +182,8 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/topthink/framework/src/think',
|
||||
1 => __DIR__ . '/..' . '/topthink/think-helper/src',
|
||||
2 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||
3 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||
2 => __DIR__ . '/..' . '/topthink/think-template/src',
|
||||
3 => __DIR__ . '/..' . '/topthink/think-orm/src',
|
||||
),
|
||||
'taoser\\think\\' =>
|
||||
array (
|
||||
|
112
vendor/composer/installed.json
vendored
112
vendor/composer/installed.json
vendored
@ -2,18 +2,24 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "2.0.7",
|
||||
"version_normalized": "2.0.7.0",
|
||||
"version": "2.0.8",
|
||||
"version_normalized": "2.0.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Bacon/BaconQrCode.git",
|
||||
"reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c"
|
||||
"reference": "8674e51bb65af933a5ffaf1c308a660387c35c22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/d70c840f68657ce49094b8d91f9ee0cc07fbf66c",
|
||||
"reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c",
|
||||
"shasum": ""
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22",
|
||||
"reference": "8674e51bb65af933a5ffaf1c308a660387c35c22",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"dasprid/enum": "^1.0.3",
|
||||
@ -29,7 +35,7 @@
|
||||
"suggest": {
|
||||
"ext-imagick": "to generate QR code images"
|
||||
},
|
||||
"time": "2022-03-14T02:02:36+00:00",
|
||||
"time": "2022-12-07T17:46:57+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -53,7 +59,7 @@
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"support": {
|
||||
"issues": "https://github.com/Bacon/BaconQrCode/issues",
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/2.0.7"
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8"
|
||||
},
|
||||
"install-path": "../bacon/bacon-qr-code"
|
||||
},
|
||||
@ -1437,17 +1443,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.6.4",
|
||||
"version_normalized": "6.6.4.0",
|
||||
"version": "v6.7.1",
|
||||
"version_normalized": "6.7.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
|
||||
"reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/49cd7ea3d2563f028d7811f06864a53b1f15ff55",
|
||||
"reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -1463,24 +1469,26 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.2",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.6.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.0"
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"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",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"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",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -1512,7 +1520,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"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": [
|
||||
{
|
||||
@ -2336,18 +2344,24 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v5.4.10",
|
||||
"version_normalized": "5.4.10.0",
|
||||
"version": "v5.4.17",
|
||||
"version_normalized": "5.4.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340"
|
||||
"reference": "2adac0a9b55f9fb40b983b790509581dc3db0fff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
|
||||
"reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
|
||||
"shasum": ""
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/2adac0a9b55f9fb40b983b790509581dc3db0fff",
|
||||
"reference": "2adac0a9b55f9fb40b983b790509581dc3db0fff",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
@ -2356,7 +2370,7 @@
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.4.9|^5.0.9|^6.0"
|
||||
},
|
||||
"time": "2022-05-27T12:56:18+00:00",
|
||||
"time": "2022-12-22T10:10:04+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -2392,7 +2406,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.10"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v5.4.17"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2983,17 +2997,17 @@
|
||||
},
|
||||
{
|
||||
"name": "topthink/think-orm",
|
||||
"version": "v2.0.54",
|
||||
"version_normalized": "2.0.54.0",
|
||||
"version": "v2.0.56",
|
||||
"version_normalized": "2.0.56.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/top-think/think-orm.git",
|
||||
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e"
|
||||
"reference": "75b8512736daaa056d511f42c15bed87c9f3605a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/97b061b47616301ff29fbd4c35ed9184e1162e4e",
|
||||
"reference": "97b061b47616301ff29fbd4c35ed9184e1162e4e",
|
||||
"url": "https://api.github.com/repos/top-think/think-orm/zipball/75b8512736daaa056d511f42c15bed87c9f3605a",
|
||||
"reference": "75b8512736daaa056d511f42c15bed87c9f3605a",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3013,7 +3027,7 @@
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7|^8|^9.5"
|
||||
},
|
||||
"time": "2022-07-05T05:25:51+00:00",
|
||||
"time": "2022-12-15T02:52:53+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3041,7 +3055,7 @@
|
||||
],
|
||||
"support": {
|
||||
"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.56"
|
||||
},
|
||||
"install-path": "../topthink/think-orm"
|
||||
},
|
||||
@ -3345,17 +3359,17 @@
|
||||
},
|
||||
{
|
||||
"name": "workerman/workerman",
|
||||
"version": "v4.1.4",
|
||||
"version_normalized": "4.1.4.0",
|
||||
"version": "v4.1.5",
|
||||
"version_normalized": "4.1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/walkor/workerman.git",
|
||||
"reference": "83e007acf936e2233ac92d7368b87716f2bae338"
|
||||
"reference": "16bcfc2c7574feea46cdadaaa8ae73f14d464b21"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/83e007acf936e2233ac92d7368b87716f2bae338",
|
||||
"reference": "83e007acf936e2233ac92d7368b87716f2bae338",
|
||||
"url": "https://api.github.com/repos/walkor/workerman/zipball/16bcfc2c7574feea46cdadaaa8ae73f14d464b21",
|
||||
"reference": "16bcfc2c7574feea46cdadaaa8ae73f14d464b21",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3370,7 +3384,7 @@
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"time": "2022-10-09T11:33:14+00:00",
|
||||
"time": "2022-12-14T11:58:06+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3561,17 +3575,17 @@
|
||||
},
|
||||
{
|
||||
"name": "yzh52521/easyhttp",
|
||||
"version": "v1.0.4",
|
||||
"version_normalized": "1.0.4.0",
|
||||
"version": "v1.0.5",
|
||||
"version_normalized": "1.0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b"
|
||||
"reference": "a74fa5a1d4f701bd20e581b0731e885aac3daf9f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
|
||||
"reference": "e34628f8f90295cf0a19e5cd2bcc4dd19000373b",
|
||||
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/a74fa5a1d4f701bd20e581b0731e885aac3daf9f",
|
||||
"reference": "a74fa5a1d4f701bd20e581b0731e885aac3daf9f",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
@ -3585,7 +3599,7 @@
|
||||
"php": "^7.2.5|^8.0",
|
||||
"psr/log": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"time": "2022-11-10T01:24:11+00:00",
|
||||
"time": "2022-12-05T12:18:34+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3616,7 +3630,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.4"
|
||||
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.5"
|
||||
},
|
||||
"install-path": "../yzh52521/easyhttp"
|
||||
}
|
||||
|
40
vendor/composer/installed.php
vendored
40
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'taoser/taoler',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => 'e3f1590beb50ab5826fd410fd37264870b5967f4',
|
||||
'reference' => '09978bd07a1c769bc266ff2cb0c8c639bc3d41e8',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -11,9 +11,9 @@
|
||||
),
|
||||
'versions' => array(
|
||||
'bacon/bacon-qr-code' => array(
|
||||
'pretty_version' => '2.0.7',
|
||||
'version' => '2.0.7.0',
|
||||
'reference' => 'd70c840f68657ce49094b8d91f9ee0cc07fbf66c',
|
||||
'pretty_version' => '2.0.8',
|
||||
'version' => '2.0.8.0',
|
||||
'reference' => '8674e51bb65af933a5ffaf1c308a660387c35c22',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../bacon/bacon-qr-code',
|
||||
'aliases' => array(),
|
||||
@ -200,9 +200,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpmailer/phpmailer' => array(
|
||||
'pretty_version' => 'v6.6.4',
|
||||
'version' => '6.6.4.0',
|
||||
'reference' => 'a94fdebaea6bd17f51be0c2373ab80d3d681269b',
|
||||
'pretty_version' => 'v6.7.1',
|
||||
'version' => '6.7.1.0',
|
||||
'reference' => '49cd7ea3d2563f028d7811f06864a53b1f15ff55',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
||||
'aliases' => array(),
|
||||
@ -347,9 +347,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-exporter' => array(
|
||||
'pretty_version' => 'v5.4.10',
|
||||
'version' => '5.4.10.0',
|
||||
'reference' => '8fc03ee75eeece3d9be1ef47d26d79bea1afb340',
|
||||
'pretty_version' => 'v5.4.17',
|
||||
'version' => '5.4.17.0',
|
||||
'reference' => '2adac0a9b55f9fb40b983b790509581dc3db0fff',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
||||
'aliases' => array(),
|
||||
@ -358,7 +358,7 @@
|
||||
'taoser/taoler' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => 'e3f1590beb50ab5826fd410fd37264870b5967f4',
|
||||
'reference' => '09978bd07a1c769bc266ff2cb0c8c639bc3d41e8',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -455,9 +455,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'topthink/think-orm' => array(
|
||||
'pretty_version' => 'v2.0.54',
|
||||
'version' => '2.0.54.0',
|
||||
'reference' => '97b061b47616301ff29fbd4c35ed9184e1162e4e',
|
||||
'pretty_version' => 'v2.0.56',
|
||||
'version' => '2.0.56.0',
|
||||
'reference' => '75b8512736daaa056d511f42c15bed87c9f3605a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../topthink/think-orm',
|
||||
'aliases' => array(),
|
||||
@ -518,9 +518,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'workerman/workerman' => array(
|
||||
'pretty_version' => 'v4.1.4',
|
||||
'version' => '4.1.4.0',
|
||||
'reference' => '83e007acf936e2233ac92d7368b87716f2bae338',
|
||||
'pretty_version' => 'v4.1.5',
|
||||
'version' => '4.1.5.0',
|
||||
'reference' => '16bcfc2c7574feea46cdadaaa8ae73f14d464b21',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../workerman/workerman',
|
||||
'aliases' => array(),
|
||||
@ -545,9 +545,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'yzh52521/easyhttp' => array(
|
||||
'pretty_version' => 'v1.0.4',
|
||||
'version' => '1.0.4.0',
|
||||
'reference' => 'e34628f8f90295cf0a19e5cd2bcc4dd19000373b',
|
||||
'pretty_version' => 'v1.0.5',
|
||||
'version' => '1.0.5.0',
|
||||
'reference' => 'a74fa5a1d4f701bd20e581b0731e885aac3daf9f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../yzh52521/easyhttp',
|
||||
'aliases' => array(),
|
||||
|
22
vendor/phpmailer/phpmailer/README.md
vendored
22
vendor/phpmailer/phpmailer/README.md
vendored
@ -16,7 +16,7 @@
|
||||
- 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
|
||||
- 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
|
||||
- Add attachments, including inline
|
||||
- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
|
||||
@ -25,7 +25,7 @@
|
||||
- Protects against header injection attacks
|
||||
- Error messages in over 50 languages!
|
||||
- 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
|
||||
- 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
|
||||
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
|
||||
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:
|
||||
|
||||
```json
|
||||
"phpmailer/phpmailer": "^6.5"
|
||||
"phpmailer/phpmailer": "^6.7.1"
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
That's it. You should now be ready to use PHPMailer!
|
||||
|
||||
## 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
|
||||
//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).
|
||||
|
||||
## 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.
|
||||
|
||||
@ -204,7 +204,7 @@ Donations are very welcome, whether in beer 🍺, T-shirts 👕, or cold, hard c
|
||||
Available as part of the Tidelift Subscription.
|
||||
|
||||
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
|
||||
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?
|
||||
- Official successor to the SourceForge and Google Code projects.
|
||||
- Test suite.
|
||||
- Continuous integration with Github Actions.
|
||||
- Continuous integration with GitHub Actions.
|
||||
- Composer support.
|
||||
- Public development.
|
||||
- Additional languages and language strings.
|
||||
- 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.
|
||||
|
2
vendor/phpmailer/phpmailer/VERSION
vendored
2
vendor/phpmailer/phpmailer/VERSION
vendored
@ -1 +1 @@
|
||||
6.6.4
|
||||
6.7.1
|
12
vendor/phpmailer/phpmailer/composer.json
vendored
12
vendor/phpmailer/phpmailer/composer.json
vendored
@ -37,21 +37,23 @@
|
||||
"ext-hash": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.2",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.6.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.0"
|
||||
"squizlabs/php_codesniffer": "^3.7.1",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"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",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"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)"
|
||||
},
|
||||
"autoload": {
|
||||
|
20
vendor/phpmailer/phpmailer/get_oauth_token.php
vendored
20
vendor/phpmailer/phpmailer/get_oauth_token.php
vendored
@ -44,6 +44,8 @@ use League\OAuth2\Client\Provider\Google;
|
||||
use Hayageek\OAuth2\Client\Provider\Yahoo;
|
||||
//@see https://github.com/stevenmaguire/oauth2-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'])) {
|
||||
?>
|
||||
@ -57,11 +59,14 @@ if (!isset($_GET['code']) && !isset($_POST['provider'])) {
|
||||
<label for="providerYahoo">Yahoo</label><br>
|
||||
<input type="radio" name="provider" value="Microsoft" id="providerMicrosoft">
|
||||
<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>
|
||||
<p>These details are obtained by setting up an app in your provider's developer console.
|
||||
</p>
|
||||
<p>ClientId: <input type="text" name="clientId"><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">
|
||||
</form>
|
||||
</body>
|
||||
@ -77,18 +82,22 @@ session_start();
|
||||
$providerName = '';
|
||||
$clientId = '';
|
||||
$clientSecret = '';
|
||||
$tenantId = '';
|
||||
|
||||
if (array_key_exists('provider', $_POST)) {
|
||||
$providerName = $_POST['provider'];
|
||||
$clientId = $_POST['clientId'];
|
||||
$clientSecret = $_POST['clientSecret'];
|
||||
$tenantId = $_POST['tenantId'];
|
||||
$_SESSION['provider'] = $providerName;
|
||||
$_SESSION['clientId'] = $clientId;
|
||||
$_SESSION['clientSecret'] = $clientSecret;
|
||||
$_SESSION['tenantId'] = $tenantId;
|
||||
} elseif (array_key_exists('provider', $_SESSION)) {
|
||||
$providerName = $_SESSION['provider'];
|
||||
$clientId = $_SESSION['clientId'];
|
||||
$clientSecret = $_SESSION['clientSecret'];
|
||||
$tenantId = $_SESSION['tenantId'];
|
||||
}
|
||||
|
||||
//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;
|
||||
case 'Azure':
|
||||
$params['tenantId'] = $tenantId;
|
||||
|
||||
$provider = new Azure($params);
|
||||
$options = [
|
||||
'scope' => [
|
||||
'https://outlook.office.com/SMTP.Send',
|
||||
'offline_access'
|
||||
]
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
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['encoding'] = 'Ukendt encode-format: ';
|
||||
$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: ';
|
||||
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
|
||||
$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: ';
|
||||
$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
|
||||
$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
|
||||
$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.';
|
||||
$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['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['smtp_code'] = 'SMTP kode: ';
|
||||
$PHPMAILER_LANG['smtp_code_ex'] = 'Yderligere SMTP info: ';
|
||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
|
||||
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
|
||||
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
|
||||
$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
|
||||
* @package PHPMailer
|
||||
* @author Matt Sturdy <matt.sturdy@gmail.com>
|
||||
* @author Crystopher Glodzienski Cardoso <crystopher.glodzienski@gmail.com>
|
||||
*/
|
||||
|
||||
$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['variable_set'] = 'No se pudo configurar la variable: ';
|
||||
$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['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
|
||||
$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['file_access'] = 'Brak dostępu do 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['invalid_address'] = 'Nie można wysłać wiadomości, ' .
|
||||
'następujący adres Odbiorcy jest nieprawidłowy: ';
|
||||
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
|
||||
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
|
||||
$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['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['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['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
|
||||
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
|
||||
|
71
vendor/phpmailer/phpmailer/src/PHPMailer.php
vendored
71
vendor/phpmailer/phpmailer/src/PHPMailer.php
vendored
@ -750,7 +750,7 @@ class PHPMailer
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.7.1';
|
||||
|
||||
/**
|
||||
* Error severity: message only, continue processing.
|
||||
@ -858,7 +858,7 @@ class PHPMailer
|
||||
private function mailPassthru($to, $subject, $body, $header, $params)
|
||||
{
|
||||
//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);
|
||||
} else {
|
||||
$subject = $this->encodeHeader($this->secureHeader($subject));
|
||||
@ -1124,6 +1124,22 @@ class PHPMailer
|
||||
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.
|
||||
* 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);
|
||||
}
|
||||
} catch (Exception $exc) {
|
||||
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
|
||||
$this->smtp->reset();
|
||||
}
|
||||
$this->setError($exc->getMessage());
|
||||
$this->edebug($exc->getMessage());
|
||||
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
|
||||
$this->smtp->reset();
|
||||
}
|
||||
if ($this->exceptions) {
|
||||
throw $exc;
|
||||
}
|
||||
@ -1863,7 +1879,7 @@ class PHPMailer
|
||||
if (!static::isPermittedPath($path)) {
|
||||
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 (strpos($path, '\\\\') !== 0) {
|
||||
$readable = $readable && is_readable($path);
|
||||
@ -2101,6 +2117,9 @@ class PHPMailer
|
||||
$this->smtp->setDebugLevel($this->SMTPDebug);
|
||||
$this->smtp->setDebugOutput($this->Debugoutput);
|
||||
$this->smtp->setVerp($this->do_verp);
|
||||
if ($this->Host === null) {
|
||||
$this->Host = 'localhost';
|
||||
}
|
||||
$hosts = explode(';', $this->Host);
|
||||
$lastexception = null;
|
||||
|
||||
@ -2791,10 +2810,7 @@ class PHPMailer
|
||||
{
|
||||
$body = '';
|
||||
//Create unique IDs and preset boundaries
|
||||
$this->uniqueid = $this->generateId();
|
||||
$this->boundary[1] = 'b1_' . $this->uniqueid;
|
||||
$this->boundary[2] = 'b2_' . $this->uniqueid;
|
||||
$this->boundary[3] = 'b3_' . $this->uniqueid;
|
||||
$this->setBoundaries();
|
||||
|
||||
if ($this->sign_key_file) {
|
||||
$body .= $this->getMailMIME() . static::$LE;
|
||||
@ -2830,7 +2846,7 @@ class PHPMailer
|
||||
$altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE;
|
||||
}
|
||||
//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) {
|
||||
case 'inline':
|
||||
$body .= $mimepre;
|
||||
@ -3066,6 +3082,18 @@ class PHPMailer
|
||||
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.
|
||||
*
|
||||
@ -4183,6 +4211,7 @@ class PHPMailer
|
||||
* @param string $name Custom header name
|
||||
* @param string|null $value Header value
|
||||
*
|
||||
* @return bool True if a header was set successfully
|
||||
* @throws Exception
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @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);
|
||||
|
||||
//Reduce multiple trailing line breaks to a single one
|
||||
return static::stripTrailingWSP($body) . self::CRLF;
|
||||
return static::stripTrailingBreaks($body) . self::CRLF;
|
||||
}
|
||||
|
||||
/**
|
||||
|
9
vendor/phpmailer/phpmailer/src/POP3.php
vendored
9
vendor/phpmailer/phpmailer/src/POP3.php
vendored
@ -46,7 +46,7 @@ class POP3
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.7.1';
|
||||
|
||||
/**
|
||||
* Default POP3 port number.
|
||||
@ -337,7 +337,12 @@ class POP3
|
||||
*/
|
||||
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.
|
||||
// Try to get it. Ignore any failures here.
|
||||
|
3
vendor/phpmailer/phpmailer/src/SMTP.php
vendored
3
vendor/phpmailer/phpmailer/src/SMTP.php
vendored
@ -35,7 +35,7 @@ class SMTP
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.7.1';
|
||||
|
||||
/**
|
||||
* SMTP line break constant.
|
||||
@ -682,7 +682,6 @@ class SMTP
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->setError('');
|
||||
$this->server_caps = null;
|
||||
$this->helo_rply = null;
|
||||
if (is_resource($this->smtp_conn)) {
|
||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// This file is automatically generated at:2022-12-03 13:32:51
|
||||
// This file is automatically generated at:2023-01-04 21:42:43
|
||||
declare (strict_types = 1);
|
||||
return array (
|
||||
0 => 'taoser\\addons\\Service',
|
||||
|
@ -149,6 +149,7 @@ class Exporter
|
||||
}
|
||||
if (null !== $sleep) {
|
||||
if (!isset($sleep[$n]) || ($i && $c !== $class)) {
|
||||
unset($arrayValue[$name]);
|
||||
continue;
|
||||
}
|
||||
$sleep[$n] = false;
|
||||
@ -164,6 +165,9 @@ class Exporter
|
||||
}
|
||||
}
|
||||
}
|
||||
if (method_exists($class, '__unserialize')) {
|
||||
$properties = $arrayValue;
|
||||
}
|
||||
|
||||
prepare_value:
|
||||
$objectsPool[$value] = [$id = \count($objectsPool)];
|
||||
|
10
vendor/topthink/think-orm/src/DbManager.php
vendored
10
vendor/topthink/think-orm/src/DbManager.php
vendored
@ -340,6 +340,16 @@ class DbManager
|
||||
{
|
||||
return $this->listen;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有连接实列
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getInstance(): array
|
||||
{
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册回调方法
|
||||
|
13
vendor/topthink/think-orm/src/Paginator.php
vendored
13
vendor/topthink/think-orm/src/Paginator.php
vendored
@ -377,6 +377,19 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据集
|
||||
*
|
||||
* @param Collection $items
|
||||
* @return $this
|
||||
*/
|
||||
public function setCollection(Collection $items)
|
||||
{
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return $this->items->isEmpty();
|
||||
|
@ -559,23 +559,4 @@ trait ModelRelationQuery
|
||||
$result->refreshOrigin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public function withTrashed()
|
||||
{
|
||||
return $this->model ? $this->model->queryWithTrashed() : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public function onlyTrashed()
|
||||
{
|
||||
return $this->model ? $this->model->queryOnlyTrashed() : $this;
|
||||
}
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ trait Attribute
|
||||
} elseif (isset($this->type[$name])) {
|
||||
// 类型转换
|
||||
$value = $this->writeTransform($value, $this->type[$name]);
|
||||
} elseif (array_key_exists($name, $this->origin) && is_object($value) && method_exists($value, '__toString')) {
|
||||
} elseif ((array_key_exists($name, $this->origin) || empty($this->origin)) && is_object($value) && method_exists($value, '__toString')) {
|
||||
// 对象类型
|
||||
$value = $value->__toString();
|
||||
}
|
||||
|
@ -18,14 +18,18 @@ use think\Model;
|
||||
/**
|
||||
* 数据软删除
|
||||
* @mixin Model
|
||||
* @method $this withTrashed()
|
||||
* @method $this onlyTrashed()
|
||||
*/
|
||||
trait SoftDelete
|
||||
{
|
||||
/**
|
||||
* 是否包含软删除数据
|
||||
* @var bool
|
||||
*/
|
||||
protected $withTrashed = false;
|
||||
|
||||
public function db($scope = []): Query
|
||||
{
|
||||
$query = parent::db($scope);
|
||||
$this->withNoTrashed($query);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前实例是否被软删除
|
||||
@ -43,74 +47,18 @@ trait SoftDelete
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public static function withTrashed(): Query
|
||||
public function scopeWithTrashed(Query $query)
|
||||
{
|
||||
$model = new static();
|
||||
|
||||
return $model->withTrashedData(true)->db();
|
||||
$query->removeOption('soft_delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public function queryWithTrashed(): Query
|
||||
{
|
||||
return $this->withTrashedData(true)->db();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含软删除数据
|
||||
* @access protected
|
||||
* @param bool $withTrashed 是否包含软删除数据
|
||||
* @return $this
|
||||
*/
|
||||
protected function withTrashedData(bool $withTrashed)
|
||||
{
|
||||
$this->withTrashed = $withTrashed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public static function onlyTrashed(): Query
|
||||
{
|
||||
$model = new static();
|
||||
$field = $model->getDeleteTimeField(true);
|
||||
|
||||
if ($field) {
|
||||
return $model
|
||||
->db()
|
||||
->useSoftDelete($field, $model->getWithTrashedExp());
|
||||
}
|
||||
|
||||
return $model->db();
|
||||
}
|
||||
|
||||
/**
|
||||
* 只查询软删除数据
|
||||
* @access public
|
||||
* @return Query
|
||||
*/
|
||||
public function queryOnlyTrashed(): Query
|
||||
public function scopeOnlyTrashed(Query $query)
|
||||
{
|
||||
$field = $this->getDeleteTimeField(true);
|
||||
|
||||
if ($field) {
|
||||
return $this->db()
|
||||
->useSoftDelete($field, $this->getWithTrashedExp());
|
||||
$query->useSoftDelete($field, $this->getWithTrashedExp());
|
||||
}
|
||||
|
||||
return $this->db();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,9 +87,9 @@ trait SoftDelete
|
||||
|
||||
if ($name && !$force) {
|
||||
// 软删除
|
||||
$this->set($name, $this->autoWriteTimestamp($name));
|
||||
$this->set($name, $this->autoWriteTimestamp());
|
||||
|
||||
$result = $this->exists()->withEvent(false)->save();
|
||||
$this->exists()->withEvent(false)->save();
|
||||
|
||||
$this->withEvent(true);
|
||||
} else {
|
||||
@ -149,7 +97,7 @@ trait SoftDelete
|
||||
$where = $this->getWhere();
|
||||
|
||||
// 删除当前模型数据
|
||||
$result = $this->db()
|
||||
$this->db()
|
||||
->where($where)
|
||||
->removeOption('soft_delete')
|
||||
->delete();
|
||||
@ -172,8 +120,8 @@ trait SoftDelete
|
||||
/**
|
||||
* 删除记录
|
||||
* @access public
|
||||
* @param mixed $data 主键列表 支持闭包查询条件
|
||||
* @param bool $force 是否强制删除
|
||||
* @param mixed $data 主键列表 支持闭包查询条件
|
||||
* @param bool $force 是否强制删除
|
||||
* @return bool
|
||||
*/
|
||||
public static function destroy($data, bool $force = false): bool
|
||||
@ -182,18 +130,20 @@ trait SoftDelete
|
||||
if (empty($data) && 0 !== $data) {
|
||||
return false;
|
||||
}
|
||||
// 仅当强制删除时包含软删除数据
|
||||
$model = (new static());
|
||||
if ($force) {
|
||||
$model->withTrashedData(true);
|
||||
}
|
||||
|
||||
$query = $model->db(false);
|
||||
|
||||
// 仅当强制删除时包含软删除数据
|
||||
if ($force) {
|
||||
$query->removeOption('soft_delete');
|
||||
}
|
||||
|
||||
if (is_array($data) && key($data) !== 0) {
|
||||
$query->where($data);
|
||||
$data = null;
|
||||
} elseif ($data instanceof \Closure) {
|
||||
call_user_func_array($data, [ & $query]);
|
||||
call_user_func_array($data, [&$query]);
|
||||
$data = null;
|
||||
} elseif (is_null($data)) {
|
||||
return false;
|
||||
@ -202,6 +152,7 @@ trait SoftDelete
|
||||
$resultSet = $query->select($data);
|
||||
|
||||
foreach ($resultSet as $result) {
|
||||
/** @var Model $result */
|
||||
$result->force($force)->delete();
|
||||
}
|
||||
|
||||
@ -211,7 +162,7 @@ trait SoftDelete
|
||||
/**
|
||||
* 恢复被软删除的记录
|
||||
* @access public
|
||||
* @param array $where 更新条件
|
||||
* @param array $where 更新条件
|
||||
* @return bool
|
||||
*/
|
||||
public function restore($where = []): bool
|
||||
@ -243,7 +194,7 @@ trait SoftDelete
|
||||
/**
|
||||
* 获取软删除字段
|
||||
* @access protected
|
||||
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
|
||||
* @param bool $read 是否查询操作 写操作的时候会自动去掉表别名
|
||||
* @return string|false
|
||||
*/
|
||||
protected function getDeleteTimeField(bool $read = false)
|
||||
@ -269,7 +220,7 @@ trait SoftDelete
|
||||
/**
|
||||
* 查询的时候默认排除软删除数据
|
||||
* @access protected
|
||||
* @param Query $query
|
||||
* @param Query $query
|
||||
* @return void
|
||||
*/
|
||||
protected function withNoTrashed(Query $query): void
|
||||
|
@ -179,7 +179,7 @@ trait TimeStamp
|
||||
protected function formatDateTime($format, $time = 'now', bool $timestamp = false)
|
||||
{
|
||||
if (empty($time)) {
|
||||
return;
|
||||
return $time;
|
||||
}
|
||||
|
||||
if (false === $format) {
|
||||
|
@ -241,7 +241,7 @@ class BelongsTo extends OneToOne
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($result, $relationModel);
|
||||
$result->hidden([$relation]);
|
||||
$result->hidden([$relation], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,7 +283,7 @@ class BelongsTo extends OneToOne
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($result, $relationModel);
|
||||
$result->hidden([$relation]);
|
||||
$result->hidden([$relation], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ class HasOne extends OneToOne
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($result, $relationModel);
|
||||
$result->hidden([$relation]);
|
||||
$result->hidden([$relation], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@ class HasOne extends OneToOne
|
||||
if (!empty($this->bindAttr)) {
|
||||
// 绑定关联属性
|
||||
$this->bindAttr($result, $relationModel);
|
||||
$result->hidden([$relation]);
|
||||
$result->hidden([$relation], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace think\model\relation;
|
||||
|
||||
use Closure;
|
||||
use think\db\exception\DbException as Exception;
|
||||
use think\db\Query;
|
||||
use think\helper\Str;
|
||||
use think\Model;
|
||||
use think\model\Relation;
|
||||
@ -46,14 +47,16 @@ class MorphTo extends Relation
|
||||
*/
|
||||
protected $relation;
|
||||
|
||||
protected $queryCaller = [];
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Model $parent 上级模型对象
|
||||
* @param string $morphType 多态字段名
|
||||
* @param string $morphKey 外键名
|
||||
* @param array $alias 多态别名定义
|
||||
* @param string $relation 关联名
|
||||
* @param Model $parent 上级模型对象
|
||||
* @param string $morphType 多态字段名
|
||||
* @param string $morphKey 外键名
|
||||
* @param array $alias 多态别名定义
|
||||
* @param ?string $relation 关联名
|
||||
*/
|
||||
public function __construct(Model $parent, string $morphType, string $morphKey, array $alias = [], string $relation = null)
|
||||
{
|
||||
@ -80,8 +83,8 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 延迟获取关联数据
|
||||
* @access public
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包查询条件
|
||||
* @param array $subRelation 子关联名
|
||||
* @param ?Closure $closure 闭包查询条件
|
||||
* @return Model
|
||||
*/
|
||||
public function getRelation(array $subRelation = [], Closure $closure = null)
|
||||
@ -95,7 +98,7 @@ class MorphTo extends Relation
|
||||
// 主键数据
|
||||
$pk = $this->parent->$morphKey;
|
||||
|
||||
$relationModel = (new $model)->relation($subRelation)->find($pk);
|
||||
$relationModel = $this->buildQuery((new $model)->relation($subRelation))->find($pk);
|
||||
|
||||
if ($relationModel) {
|
||||
$relationModel->setParent(clone $this->parent);
|
||||
@ -107,11 +110,11 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param string $operator 比较操作符
|
||||
* @param integer $count 个数
|
||||
* @param string $id 关联表的统计字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @param string $operator 比较操作符
|
||||
* @param integer $count 个数
|
||||
* @param string $id 关联表的统计字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = '', Query $query = null)
|
||||
@ -122,22 +125,46 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 根据关联条件查询当前模型
|
||||
* @access public
|
||||
* @param mixed $where 查询条件(数组或者闭包)
|
||||
* @param mixed $fields 字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param Query $query Query对象
|
||||
* @param mixed $where 查询条件(数组或者闭包)
|
||||
* @param mixed $fields 字段
|
||||
* @param string $joinType JOIN类型
|
||||
* @param ?Query $query Query对象
|
||||
* @return Query
|
||||
*/
|
||||
public function hasWhere($where = [], $fields = null, string $joinType = '', Query $query = null)
|
||||
{
|
||||
throw new Exception('relation not support: hasWhere');
|
||||
$alias = class_basename($this->parent);
|
||||
|
||||
$types = $this->parent->distinct()->column($this->morphType);
|
||||
|
||||
$query = $query ?: $this->parent->db();
|
||||
|
||||
return $query->alias($alias)
|
||||
->where(function (Query $query) use ($types, $where, $alias) {
|
||||
foreach ($types as $type) {
|
||||
if ($type) {
|
||||
$query->whereExists(function (Query $query) use ($type, $where, $alias) {
|
||||
$class = $this->parseModel($type);
|
||||
/** @var Model $model */
|
||||
$model = new $class();
|
||||
|
||||
$table = $model->getTable();
|
||||
$query
|
||||
->table($table)
|
||||
->where($alias . '.' . $this->morphType, $type)
|
||||
->whereRaw("`{$alias}`.`{$this->morphKey}`=`{$table}`.`{$model->getPk()}`")
|
||||
->where($where);
|
||||
}, 'OR');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析模型的完整命名空间
|
||||
* @access protected
|
||||
* @param string $model 模型名(或者完整类名)
|
||||
* @return string
|
||||
* @param string $model 模型名(或者完整类名)
|
||||
* @return Model
|
||||
*/
|
||||
protected function parseModel(string $model): string
|
||||
{
|
||||
@ -158,7 +185,7 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 设置多态别名
|
||||
* @access public
|
||||
* @param array $alias 别名定义
|
||||
* @param array $alias 别名定义
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlias(array $alias)
|
||||
@ -173,7 +200,7 @@ class MorphTo extends Relation
|
||||
* @access public
|
||||
* @return $this
|
||||
*/
|
||||
public function removeOption()
|
||||
public function removeOption(string $option = '')
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
@ -181,11 +208,11 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param array $resultSet 数据集
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @param array $resultSet 数据集
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param ?Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
@ -211,8 +238,8 @@ class MorphTo extends Relation
|
||||
if (!\is_null($closure)) {
|
||||
$obj = $closure($obj);
|
||||
}
|
||||
$pk = $obj->getPk();
|
||||
$list = $obj->with($subRelation)
|
||||
$pk = $obj->getPk();
|
||||
$list = $obj->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->select($val);
|
||||
$data = [];
|
||||
@ -242,11 +269,11 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 预载入关联查询
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @param Model $result 数据对象
|
||||
* @param string $relation 当前关联名
|
||||
* @param array $subRelation 子关联名
|
||||
* @param ?Closure $closure 闭包
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null, array $cache = []): void
|
||||
@ -260,36 +287,42 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 关联统计
|
||||
* @access public
|
||||
* @param Model $result 数据对象
|
||||
* @param Closure $closure 闭包
|
||||
* @param string $aggregate 聚合查询方法
|
||||
* @param string $field 字段
|
||||
* @param Model $result 数据对象
|
||||
* @param ?Closure $closure 闭包
|
||||
* @param string $aggregate 聚合查询方法
|
||||
* @param string $field 字段
|
||||
* @return integer
|
||||
*/
|
||||
public function relationCount(Model $result, Closure $closure = null, string $aggregate = 'count', string $field = '*')
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 多态MorphTo 关联模型预查询
|
||||
* @access protected
|
||||
* @param string $model 关联模型对象
|
||||
* @param string $relation 关联名
|
||||
* @param Model $result
|
||||
* @param array $subRelation 子关联
|
||||
* @param array $cache 关联缓存
|
||||
* @param string $model 关联模型对象
|
||||
* @param string $relation 关联名
|
||||
* @param Model $result
|
||||
* @param array $subRelation 子关联
|
||||
* @param array $cache 关联缓存
|
||||
* @return void
|
||||
*/
|
||||
protected function eagerlyMorphToOne(string $model, string $relation, Model $result, array $subRelation = [], array $cache = []): void
|
||||
{
|
||||
// 预载入关联查询 支持嵌套预载入
|
||||
$pk = $this->parent->{$this->morphKey};
|
||||
$data = (new $model)->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->find($pk);
|
||||
$pk = $this->parent->{$this->morphKey};
|
||||
|
||||
if ($data) {
|
||||
$data->setParent(clone $result);
|
||||
$data->exists(true);
|
||||
$data = null;
|
||||
|
||||
if (\class_exists($model)) {
|
||||
$data = (new $model)->with($subRelation)
|
||||
->cache($cache[0] ?? false, $cache[1] ?? null, $cache[2] ?? null)
|
||||
->find($pk);
|
||||
|
||||
if ($data) {
|
||||
$data->setParent(clone $result);
|
||||
$data->exists(true);
|
||||
}
|
||||
}
|
||||
|
||||
$result->setRelation($relation, $data ?: null);
|
||||
@ -298,8 +331,8 @@ class MorphTo extends Relation
|
||||
/**
|
||||
* 添加关联数据
|
||||
* @access public
|
||||
* @param Model $model 关联模型对象
|
||||
* @param string $type 多态类型
|
||||
* @param Model $model 关联模型对象
|
||||
* @param string $type 多态类型
|
||||
* @return Model
|
||||
*/
|
||||
public function associate(Model $model, string $type = ''): Model
|
||||
@ -332,4 +365,18 @@ class MorphTo extends Relation
|
||||
return $this->parent->setRelation($this->relation, null);
|
||||
}
|
||||
|
||||
protected function buildQuery(Query $query)
|
||||
{
|
||||
foreach ($this->queryCaller as $caller) {
|
||||
call_user_func_array([$query, $caller[0]], $caller[1]);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$this->queryCaller[] = [$method, $args];
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -91,9 +91,23 @@ abstract class OneToOne extends Relation
|
||||
$query->via($joinAlias);
|
||||
|
||||
if ($this instanceof BelongsTo) {
|
||||
$joinOn = $name . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey;
|
||||
|
||||
$foreignKeyExp = $this->foreignKey;
|
||||
|
||||
if (strpos($foreignKeyExp, '.') === false) {
|
||||
$foreignKeyExp = $name . '.' . $this->foreignKey;
|
||||
}
|
||||
|
||||
$joinOn = $foreignKeyExp . '=' . $joinAlias . '.' . $this->localKey;
|
||||
} else {
|
||||
$joinOn = $name . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey;
|
||||
|
||||
$foreignKeyExp = $this->foreignKey;
|
||||
|
||||
if (strpos($foreignKeyExp, '.') === false) {
|
||||
$foreignKeyExp = $joinAlias . '.' . $this->foreignKey;
|
||||
}
|
||||
|
||||
$joinOn = $name . '.' . $this->localKey . '=' . $foreignKeyExp;
|
||||
}
|
||||
|
||||
if ($closure) {
|
||||
|
@ -157,6 +157,13 @@ class TcpConnection extends ConnectionInterface
|
||||
*/
|
||||
public $maxSendBufferSize = 1048576;
|
||||
|
||||
/**
|
||||
* Context.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $context = null;
|
||||
|
||||
/**
|
||||
* Default send buffer size.
|
||||
*
|
||||
@ -170,7 +177,7 @@ class TcpConnection extends ConnectionInterface
|
||||
* @var int
|
||||
*/
|
||||
public $maxPackageSize = 1048576;
|
||||
|
||||
|
||||
/**
|
||||
* Default maximum acceptable packet size.
|
||||
*
|
||||
@ -285,6 +292,7 @@ class TcpConnection extends ConnectionInterface
|
||||
$this->maxPackageSize = self::$defaultMaxPackageSize;
|
||||
$this->_remoteAddress = $remote_address;
|
||||
static::$connections[$this->id] = $this;
|
||||
$this->context = new \stdClass;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -720,23 +728,23 @@ class TcpConnection extends ConnectionInterface
|
||||
return false;
|
||||
}
|
||||
$async = $this instanceof AsyncTcpConnection;
|
||||
|
||||
|
||||
/**
|
||||
* We disabled ssl3 because https://blog.qualys.com/ssllabs/2014/10/15/ssl-3-is-dead-killed-by-the-poodle-attack.
|
||||
* You can enable ssl3 by the codes below.
|
||||
*/
|
||||
* We disabled ssl3 because https://blog.qualys.com/ssllabs/2014/10/15/ssl-3-is-dead-killed-by-the-poodle-attack.
|
||||
* You can enable ssl3 by the codes below.
|
||||
*/
|
||||
/*if($async){
|
||||
$type = STREAM_CRYPTO_METHOD_SSLv2_CLIENT | STREAM_CRYPTO_METHOD_SSLv23_CLIENT | STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
|
||||
}else{
|
||||
$type = STREAM_CRYPTO_METHOD_SSLv2_SERVER | STREAM_CRYPTO_METHOD_SSLv23_SERVER | STREAM_CRYPTO_METHOD_SSLv3_SERVER;
|
||||
}*/
|
||||
|
||||
|
||||
if($async){
|
||||
$type = \STREAM_CRYPTO_METHOD_SSLv2_CLIENT | \STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
|
||||
}else{
|
||||
$type = \STREAM_CRYPTO_METHOD_SSLv2_SERVER | \STREAM_CRYPTO_METHOD_SSLv23_SERVER;
|
||||
}
|
||||
|
||||
|
||||
// Hidden error.
|
||||
\set_error_handler(function($errno, $errstr, $file){
|
||||
if (!Worker::$daemonize) {
|
||||
@ -822,7 +830,7 @@ class TcpConnection extends ConnectionInterface
|
||||
}
|
||||
|
||||
$this->_status = self::STATUS_CLOSING;
|
||||
|
||||
|
||||
if ($this->_sendBuffer === '') {
|
||||
$this->destroy();
|
||||
} else {
|
||||
@ -882,7 +890,7 @@ class TcpConnection extends ConnectionInterface
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether send buffer is Empty.
|
||||
*
|
||||
@ -890,7 +898,7 @@ class TcpConnection extends ConnectionInterface
|
||||
*/
|
||||
public function bufferIsEmpty()
|
||||
{
|
||||
return empty($this->_sendBuffer);
|
||||
return empty($this->_sendBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,7 +565,7 @@ class Request
|
||||
'tmp_name' => $tmp_file,
|
||||
'size' => $size,
|
||||
'error' => $error,
|
||||
'type' => null,
|
||||
'type' => '',
|
||||
];
|
||||
break;
|
||||
} // Is post field.
|
||||
|
315
vendor/workerman/workerman/Protocols/Websocket.php
vendored
315
vendor/workerman/workerman/Protocols/Websocket.php
vendored
@ -11,10 +11,12 @@
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace Workerman\Protocols;
|
||||
|
||||
use Workerman\Connection\ConnectionInterface;
|
||||
use Workerman\Connection\TcpConnection;
|
||||
use Workerman\Protocols\Http\Request;
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
@ -29,6 +31,13 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
*/
|
||||
const BINARY_TYPE_BLOB = "\x81";
|
||||
|
||||
/**
|
||||
* Websocket blob type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const BINARY_TYPE_BLOB_DEFLATE = "\xc1";
|
||||
|
||||
/**
|
||||
* Websocket arraybuffer type.
|
||||
*
|
||||
@ -36,10 +45,17 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
*/
|
||||
const BINARY_TYPE_ARRAYBUFFER = "\x82";
|
||||
|
||||
/**
|
||||
* Websocket arraybuffer type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const BINARY_TYPE_ARRAYBUFFER_DEFLATE = "\xc2";
|
||||
|
||||
/**
|
||||
* Check the integrity of the package.
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param string $buffer
|
||||
* @param ConnectionInterface $connection
|
||||
* @return int
|
||||
*/
|
||||
@ -53,23 +69,23 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
}
|
||||
|
||||
// Has not yet completed the handshake.
|
||||
if (empty($connection->websocketHandshake)) {
|
||||
if (empty($connection->context->websocketHandshake)) {
|
||||
return static::dealHandshake($buffer, $connection);
|
||||
}
|
||||
|
||||
// Buffer websocket frame data.
|
||||
if ($connection->websocketCurrentFrameLength) {
|
||||
if ($connection->context->websocketCurrentFrameLength) {
|
||||
// We need more frame data.
|
||||
if ($connection->websocketCurrentFrameLength > $recv_len) {
|
||||
if ($connection->context->websocketCurrentFrameLength > $recv_len) {
|
||||
// Return 0, because it is not clear the full packet length, waiting for the frame of fin=1.
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
$firstbyte = \ord($buffer[0]);
|
||||
$secondbyte = \ord($buffer[1]);
|
||||
$data_len = $secondbyte & 127;
|
||||
$is_fin_frame = $firstbyte >> 7;
|
||||
$masked = $secondbyte >> 7;
|
||||
$first_byte = \ord($buffer[0]);
|
||||
$second_byte = \ord($buffer[1]);
|
||||
$data_len = $second_byte & 127;
|
||||
$is_fin_frame = $first_byte >> 7;
|
||||
$masked = $second_byte >> 7;
|
||||
|
||||
if (!$masked) {
|
||||
Worker::safeEcho("frame not masked so close the connection\n");
|
||||
@ -77,7 +93,7 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
return 0;
|
||||
}
|
||||
|
||||
$opcode = $firstbyte & 0xf;
|
||||
$opcode = $first_byte & 0xf;
|
||||
switch ($opcode) {
|
||||
case 0x0:
|
||||
break;
|
||||
@ -90,12 +106,11 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
// Close package.
|
||||
case 0x8:
|
||||
// Try to emit onWebSocketClose callback.
|
||||
if (isset($connection->onWebSocketClose) || isset($connection->worker->onWebSocketClose)) {
|
||||
$close_cb = $connection->onWebSocketClose ?? $connection->worker->onWebSocketClose ?? false;
|
||||
if ($close_cb) {
|
||||
try {
|
||||
\call_user_func(isset($connection->onWebSocketClose)?$connection->onWebSocketClose:$connection->worker->onWebSocketClose, $connection);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
$close_cb($connection);
|
||||
} catch (\Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
} // Close connection.
|
||||
@ -109,7 +124,7 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
// Pong package.
|
||||
case 0xa:
|
||||
break;
|
||||
// Wrong opcode.
|
||||
// Wrong opcode.
|
||||
default :
|
||||
Worker::safeEcho("error opcode $opcode and close websocket connection. Buffer:" . bin2hex($buffer) . "\n");
|
||||
$connection->close();
|
||||
@ -123,7 +138,7 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
if ($head_len > $recv_len) {
|
||||
return 0;
|
||||
}
|
||||
$pack = \unpack('nn/ntotal_len', $buffer);
|
||||
$pack = \unpack('nn/ntotal_len', $buffer);
|
||||
$data_len = $pack['total_len'];
|
||||
} else {
|
||||
if ($data_len === 127) {
|
||||
@ -131,13 +146,13 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
if ($head_len > $recv_len) {
|
||||
return 0;
|
||||
}
|
||||
$arr = \unpack('n/N2c', $buffer);
|
||||
$data_len = $arr['c1']*4294967296 + $arr['c2'];
|
||||
$arr = \unpack('n/N2c', $buffer);
|
||||
$data_len = $arr['c1'] * 4294967296 + $arr['c2'];
|
||||
}
|
||||
}
|
||||
$current_frame_length = $head_len + $data_len;
|
||||
|
||||
$total_package_size = \strlen($connection->websocketDataBuffer) + $current_frame_length;
|
||||
$total_package_size = \strlen($connection->context->websocketDataBuffer) + $current_frame_length;
|
||||
if ($total_package_size > $connection->maxPackageSize) {
|
||||
Worker::safeEcho("error package. package_length=$total_package_size\n");
|
||||
$connection->close();
|
||||
@ -151,12 +166,11 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
$connection->consumeRecvBuffer($current_frame_length);
|
||||
$tmp_connection_type = isset($connection->websocketType) ? $connection->websocketType : static::BINARY_TYPE_BLOB;
|
||||
$connection->websocketType = "\x8a";
|
||||
if (isset($connection->onWebSocketPing) || isset($connection->worker->onWebSocketPing)) {
|
||||
$ping_cb = $connection->onWebSocketPing ?? $connection->worker->onWebSocketPing ?? false;
|
||||
if ($ping_cb) {
|
||||
try {
|
||||
\call_user_func(isset($connection->onWebSocketPing)?$connection->onWebSocketPing:$connection->worker->onWebSocketPing, $connection, $ping_data);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
$ping_cb($connection, $ping_data);
|
||||
} catch (\Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
} else {
|
||||
@ -175,12 +189,11 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
$tmp_connection_type = isset($connection->websocketType) ? $connection->websocketType : static::BINARY_TYPE_BLOB;
|
||||
$connection->websocketType = "\x8a";
|
||||
// Try to emit onWebSocketPong callback.
|
||||
if (isset($connection->onWebSocketPong) || isset($connection->worker->onWebSocketPong)) {
|
||||
$pong_cb = $connection->onWebSocketPong ?? $connection->worker->onWebSocketPong ?? false;
|
||||
if ($pong_cb) {
|
||||
try {
|
||||
\call_user_func(isset($connection->onWebSocketPong)?$connection->onWebSocketPong:$connection->worker->onWebSocketPong, $connection, $pong_data);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
$pong_cb($connection, $pong_data);
|
||||
} catch (\Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
@ -193,22 +206,22 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
}
|
||||
return $current_frame_length;
|
||||
} else {
|
||||
$connection->websocketCurrentFrameLength = $current_frame_length;
|
||||
$connection->context->websocketCurrentFrameLength = $current_frame_length;
|
||||
}
|
||||
}
|
||||
|
||||
// Received just a frame length data.
|
||||
if ($connection->websocketCurrentFrameLength === $recv_len) {
|
||||
if ($connection->context->websocketCurrentFrameLength === $recv_len) {
|
||||
static::decode($buffer, $connection);
|
||||
$connection->consumeRecvBuffer($connection->websocketCurrentFrameLength);
|
||||
$connection->websocketCurrentFrameLength = 0;
|
||||
$connection->consumeRecvBuffer($connection->context->websocketCurrentFrameLength);
|
||||
$connection->context->websocketCurrentFrameLength = 0;
|
||||
return 0;
|
||||
} // The length of the received data is greater than the length of a frame.
|
||||
elseif ($connection->websocketCurrentFrameLength < $recv_len) {
|
||||
static::decode(\substr($buffer, 0, $connection->websocketCurrentFrameLength), $connection);
|
||||
$connection->consumeRecvBuffer($connection->websocketCurrentFrameLength);
|
||||
$current_frame_length = $connection->websocketCurrentFrameLength;
|
||||
$connection->websocketCurrentFrameLength = 0;
|
||||
elseif ($connection->context->websocketCurrentFrameLength < $recv_len) {
|
||||
static::decode(\substr($buffer, 0, $connection->context->websocketCurrentFrameLength), $connection);
|
||||
$connection->consumeRecvBuffer($connection->context->websocketCurrentFrameLength);
|
||||
$current_frame_length = $connection->context->websocketCurrentFrameLength;
|
||||
$connection->context->websocketCurrentFrameLength = 0;
|
||||
// Continue to read next frame.
|
||||
return static::input(\substr($buffer, $current_frame_length), $connection);
|
||||
} // The length of the received data is less than the length of a frame.
|
||||
@ -220,7 +233,7 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
/**
|
||||
* Websocket encode.
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param string $buffer
|
||||
* @param ConnectionInterface $connection
|
||||
* @return string
|
||||
*/
|
||||
@ -229,12 +242,18 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
if (!is_scalar($buffer)) {
|
||||
throw new \Exception("You can't send(" . \gettype($buffer) . ") to client, you need to convert it to a string. ");
|
||||
}
|
||||
$len = \strlen($buffer);
|
||||
|
||||
if (empty($connection->websocketType)) {
|
||||
$connection->websocketType = static::BINARY_TYPE_BLOB;
|
||||
}
|
||||
|
||||
// permessage-deflate
|
||||
if (\ord($connection->websocketType) & 64) {
|
||||
$buffer = static::deflate($connection, $buffer);
|
||||
}
|
||||
|
||||
$first_byte = $connection->websocketType;
|
||||
$len = \strlen($buffer);
|
||||
|
||||
if ($len <= 125) {
|
||||
$encode_buffer = $first_byte . \chr($len) . $buffer;
|
||||
@ -247,37 +266,32 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
}
|
||||
|
||||
// Handshake not completed so temporary buffer websocket data waiting for send.
|
||||
if (empty($connection->websocketHandshake)) {
|
||||
if (empty($connection->tmpWebsocketData)) {
|
||||
$connection->tmpWebsocketData = '';
|
||||
if (empty($connection->context->websocketHandshake)) {
|
||||
if (empty($connection->context->tmpWebsocketData)) {
|
||||
$connection->context->tmpWebsocketData = '';
|
||||
}
|
||||
// If buffer has already full then discard the current package.
|
||||
if (\strlen($connection->tmpWebsocketData) > $connection->maxSendBufferSize) {
|
||||
if (\strlen($connection->context->tmpWebsocketData) > $connection->maxSendBufferSize) {
|
||||
if ($connection->onError) {
|
||||
try {
|
||||
\call_user_func($connection->onError, $connection, \WORKERMAN_SEND_FAIL, 'send buffer full and drop package');
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
($connection->onError)($connection, ConnectionInterface::SEND_FAIL, 'send buffer full and drop package');
|
||||
} catch (\Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
$connection->tmpWebsocketData .= $encode_buffer;
|
||||
$connection->context->tmpWebsocketData .= $encode_buffer;
|
||||
// Check buffer is full.
|
||||
if ($connection->maxSendBufferSize <= \strlen($connection->tmpWebsocketData)) {
|
||||
if ($connection->maxSendBufferSize <= \strlen($connection->context->tmpWebsocketData)) {
|
||||
if ($connection->onBufferFull) {
|
||||
try {
|
||||
\call_user_func($connection->onBufferFull, $connection);
|
||||
} catch (\Exception $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
} catch (\Error $e) {
|
||||
($connection->onBufferFull)($connection);
|
||||
} catch (\Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return empty string.
|
||||
return '';
|
||||
}
|
||||
@ -288,64 +302,125 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
/**
|
||||
* Websocket decode.
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param string $buffer
|
||||
* @param ConnectionInterface $connection
|
||||
* @return string
|
||||
*/
|
||||
public static function decode($buffer, ConnectionInterface $connection)
|
||||
{
|
||||
$len = \ord($buffer[1]) & 127;
|
||||
$first_byte = \ord($buffer[0]);
|
||||
$second_byte = \ord($buffer[1]);
|
||||
$len = $second_byte & 127;
|
||||
$is_fin_frame = $first_byte >> 7;
|
||||
$rsv1 = 64 === ($first_byte & 64);
|
||||
|
||||
if ($len === 126) {
|
||||
$masks = \substr($buffer, 4, 4);
|
||||
$data = \substr($buffer, 8);
|
||||
$data = \substr($buffer, 8);
|
||||
} else {
|
||||
if ($len === 127) {
|
||||
$masks = \substr($buffer, 10, 4);
|
||||
$data = \substr($buffer, 14);
|
||||
$data = \substr($buffer, 14);
|
||||
} else {
|
||||
$masks = \substr($buffer, 2, 4);
|
||||
$data = \substr($buffer, 6);
|
||||
$data = \substr($buffer, 6);
|
||||
}
|
||||
}
|
||||
$dataLength = \strlen($data);
|
||||
$masks = \str_repeat($masks, \floor($dataLength / 4)) . \substr($masks, 0, $dataLength % 4);
|
||||
$decoded = $data ^ $masks;
|
||||
if ($connection->websocketCurrentFrameLength) {
|
||||
$connection->websocketDataBuffer .= $decoded;
|
||||
return $connection->websocketDataBuffer;
|
||||
if ($connection->context->websocketCurrentFrameLength) {
|
||||
$connection->context->websocketDataBuffer .= $decoded;
|
||||
if ($rsv1) {
|
||||
return static::inflate($connection, $connection->context->websocketDataBuffer, $is_fin_frame);
|
||||
}
|
||||
return $connection->context->websocketDataBuffer;
|
||||
} else {
|
||||
if ($connection->websocketDataBuffer !== '') {
|
||||
$decoded = $connection->websocketDataBuffer . $decoded;
|
||||
$connection->websocketDataBuffer = '';
|
||||
if ($connection->context->websocketDataBuffer !== '') {
|
||||
$decoded = $connection->context->websocketDataBuffer . $decoded;
|
||||
$connection->context->websocketDataBuffer = '';
|
||||
}
|
||||
if ($rsv1) {
|
||||
return static::inflate($connection, $decoded, $is_fin_frame);
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflate.
|
||||
*
|
||||
* @param $connection
|
||||
* @param $buffer
|
||||
* @param $is_fin_frame
|
||||
* @return false|string
|
||||
*/
|
||||
protected static function inflate($connection, $buffer, $is_fin_frame)
|
||||
{
|
||||
if (!isset($connection->context->inflator)) {
|
||||
$connection->context->inflator = \inflate_init(
|
||||
\ZLIB_ENCODING_RAW,
|
||||
[
|
||||
'level' => -1,
|
||||
'memory' => 8,
|
||||
'window' => 9,
|
||||
'strategy' => \ZLIB_DEFAULT_STRATEGY
|
||||
]
|
||||
);
|
||||
}
|
||||
if ($is_fin_frame) {
|
||||
$buffer .= "\x00\x00\xff\xff";
|
||||
}
|
||||
return \inflate_add($connection->context->inflator, $buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deflate.
|
||||
*
|
||||
* @param $connection
|
||||
* @param $buffer
|
||||
* @return false|string
|
||||
*/
|
||||
protected static function deflate($connection, $buffer)
|
||||
{
|
||||
if (!isset($connection->context->deflator)) {
|
||||
$connection->context->deflator = \deflate_init(
|
||||
\ZLIB_ENCODING_RAW,
|
||||
[
|
||||
'level' => -1,
|
||||
'memory' => 8,
|
||||
'window' => 9,
|
||||
'strategy' => \ZLIB_DEFAULT_STRATEGY
|
||||
]
|
||||
);
|
||||
}
|
||||
return \substr(\deflate_add($connection->context->deflator, $buffer), 0, -4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Websocket handshake.
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param string $buffer
|
||||
* @param TcpConnection $connection
|
||||
* @return int
|
||||
*/
|
||||
public static function dealHandshake($buffer, TcpConnection $connection)
|
||||
public static function dealHandshake($buffer, $connection)
|
||||
{
|
||||
// HTTP protocol.
|
||||
if (0 === \strpos($buffer, 'GET')) {
|
||||
// Find \r\n\r\n.
|
||||
$heder_end_pos = \strpos($buffer, "\r\n\r\n");
|
||||
if (!$heder_end_pos) {
|
||||
$header_end_pos = \strpos($buffer, "\r\n\r\n");
|
||||
if (!$header_end_pos) {
|
||||
return 0;
|
||||
}
|
||||
$header_length = $heder_end_pos + 4;
|
||||
$header_length = $header_end_pos + 4;
|
||||
|
||||
// Get Sec-WebSocket-Key.
|
||||
$Sec_WebSocket_Key = '';
|
||||
if (\preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i", $buffer, $match)) {
|
||||
$Sec_WebSocket_Key = $match[1];
|
||||
} else {
|
||||
$connection->close("HTTP/1.1 200 WebSocket\r\nServer: workerman/".Worker::VERSION."\r\n\r\n<div style=\"text-align:center\"><h1>WebSocket</h1><hr>workerman/".Worker::VERSION."</div>",
|
||||
$connection->close("HTTP/1.1 200 WebSocket\r\nServer: workerman/" . Worker::VERSION . "\r\n\r\n<div style=\"text-align:center\"><h1>WebSocket</h1><hr>workerman/" . Worker::VERSION . "</div>",
|
||||
true);
|
||||
return 0;
|
||||
}
|
||||
@ -353,54 +428,22 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
$new_key = \base64_encode(\sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
|
||||
// Handshake response data.
|
||||
$handshake_message = "HTTP/1.1 101 Switching Protocols\r\n"
|
||||
."Upgrade: websocket\r\n"
|
||||
."Sec-WebSocket-Version: 13\r\n"
|
||||
."Connection: Upgrade\r\n"
|
||||
."Sec-WebSocket-Accept: " . $new_key . "\r\n";
|
||||
. "Upgrade: websocket\r\n"
|
||||
. "Sec-WebSocket-Version: 13\r\n"
|
||||
. "Connection: Upgrade\r\n"
|
||||
. "Sec-WebSocket-Accept: " . $new_key . "\r\n";
|
||||
|
||||
// Websocket data buffer.
|
||||
$connection->websocketDataBuffer = '';
|
||||
$connection->context->websocketDataBuffer = '';
|
||||
// Current websocket frame length.
|
||||
$connection->websocketCurrentFrameLength = 0;
|
||||
$connection->context->websocketCurrentFrameLength = 0;
|
||||
// Current websocket frame data.
|
||||
$connection->websocketCurrentFrameBuffer = '';
|
||||
$connection->context->websocketCurrentFrameBuffer = '';
|
||||
// Consume handshake data.
|
||||
$connection->consumeRecvBuffer($header_length);
|
||||
|
||||
// blob or arraybuffer
|
||||
if (empty($connection->websocketType)) {
|
||||
$connection->websocketType = static::BINARY_TYPE_BLOB;
|
||||
}
|
||||
|
||||
$has_server_header = false;
|
||||
|
||||
if (isset($connection->headers)) {
|
||||
if (\is_array($connection->headers)) {
|
||||
foreach ($connection->headers as $header) {
|
||||
if (\stripos($header, 'Server:') === 0) {
|
||||
$has_server_header = true;
|
||||
}
|
||||
$handshake_message .= "$header\r\n";
|
||||
}
|
||||
} else {
|
||||
if (\stripos($connection->headers, 'Server:') !== false) {
|
||||
$has_server_header = true;
|
||||
}
|
||||
$handshake_message .= "$connection->headers\r\n";
|
||||
}
|
||||
}
|
||||
if (!$has_server_header) {
|
||||
$handshake_message .= "Server: workerman/".Worker::VERSION."\r\n";
|
||||
}
|
||||
$handshake_message .= "\r\n";
|
||||
// Send handshake response.
|
||||
$connection->send($handshake_message, true);
|
||||
// Mark handshake complete..
|
||||
$connection->websocketHandshake = true;
|
||||
|
||||
// Try to emit onWebSocketConnect callback.
|
||||
$on_websocket_connect = isset($connection->onWebSocketConnect) ? $connection->onWebSocketConnect :
|
||||
(isset($connection->worker->onWebSocketConnect) ? $connection->worker->onWebSocketConnect : false);
|
||||
$on_websocket_connect = $connection->onWebSocketConnect ?? $connection->worker->onWebSocketConnect ?? false;
|
||||
if ($on_websocket_connect) {
|
||||
static::parseHttpHeader($buffer);
|
||||
try {
|
||||
@ -416,24 +459,49 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
$_GET = $_SERVER = $_SESSION = $_COOKIE = array();
|
||||
}
|
||||
|
||||
// blob or arraybuffer
|
||||
if (empty($connection->websocketType)) {
|
||||
$connection->websocketType = static::BINARY_TYPE_BLOB;
|
||||
}
|
||||
|
||||
$has_server_header = false;
|
||||
|
||||
if (isset($connection->headers)) {
|
||||
if (\is_array($connection->headers)) {
|
||||
foreach ($connection->headers as $header) {
|
||||
if (\stripos($header, 'Server:') === 0) {
|
||||
$has_server_header = true;
|
||||
}
|
||||
$handshake_message .= "$header\r\n";
|
||||
}
|
||||
} else {
|
||||
if (\stripos($connection->headers, 'Server:') !== false) {
|
||||
$has_server_header = true;
|
||||
}
|
||||
$handshake_message .= "$connection->headers\r\n";
|
||||
}
|
||||
}
|
||||
if (!$has_server_header) {
|
||||
$handshake_message .= "Server: workerman/" . Worker::VERSION . "\r\n";
|
||||
}
|
||||
$handshake_message .= "\r\n";
|
||||
// Send handshake response.
|
||||
$connection->send($handshake_message, true);
|
||||
// Mark handshake complete..
|
||||
$connection->context->websocketHandshake = true;
|
||||
|
||||
// There are data waiting to be sent.
|
||||
if (!empty($connection->tmpWebsocketData)) {
|
||||
$connection->send($connection->tmpWebsocketData, true);
|
||||
$connection->tmpWebsocketData = '';
|
||||
if (!empty($connection->context->tmpWebsocketData)) {
|
||||
$connection->send($connection->context->tmpWebsocketData, true);
|
||||
$connection->context->tmpWebsocketData = '';
|
||||
}
|
||||
if (\strlen($buffer) > $header_length) {
|
||||
return static::input(\substr($buffer, $header_length), $connection);
|
||||
}
|
||||
return 0;
|
||||
} // Is flash policy-file-request.
|
||||
elseif (0 === \strpos($buffer, '<polic')) {
|
||||
$policy_xml = '<?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>' . "\0";
|
||||
$connection->send($policy_xml, true);
|
||||
$connection->consumeRecvBuffer(\strlen($buffer));
|
||||
return 0;
|
||||
}
|
||||
// Bad websocket handshake request.
|
||||
$connection->close("HTTP/1.1 200 WebSocket\r\nServer: workerman/".Worker::VERSION."\r\n\r\n<div style=\"text-align:center\"><h1>WebSocket</h1><hr>workerman/".Worker::VERSION."</div>",
|
||||
$connection->close("HTTP/1.1 200 WebSocket\r\nServer: workerman/" . Worker::VERSION . "\r\n\r\n<div style=\"text-align:center\"><h1>WebSocket</h1><hr>workerman/" . Worker::VERSION . "</div>",
|
||||
true);
|
||||
return 0;
|
||||
}
|
||||
@ -492,4 +560,5 @@ class Websocket implements \Workerman\Protocols\ProtocolInterface
|
||||
$_SERVER['QUERY_STRING'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
4
vendor/workerman/workerman/Timer.php
vendored
4
vendor/workerman/workerman/Timer.php
vendored
@ -210,7 +210,9 @@ class Timer
|
||||
public static function delAll()
|
||||
{
|
||||
self::$_tasks = self::$_status = array();
|
||||
\pcntl_alarm(0);
|
||||
if (\function_exists('pcntl_alarm')) {
|
||||
\pcntl_alarm(0);
|
||||
}
|
||||
if (self::$_event) {
|
||||
self::$_event->clearAllTimer();
|
||||
}
|
||||
|
10
vendor/workerman/workerman/Worker.php
vendored
10
vendor/workerman/workerman/Worker.php
vendored
@ -34,7 +34,7 @@ class Worker
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '4.1.4';
|
||||
const VERSION = '4.1.5';
|
||||
|
||||
/**
|
||||
* Status starting.
|
||||
@ -1218,7 +1218,7 @@ class Worker
|
||||
case \SIGINT:
|
||||
case \SIGTERM:
|
||||
case \SIGHUP:
|
||||
case \SIGTSTP;
|
||||
case \SIGTSTP:
|
||||
static::$_gracefulStop = false;
|
||||
static::stopAll();
|
||||
break;
|
||||
@ -1304,7 +1304,7 @@ class Worker
|
||||
$STDOUT = \fopen(static::$stdoutFile, "a");
|
||||
$STDERR = \fopen(static::$stdoutFile, "a");
|
||||
// Fix standard output cannot redirect of PHP 8.1.8's bug
|
||||
if (\posix_isatty(2)) {
|
||||
if (\function_exists('posix_isatty') && \posix_isatty(2)) {
|
||||
\ob_start(function ($string) {
|
||||
\file_put_contents(static::$stdoutFile, $string, FILE_APPEND);
|
||||
}, 1);
|
||||
@ -1610,7 +1610,7 @@ class Worker
|
||||
// Get uid.
|
||||
$user_info = \posix_getpwnam($this->user);
|
||||
if (!$user_info) {
|
||||
static::log("Warning: User {$this->user} not exsits");
|
||||
static::log("Warning: User {$this->user} not exists");
|
||||
return;
|
||||
}
|
||||
$uid = $user_info['uid'];
|
||||
@ -1618,7 +1618,7 @@ class Worker
|
||||
if ($this->group) {
|
||||
$group_info = \posix_getgrnam($this->group);
|
||||
if (!$group_info) {
|
||||
static::log("Warning: Group {$this->group} not exsits");
|
||||
static::log("Warning: Group {$this->group} not exists");
|
||||
return;
|
||||
}
|
||||
$gid = $group_info['gid'];
|
||||
|
4
vendor/yzh52521/easyhttp/src/Request.php
vendored
4
vendor/yzh52521/easyhttp/src/Request.php
vendored
@ -291,7 +291,7 @@ class Request
|
||||
//请求头
|
||||
$requestHeaders = [];
|
||||
|
||||
foreach ( $request->getHeaders() as $k => $vs ) {
|
||||
foreach ( (array)$request->getHeaders() as $k => $vs ) {
|
||||
foreach ( $vs as $v ) {
|
||||
$requestHeaders[] = "$k: $v";
|
||||
}
|
||||
@ -300,7 +300,7 @@ class Request
|
||||
//响应头
|
||||
$responseHeaders = [];
|
||||
|
||||
foreach ( $response->getHeaders() as $k => $vs ) {
|
||||
foreach ( (array)$response->getHeaders() as $k => $vs ) {
|
||||
foreach ( $vs as $v ) {
|
||||
$responseHeaders[] = "$k: $v";
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
<div class="layui-form layui-form-pane layui-tab-item layui-show">
|
||||
<div class="layui-form-item">
|
||||
<label for="L_email" class="layui-form-label">邮箱</label>
|
||||
<input type="hidden" name="user_id" value="{:session('user_id')}">
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="L_email" name="email" lay-verify="email" autocomplete="off" value="{$user.email}" class="layui-input" placeholder="{$user.email}">
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user