From 3e781226591d946778822b4fcc6b223e50a8889c Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Thu, 20 Nov 2025 11:45:53 +0800 Subject: [PATCH 01/10] =?UTF-8?q?composer=E4=BE=9D=E8=B5=96=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/composer.json | 48 +- Server/composer.lock | 4299 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 4320 insertions(+), 27 deletions(-) diff --git a/Server/composer.json b/Server/composer.json index 61d3fa7c..1f70969d 100644 --- a/Server/composer.json +++ b/Server/composer.json @@ -13,21 +13,59 @@ { "name": "liu21st", "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" } ], "require": { - "php": ">=5.4.0", - "topthink/framework": "5.0.*" + "php": ">=5.6.0", + "topthink/framework": "5.1.41", + "topthink/think-installer": "2.*", + "topthink/think-captcha": "^2.0", + "topthink/think-helper": "^3.0", + "topthink/think-image": "^1.0", + "topthink/think-queue": "^2.0", + "topthink/think-worker": "^2.0", + "textalk/websocket": "^1.5", + "aliyuncs/oss-sdk-php": "^2.6", + "monolog/monolog": "^1.27", + "guzzlehttp/guzzle": "^6.5", + "overtrue/wechat": "~4.6", + "endroid/qr-code": "^3.9", + "phpoffice/phpspreadsheet": "^1.29", + "workerman/workerman": "^3.5", + "workerman/gateway-worker": "^3.0", + "hashids/hashids": "^2.0", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "lizhichao/word": "^2.0", + "adbario/php-dot-notation": "^2.2" + }, + "require-dev": { + "symfony/var-dumper": "^3.4|^4.4", + "topthink/think-migration": "^2.0", + "phpunit/phpunit": "^5.0|^6.0" }, "autoload": { "psr-4": { "app\\": "application" - } + }, + "files": [ + "application/common.php" + ], + "classmap": [] }, "extra": { "think-path": "thinkphp" }, "config": { - "preferred-install": "dist" - } + "preferred-install": "dist", + "allow-plugins": { + "topthink/think-installer": true, + "easywechat-composer/easywechat-composer": true + } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/Server/composer.lock b/Server/composer.lock index 50bf3cea..56ff4a97 100644 --- a/Server/composer.lock +++ b/Server/composer.lock @@ -4,48 +4,3832 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ba81097bd3bedb9a9265465b0f578307", + "content-hash": "5bca28194f84a7d13965d1851e6ce38a", "packages": [ { - "name": "topthink/framework", - "version": "v5.0.25", + "name": "adbario/php-dot-notation", + "version": "2.5.0", "source": { "type": "git", - "url": "https://github.com/top-think/framework.git", - "reference": "643c58ed1bd22a2823ce5e95b3b68a5075f9087c" + "url": "https://github.com/adbario/php-dot-notation.git", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/top-think/framework/zipball/643c58ed1bd22a2823ce5e95b3b68a5075f9087c", - "reference": "643c58ed1bd22a2823ce5e95b3b68a5075f9087c", + "url": "https://api.github.com/repos/adbario/php-dot-notation/zipball/081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae", + "reference": "081e2cca50c84bfeeea2e3ef9b2c8d206d80ccae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7|^6.6|^7.5|^8.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Adbar\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Riku Särkinen", + "email": "riku@adbar.io" + } + ], + "description": "PHP dot notation access to arrays", + "homepage": "https://github.com/adbario/php-dot-notation", + "keywords": [ + "ArrayAccess", + "dotnotation" + ], + "support": { + "issues": "https://github.com/adbario/php-dot-notation/issues", + "source": "https://github.com/adbario/php-dot-notation/tree/2.5.0" + }, + "time": "2022-10-14T20:31:46+00:00" + }, + { + "name": "aliyuncs/oss-sdk-php", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/aliyun/aliyun-oss-php-sdk.git", + "reference": "483dd0b8bff5d47f0e4ffc99f6077a295c5ccbb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aliyun/aliyun-oss-php-sdk/zipball/483dd0b8bff5d47f0e4ffc99f6077a295c5ccbb5", + "reference": "483dd0b8bff5d47f0e4ffc99f6077a295c5ccbb5", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "php-coveralls/php-coveralls": "*", + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "OSS\\": "src/OSS" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aliyuncs", + "homepage": "http://www.aliyun.com" + } + ], + "description": "Aliyun OSS SDK for PHP", + "homepage": "http://www.aliyun.com/product/oss/", + "support": { + "issues": "https://github.com/aliyun/aliyun-oss-php-sdk/issues", + "source": "https://github.com/aliyun/aliyun-oss-php-sdk/tree/v2.7.2" + }, + "time": "2024-10-28T10:41:12+00:00" + }, + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "time": "2022-12-07T17:46:57+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "time": "2025-09-16T12:23:56+00:00" + }, + { + "name": "easywechat-composer/easywechat-composer", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/mingyoung/easywechat-composer.git", + "reference": "3fc6a7ab6d3853c0f4e2922539b56cc37ef361cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mingyoung/easywechat-composer/zipball/3fc6a7ab6d3853c0f4e2922539b56cc37ef361cd", + "reference": "3fc6a7ab6d3853c0f4e2922539b56cc37ef361cd", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=7.0" + }, + "require-dev": { + "composer/composer": "^1.0 || ^2.0", + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "type": "composer-plugin", + "extra": { + "class": "EasyWeChatComposer\\Plugin" + }, + "autoload": { + "psr-4": { + "EasyWeChatComposer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "张铭阳", + "email": "mingyoungcheung@gmail.com" + } + ], + "description": "The composer plugin for EasyWeChat", + "support": { + "issues": "https://github.com/mingyoung/easywechat-composer/issues", + "source": "https://github.com/mingyoung/easywechat-composer/tree/1.4.1" + }, + "time": "2021-07-05T04:03:22+00:00" + }, + { + "name": "endroid/qr-code", + "version": "3.9.7", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "94563d7b3105288e6ac53a67ae720e3669fac1f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/94563d7b3105288e6ac53a67ae720e3669fac1f6", + "reference": "94563d7b3105288e6ac53a67ae720e3669fac1f6", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "khanamiryan/qrcode-detector-decoder": "^1.0.5", + "myclabs/php-enum": "^1.5", + "php": "^7.3||^8.0", + "symfony/options-resolver": "^3.4||^4.4||^5.0", + "symfony/property-access": "^3.4||^4.4||^5.0" + }, + "require-dev": { + "endroid/quality": "^1.5.2", + "setasign/fpdf": "^1.8" + }, + "suggest": { + "ext-gd": "Required for generating PNG images", + "roave/security-advisories": "Avoids installation of package versions with vulnerabilities", + "setasign/fpdf": "Required to use the FPDF writer.", + "symfony/security-checker": "Checks your composer.lock for vulnerabilities" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/qr-code", + "keywords": [ + "bundle", + "code", + "endroid", + "php", + "qr", + "qrcode" + ], + "support": { + "issues": "https://github.com/endroid/qr-code/issues", + "source": "https://github.com/endroid/qr-code/tree/3.9.7" + }, + "funding": [ + { + "url": "https://github.com/endroid", + "type": "github" + } + ], + "time": "2021-04-20T19:10:54+00:00" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.19.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/b287d2a16aceffbf6e0295559b39662612b77fcf", + "reference": "b287d2a16aceffbf6e0295559b39662612b77fcf", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.19.0" + }, + "time": "2025-10-17T16:34:55+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.8", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.9", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5.8" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-06-20T22:16:07+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-05-21T12:31:43+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", "shasum": "" }, "require": { "php": ">=5.4.0", - "topthink/think-installer": "~1.0" + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" }, "require-dev": { - "johnkary/phpunit-speedtrap": "^1.0", - "mikey179/vfsstream": "~1.6", - "phpdocumentor/reflection-docblock": "^2.0", - "phploc/phploc": "2.*", - "phpunit/phpunit": "4.8.*", - "sebastian/phpcpd": "2.*" + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-04-17T16:00:37+00:00" + }, + { + "name": "hashids/hashids", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/vinkla/hashids.git", + "reference": "7a945a5192d4a5c8888364970feece9bc26179df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vinkla/hashids/zipball/7a945a5192d4a5c8888364970feece9bc26179df", + "reference": "7a945a5192d4a5c8888364970feece9bc26179df", + "shasum": "" + }, + "require": { + "php": "^5.6.4 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.3" + }, + "suggest": { + "ext-bcmatch": "Required to use BC Math arbitrary precision mathematics (*).", + "ext-gmp": "Required to use GNU multiple precision mathematics (*)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } }, - "type": "think-framework", "autoload": { "psr-4": { - "think\\": "library/think" + "Hashids\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Akimov", + "email": "ivan@barreleye.com", + "homepage": "https://twitter.com/IvanAkimov" + }, + { + "name": "Vincent Klaiber", + "email": "hello@vinkla.com", + "homepage": "https://vinkla.com" + } + ], + "description": "Generate short, unique, non-sequential ids (like YouTube and Bitly) from numbers", + "homepage": "http://hashids.org/php", + "keywords": [ + "bitly", + "decode", + "encode", + "hash", + "hashid", + "hashids", + "ids", + "obfuscate", + "youtube" + ], + "support": { + "issues": "https://github.com/vinkla/hashids/issues", + "source": "https://github.com/vinkla/hashids/tree/2.0.4" + }, + "time": "2017-10-28T11:24:20+00:00" + }, + { + "name": "khanamiryan/qrcode-detector-decoder", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git", + "reference": "45326fb83a2a375065dbb3a134b5b8a5872da569" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/45326fb83a2a375065dbb3a134b5b8a5872da569", + "reference": "45326fb83a2a375065dbb3a134b5b8a5872da569", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 | ^7.5 | ^8.0 | ^9.0", + "rector/rector": "^0.13.6", + "symplify/easy-coding-standard": "^11.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Common/customFunctions.php" + ], + "psr-4": { + "Zxing\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT", + "Apache-2.0" + ], + "authors": [ + { + "name": "Ashot Khanamiryan", + "email": "a.khanamiryan@gmail.com", + "homepage": "https://github.com/khanamiryan", + "role": "Developer" + } + ], + "description": "QR code decoder / reader", + "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder/", + "keywords": [ + "barcode", + "qr", + "zxing" + ], + "support": { + "issues": "https://github.com/khanamiryan/php-qrcode-detector-decoder/issues", + "source": "https://github.com/khanamiryan/php-qrcode-detector-decoder/tree/1.0.6" + }, + "time": "2022-06-29T09:25:13+00:00" + }, + { + "name": "lizhichao/word", + "version": "v2.1", + "source": { + "type": "git", + "url": "https://github.com/lizhichao/VicWord.git", + "reference": "f17172d45f505e7140da0bde2103defc13255326" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lizhichao/VicWord/zipball/f17172d45f505e7140da0bde2103defc13255326", + "reference": "f17172d45f505e7140da0bde2103defc13255326", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lizhichao\\Word\\": "Lib" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], + "authors": [ + { + "name": "tanszhe", + "email": "1018595261@qq.com" + } + ], + "description": "This is a participle library", + "support": { + "issues": "https://github.com/lizhichao/VicWord/issues", + "source": "https://github.com/lizhichao/VicWord/tree/master" + }, + "time": "2020-07-30T07:33:06+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "2.2.6", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "shasum": "" + }, + "require": { + "myclabs/php-enum": "^1.5", + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.9", + "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpunit": "^8.5.8 || ^9.4.2", + "vimeo/psalm": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.6" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + }, + { + "url": "https://opencollective.com/zipstream", + "type": "open_collective" + } + ], + "time": "2022-11-25T18:57:19+00:00" + }, + { + "name": "markbaker/complex", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2" + }, + "time": "2022-12-06T16:21:08+00:00" + }, + { + "name": "markbaker/matrix", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPMatrix.git", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c", + "reference": "728434227fe21be27ff6d86621a1b13107a2562c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "phpcompatibility/php-compatibility": "^9.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "^4.0", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "sebastian/phpcpd": "^4.0", + "squizlabs/php_codesniffer": "^3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Matrix\\": "classes/src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@demon-angel.eu" + } + ], + "description": "PHP Class for working with matrices", + "homepage": "https://github.com/MarkBaker/PHPMatrix", + "keywords": [ + "mathematics", + "matrix", + "vector" + ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1" + }, + "time": "2022-12-02T22:17:43+00:00" + }, + { + "name": "monolog/monolog", + "version": "1.27.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "904713c5929655dc9b97288b69cfeedad610c9a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/904713c5929655dc9b97288b69cfeedad610c9a1", + "reference": "904713c5929655dc9b97288b69cfeedad610c9a1", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpstan/phpstan": "^0.12.59", + "phpunit/phpunit": "~4.5", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/1.27.1" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-06-09T08:53:42+00:00" + }, + { + "name": "myclabs/php-enum", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "e7be26966b7398204a234f8673fdad5ac6277802" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/e7be26966b7398204a234f8673fdad5ac6277802", + "reference": "e7be26966b7398204a234f8673fdad5ac6277802", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2 || ^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "https://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.5" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2025-01-14T11:49:03+00:00" + }, + { + "name": "overtrue/socialite", + "version": "2.0.24", + "source": { + "type": "git", + "url": "https://github.com/overtrue/socialite.git", + "reference": "ee7e7b000ec7d64f2b8aba1f6a2eec5cdf3f8bec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/socialite/zipball/ee7e7b000ec7d64f2b8aba1f6a2eec5cdf3f8bec", + "reference": "ee7e7b000ec7d64f2b8aba1f6a2eec5cdf3f8bec", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^5.0|^6.0|^7.0", + "php": ">=5.6", + "symfony/http-foundation": "^2.7|^3.0|^4.0|^5.0" + }, + "require-dev": { + "mockery/mockery": "~1.2", + "phpunit/phpunit": "^6.0|^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Overtrue\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "A collection of OAuth 2 packages that extracts from laravel/socialite.", + "keywords": [ + "login", + "oauth", + "qq", + "social", + "wechat", + "weibo" + ], + "support": { + "issues": "https://github.com/overtrue/socialite/issues", + "source": "https://github.com/overtrue/socialite/tree/2.0.24" + }, + "funding": [ + { + "url": "https://www.patreon.com/overtrue", + "type": "patreon" + } + ], + "time": "2021-05-13T16:04:48+00:00" + }, + { + "name": "overtrue/wechat", + "version": "4.9.0", + "source": { + "type": "git", + "url": "https://github.com/w7corp/easywechat.git", + "reference": "92791f5d957269c633b9aa175f842f6006f945b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/w7corp/easywechat/zipball/92791f5d957269c633b9aa175f842f6006f945b1", + "reference": "92791f5d957269c633b9aa175f842f6006f945b1", + "shasum": "" + }, + "require": { + "easywechat-composer/easywechat-composer": "^1.1", + "ext-fileinfo": "*", + "ext-openssl": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.2 || ^7.0", + "monolog/monolog": "^1.22 || ^2.0", + "overtrue/socialite": "~2.0", + "php": ">=7.2", + "pimple/pimple": "^3.0", + "psr/simple-cache": "^1.0", + "symfony/cache": "^3.3 || ^4.3 || ^5.0", + "symfony/event-dispatcher": "^4.3 || ^5.0", + "symfony/http-foundation": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/psr-http-message-bridge": "^0.3 || ^1.0 || ^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.2.3", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/Kernel/Support/Helpers.php", + "src/Kernel/Helpers.php" + ], + "psr-4": { + "EasyWeChat\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + } + ], + "description": "微信SDK", + "keywords": [ + "easywechat", + "sdk", + "wechat", + "weixin", + "weixin-sdk" + ], + "support": { + "issues": "https://github.com/w7corp/easywechat/issues", + "source": "https://github.com/w7corp/easywechat/tree/4.9.0" + }, + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "abandoned": "w7corp/easywechat", + "time": "2023-04-28T03:30:34+00:00" + }, + { + "name": "phpoffice/phpspreadsheet", + "version": "1.30.1", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "fa8257a579ec623473eabfe49731de5967306c4c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/fa8257a579ec623473eabfe49731de5967306c4c", + "reference": "fa8257a579ec623473eabfe49731de5967306c4c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1||^2||^3", + "ext-ctype": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.15", + "maennchen/zipstream-php": "^2.1 || ^3.0", + "markbaker/complex": "^3.0", + "markbaker/matrix": "^3.0", + "php": ">=7.4.0 <8.5.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "dev-main", + "dompdf/dompdf": "^1.0 || ^2.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.2", + "mitoteam/jpgraph": "^10.3", + "mpdf/mpdf": "^8.1.1", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.7", + "tecnickcom/tcpdf": "^6.5" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-intl": "PHP Internationalization Functions", + "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "https://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker", + "homepage": "https://markbakeruk.net" + }, + { + "name": "Franck Lefevre", + "homepage": "https://rootslabs.net" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Adrien Crivelli" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.30.1" + }, + "time": "2025-10-26T16:01:04+00:00" + }, + { + "name": "phrity/net-uri", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-net-uri.git", + "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-net-uri/zipball/3f458e0c4d1ddc0e218d7a5b9420127c63925f43", + "reference": "3f458e0c4d1ddc0e218d7a5b9420127c63925f43", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 | ^2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Net\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "PSR-7 Uri and PSR-17 UriFactory implementation", + "homepage": "https://phrity.sirn.se/net-uri", + "keywords": [ + "psr-17", + "psr-7", + "uri", + "uri factory" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-net-uri/issues", + "source": "https://github.com/sirn-se/phrity-net-uri/tree/1.3.0" + }, + "time": "2023-08-21T10:33:06+00:00" + }, + { + "name": "phrity/util-errorhandler", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sirn-se/phrity-util-errorhandler.git", + "reference": "483228156e06673963902b1cc1e6bd9541ab4d5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirn-se/phrity-util-errorhandler/zipball/483228156e06673963902b1cc1e6bd9541ab4d5e", + "reference": "483228156e06673963902b1cc1e6bd9541ab4d5e", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0 | ^10.0 | ^11.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Phrity\\Util\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sören Jensen", + "email": "sirn@sirn.se", + "homepage": "https://phrity.sirn.se" + } + ], + "description": "Inline error handler; catch and resolve errors for code block.", + "homepage": "https://phrity.sirn.se/util-errorhandler", + "keywords": [ + "error", + "warning" + ], + "support": { + "issues": "https://github.com/sirn-se/phrity-util-errorhandler/issues", + "source": "https://github.com/sirn-se/phrity-util-errorhandler/tree/1.1.1" + }, + "time": "2024-09-12T06:49:16+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a70f552d338f9266eec6606c1f0b324da5514c96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a70f552d338f9266eec6606c1f0b324da5514c96", + "reference": "a70f552d338f9266eec6606c1f0b324da5514c96", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", + "keywords": [ + "container", + "dependency injection" + ], + "support": { + "source": "https://github.com/silexphp/Pimple/tree/v3.6.0" + }, + "time": "2025-11-12T12:31:38+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/cache", + "version": "v4.3.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "8794ccf68ac341fc19311919d2287f7557bfccba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/8794ccf68ac341fc19311919d2287f7557bfccba", + "reference": "8794ccf68ac341fc19311919d2287f7557bfccba", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "symfony/cache-contracts": "^1.1", + "symfony/service-contracts": "^1.1", + "symfony/var-exporter": "^4.2" + }, + "conflict": { + "doctrine/dbal": "<2.5", + "symfony/dependency-injection": "<3.4", + "symfony/var-dumper": "<3.4" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0", + "symfony/cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "~1.6", + "doctrine/dbal": "~2.5", + "predis/predis": "~1.1", + "psr/simple-cache": "^1.0", + "symfony/config": "~4.2", + "symfony/dependency-injection": "~3.4|~4.1", + "symfony/var-dumper": "^4.1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v4.3.11" + }, + "time": "2020-01-27T09:15:09+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "a872a66e0bf7bac179c89bc96c7098bef1949f81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/a872a66e0bf7bac179c89bc96c7098bef1949f81", + "reference": "a872a66e0bf7bac179c89bc96c7098bef1949f81", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v1.10.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:41:36+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/72982eb416f61003e9bb6e91f8b3213600dcf9e9", + "reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f", + "reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v5.4.50", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "1a0706e8b8041046052ea2695eb8aeee04f97609" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/1a0706e8b8041046052ea2695eb8aeee04f97609", + "reference": "1a0706e8b8041046052ea2695eb8aeee04f97609", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "predis/predis": "^1.0|^2.0", + "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v5.4.50" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-03T12:58:48+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6", + "reference": "74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/property-access", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "111e7ed617509f1a9139686055d234aad6e388e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/111e7ed617509f1a9139686055d234aad6e388e0", + "reference": "111e7ed617509f1a9139686055d234aad6e388e0", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16", + "symfony/property-info": "^5.2|^6.0" + }, + "require-dev": { + "symfony/cache": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/property-info", + "version": "v5.4.48", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "a0396295ad585f95fccd690bc6a281e5bd303902" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/a0396295ad585f95fccd690bc6a281e5bd303902", + "reference": "a0396295ad585f95fccd690bc6a281e5bd303902", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/dependency-injection": "<4.4" + }, + "require-dev": { + "doctrine/annotations": "^1.10.4|^2", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/serializer": "^4.4|^5.0|^6.0" + }, + "suggest": { + "phpdocumentor/reflection-docblock": "To use the PHPDoc", + "psr/cache-implementation": "To cache results", + "symfony/doctrine-bridge": "To use Doctrine metadata", + "symfony/serializer": "To use Serializer metadata" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v5.4.48" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T16:14:41+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "reference": "581ca6067eb62640de5ff08ee1ba6850a0ee472e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-26T11:53:26+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/191afdcb5804db960d26d8566b7e9a2843cab3a0", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "suggest": { + "psr/container": "", + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v1.1.2" + }, + "time": "2019-05-28T07:50:59+00:00" + }, + { + "name": "symfony/string", + "version": "v5.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-10T20:33:58+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v4.4.43", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "4a7a3a3d55c471d396e6d28011368b7b83cb518b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/4a7a3a3d55c471d396e6d28011368b7b83cb518b", + "reference": "4a7a3a3d55c471d396e6d28011368b7b83cb518b", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v4.4.43" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-27T11:44:32+00:00" + }, + { + "name": "textalk/websocket", + "version": "1.6.3", + "source": { + "type": "git", + "url": "https://github.com/Textalk/websocket-php.git", + "reference": "67de79745b1a357caf812bfc44e0abf481cee012" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/67de79745b1a357caf812bfc44e0abf481cee012", + "reference": "67de79745b1a357caf812bfc44e0abf481cee012", + "shasum": "" + }, + "require": { + "php": "^7.4 | ^8.0", + "phrity/net-uri": "^1.0", + "phrity/util-errorhandler": "^1.0", + "psr/http-message": "^1.0", + "psr/log": "^1.0 | ^2.0 | ^3.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen" + } + ], + "description": "WebSocket client and server", + "support": { + "issues": "https://github.com/Textalk/websocket-php/issues", + "source": "https://github.com/Textalk/websocket-php/tree/1.6.3" + }, + "time": "2022-11-07T18:59:33+00:00" + }, + { + "name": "topthink/framework", + "version": "v5.1.12", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "f879603ee321af8fde56d8855445cf98bc81b042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/f879603ee321af8fde56d8855445cf98bc81b042", + "reference": "f879603ee321af8fde56d8855445cf98bc81b042", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "topthink/think-installer": "~1.0" + }, + "require-dev": { + "johnkary/phpunit-speedtrap": "^1.0", + "mikey179/vfsstream": "~1.6", + "phpdocumentor/reflection-docblock": "^2.0", + "phploc/phploc": "2.*", + "phpunit/phpunit": "^5.0|^6.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "think-framework", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], "authors": [ { "name": "liu21st", "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" } ], "description": "the new thinkphp framework", @@ -55,7 +3839,144 @@ "orm", "thinkphp" ], - "time": "2022-10-25T14:59:38+00:00" + "support": { + "issues": "https://github.com/top-think/framework/issues", + "source": "https://github.com/top-think/framework/tree/5.1" + }, + "time": "2018-04-26T03:46:41+00:00" + }, + { + "name": "topthink/think-captcha", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-captcha.git", + "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-captcha/zipball/54c8a51552f99ff9ea89ea9c272383a8f738ceee", + "reference": "54c8a51552f99ff9ea89ea9c272383a8f738ceee", + "shasum": "" + }, + "require": { + "topthink/framework": "5.1.*" + }, + "type": "library", + "autoload": { + "files": [ + "src/helper.php" + ], + "psr-4": { + "think\\captcha\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "captcha package for thinkphp5", + "support": { + "issues": "https://github.com/top-think/think-captcha/issues", + "source": "https://github.com/top-think/think-captcha/tree/2.0" + }, + "time": "2017-12-31T16:37:49+00:00" + }, + { + "name": "topthink/think-helper", + "version": "v3.1.11", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-helper.git", + "reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-helper/zipball/1d6ada9b9f3130046bf6922fe1bd159c8d88a33c", + "reference": "1d6ada9b9f3130046bf6922fe1bd159c8d88a33c", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/helper.php" + ], + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP6 Helper Package", + "support": { + "issues": "https://github.com/top-think/think-helper/issues", + "source": "https://github.com/top-think/think-helper/tree/v3.1.11" + }, + "time": "2025-04-07T06:55:59+00:00" + }, + { + "name": "topthink/think-image", + "version": "v1.0.8", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-image.git", + "reference": "d1d748cbb2fe2f29fca6138cf96cb8b5113892f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-image/zipball/d1d748cbb2fe2f29fca6138cf96cb8b5113892f1", + "reference": "d1d748cbb2fe2f29fca6138cf96cb8b5113892f1", + "shasum": "" + }, + "require": { + "ext-gd": "*" + }, + "require-dev": { + "phpunit/phpunit": "4.8.*", + "topthink/framework": "^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP5 Image Package", + "support": { + "issues": "https://github.com/top-think/think-image/issues", + "source": "https://github.com/top-think/think-image/tree/v1.0.8" + }, + "time": "2024-08-07T10:06:35+00:00" }, { "name": "topthink/think-installer", @@ -96,17 +4017,351 @@ "email": "448901948@qq.com" } ], + "support": { + "issues": "https://github.com/top-think/think-installer/issues", + "source": "https://github.com/top-think/think-installer/tree/v1.0.14" + }, "time": "2021-03-25T08:34:02+00:00" + }, + { + "name": "topthink/think-queue", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-queue.git", + "reference": "465320c9cb7811df22d4ff8f29f58ead7d104348" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-queue/zipball/465320c9cb7811df22d4ff8f29f58ead7d104348", + "reference": "465320c9cb7811df22d4ff8f29f58ead7d104348", + "shasum": "" + }, + "require": { + "topthink/think-helper": ">=1.0.4", + "topthink/think-installer": ">=1.0.10" + }, + "type": "think-extend", + "extra": { + "think-config": { + "queue": "src/config.php" + } + }, + "autoload": { + "files": [ + "src/common.php" + ], + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP5 Queue Package", + "support": { + "issues": "https://github.com/top-think/think-queue/issues", + "source": "https://github.com/top-think/think-queue/tree/master" + }, + "time": "2018-05-04T05:29:53+00:00" + }, + { + "name": "topthink/think-worker", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-worker.git", + "reference": "7b7a64b2911cc11298b11677508f1a1936a2fb70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-worker/zipball/7b7a64b2911cc11298b11677508f1a1936a2fb70", + "reference": "7b7a64b2911cc11298b11677508f1a1936a2fb70", + "shasum": "" + }, + "require": { + "topthink/framework": "5.1.*", + "workerman/workerman": "^3.3.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/config.php" + ], + "psr-4": { + "think\\worker\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "workerman extend for thinkphp5", + "support": { + "issues": "https://github.com/top-think/think-worker/issues", + "source": "https://github.com/top-think/think-worker/tree/2.0" + }, + "time": "2018-06-28T06:04:53+00:00" + }, + { + "name": "workerman/gateway-worker", + "version": "v3.0.22", + "source": { + "type": "git", + "url": "https://github.com/walkor/GatewayWorker.git", + "reference": "a615036c482d11f68b693998575e804752ef9068" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/walkor/GatewayWorker/zipball/a615036c482d11f68b693998575e804752ef9068", + "reference": "a615036c482d11f68b693998575e804752ef9068", + "shasum": "" + }, + "require": { + "workerman/workerman": ">=3.5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "GatewayWorker\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "homepage": "http://www.workerman.net", + "keywords": [ + "communication", + "distributed" + ], + "support": { + "issues": "https://github.com/walkor/GatewayWorker/issues", + "source": "https://github.com/walkor/GatewayWorker/tree/v3.0.22" + }, + "funding": [ + { + "url": "https://opencollective.com/walkor", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/walkor", + "type": "patreon" + } + ], + "time": "2021-12-23T13:13:09+00:00" + }, + { + "name": "workerman/workerman", + "version": "v3.5.35", + "source": { + "type": "git", + "url": "https://github.com/walkor/workerman.git", + "reference": "3cc0adae51ba36db38b11e7996c64250d356dbe7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/walkor/workerman/zipball/3cc0adae51ba36db38b11e7996c64250d356dbe7", + "reference": "3cc0adae51ba36db38b11e7996c64250d356dbe7", + "shasum": "" + }, + "require": { + "php": "^5.3||^7.0" + }, + "suggest": { + "ext-event": "For better performance. " + }, + "type": "library", + "autoload": { + "psr-4": { + "Workerman\\": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "walkor", + "email": "walkor@workerman.net", + "homepage": "http://www.workerman.net", + "role": "Developer" + } + ], + "description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.", + "homepage": "http://www.workerman.net", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "email": "walkor@workerman.net", + "forum": "http://wenda.workerman.net/", + "issues": "https://github.com/walkor/workerman/issues", + "source": "https://github.com/walkor/workerman", + "wiki": "http://doc.workerman.net/" + }, + "funding": [ + { + "url": "https://opencollective.com/workerman", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/walkor", + "type": "patreon" + } + ], + "time": "2023-09-13T14:30:13+00:00" + } + ], + "packages-dev": [ + { + "name": "symfony/var-dumper", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "0719f6cf4633a38b2c1585140998579ce23b4b7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0719f6cf4633a38b2c1585140998579ce23b4b7d", + "reference": "0719f6cf4633a38b2c1585140998579ce23b4b7d", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" + }, + "require-dev": { + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "ext-symfony_debug": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "topthink/think-migration", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-migration.git", + "reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-migration/zipball/70c89850ca29c2eab988c7c3475d1d5331901bb8", + "reference": "70c89850ca29c2eab988c7c3475d1d5331901bb8", + "shasum": "" + }, + "require": { + "topthink/framework": "5.1.*" + }, + "type": "library", + "autoload": { + "files": [ + "src/config.php" + ], + "psr-4": { + "Phinx\\": "phinx/src/Phinx", + "think\\migration\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "support": { + "issues": "https://github.com/top-think/think-migration/issues", + "source": "https://github.com/top-think/think-migration/tree/2.0" + }, + "time": "2017-12-31T16:32:22+00:00" } ], - "packages-dev": [], "aliases": [], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": [], - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=5.4.0" + "php": ">=5.6.0" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.3.0" } From 5a5160b92d8c77c193ea1f8bc044e5d18bf27b63 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Thu, 20 Nov 2025 11:48:31 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/common.php | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/Server/application/common.php b/Server/application/common.php index 37a12739..8785f12c 100644 --- a/Server/application/common.php +++ b/Server/application/common.php @@ -75,7 +75,18 @@ if (!function_exists('requestCurl')) { if (!function_exists('dataBuild')) { function dataBuild($array) { - return is_array($array) ? http_build_query($array) : $array; + if (!is_array($array)) { + return $array; + } + + // 处理嵌套数组 + foreach ($array as $key => $value) { + if (is_array($value)) { + $array[$key] = json_encode($value); + } + } + + return http_build_query($array); } } @@ -550,14 +561,15 @@ if (!function_exists('exit_data')) { exit(); } } - -/** - * 调试打印变量但不终止程序 - * @return void - */ -function dump() -{ - call_user_func_array(['app\\common\\helper\\Debug', 'dump'], func_get_args()); +if (!function_exists('dump')) { + /** + * 调试打印变量但不终止程序 + * @return void + */ + function dump() + { + call_user_func_array(['app\\common\\helper\\Debug', 'dump'], func_get_args()); + } } if (!function_exists('artificialAllotWechatFriend')) { From d3fae3bbd0a3ee8693116e1eb6b89d7097cab9a5 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 15:42:54 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E9=98=9F=E5=88=97=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/README_scheduler.md | 254 ++++++++++ Server/application/command.php | 3 + .../command/TaskSchedulerCommand.php | 457 ++++++++++++++++++ Server/config/task_scheduler.php | 301 ++++++++++++ 4 files changed, 1015 insertions(+) create mode 100644 Server/README_scheduler.md create mode 100644 Server/application/command/TaskSchedulerCommand.php create mode 100644 Server/config/task_scheduler.php diff --git a/Server/README_scheduler.md b/Server/README_scheduler.md new file mode 100644 index 00000000..4c485684 --- /dev/null +++ b/Server/README_scheduler.md @@ -0,0 +1,254 @@ +# 统一任务调度器使用说明 + +## 概述 + +统一任务调度器(TaskSchedulerCommand)是一个集中管理所有定时任务的调度系统,支持: +- ✅ 单条 crontab 配置管理所有任务 +- ✅ 多进程并发执行任务 +- ✅ 自动根据 cron 表达式判断任务执行时间 +- ✅ 任务锁机制,防止重复执行 +- ✅ 完善的日志记录 + +## 安装配置 + +### 1. 配置文件 + +任务配置位于 `config/task_scheduler.php`,格式如下: + +```php +'任务标识' => [ + 'command' => '命令名称', // 必填:执行的命令 + 'schedule' => 'cron表达式', // 必填:cron表达式 + 'options' => ['--option=value'], // 可选:命令参数 + 'enabled' => true, // 可选:是否启用 + 'max_concurrent' => 1, // 可选:最大并发数 + 'timeout' => 3600, // 可选:超时时间(秒) + 'log_file' => 'custom.log', // 可选:自定义日志文件 +] +``` + +### 2. Cron 表达式格式 + +标准 cron 格式:`分钟 小时 日 月 星期` + +示例: +- `*/1 * * * *` - 每分钟执行 +- `*/5 * * * *` - 每5分钟执行 +- `*/30 * * * *` - 每30分钟执行 +- `0 2 * * *` - 每天凌晨2点执行 +- `0 3 */3 * *` - 每3天的3点执行 + +### 3. Crontab 配置 + +**只需要在 crontab 中添加一条任务:** + +```bash +# 每分钟执行一次调度器(调度器内部会根据 cron 表达式判断哪些任务需要执行) +* * * * * cd /www/wwwroot/mckb_quwanzhi_com/Server && php think scheduler:run >> /www/wwwroot/mckb_quwanzhi_com/Server/runtime/log/scheduler.log 2>&1 +``` + +### 4. 系统要求 + +- PHP >= 5.6.0 +- 推荐启用 `pcntl` 扩展以支持多进程并发(非必需,未启用时使用单进程顺序执行) + +检查 pcntl 扩展: +```bash +php -m | grep pcntl +``` + +## 使用方法 + +### 手动执行调度器 + +```bash +# 执行调度器(会自动判断当前时间需要执行的任务) +php think scheduler:run +``` + +### 查看任务配置 + +```bash +# 查看所有已注册的命令 +php think list +``` + +### 启用/禁用任务 + +编辑 `config/task_scheduler.php`,设置 `'enabled' => false` 即可禁用任务。 + +## 功能特性 + +### 1. 多进程并发执行 + +- 默认最大并发数:10 个进程 +- 自动管理进程池 +- 自动清理僵尸进程 + +### 2. 任务锁机制 + +- 每个任务在执行时会设置锁(5分钟内不重复执行) +- 防止任务重复执行 +- 锁存储在缓存中,自动过期 + +### 3. 日志记录 + +- 调度器日志:`runtime/log/scheduler.log` +- 每个任务的日志:`runtime/log/{log_file}` +- 任务执行开始和结束都有标记 + +### 4. 超时控制 + +- 默认超时时间:3600 秒(1小时) +- 可在配置中为每个任务单独设置超时时间 +- 超时后自动终止任务 + +## 配置示例 + +### 高频任务(每分钟) + +```php +'wechat_friends_active' => [ + 'command' => 'wechatFriends:list', + 'schedule' => '*/1 * * * *', + 'options' => ['--isDel=0'], + 'enabled' => true, +], +``` + +### 中频任务(每5分钟) + +```php +'device_active' => [ + 'command' => 'device:list', + 'schedule' => '*/5 * * * *', + 'options' => ['--isDel=0'], + 'enabled' => true, +], +``` + +### 每日任务 + +```php +'wechat_calculate_score' => [ + 'command' => 'wechat:calculate-score', + 'schedule' => '0 2 * * *', // 每天凌晨2点 + 'options' => [], + 'enabled' => true, +], +``` + +### 定期任务(每3天) + +```php +'sync_all_friends' => [ + 'command' => 'sync:allFriends', + 'schedule' => '0 3 */3 * *', // 每3天的3点 + 'options' => [], + 'enabled' => true, +], +``` + +## 从旧配置迁移 + +### 旧配置(多条 crontab) + +```bash +*/5 * * * * cd /path && php think device:list --isDel=0 >> log1.log 2>&1 +*/1 * * * * cd /path && php think wechatFriends:list >> log2.log 2>&1 +``` + +### 新配置(单条 crontab + 配置文件) + +**Crontab:** +```bash +* * * * * cd /path && php think scheduler:run >> scheduler.log 2>&1 +``` + +**config/task_scheduler.php:** +```php +'device_active' => [ + 'command' => 'device:list', + 'schedule' => '*/5 * * * *', + 'options' => ['--isDel=0'], + 'log_file' => 'log1.log', +], +'wechat_friends' => [ + 'command' => 'wechatFriends:list', + 'schedule' => '*/1 * * * *', + 'log_file' => 'log2.log', +], +``` + +## 监控和调试 + +### 查看调度器日志 + +```bash +tail -f runtime/log/scheduler.log +``` + +### 查看任务执行日志 + +```bash +tail -f runtime/log/crontab_device_active.log +``` + +### 检查任务是否在执行 + +```bash +# 查看进程 +ps aux | grep "php think" +``` + +### 手动测试任务 + +```bash +# 直接执行某个任务 +php think device:list --isDel=0 +``` + +## 注意事项 + +1. **时间同步**:确保服务器时间准确,调度器依赖系统时间判断任务执行时间 +2. **资源限制**:根据服务器性能调整 `maxConcurrent` 参数 +3. **日志清理**:定期清理日志文件,避免占用过多磁盘空间 +4. **任务冲突**:如果任务执行时间较长,建议调整执行频率或增加并发数 +5. **缓存依赖**:任务锁使用缓存,确保缓存服务正常运行 + +## 故障排查 + +### 任务未执行 + +1. 检查任务是否启用:`'enabled' => true` +2. 检查 cron 表达式是否正确 +3. 检查调度器是否正常运行:查看 `scheduler.log` +4. 检查任务锁:任务可能在5分钟内重复执行被跳过 + +### 任务执行失败 + +1. 查看任务日志:`runtime/log/{log_file}` +2. 检查命令是否正确:手动执行命令测试 +3. 检查权限:确保有执行权限和日志写入权限 + +### 多进程不工作 + +1. 检查 pcntl 扩展:`php -m | grep pcntl` +2. 检查系统限制:`ulimit -u` 查看最大进程数 +3. 查看调度器日志中的错误信息 + +## 性能优化建议 + +1. **合理设置并发数**:根据服务器 CPU 核心数和内存大小调整 +2. **错开高频任务**:避免所有任务在同一分钟执行 +3. **优化任务执行时间**:减少任务执行时长 +4. **使用队列**:对于耗时任务,建议使用队列异步处理 + +## 更新日志 + +### v1.0.0 (2024-01-XX) +- 初始版本 +- 支持多进程并发执行 +- 支持 cron 表达式调度 +- 支持任务锁机制 + diff --git a/Server/application/command.php b/Server/application/command.php index b5c4d0e5..ce06453b 100644 --- a/Server/application/command.php +++ b/Server/application/command.php @@ -42,4 +42,7 @@ return [ 'wechat:calculate-score' => 'app\command\CalculateWechatAccountScoreCommand', // 统一计算微信账号健康分 'wechat:update-score' => 'app\command\UpdateWechatAccountScoreCommand', // 更新微信账号评分记录 + + // 统一任务调度器 + 'scheduler:run' => 'app\command\TaskSchedulerCommand', // 统一任务调度器,支持多进程并发执行 ]; diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php new file mode 100644 index 00000000..06a1dbaf --- /dev/null +++ b/Server/application/command/TaskSchedulerCommand.php @@ -0,0 +1,457 @@ +> /path/to/log/scheduler.log 2>&1 + */ +class TaskSchedulerCommand extends Command +{ + /** + * 任务配置 + */ + protected $tasks = []; + + /** + * 最大并发进程数 + */ + protected $maxConcurrent = 10; + + /** + * 当前运行的进程数 + */ + protected $runningProcesses = []; + + /** + * 日志目录 + */ + protected $logDir = ''; + + protected function configure() + { + $this->setName('scheduler:run') + ->setDescription('统一任务调度器,支持多进程并发执行所有定时任务'); + } + + protected function execute(Input $input, Output $output) + { + $output->writeln('=========================================='); + $output->writeln('任务调度器启动'); + $output->writeln('时间: ' . date('Y-m-d H:i:s')); + $output->writeln('=========================================='); + + // 检查是否支持 pcntl 扩展 + if (!function_exists('pcntl_fork')) { + $output->writeln('错误:系统不支持 pcntl 扩展,无法使用多进程功能'); + $output->writeln('提示:将使用单进程顺序执行任务'); + $this->maxConcurrent = 1; + } + + // 加载任务配置 + $this->tasks = Config::get('task_scheduler', []); + if (empty($this->tasks)) { + $output->writeln('错误:未找到任务配置'); + return false; + } + + // 设置日志目录 + $this->logDir = runtime_path() . 'log' . DIRECTORY_SEPARATOR; + if (!is_dir($this->logDir)) { + mkdir($this->logDir, 0755, true); + } + + // 获取当前时间 + $currentTime = time(); + $currentMinute = date('i', $currentTime); + $currentHour = date('H', $currentTime); + $currentDay = date('d', $currentTime); + $currentMonth = date('m', $currentTime); + $currentWeekday = date('w', $currentTime); // 0=Sunday, 6=Saturday + + $output->writeln("当前时间: {$currentHour}:{$currentMinute}"); + $output->writeln("已加载 " . count($this->tasks) . " 个任务配置"); + + // 筛选需要执行的任务 + $tasksToRun = []; + foreach ($this->tasks as $taskId => $task) { + if (!isset($task['enabled']) || !$task['enabled']) { + continue; + } + + if ($this->shouldRun($task['schedule'], $currentMinute, $currentHour, $currentDay, $currentMonth, $currentWeekday)) { + $tasksToRun[$taskId] = $task; + } + } + + if (empty($tasksToRun)) { + $output->writeln('当前时间没有需要执行的任务'); + return true; + } + + $output->writeln("找到 " . count($tasksToRun) . " 个需要执行的任务"); + + // 执行任务 + if ($this->maxConcurrent > 1 && function_exists('pcntl_fork')) { + $this->executeConcurrent($tasksToRun, $output); + } else { + $this->executeSequential($tasksToRun, $output); + } + + // 清理僵尸进程 + $this->cleanupZombieProcesses(); + + $output->writeln('=========================================='); + $output->writeln('任务调度器执行完成'); + $output->writeln('=========================================='); + + return true; + } + + /** + * 判断任务是否应该执行 + * + * @param string $schedule cron表达式,格式:分钟 小时 日 月 星期 + * @param int $minute 当前分钟 + * @param int $hour 当前小时 + * @param int $day 当前日期 + * @param int $month 当前月份 + * @param int $weekday 当前星期 + * @return bool + */ + protected function shouldRun($schedule, $minute, $hour, $day, $month, $weekday) + { + $parts = preg_split('/\s+/', trim($schedule)); + if (count($parts) < 5) { + return false; + } + + list($scheduleMinute, $scheduleHour, $scheduleDay, $scheduleMonth, $scheduleWeekday) = $parts; + + // 解析分钟 + if (!$this->matchCronField($scheduleMinute, $minute)) { + return false; + } + + // 解析小时 + if (!$this->matchCronField($scheduleHour, $hour)) { + return false; + } + + // 解析日期 + if (!$this->matchCronField($scheduleDay, $day)) { + return false; + } + + // 解析月份 + if (!$this->matchCronField($scheduleMonth, $month)) { + return false; + } + + // 解析星期(注意:cron中0和7都表示星期日) + if ($scheduleWeekday !== '*') { + $scheduleWeekday = str_replace('7', '0', $scheduleWeekday); + if (!$this->matchCronField($scheduleWeekday, $weekday)) { + return false; + } + } + + return true; + } + + /** + * 匹配cron字段 + * + * @param string $field cron字段表达式 + * @param int $value 当前值 + * @return bool + */ + protected function matchCronField($field, $value) + { + // 通配符 + if ($field === '*') { + return true; + } + + // 列表(逗号分隔) + if (strpos($field, ',') !== false) { + $values = explode(',', $field); + foreach ($values as $v) { + if ($this->matchCronField(trim($v), $value)) { + return true; + } + } + return false; + } + + // 范围(如 1-5) + if (strpos($field, '-') !== false) { + list($start, $end) = explode('-', $field); + return $value >= (int)$start && $value <= (int)$end; + } + + // 步长(如 */5 或 0-59/5) + if (strpos($field, '/') !== false) { + $parts = explode('/', $field); + $base = $parts[0]; + $step = (int)$parts[1]; + + if ($base === '*') { + return $value % $step === 0; + } else { + // 处理范围步长,如 0-59/5 + if (strpos($base, '-') !== false) { + list($start, $end) = explode('-', $base); + if ($value >= (int)$start && $value <= (int)$end) { + return ($value - (int)$start) % $step === 0; + } + return false; + } else { + return $value % $step === 0; + } + } + } + + // 精确匹配 + return (int)$field === $value; + } + + /** + * 并发执行任务(多进程) + * + * @param array $tasks 任务列表 + * @param Output $output 输出对象 + */ + protected function executeConcurrent($tasks, Output $output) + { + $output->writeln('使用多进程并发执行任务(最大并发数:' . $this->maxConcurrent . ')'); + + foreach ($tasks as $taskId => $task) { + // 等待可用进程槽 + while (count($this->runningProcesses) >= $this->maxConcurrent) { + $this->waitForProcesses(); + usleep(100000); // 等待100ms + } + + // 检查任务是否已经在运行(防止重复执行) + $lockKey = "scheduler_task_lock:{$taskId}"; + $lockTime = Cache::get($lockKey); + if ($lockTime && (time() - $lockTime) < 300) { // 5分钟内不重复执行 + $output->writeln("任务 {$taskId} 正在运行中,跳过"); + continue; + } + + // 创建子进程 + $pid = pcntl_fork(); + + if ($pid == -1) { + // 创建进程失败 + $output->writeln("创建子进程失败:{$taskId}"); + Log::error("任务调度器:创建子进程失败", ['task' => $taskId]); + continue; + } elseif ($pid == 0) { + // 子进程:执行任务 + $this->runTask($taskId, $task); + exit(0); + } else { + // 父进程:记录子进程PID + $this->runningProcesses[$pid] = [ + 'task_id' => $taskId, + 'start_time' => time(), + ]; + $output->writeln("启动任务:{$taskId} (PID: {$pid})"); + + // 设置任务锁 + Cache::set($lockKey, time(), 600); // 10分钟过期 + } + } + + // 等待所有子进程完成 + while (!empty($this->runningProcesses)) { + $this->waitForProcesses(); + usleep(500000); // 等待500ms + } + } + + /** + * 顺序执行任务(单进程) + * + * @param array $tasks 任务列表 + * @param Output $output 输出对象 + */ + protected function executeSequential($tasks, Output $output) + { + $output->writeln('使用单进程顺序执行任务'); + + foreach ($tasks as $taskId => $task) { + $output->writeln("执行任务:{$taskId}"); + $this->runTask($taskId, $task); + } + } + + /** + * 执行单个任务 + * + * @param string $taskId 任务ID + * @param array $task 任务配置 + */ + protected function runTask($taskId, $task) + { + $startTime = microtime(true); + $logFile = $this->logDir . ($task['log_file'] ?? "scheduler_{$taskId}.log"); + + // 确保日志目录存在 + $logDir = dirname($logFile); + if (!is_dir($logDir)) { + mkdir($logDir, 0755, true); + } + + // 构建命令 + $thinkPath = root_path() . 'think'; + $command = "php {$thinkPath} {$task['command']}"; + if (!empty($task['options'])) { + foreach ($task['options'] as $option) { + $command .= ' ' . escapeshellarg($option); + } + } + + // 添加日志重定向 + $command .= " >> " . escapeshellarg($logFile) . " 2>&1"; + + // 记录任务开始 + $logMessage = "\n" . str_repeat('=', 60) . "\n"; + $logMessage .= "任务开始执行: {$taskId}\n"; + $logMessage .= "执行时间: " . date('Y-m-d H:i:s') . "\n"; + $logMessage .= "命令: {$command}\n"; + $logMessage .= str_repeat('=', 60) . "\n"; + file_put_contents($logFile, $logMessage, FILE_APPEND); + + // 执行命令 + $descriptorspec = [ + 0 => ['file', (PHP_OS_FAMILY === 'Windows' ? 'NUL' : '/dev/null'), 'r'], // stdin + 1 => ['file', $logFile, 'a'], // stdout + 2 => ['file', $logFile, 'a'], // stderr + ]; + + $process = @proc_open($command, $descriptorspec, $pipes, root_path()); + + if (is_resource($process)) { + // 关闭管道 + if (isset($pipes[0])) @fclose($pipes[0]); + if (isset($pipes[1])) @fclose($pipes[1]); + if (isset($pipes[2])) @fclose($pipes[2]); + + // 设置超时 + $timeout = $task['timeout'] ?? 3600; + $startWaitTime = time(); + + // 等待进程完成或超时 + while (true) { + $status = proc_get_status($process); + + if (!$status['running']) { + break; + } + + // 检查超时 + if ((time() - $startWaitTime) > $timeout) { + if (function_exists('proc_terminate')) { + proc_terminate($process, SIGTERM); + // 等待进程终止 + sleep(2); + $status = proc_get_status($process); + if ($status['running']) { + // 强制终止 + proc_terminate($process, SIGKILL); + } + } + Log::warning("任务执行超时", [ + 'task' => $taskId, + 'timeout' => $timeout, + ]); + break; + } + + usleep(500000); // 等待500ms + } + + // 关闭进程 + proc_close($process); + } else { + // 如果 proc_open 失败,尝试直接执行(后台执行) + if (PHP_OS_FAMILY === 'Windows') { + pclose(popen("start /B " . $command, "r")); + } else { + exec($command . ' > /dev/null 2>&1 &'); + } + } + + $endTime = microtime(true); + $duration = round($endTime - $startTime, 2); + + // 记录任务完成 + $logMessage = "\n" . str_repeat('=', 60) . "\n"; + $logMessage .= "任务执行完成: {$taskId}\n"; + $logMessage .= "完成时间: " . date('Y-m-d H:i:s') . "\n"; + $logMessage .= "执行时长: {$duration} 秒\n"; + $logMessage .= str_repeat('=', 60) . "\n"; + file_put_contents($logFile, $logMessage, FILE_APPEND); + + Log::info("任务执行完成", [ + 'task' => $taskId, + 'duration' => $duration, + ]); + } + + /** + * 等待进程完成 + */ + protected function waitForProcesses() + { + foreach ($this->runningProcesses as $pid => $info) { + $status = 0; + $result = pcntl_waitpid($pid, $status, WNOHANG); + + if ($result == $pid || $result == -1) { + // 进程已结束 + unset($this->runningProcesses[$pid]); + + $duration = time() - $info['start_time']; + Log::info("子进程执行完成", [ + 'pid' => $pid, + 'task' => $info['task_id'], + 'duration' => $duration, + ]); + } + } + } + + /** + * 清理僵尸进程 + */ + protected function cleanupZombieProcesses() + { + if (!function_exists('pcntl_waitpid')) { + return; + } + + $status = 0; + while (($pid = pcntl_waitpid(-1, $status, WNOHANG)) > 0) { + // 清理僵尸进程 + } + } +} + diff --git a/Server/config/task_scheduler.php b/Server/config/task_scheduler.php new file mode 100644 index 00000000..7fa7ea37 --- /dev/null +++ b/Server/config/task_scheduler.php @@ -0,0 +1,301 @@ + [ + // 'command' => '命令名称', // 必填:执行的 ThinkPHP 命令(见 application/command.php) + // 'schedule' => 'cron表达式', // 必填:cron 表达式,如 '*/5 * * * *' 表示每5分钟 + // 'options' => ['--option=value'], // 可选:命令参数(原来 crontab 里的 --xxx=yyy) + // 'enabled' => true, // 可选:是否启用,默认 true + // 'max_concurrent'=> 1, // 可选:单任务最大并发数(目前由调度器统一控制,可预留) + // 'timeout' => 3600, // 可选:超时时间(秒),默认 3600 + // 'log_file' => 'custom.log', // 可选:日志文件名,默认使用任务标识 + // ] + + // =========================== + // 高频任务(每分钟或更频繁) + // =========================== + + // 同步微信好友列表(未删除好友),用于保持系统中好友数据实时更新 + 'wechat_friends_active' => [ + 'command' => 'wechatFriends:list', + 'schedule' => '*/1 * * * *', // 每1分钟 + 'options' => ['--isDel=0'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_wechatFriends_active.log', + ], + + // 拉取“添加好友任务”列表,驱动自动加好友的任务队列 + 'friend_task' => [ + 'command' => 'friendTask:list', + 'schedule' => '*/1 * * * *', // 每1分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_friendTask.log', + ], + + // 同步微信好友私聊消息列表,写入消息表,供客服工作台使用 + 'message_friends' => [ + 'command' => 'message:friendsList', + 'schedule' => '*/1 * * * *', // 每1分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_messageFriends.log', + ], + + // 同步微信群聊消息列表,写入消息表,供群聊记录与风控分析 + 'message_chatroom' => [ + 'command' => 'message:chatroomList', + 'schedule' => '*/1 * * * *', // 每1分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_messageChatroom.log', + ], + + // 客服端消息提醒任务,负责给在线客服推送新消息通知 + 'kf_notice' => [ + 'command' => 'kf:notice', + 'schedule' => '*/1 * * * *', // 每1分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'kf_notice.log', + ], + + // =========================== + // 中频任务(每 2-5 分钟) + // =========================== + + // 同步微信设备列表(未删除设备),用于设备管理与监控 + 'device_active' => [ + 'command' => 'device:list', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => ['--isDel=0'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_device_active.log', + ], + + // 同步微信群聊列表(未删除群),用于群管理与后续任务分配 + 'wechat_chatroom_active' => [ + 'command' => 'wechatChatroom:list', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => ['--isDel=0'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_wechatChatroom_active.log', + ], + + // 同步微信群成员列表(群好友),维持群成员明细数据 + 'group_friends' => [ + 'command' => 'groupFriends:list', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_groupFriends.log', + ], + + // 同步“微信客服列表”,获取绑定到公司的微信号,用于工作台与分配规则 + 'wechat_list' => [ + 'command' => 'wechatList:list', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_wechatList.log', + ], + + // 同步公司账号列表(企业/租户账号),供后台管理与统计 + 'account_list' => [ + 'command' => 'account:list', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_account.log', + ], + + // 内容采集任务,将外部或设备内容同步到系统内容库 + 'content_collect' => [ + 'command' => 'content:collect', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_contentCollect.log', + ], + + // 工作台:自动点赞好友/客户朋友圈,提高账号活跃度 + 'workbench_auto_like' => [ + 'command' => 'workbench:autoLike', + 'schedule' => '*/6 * * * *', // 每6分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_workbench_autoLike.log', + ], + + // 工作台:自动建群任务,按规则批量创建微信群 + 'workbench_group_create' => [ + 'command' => 'workbench:groupCreate', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'workbench_groupCreate.log', + ], + + // 工作台:自动导入通讯录到系统,生成加粉/建群等任务 + 'workbench_import_contact' => [ + 'command' => 'workbench:import-contact', + 'schedule' => '*/5 * * * *', // 每5分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'import_contact.log', + ], + + // =========================== + // 低频任务(每 2 分钟) + // =========================== + + // 清洗并同步微信原始数据到存客宝业务表(数据治理任务) + 'sync_wechat_data' => [ + 'command' => 'sync:wechatData', + 'schedule' => '*/2 * * * *', // 每2分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'sync_wechat_data.log', + ], + + // 工作台:流量分发任务,把流量池中的线索按规则分配给微信号或员工 + 'workbench_traffic_distribute' => [ + 'command' => 'workbench:trafficDistribute', + 'schedule' => '*/2 * * * *', // 每2分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'traffic_distribute.log', + ], + + // 工作台:朋友圈同步任务,拉取并落库朋友圈内容 + 'workbench_moments' => [ + 'command' => 'workbench:moments', + 'schedule' => '*/2 * * * *', // 每2分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'workbench_moments.log', + ], + + // 预防性切换好友任务,监控频繁/风控风险,自动切换加人对象,保护微信号 + 'switch_friends' => [ + 'command' => 'switch:friends', + 'schedule' => '*/2 * * * *', // 每2分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'switch_friends.log', + ], + + // =========================== + // 低频任务(每 30 分钟) + // =========================== + + // 拉取设备通话记录(语音/电话),用于质检、统计或标签打分 + 'call_recording' => [ + 'command' => 'call-recording:list', + 'schedule' => '*/30 * * * *', // 每30分钟 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'call_recording.log', + ], + + // =========================== + // 每日 / 每几天任务 + // =========================== + + // 每日 1:00 同步“已删除设备”列表,补齐历史状态 + 'device_deleted' => [ + 'command' => 'device:list', + 'schedule' => '0 1 * * *', // 每天1点 + 'options' => ['--isDel=1'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_device_deleted.log', + ], + + // 每日 1:10 同步“已停用设备”列表,更新停用状态 + 'device_stopped' => [ + 'command' => 'device:list', + 'schedule' => '10 1 * * *', // 每天1:10 + 'options' => ['--isDel=2'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_device_stopped.log', + ], + + // 每日 1:30 同步“已删除微信好友”,用于历史恢复与报表 + 'wechat_friends_deleted' => [ + 'command' => 'wechatFriends:list', + 'schedule' => '30 1 * * *', // 每天1:30 + 'options' => ['--isDel=1'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_wechatFriends_deleted.log', + ], + + // 每日 1:30 同步“已删除微信群聊”,用于统计与留痕 + 'wechat_chatroom_deleted' => [ + 'command' => 'wechatChatroom:list', + 'schedule' => '30 1 * * *', // 每天1:30 + 'options' => ['--isDel=1'], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'crontab_wechatChatroom_deleted.log', + ], + + // 每日 2:00 统一计算所有微信账号健康分(基础分 + 动态分) + 'wechat_calculate_score' => [ + 'command' => 'wechat:calculate-score', + 'schedule' => '0 2 * * *', // 每天2点 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'calculate_score.log', + ], + + // 每 3 天执行的全量任务 + + // 每 3 天 3:00 全量同步所有在线好友,做一次大规模校准 + 'sync_all_friends' => [ + 'command' => 'sync:allFriends', + 'schedule' => '0 3 */3 * *', // 每3天的3点 + 'options' => [], + 'enabled' => true, + 'max_concurrent' => 1, + 'log_file' => 'all_friends.log', + ], + + // 已禁用的任务(注释掉的任务) + // 'workbench_group_push' => [ + // 'command' => 'workbench:groupPush', + // 'schedule' => '*/2 * * * *', + // 'options' => [], + // 'enabled' => false, + // 'log_file' => 'workbench_groupPush.log', + // ], +]; + From 44edfe7a810fc68d166cf41221aed47596aba683 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 16:25:15 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/MessageController.php | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/Server/application/api/controller/MessageController.php b/Server/application/api/controller/MessageController.php index 6b47ebe4..734f3f7d 100644 --- a/Server/application/api/controller/MessageController.php +++ b/Server/application/api/controller/MessageController.php @@ -61,10 +61,8 @@ class MessageController extends BaseController // 发送请求获取好友列表 $result = requestCurl($this->baseUrl . 'api/WechatFriend/listWechatFriendForMsgPagination', $params, 'POST', $header, 'json'); $response = handleApiResponse($result); - // 获取同步消息标志 $syncMessages = $this->request->param('syncMessages', true); - // 如果需要同步消息,则获取每个好友的消息 if ($syncMessages && !empty($response['results'])) { $from = strtotime($fromTime) * 1000; @@ -90,7 +88,6 @@ class MessageController extends BaseController // 调用获取消息的接口 $messageResult = requestCurl($this->baseUrl . 'api/FriendMessage/searchMessage', $messageParams, 'GET', $header, 'json'); $messageResponse = handleApiResponse($messageResult); - // 保存消息到数据库 if (!empty($messageResponse)) { foreach ($messageResponse as $item) { @@ -353,12 +350,6 @@ class MessageController extends BaseController { // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id']) ->find(); - - // 如果消息已存在,直接返回 - if ($exists) { - return; - } - // 将毫秒时间戳转换为秒级时间戳 $createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null; $deleteTime = !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : null; @@ -387,7 +378,8 @@ class MessageController extends BaseController 'wechatTime' => $wechatTime ]; - //已被删除 + + //已被删除 if ($item['msgType'] == 10000 && strpos($item['content'],'开启了朋友验证') !== false) { Db::table('s2_wechat_friend')->where('id',$item['wechatFriendId'])->update(['isDeleted'=> 1,'deleteTime' => $wechatTime]); }else{ @@ -425,8 +417,19 @@ class MessageController extends BaseController } } } - // 创建新记录 - $res = WechatMessageModel::create($data); + + $id = ''; + if (empty($exists)){ + // 创建新记录 + $res = WechatMessageModel::create($data); + $id= $res['id']; + }else{ + $id = $data['id']; + unset($data['id']); + $res = $exists->save($data); + } + + // 1 文字 3图片 47动态图片 34语言 43视频 42名片 40/20链接 49文件 if (!empty($res) && empty($item['isSend']) && in_array($item['msgType'],[1,3,20,34,40,42,43,47,49])){ @@ -439,13 +442,14 @@ class MessageController extends BaseController 'companyId' => $friend['companyId'], 'trafficPoolId' => $trafficPoolId, 'source' => 0, - 'uniqueId' => $res['id'], + 'uniqueId' => $id, 'sourceData' => json_encode([]), 'remark' => '用户发送了消息', 'createTime' => time(), 'updateTime' => time() ]; - Db::name('user_portrait')->insert($data); + Db::name('user_portrait')->insert($data); + } } } @@ -461,11 +465,7 @@ class MessageController extends BaseController { // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id'])->find(); - - // 如果消息已存在,直接返回 - if ($exists) { - return true; - } + // 处理发送者信息 $sender = $item['sender'] ?? []; @@ -515,7 +515,12 @@ class MessageController extends BaseController // 创建新记录 try { - WechatMessageModel::create($data); + if(empty($exists)){ + WechatMessageModel::create($data); + }else{ + unset($data['id']); + $exists->save($data); + } return true; } catch (\Exception $e) { return false; From 0bc6c3a22a225f380ab67588c330a211eb53ff52 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 16:41:40 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/TaskSchedulerCommand.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php index 06a1dbaf..b91bb06d 100644 --- a/Server/application/command/TaskSchedulerCommand.php +++ b/Server/application/command/TaskSchedulerCommand.php @@ -61,10 +61,23 @@ class TaskSchedulerCommand extends Command $this->maxConcurrent = 1; } - // 加载任务配置 + // 加载任务配置(优先使用框架配置,其次直接引入配置文件,避免加载失败) $this->tasks = Config::get('task_scheduler', []); + + // 如果通过 Config 没有读到,再尝试直接 include 配置文件 if (empty($this->tasks)) { - $output->writeln('错误:未找到任务配置'); + // 以项目根目录为基准查找 config/task_scheduler.php + $configFile = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'task_scheduler.php'; + if (is_file($configFile)) { + $config = include $configFile; + if (is_array($config) && !empty($config)) { + $this->tasks = $config; + } + } + } + + if (empty($this->tasks)) { + $output->writeln('错误:未找到任务配置(task_scheduler),请检查 config/task_scheduler.php 是否存在且返回数组'); return false; } From ff7097f2d961005f75b6ab543042d6dddc6d7fc6 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 16:46:23 +0800 Subject: [PATCH 06/10] 1 --- Server/application/command/TaskSchedulerCommand.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php index b91bb06d..0ad3cc48 100644 --- a/Server/application/command/TaskSchedulerCommand.php +++ b/Server/application/command/TaskSchedulerCommand.php @@ -81,8 +81,8 @@ class TaskSchedulerCommand extends Command return false; } - // 设置日志目录 - $this->logDir = runtime_path() . 'log' . DIRECTORY_SEPARATOR; + // 设置日志目录(注意要使用全局函数,避免命名空间影响) + $this->logDir = \runtime_path() . 'log' . DIRECTORY_SEPARATOR; if (!is_dir($this->logDir)) { mkdir($this->logDir, 0755, true); } @@ -333,7 +333,8 @@ class TaskSchedulerCommand extends Command } // 构建命令 - $thinkPath = root_path() . 'think'; + // 使用项目根目录下的 think 脚本(同命令行 php think) + $thinkPath = \root_path() . 'think'; $command = "php {$thinkPath} {$task['command']}"; if (!empty($task['options'])) { foreach ($task['options'] as $option) { From 2939b63998d03aaabded67d04f48b102b205173b Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 16:47:57 +0800 Subject: [PATCH 07/10] 1 --- .../application/command/TaskSchedulerCommand.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php index 0ad3cc48..9cad5c14 100644 --- a/Server/application/command/TaskSchedulerCommand.php +++ b/Server/application/command/TaskSchedulerCommand.php @@ -81,8 +81,12 @@ class TaskSchedulerCommand extends Command return false; } - // 设置日志目录(注意要使用全局函数,避免命名空间影响) - $this->logDir = \runtime_path() . 'log' . DIRECTORY_SEPARATOR; + // 设置日志目录(ThinkPHP5 中无 runtime_path 辅助函数,直接使用 ROOT_PATH/runtime/log) + if (!defined('ROOT_PATH')) { + // CLI 下正常情况下 ROOT_PATH 已在入口脚本 define,这里兜底一次 + define('ROOT_PATH', dirname(__DIR__, 2)); + } + $this->logDir = ROOT_PATH . DIRECTORY_SEPARATOR . 'runtime' . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR; if (!is_dir($this->logDir)) { mkdir($this->logDir, 0755, true); } @@ -334,7 +338,10 @@ class TaskSchedulerCommand extends Command // 构建命令 // 使用项目根目录下的 think 脚本(同命令行 php think) - $thinkPath = \root_path() . 'think'; + if (!defined('ROOT_PATH')) { + define('ROOT_PATH', dirname(__DIR__, 2)); + } + $thinkPath = ROOT_PATH . DIRECTORY_SEPARATOR . 'think'; $command = "php {$thinkPath} {$task['command']}"; if (!empty($task['options'])) { foreach ($task['options'] as $option) { @@ -360,7 +367,7 @@ class TaskSchedulerCommand extends Command 2 => ['file', $logFile, 'a'], // stderr ]; - $process = @proc_open($command, $descriptorspec, $pipes, root_path()); + $process = @proc_open($command, $descriptorspec, $pipes, ROOT_PATH); if (is_resource($process)) { // 关闭管道 From 2c37314c4fdf49d19660eb6c694677f041e45379 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 17:41:57 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/api/controller/MessageController.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Server/application/api/controller/MessageController.php b/Server/application/api/controller/MessageController.php index 734f3f7d..0f7f6d3d 100644 --- a/Server/application/api/controller/MessageController.php +++ b/Server/application/api/controller/MessageController.php @@ -350,6 +350,12 @@ class MessageController extends BaseController { // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id']) ->find(); + + if ($exists['sendStatus'] == 0){ + return true; + } + + // 将毫秒时间戳转换为秒级时间戳 $createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null; $deleteTime = !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : null; @@ -466,6 +472,9 @@ class MessageController extends BaseController // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id'])->find(); + if ($exists['sendStatus'] == 0){ + return true; + } // 处理发送者信息 $sender = $item['sender'] ?? []; From 354d6c4f6276400e278cf14be896b38135bb82a8 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Mon, 1 Dec 2025 18:09:06 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/api/controller/MessageController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/application/api/controller/MessageController.php b/Server/application/api/controller/MessageController.php index 0f7f6d3d..98b4fe49 100644 --- a/Server/application/api/controller/MessageController.php +++ b/Server/application/api/controller/MessageController.php @@ -351,7 +351,7 @@ class MessageController extends BaseController // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id']) ->find(); - if ($exists['sendStatus'] == 0){ + if (!empty($exists) && $exists['sendStatus'] == 0){ return true; } @@ -472,7 +472,7 @@ class MessageController extends BaseController // 检查消息是否已存在 $exists = WechatMessageModel::where('id', $item['id'])->find(); - if ($exists['sendStatus'] == 0){ + if (!empty($exists) && $exists['sendStatus'] == 0){ return true; } From 5f5b567749ac255355957a6691ef26ba0c1d32ee Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Tue, 2 Dec 2025 10:51:27 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/application/api/controller/MessageController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Server/application/api/controller/MessageController.php b/Server/application/api/controller/MessageController.php index 98b4fe49..87575f31 100644 --- a/Server/application/api/controller/MessageController.php +++ b/Server/application/api/controller/MessageController.php @@ -75,7 +75,7 @@ class MessageController extends BaseController 'keyword' => '', 'msgType' => '', 'accountId' => '', - 'count' => 100, + 'count' => 20, 'messageId' => '', 'olderData' => true, 'wechatAccountId' => $friend['wechatAccountId'], @@ -238,7 +238,7 @@ class MessageController extends BaseController 'keyword' => '', 'msgType' =>'', 'accountId' => '', - 'count' => 100, + 'count' => 20, 'messageId' => '', 'olderData' => true, 'wechatId' => '',