diff options
author | Côme Chilliet <come.chilliet@nextcloud.com> | 2022-06-14 11:27:36 +0300 |
---|---|---|
committer | Côme Chilliet <come.chilliet@nextcloud.com> | 2022-06-14 11:27:36 +0300 |
commit | 02403021310540a848eb2385e979fcc0563ee730 (patch) | |
tree | f1787ada5e662703acc8fd2fd6ecabee5f957499 | |
parent | 70e442d437625996457bb36431fc14f288d4640d (diff) |
Migrate from opis/closure to laravel/serializable-closurefix/replace-opis-closure-by-laravel-fork
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
41 files changed, 1731 insertions, 1915 deletions
diff --git a/composer.json b/composer.json index 06239c4d..c2fc2444 100644 --- a/composer.json +++ b/composer.json @@ -29,11 +29,11 @@ "guzzlehttp/guzzle": "^7.4.0", "icewind/searchdav": "^3.0", "icewind/streams": "v0.7.5", + "laravel/serializable-closure": "^1.2", "mexitek/phpcolors": "^1.0", "microsoft/azure-storage-blob": "^1.5", "nextcloud/lognormalizer": "^1.0", "nikic/php-parser": "^4.2", - "opis/closure": "^3.6", "pear/archive_tar": "^1.4.9", "pear/pear-core-minimal": "^v1.10", "php-ds/php-ds": "^1.3", diff --git a/composer.lock b/composer.lock index 2bc2ff84..7571fb70 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b0f529d60a781dfe43ba422f58e294aa", + "content-hash": "e0d2361c53dfcb8895529aef14967a7a", "packages": [ { "name": "aws/aws-sdk-php", @@ -1765,6 +1765,65 @@ "time": "2020-05-27T16:41:55+00:00" }, { + "name": "laravel/serializable-closure", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-05-16T17:09:47+00:00" + }, + { "name": "league/uri", "version": "6.4.0", "source": { @@ -2249,71 +2308,6 @@ "time": "2021-05-03T19:11:20+00:00" }, { - "name": "opis/closure", - "version": "3.6.2", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/06e2ebd25f2869e54a306dda991f7db58066f7f6", - "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, - "files": [ - "functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.2" - }, - "time": "2021-04-09T13:42:10+00:00" - }, - { "name": "pear/archive_tar", "version": "1.4.14", "source": { diff --git a/composer/InstalledVersions.php b/composer/InstalledVersions.php index 41bc143c..c6b54af7 100644 --- a/composer/InstalledVersions.php +++ b/composer/InstalledVersions.php @@ -28,7 +28,7 @@ class InstalledVersions { /** * @var mixed[]|null - * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null */ private static $installed; @@ -39,7 +39,7 @@ class InstalledVersions /** * @var array[] - * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ private static $installedByVendor = array(); @@ -243,7 +243,7 @@ class InstalledVersions /** * @return array - * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} */ public static function getRootPackage() { @@ -257,7 +257,7 @@ class InstalledVersions * * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} */ public static function getRawData() { @@ -280,7 +280,7 @@ class InstalledVersions * Returns the raw data of all installed.php which are currently loaded for custom implementations * * @return array[] - * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ public static function getAllRawData() { @@ -303,7 +303,7 @@ class InstalledVersions * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data */ public static function reload($data) { @@ -313,7 +313,7 @@ class InstalledVersions /** * @return array[] - * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ private static function getInstalled() { diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index b2a945b9..7bbafbcb 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -1515,6 +1515,19 @@ return array( 'JsonSchema\\Uri\\UriResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', 'JsonSchema\\Uri\\UriRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', 'JsonSchema\\Validator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', + 'Laravel\\SerializableClosure\\Contracts\\Serializable' => $vendorDir . '/laravel/serializable-closure/src/Contracts/Serializable.php', + 'Laravel\\SerializableClosure\\Contracts\\Signer' => $vendorDir . '/laravel/serializable-closure/src/Contracts/Signer.php', + 'Laravel\\SerializableClosure\\Exceptions\\InvalidSignatureException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php', + 'Laravel\\SerializableClosure\\Exceptions\\MissingSecretKeyException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php', + 'Laravel\\SerializableClosure\\Exceptions\\PhpVersionNotSupportedException' => $vendorDir . '/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php', + 'Laravel\\SerializableClosure\\SerializableClosure' => $vendorDir . '/laravel/serializable-closure/src/SerializableClosure.php', + 'Laravel\\SerializableClosure\\Serializers\\Native' => $vendorDir . '/laravel/serializable-closure/src/Serializers/Native.php', + 'Laravel\\SerializableClosure\\Serializers\\Signed' => $vendorDir . '/laravel/serializable-closure/src/Serializers/Signed.php', + 'Laravel\\SerializableClosure\\Signers\\Hmac' => $vendorDir . '/laravel/serializable-closure/src/Signers/Hmac.php', + 'Laravel\\SerializableClosure\\Support\\ClosureScope' => $vendorDir . '/laravel/serializable-closure/src/Support/ClosureScope.php', + 'Laravel\\SerializableClosure\\Support\\ClosureStream' => $vendorDir . '/laravel/serializable-closure/src/Support/ClosureStream.php', + 'Laravel\\SerializableClosure\\Support\\ReflectionClosure' => $vendorDir . '/laravel/serializable-closure/src/Support/ReflectionClosure.php', + 'Laravel\\SerializableClosure\\Support\\SelfReference' => $vendorDir . '/laravel/serializable-closure/src/Support/SelfReference.php', 'League\\Uri\\Contracts\\AuthorityInterface' => $vendorDir . '/league/uri-interfaces/src/Contracts/AuthorityInterface.php', 'League\\Uri\\Contracts\\DataPathInterface' => $vendorDir . '/league/uri-interfaces/src/Contracts/DataPathInterface.php', 'League\\Uri\\Contracts\\DomainHostInterface' => $vendorDir . '/league/uri-interfaces/src/Contracts/DomainHostInterface.php', @@ -1801,16 +1814,6 @@ return array( 'OpenStack\\ObjectStore\\v1\\Params' => $vendorDir . '/php-opencloud/openstack/src/ObjectStore/v1/Params.php', 'OpenStack\\ObjectStore\\v1\\Service' => $vendorDir . '/php-opencloud/openstack/src/ObjectStore/v1/Service.php', 'OpenStack\\OpenStack' => $vendorDir . '/php-opencloud/openstack/src/OpenStack.php', - 'Opis\\Closure\\Analyzer' => $vendorDir . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => $vendorDir . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => $vendorDir . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => $vendorDir . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => $vendorDir . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => $vendorDir . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => $vendorDir . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => $vendorDir . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => $vendorDir . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => $vendorDir . '/opis/closure/src/SerializableClosure.php', 'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php', diff --git a/composer/autoload_files.php b/composer/autoload_files.php index 02b06c86..1ae107d3 100644 --- a/composer/autoload_files.php +++ b/composer/autoload_files.php @@ -119,7 +119,6 @@ return array( 'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php', '8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php', - '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php', '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php index 518c268b..b5e49156 100644 --- a/composer/autoload_psr4.php +++ b/composer/autoload_psr4.php @@ -54,12 +54,12 @@ return array( 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'PackageVersions\\' => array($vendorDir . '/composer/package-versions-deprecated/src/PackageVersions'), - 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'), 'OpenStack\\' => array($vendorDir . '/php-opencloud/openstack/src'), 'Nextcloud\\LogNormalizer\\' => array($vendorDir . '/nextcloud/lognormalizer/src'), 'MicrosoftAzure\\Storage\\Common\\' => array($vendorDir . '/microsoft/azure-storage-common/src/Common'), 'MicrosoftAzure\\Storage\\Blob\\' => array($vendorDir . '/microsoft/azure-storage-blob/src/Blob'), 'League\\Uri\\' => array($vendorDir . '/league/uri/src', $vendorDir . '/league/uri-interfaces/src'), + 'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'), 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'), 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'Icewind\\Streams\\' => array($vendorDir . '/icewind/streams/src'), diff --git a/composer/autoload_static.php b/composer/autoload_static.php index c79fca14..511885fc 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -120,7 +120,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php', '356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php', '8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php', - '538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', '2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php', '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', @@ -207,7 +206,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 ), 'O' => array ( - 'Opis\\Closure\\' => 13, 'OpenStack\\' => 10, ), 'N' => @@ -222,6 +220,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'L' => array ( 'League\\Uri\\' => 11, + 'Laravel\\SerializableClosure\\' => 28, ), 'J' => array ( @@ -477,10 +476,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 array ( 0 => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions', ), - 'Opis\\Closure\\' => - array ( - 0 => __DIR__ . '/..' . '/opis/closure/src', - ), 'OpenStack\\' => array ( 0 => __DIR__ . '/..' . '/php-opencloud/openstack/src', @@ -502,6 +497,10 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 0 => __DIR__ . '/..' . '/league/uri/src', 1 => __DIR__ . '/..' . '/league/uri-interfaces/src', ), + 'Laravel\\SerializableClosure\\' => + array ( + 0 => __DIR__ . '/..' . '/laravel/serializable-closure/src', + ), 'JsonSchema\\' => array ( 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema', @@ -2146,6 +2145,19 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'JsonSchema\\Uri\\UriResolver' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', 'JsonSchema\\Uri\\UriRetriever' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', 'JsonSchema\\Validator' => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', + 'Laravel\\SerializableClosure\\Contracts\\Serializable' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Contracts/Serializable.php', + 'Laravel\\SerializableClosure\\Contracts\\Signer' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Contracts/Signer.php', + 'Laravel\\SerializableClosure\\Exceptions\\InvalidSignatureException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php', + 'Laravel\\SerializableClosure\\Exceptions\\MissingSecretKeyException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php', + 'Laravel\\SerializableClosure\\Exceptions\\PhpVersionNotSupportedException' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php', + 'Laravel\\SerializableClosure\\SerializableClosure' => __DIR__ . '/..' . '/laravel/serializable-closure/src/SerializableClosure.php', + 'Laravel\\SerializableClosure\\Serializers\\Native' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Serializers/Native.php', + 'Laravel\\SerializableClosure\\Serializers\\Signed' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Serializers/Signed.php', + 'Laravel\\SerializableClosure\\Signers\\Hmac' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Signers/Hmac.php', + 'Laravel\\SerializableClosure\\Support\\ClosureScope' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Support/ClosureScope.php', + 'Laravel\\SerializableClosure\\Support\\ClosureStream' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Support/ClosureStream.php', + 'Laravel\\SerializableClosure\\Support\\ReflectionClosure' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Support/ReflectionClosure.php', + 'Laravel\\SerializableClosure\\Support\\SelfReference' => __DIR__ . '/..' . '/laravel/serializable-closure/src/Support/SelfReference.php', 'League\\Uri\\Contracts\\AuthorityInterface' => __DIR__ . '/..' . '/league/uri-interfaces/src/Contracts/AuthorityInterface.php', 'League\\Uri\\Contracts\\DataPathInterface' => __DIR__ . '/..' . '/league/uri-interfaces/src/Contracts/DataPathInterface.php', 'League\\Uri\\Contracts\\DomainHostInterface' => __DIR__ . '/..' . '/league/uri-interfaces/src/Contracts/DomainHostInterface.php', @@ -2432,16 +2444,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'OpenStack\\ObjectStore\\v1\\Params' => __DIR__ . '/..' . '/php-opencloud/openstack/src/ObjectStore/v1/Params.php', 'OpenStack\\ObjectStore\\v1\\Service' => __DIR__ . '/..' . '/php-opencloud/openstack/src/ObjectStore/v1/Service.php', 'OpenStack\\OpenStack' => __DIR__ . '/..' . '/php-opencloud/openstack/src/OpenStack.php', - 'Opis\\Closure\\Analyzer' => __DIR__ . '/..' . '/opis/closure/src/Analyzer.php', - 'Opis\\Closure\\ClosureContext' => __DIR__ . '/..' . '/opis/closure/src/ClosureContext.php', - 'Opis\\Closure\\ClosureScope' => __DIR__ . '/..' . '/opis/closure/src/ClosureScope.php', - 'Opis\\Closure\\ClosureStream' => __DIR__ . '/..' . '/opis/closure/src/ClosureStream.php', - 'Opis\\Closure\\ISecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/ISecurityProvider.php', - 'Opis\\Closure\\ReflectionClosure' => __DIR__ . '/..' . '/opis/closure/src/ReflectionClosure.php', - 'Opis\\Closure\\SecurityException' => __DIR__ . '/..' . '/opis/closure/src/SecurityException.php', - 'Opis\\Closure\\SecurityProvider' => __DIR__ . '/..' . '/opis/closure/src/SecurityProvider.php', - 'Opis\\Closure\\SelfReference' => __DIR__ . '/..' . '/opis/closure/src/SelfReference.php', - 'Opis\\Closure\\SerializableClosure' => __DIR__ . '/..' . '/opis/closure/src/SerializableClosure.php', 'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php', diff --git a/composer/installed.json b/composer/installed.json index 8678072d..4b0b87dc 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -1834,6 +1834,68 @@ "install-path": "../justinrainbow/json-schema" }, { + "name": "laravel/serializable-closure", + "version": "v1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "time": "2022-05-16T17:09:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "install-path": "../laravel/serializable-closure" + }, + { "name": "league/uri", "version": "6.4.0", "version_normalized": "6.4.0.0", @@ -2342,74 +2404,6 @@ "install-path": "../nikic/php-parser" }, { - "name": "opis/closure", - "version": "3.6.2", - "version_normalized": "3.6.2.0", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/06e2ebd25f2869e54a306dda991f7db58066f7f6", - "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "time": "2021-04-09T13:42:10+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, - "files": [ - "functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.2" - }, - "install-path": "../opis/closure" - }, - { "name": "pear/archive_tar", "version": "1.4.14", "version_normalized": "1.4.14.0", @@ -6428,6 +6422,6 @@ "install-path": "../web-auth/webauthn-lib" } ], - "dev": true, + "dev": false, "dev-package-names": [] } diff --git a/composer/installed.php b/composer/installed.php index fc14425a..0e9276d4 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -1,319 +1,328 @@ <?php return array( 'root' => array( + 'name' => 'nextcloud/3rdparty', 'pretty_version' => 'dev-master', 'version' => 'dev-master', + 'reference' => '70e442d437625996457bb36431fc14f288d4640d', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), - 'reference' => '59f4851dc2729f449d4a9e6fb211bebe3818cb6f', - 'name' => 'nextcloud/3rdparty', - 'dev' => true, + 'dev' => false, ), 'versions' => array( 'aws/aws-sdk-php' => array( 'pretty_version' => '3.184.6', 'version' => '3.184.6.0', + 'reference' => '0b7187c96ced465d400ad9427157e05ddee68edc', 'type' => 'library', 'install_path' => __DIR__ . '/../aws/aws-sdk-php', 'aliases' => array(), - 'reference' => '0b7187c96ced465d400ad9427157e05ddee68edc', 'dev_requirement' => false, ), 'bantu/ini-get-wrapper' => array( 'pretty_version' => 'v1.0.1', 'version' => '1.0.1.0', + 'reference' => '4770c7feab370c62e23db4f31c112b7c6d90aee2', 'type' => 'library', 'install_path' => __DIR__ . '/../bantu/ini-get-wrapper', 'aliases' => array(), - 'reference' => '4770c7feab370c62e23db4f31c112b7c6d90aee2', 'dev_requirement' => false, ), 'beberlei/assert' => array( 'pretty_version' => 'v3.3.1', 'version' => '3.3.1.0', + 'reference' => '5e721d7e937ca3ba2cdec1e1adf195f9e5188372', 'type' => 'library', 'install_path' => __DIR__ . '/../beberlei/assert', 'aliases' => array(), - 'reference' => '5e721d7e937ca3ba2cdec1e1adf195f9e5188372', 'dev_requirement' => false, ), 'brick/math' => array( 'pretty_version' => '0.9.2', 'version' => '0.9.2.0', + 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0', 'type' => 'library', 'install_path' => __DIR__ . '/../brick/math', 'aliases' => array(), - 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0', 'dev_requirement' => false, ), 'christophwurst/id3parser' => array( 'pretty_version' => 'v0.1.4', 'version' => '0.1.4.0', + 'reference' => '050c9d81ea89b0cf53e23a27efc4e1840f9ab260', 'type' => 'library', 'install_path' => __DIR__ . '/../christophwurst/id3parser', 'aliases' => array(), - 'reference' => '050c9d81ea89b0cf53e23a27efc4e1840f9ab260', 'dev_requirement' => false, ), 'composer/package-versions-deprecated' => array( 'pretty_version' => '1.11.99.4', 'version' => '1.11.99.4', + 'reference' => 'b174585d1fe49ceed21928a945138948cb394600', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/./package-versions-deprecated', 'aliases' => array(), - 'reference' => 'b174585d1fe49ceed21928a945138948cb394600', 'dev_requirement' => false, ), 'cweagans/composer-patches' => array( 'pretty_version' => '1.7.1', 'version' => '1.7.1.0', + 'reference' => '9888dcc74993c030b75f3dd548bb5e20cdbd740c', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../cweagans/composer-patches', 'aliases' => array(), - 'reference' => '9888dcc74993c030b75f3dd548bb5e20cdbd740c', 'dev_requirement' => false, ), 'deepdiver/zipstreamer' => array( 'pretty_version' => '2.0.0', 'version' => '2.0.0.0', + 'reference' => 'b8c59647ff34fb97e8937aefb2a65de2bc4b4755', 'type' => 'library', 'install_path' => __DIR__ . '/../deepdiver/zipstreamer', 'aliases' => array(), - 'reference' => 'b8c59647ff34fb97e8937aefb2a65de2bc4b4755', 'dev_requirement' => false, ), 'deepdiver1975/tarstreamer' => array( 'pretty_version' => '2.0.0', 'version' => '2.0.0.0', + 'reference' => 'ad48505d1ab54a8e94e6b1cc5297bbed72e956de', 'type' => 'library', 'install_path' => __DIR__ . '/../deepdiver1975/tarstreamer', 'aliases' => array(), - 'reference' => 'ad48505d1ab54a8e94e6b1cc5297bbed72e956de', 'dev_requirement' => false, ), 'doctrine/cache' => array( 'pretty_version' => '2.1.1', 'version' => '2.1.1.0', + 'reference' => '331b4d5dbaeab3827976273e9356b3b453c300ce', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/cache', 'aliases' => array(), - 'reference' => '331b4d5dbaeab3827976273e9356b3b453c300ce', 'dev_requirement' => false, ), 'doctrine/dbal' => array( 'pretty_version' => '3.1.4', 'version' => '3.1.4.0', + 'reference' => '821b4f01a36ce63ed36c090ea74767b72db367e9', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/dbal', 'aliases' => array(), - 'reference' => '821b4f01a36ce63ed36c090ea74767b72db367e9', 'dev_requirement' => false, ), 'doctrine/deprecations' => array( 'pretty_version' => 'v0.5.3', 'version' => '0.5.3.0', + 'reference' => '9504165960a1f83cc1480e2be1dd0a0478561314', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/deprecations', 'aliases' => array(), - 'reference' => '9504165960a1f83cc1480e2be1dd0a0478561314', 'dev_requirement' => false, ), 'doctrine/event-manager' => array( 'pretty_version' => '1.1.1', 'version' => '1.1.1.0', + 'reference' => '41370af6a30faa9dc0368c4a6814d596e81aba7f', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/event-manager', 'aliases' => array(), - 'reference' => '41370af6a30faa9dc0368c4a6814d596e81aba7f', 'dev_requirement' => false, ), 'doctrine/lexer' => array( 'pretty_version' => '1.2.1', 'version' => '1.2.1.0', + 'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/lexer', 'aliases' => array(), - 'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042', 'dev_requirement' => false, ), 'egulias/email-validator' => array( 'pretty_version' => '3.1.1', 'version' => '3.1.1.0', + 'reference' => 'c81f18a3efb941d8c4d2e025f6183b5c6d697307', 'type' => 'library', 'install_path' => __DIR__ . '/../egulias/email-validator', 'aliases' => array(), - 'reference' => 'c81f18a3efb941d8c4d2e025f6183b5c6d697307', 'dev_requirement' => false, ), 'fgrosse/phpasn1' => array( 'pretty_version' => 'v2.3.0', 'version' => '2.3.0.0', + 'reference' => '20299033c35f4300eb656e7e8e88cf52d1d6694e', 'type' => 'library', 'install_path' => __DIR__ . '/../fgrosse/phpasn1', 'aliases' => array(), - 'reference' => '20299033c35f4300eb656e7e8e88cf52d1d6694e', 'dev_requirement' => false, ), 'giggsey/libphonenumber-for-php' => array( 'pretty_version' => '8.12.38', 'version' => '8.12.38.0', + 'reference' => '0a6293c57de9256f4bd0d673280fbfbfd1e47533', 'type' => 'library', 'install_path' => __DIR__ . '/../giggsey/libphonenumber-for-php', 'aliases' => array(), - 'reference' => '0a6293c57de9256f4bd0d673280fbfbfd1e47533', 'dev_requirement' => false, ), 'giggsey/locale' => array( 'pretty_version' => '2.1', 'version' => '2.1.0.0', + 'reference' => '8d324583b5899e6280a875c43bf1fc9658bc6962', 'type' => 'library', 'install_path' => __DIR__ . '/../giggsey/locale', 'aliases' => array(), - 'reference' => '8d324583b5899e6280a875c43bf1fc9658bc6962', 'dev_requirement' => false, ), 'guzzlehttp/guzzle' => array( 'pretty_version' => '7.4.0', 'version' => '7.4.0.0', + 'reference' => '868b3571a039f0ebc11ac8f344f4080babe2cb94', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), - 'reference' => '868b3571a039f0ebc11ac8f344f4080babe2cb94', 'dev_requirement' => false, ), 'guzzlehttp/promises' => array( 'pretty_version' => '1.5.1', 'version' => '1.5.1.0', + 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), - 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da', 'dev_requirement' => false, ), 'guzzlehttp/psr7' => array( 'pretty_version' => '1.8.5', 'version' => '1.8.5.0', + 'reference' => '337e3ad8e5716c15f9657bd214d16cc5e69df268', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), - 'reference' => '337e3ad8e5716c15f9657bd214d16cc5e69df268', 'dev_requirement' => false, ), 'guzzlehttp/uri-template' => array( 'pretty_version' => 'v0.2.0', 'version' => '0.2.0.0', + 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/uri-template', 'aliases' => array(), - 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce', 'dev_requirement' => false, ), 'icewind/searchdav' => array( 'pretty_version' => 'v3.0.1', 'version' => '3.0.1.0', + 'reference' => '52c8cfc21bd69271f224671c4924d260b0a8d4fb', 'type' => 'library', 'install_path' => __DIR__ . '/../icewind/searchdav', 'aliases' => array(), - 'reference' => '52c8cfc21bd69271f224671c4924d260b0a8d4fb', 'dev_requirement' => false, ), 'icewind/streams' => array( 'pretty_version' => 'v0.7.5', 'version' => '0.7.5.0', + 'reference' => '0c6aae16ebdadb257f0bd089c1e1e4cf5e20ddc2', 'type' => 'library', 'install_path' => __DIR__ . '/../icewind/streams', 'aliases' => array(), - 'reference' => '0c6aae16ebdadb257f0bd089c1e1e4cf5e20ddc2', 'dev_requirement' => false, ), 'justinrainbow/json-schema' => array( 'pretty_version' => '5.2.10', 'version' => '5.2.10.0', + 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b', 'type' => 'library', 'install_path' => __DIR__ . '/../justinrainbow/json-schema', 'aliases' => array(), - 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b', + 'dev_requirement' => false, + ), + 'laravel/serializable-closure' => array( + 'pretty_version' => 'v1.2.0', + 'version' => '1.2.0.0', + 'reference' => '09f0e9fb61829f628205b7c94906c28740ff9540', + 'type' => 'library', + 'install_path' => __DIR__ . '/../laravel/serializable-closure', + 'aliases' => array(), 'dev_requirement' => false, ), 'league/uri' => array( 'pretty_version' => '6.4.0', 'version' => '6.4.0.0', + 'reference' => '09da64118eaf4c5d52f9923a1e6a5be1da52fd9a', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri', 'aliases' => array(), - 'reference' => '09da64118eaf4c5d52f9923a1e6a5be1da52fd9a', 'dev_requirement' => false, ), 'league/uri-interfaces' => array( 'pretty_version' => '2.2.0', 'version' => '2.2.0.0', + 'reference' => '667f150e589d65d79c89ffe662e426704f84224f', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri-interfaces', 'aliases' => array(), - 'reference' => '667f150e589d65d79c89ffe662e426704f84224f', 'dev_requirement' => false, ), 'mexitek/phpcolors' => array( 'pretty_version' => 'v1.0.4', 'version' => '1.0.4.0', + 'reference' => '4043974240ca7dc3c2bec3c158588148b605b206', 'type' => 'library', 'install_path' => __DIR__ . '/../mexitek/phpcolors', 'aliases' => array(), - 'reference' => '4043974240ca7dc3c2bec3c158588148b605b206', 'dev_requirement' => false, ), 'microsoft/azure-storage-blob' => array( 'pretty_version' => '1.5.2', 'version' => '1.5.2.0', + 'reference' => '2475330963372d519387cb8135d6a9cfd42272da', 'type' => 'library', 'install_path' => __DIR__ . '/../microsoft/azure-storage-blob', 'aliases' => array(), - 'reference' => '2475330963372d519387cb8135d6a9cfd42272da', 'dev_requirement' => false, ), 'microsoft/azure-storage-common' => array( 'pretty_version' => '1.5.1', 'version' => '1.5.1.0', + 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d', 'type' => 'library', 'install_path' => __DIR__ . '/../microsoft/azure-storage-common', 'aliases' => array(), - 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d', 'dev_requirement' => false, ), 'mtdowling/jmespath.php' => array( 'pretty_version' => '2.6.1', 'version' => '2.6.1.0', + 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb', 'type' => 'library', 'install_path' => __DIR__ . '/../mtdowling/jmespath.php', 'aliases' => array(), - 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb', 'dev_requirement' => false, ), 'nextcloud/3rdparty' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', + 'reference' => '70e442d437625996457bb36431fc14f288d4640d', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), - 'reference' => '59f4851dc2729f449d4a9e6fb211bebe3818cb6f', 'dev_requirement' => false, ), 'nextcloud/lognormalizer' => array( 'pretty_version' => 'v1.0.0', 'version' => '1.0.0.0', + 'reference' => '87445d69225c247aaff64643b1fc83c6d6df741f', 'type' => 'library', 'install_path' => __DIR__ . '/../nextcloud/lognormalizer', 'aliases' => array(), - 'reference' => '87445d69225c247aaff64643b1fc83c6d6df741f', 'dev_requirement' => false, ), 'nikic/php-parser' => array( 'pretty_version' => 'v4.10.5', 'version' => '4.10.5.0', + 'reference' => '4432ba399e47c66624bc73c8c0f811e5c109576f', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), - 'reference' => '4432ba399e47c66624bc73c8c0f811e5c109576f', 'dev_requirement' => false, ), 'ocramius/package-versions' => array( @@ -322,58 +331,49 @@ 0 => '1.11.99', ), ), - 'opis/closure' => array( - 'pretty_version' => '3.6.2', - 'version' => '3.6.2.0', - 'type' => 'library', - 'install_path' => __DIR__ . '/../opis/closure', - 'aliases' => array(), - 'reference' => '06e2ebd25f2869e54a306dda991f7db58066f7f6', - 'dev_requirement' => false, - ), 'pear/archive_tar' => array( 'pretty_version' => '1.4.14', 'version' => '1.4.14.0', + 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/archive_tar', 'aliases' => array(), - 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa', 'dev_requirement' => false, ), 'pear/console_getopt' => array( 'pretty_version' => 'v1.4.3', 'version' => '1.4.3.0', + 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/console_getopt', 'aliases' => array(), - 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0', 'dev_requirement' => false, ), 'pear/pear-core-minimal' => array( 'pretty_version' => 'v1.10.10', 'version' => '1.10.10.0', + 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/pear-core-minimal', 'aliases' => array(), - 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7', 'dev_requirement' => false, ), 'pear/pear_exception' => array( 'pretty_version' => 'v1.0.2', 'version' => '1.0.2.0', + 'reference' => 'b14fbe2ddb0b9f94f5b24cf08783d599f776fff0', 'type' => 'class', 'install_path' => __DIR__ . '/../pear/pear_exception', 'aliases' => array(), - 'reference' => 'b14fbe2ddb0b9f94f5b24cf08783d599f776fff0', 'dev_requirement' => false, ), 'php-ds/php-ds' => array( 'pretty_version' => 'v1.3.0', 'version' => '1.3.0.0', + 'reference' => 'b98396862fb8a13cbdbbaf4d18be28ee5c01ed3c', 'type' => 'library', 'install_path' => __DIR__ . '/../php-ds/php-ds', 'aliases' => array(), - 'reference' => 'b98396862fb8a13cbdbbaf4d18be28ee5c01ed3c', 'dev_requirement' => false, ), 'php-http/async-client-implementation' => array( @@ -391,73 +391,73 @@ 'php-http/guzzle7-adapter' => array( 'pretty_version' => '1.0.0', 'version' => '1.0.0.0', + 'reference' => 'fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01', 'type' => 'library', 'install_path' => __DIR__ . '/../php-http/guzzle7-adapter', 'aliases' => array(), - 'reference' => 'fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01', 'dev_requirement' => false, ), 'php-http/httplug' => array( 'pretty_version' => '2.2.0', 'version' => '2.2.0.0', + 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', 'type' => 'library', 'install_path' => __DIR__ . '/../php-http/httplug', 'aliases' => array(), - 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', 'dev_requirement' => false, ), 'php-http/promise' => array( 'pretty_version' => '1.1.0', 'version' => '1.1.0.0', + 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', 'type' => 'library', 'install_path' => __DIR__ . '/../php-http/promise', 'aliases' => array(), - 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', 'dev_requirement' => false, ), 'php-opencloud/openstack' => array( 'pretty_version' => 'v3.1.0', 'version' => '3.1.0.0', + 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e', 'type' => 'library', 'install_path' => __DIR__ . '/../php-opencloud/openstack', 'aliases' => array(), - 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e', 'dev_requirement' => false, ), 'phpseclib/phpseclib' => array( 'pretty_version' => '2.0.32', 'version' => '2.0.32.0', + 'reference' => 'f5c4c19880d45d0be3e7d24ae8ac434844a898cd', 'type' => 'library', 'install_path' => __DIR__ . '/../phpseclib/phpseclib', 'aliases' => array(), - 'reference' => 'f5c4c19880d45d0be3e7d24ae8ac434844a898cd', 'dev_requirement' => false, ), 'pimple/pimple' => array( 'pretty_version' => 'v3.5.0', 'version' => '3.5.0.0', + 'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed', 'type' => 'library', 'install_path' => __DIR__ . '/../pimple/pimple', 'aliases' => array(), - 'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed', 'dev_requirement' => false, ), 'psr/container' => array( 'pretty_version' => '1.1.1', 'version' => '1.1.1.0', + 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), - 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', 'dev_requirement' => false, ), 'psr/event-dispatcher' => array( 'pretty_version' => '1.0.0', 'version' => '1.0.0.0', + 'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/event-dispatcher', 'aliases' => array(), - 'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0', 'dev_requirement' => false, ), 'psr/event-dispatcher-implementation' => array( @@ -469,10 +469,10 @@ 'psr/http-client' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', + 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(), - 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621', 'dev_requirement' => false, ), 'psr/http-client-implementation' => array( @@ -484,19 +484,19 @@ 'psr/http-factory' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', + 'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), - 'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be', 'dev_requirement' => false, ), 'psr/http-message' => array( 'pretty_version' => '1.0.1', 'version' => '1.0.1.0', + 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', 'dev_requirement' => false, ), 'psr/http-message-implementation' => array( @@ -508,10 +508,10 @@ 'psr/log' => array( 'pretty_version' => '1.1.4', 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), - 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'dev_requirement' => false, ), 'psr/log-implementation' => array( @@ -535,37 +535,37 @@ 'punic/punic' => array( 'pretty_version' => '1.6.5', 'version' => '1.6.5.0', + 'reference' => '7bc85ce1137cf52db4d2a6298256a4c4a24da99a', 'type' => 'library', 'install_path' => __DIR__ . '/../punic/punic', 'aliases' => array(), - 'reference' => '7bc85ce1137cf52db4d2a6298256a4c4a24da99a', 'dev_requirement' => false, ), 'ralouphie/getallheaders' => array( 'pretty_version' => '3.0.3', 'version' => '3.0.3.0', + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'dev_requirement' => false, ), 'ramsey/collection' => array( 'pretty_version' => '1.1.3', 'version' => '1.1.3.0', + 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/collection', 'aliases' => array(), - 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1', 'dev_requirement' => false, ), 'ramsey/uuid' => array( 'pretty_version' => '4.1.1', 'version' => '4.1.1.0', + 'reference' => 'cd4032040a750077205918c86049aa0f43d22947', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/uuid', 'aliases' => array(), - 'reference' => 'cd4032040a750077205918c86049aa0f43d22947', 'dev_requirement' => false, ), 'rhumsaa/uuid' => array( @@ -583,136 +583,136 @@ 'sabre/dav' => array( 'pretty_version' => '4.2.1', 'version' => '4.2.1.0', + 'reference' => '5e651f9ddc2b05745f5b28cd697c8e8c6a0b6146', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/dav', 'aliases' => array(), - 'reference' => '5e651f9ddc2b05745f5b28cd697c8e8c6a0b6146', 'dev_requirement' => false, ), 'sabre/event' => array( 'pretty_version' => '5.1.4', 'version' => '5.1.4.0', + 'reference' => 'd7da22897125d34d7eddf7977758191c06a74497', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/event', 'aliases' => array(), - 'reference' => 'd7da22897125d34d7eddf7977758191c06a74497', 'dev_requirement' => false, ), 'sabre/http' => array( 'pretty_version' => '5.1.3', 'version' => '5.1.3.0', + 'reference' => '315f592adfcba8aeb73c2fd64285205747acbbd7', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/http', 'aliases' => array(), - 'reference' => '315f592adfcba8aeb73c2fd64285205747acbbd7', 'dev_requirement' => false, ), 'sabre/uri' => array( 'pretty_version' => '2.2.2', 'version' => '2.2.2.0', + 'reference' => '7cb0f489578afad5006e85cd60f18ff33f2d440d', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/uri', 'aliases' => array(), - 'reference' => '7cb0f489578afad5006e85cd60f18ff33f2d440d', 'dev_requirement' => false, ), 'sabre/vobject' => array( 'pretty_version' => '4.4.1', 'version' => '4.4.1.0', + 'reference' => '06feff370141fd3118609f808e86d9315864bf14', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/vobject', 'aliases' => array(), - 'reference' => '06feff370141fd3118609f808e86d9315864bf14', 'dev_requirement' => false, ), 'sabre/xml' => array( 'pretty_version' => '2.2.5', 'version' => '2.2.5.0', + 'reference' => 'a6af111850e7536d200d9637c34885cd3c77a86c', 'type' => 'library', 'install_path' => __DIR__ . '/../sabre/xml', 'aliases' => array(), - 'reference' => 'a6af111850e7536d200d9637c34885cd3c77a86c', 'dev_requirement' => false, ), 'scssphp/scssphp' => array( 'pretty_version' => 'v1.8.1', 'version' => '1.8.1.0', + 'reference' => '5e37759a63caf54392a4b709358a39ac7425a69f', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/scssphp', 'aliases' => array(), - 'reference' => '5e37759a63caf54392a4b709358a39ac7425a69f', 'dev_requirement' => false, ), 'spomky-labs/base64url' => array( 'pretty_version' => 'v2.0.4', 'version' => '2.0.4.0', + 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d', 'type' => 'library', 'install_path' => __DIR__ . '/../spomky-labs/base64url', 'aliases' => array(), - 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d', 'dev_requirement' => false, ), 'spomky-labs/cbor-php' => array( 'pretty_version' => 'v2.0.1', 'version' => '2.0.1.0', + 'reference' => '9776578000be884cd7864eeb7c37a4ac92d8c995', 'type' => 'library', 'install_path' => __DIR__ . '/../spomky-labs/cbor-php', 'aliases' => array(), - 'reference' => '9776578000be884cd7864eeb7c37a4ac92d8c995', 'dev_requirement' => false, ), 'stecman/symfony-console-completion' => array( 'pretty_version' => '0.11.0', 'version' => '0.11.0.0', + 'reference' => 'a9502dab59405e275a9f264536c4e1cb61fc3518', 'type' => 'library', 'install_path' => __DIR__ . '/../stecman/symfony-console-completion', 'aliases' => array(), - 'reference' => 'a9502dab59405e275a9f264536c4e1cb61fc3518', 'dev_requirement' => false, ), 'swiftmailer/swiftmailer' => array( 'pretty_version' => 'v6.2.7', 'version' => '6.2.7.0', + 'reference' => '15f7faf8508e04471f666633addacf54c0ab5933', 'type' => 'library', 'install_path' => __DIR__ . '/../swiftmailer/swiftmailer', 'aliases' => array(), - 'reference' => '15f7faf8508e04471f666633addacf54c0ab5933', 'dev_requirement' => false, ), 'symfony/console' => array( 'pretty_version' => 'v4.4.30', 'version' => '4.4.30.0', + 'reference' => 'a3f7189a0665ee33b50e9e228c46f50f5acbed22', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), - 'reference' => 'a3f7189a0665ee33b50e9e228c46f50f5acbed22', 'dev_requirement' => false, ), 'symfony/deprecation-contracts' => array( 'pretty_version' => 'v2.5.0', 'version' => '2.5.0.0', + 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), - 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8', 'dev_requirement' => false, ), 'symfony/event-dispatcher' => array( 'pretty_version' => 'v4.4.30', 'version' => '4.4.30.0', + 'reference' => '2fe81680070043c4c80e7cedceb797e34f377bac', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'aliases' => array(), - 'reference' => '2fe81680070043c4c80e7cedceb797e34f377bac', 'dev_requirement' => false, ), 'symfony/event-dispatcher-contracts' => array( 'pretty_version' => 'v1.1.9', 'version' => '1.1.9.0', + 'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts', 'aliases' => array(), - 'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7', 'dev_requirement' => false, ), 'symfony/event-dispatcher-implementation' => array( @@ -724,127 +724,127 @@ 'symfony/polyfill-ctype' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), - 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce', 'dev_requirement' => false, ), 'symfony/polyfill-iconv' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-iconv', 'aliases' => array(), - 'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933', 'dev_requirement' => false, ), 'symfony/polyfill-intl-grapheme' => array( 'pretty_version' => 'v1.23.1', 'version' => '1.23.1.0', + 'reference' => '16880ba9c5ebe3642d1995ab866db29270b36535', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'aliases' => array(), - 'reference' => '16880ba9c5ebe3642d1995ab866db29270b36535', 'dev_requirement' => false, ), 'symfony/polyfill-intl-idn' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn', 'aliases' => array(), - 'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65', 'dev_requirement' => false, ), 'symfony/polyfill-intl-normalizer' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), - 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8', 'dev_requirement' => false, ), 'symfony/polyfill-mbstring' => array( 'pretty_version' => 'v1.23.1', 'version' => '1.23.1.0', + 'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), - 'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6', 'dev_requirement' => false, ), 'symfony/polyfill-php72' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php72', 'aliases' => array(), - 'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976', 'dev_requirement' => false, ), 'symfony/polyfill-php73' => array( 'pretty_version' => 'v1.23.0', 'version' => '1.23.0.0', + 'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php73', 'aliases' => array(), - 'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010', 'dev_requirement' => false, ), 'symfony/polyfill-php80' => array( 'pretty_version' => 'v1.23.1', 'version' => '1.23.1.0', + 'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), - 'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be', 'dev_requirement' => false, ), 'symfony/process' => array( 'pretty_version' => 'v4.4.30', 'version' => '4.4.30.0', + 'reference' => '13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), - 'reference' => '13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d', 'dev_requirement' => false, ), 'symfony/routing' => array( 'pretty_version' => 'v4.4.30', 'version' => '4.4.30.0', + 'reference' => '9ddf033927ad9f30ba2bfd167a7b342cafa13e8e', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/routing', 'aliases' => array(), - 'reference' => '9ddf033927ad9f30ba2bfd167a7b342cafa13e8e', 'dev_requirement' => false, ), 'symfony/service-contracts' => array( 'pretty_version' => 'v2.4.0', 'version' => '2.4.0.0', + 'reference' => 'f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), - 'reference' => 'f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb', 'dev_requirement' => false, ), 'symfony/translation' => array( 'pretty_version' => 'v4.4.41', 'version' => '4.4.41.0', + 'reference' => 'dcb67eae126e74507e0b4f0b9ac6ef35b37c3331', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/translation', 'aliases' => array(), - 'reference' => 'dcb67eae126e74507e0b4f0b9ac6ef35b37c3331', 'dev_requirement' => false, ), 'symfony/translation-contracts' => array( 'pretty_version' => 'v2.4.0', 'version' => '2.4.0.0', + 'reference' => '95c812666f3e91db75385749fe219c5e494c7f95', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/translation-contracts', 'aliases' => array(), - 'reference' => '95c812666f3e91db75385749fe219c5e494c7f95', 'dev_requirement' => false, ), 'symfony/translation-implementation' => array( @@ -856,37 +856,37 @@ 'thecodingmachine/safe' => array( 'pretty_version' => 'v1.3.3', 'version' => '1.3.3.0', + 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc', 'type' => 'library', 'install_path' => __DIR__ . '/../thecodingmachine/safe', 'aliases' => array(), - 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc', 'dev_requirement' => false, ), 'web-auth/cose-lib' => array( 'pretty_version' => 'v3.3.9', 'version' => '3.3.9.0', + 'reference' => 'ed172d2dc1a6b87b5c644c07c118cd30c1b3819b', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/cose-lib', 'aliases' => array(), - 'reference' => 'ed172d2dc1a6b87b5c644c07c118cd30c1b3819b', 'dev_requirement' => false, ), 'web-auth/metadata-service' => array( 'pretty_version' => 'v3.3.9', 'version' => '3.3.9.0', + 'reference' => '8488d3a832a38cc81c670fce05de1e515c6e64b1', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/metadata-service', 'aliases' => array(), - 'reference' => '8488d3a832a38cc81c670fce05de1e515c6e64b1', 'dev_requirement' => false, ), 'web-auth/webauthn-lib' => array( 'pretty_version' => 'v3.3.9', 'version' => '3.3.9.0', + 'reference' => '04b98ee3d39cb79dad68a7c15c297c085bf66bfe', 'type' => 'library', 'install_path' => __DIR__ . '/../web-auth/webauthn-lib', 'aliases' => array(), - 'reference' => '04b98ee3d39cb79dad68a7c15c297c085bf66bfe', 'dev_requirement' => false, ), ), diff --git a/laravel/serializable-closure/LICENSE.md b/laravel/serializable-closure/LICENSE.md new file mode 100644 index 00000000..79810c84 --- /dev/null +++ b/laravel/serializable-closure/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Taylor Otwell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/laravel/serializable-closure/README.md b/laravel/serializable-closure/README.md new file mode 100644 index 00000000..a9c25135 --- /dev/null +++ b/laravel/serializable-closure/README.md @@ -0,0 +1,71 @@ +# Serializable Closure + +<a href="https://github.com/laravel/serializable-closure/actions"> + <img src="https://github.com/laravel/serializable-closure/workflows/tests/badge.svg" alt="Build Status"> +</a> +<a href="https://packagist.org/packages/laravel/serializable-closure"> + <img src="https://img.shields.io/packagist/dt/laravel/serializable-closure" alt="Total Downloads"> +</a> +<a href="https://packagist.org/packages/laravel/serializable-closure"> + <img src="https://img.shields.io/packagist/v/laravel/serializable-closure" alt="Latest Stable Version"> +</a> +<a href="https://packagist.org/packages/laravel/serializable-closure"> + <img src="https://img.shields.io/packagist/l/laravel/serializable-closure" alt="License"> +</a> + +## Introduction + +> This project is a fork of the excellent [opis/closure: 3.x](https://github.com/opis/closure) package. At Laravel, we decided to fork this package as the upcoming version [4.x](https://github.com/opis/closure) is a complete rewrite on top of the [FFI extension](https://www.php.net/manual/en/book.ffi.php). As Laravel is a web framework, and FFI is not enabled by default in web requests, this fork allows us to keep using the `3.x` series while adding support for new PHP versions. + +Laravel Serializable Closure provides an easy and secure way to **serialize closures in PHP**. + +## Official Documentation + +### Installation + +> **Requires [PHP 7.4+](https://php.net/releases/)** + +First, install Laravel Serializable Closure via the [Composer](https://getcomposer.org/) package manager: + +```bash +composer require laravel/serializable-closure +``` + +### Usage + +You may serialize a closure this way: + +```php +use Laravel\SerializableClosure\SerializableClosure; + +$closure = fn () => 'james'; + +// Recommended +SerializableClosure::setSecretKey('secret'); + +$serialized = serialize(new SerializableClosure($closure)); +$closure = unserialize($serialized)->getClosure(); + +echo $closure(); // james; +``` + +### Caveats + +1. Creating **anonymous classes** within closures is not supported. +2. Using attributes within closures is not supported. + +## Contributing + +Thank you for considering contributing to Serializable Closure! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). + +## Code of Conduct + +In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). + +## Security Vulnerabilities + +Please review [our security policy](https://github.com/laravel/serializable-closure/security/policy) on how to report security vulnerabilities. + +## License + +Serializable Closure is open-sourced software licensed under the [MIT license](LICENSE.md). diff --git a/laravel/serializable-closure/composer.json b/laravel/serializable-closure/composer.json new file mode 100644 index 00000000..5e8fbbc8 --- /dev/null +++ b/laravel/serializable-closure/composer.json @@ -0,0 +1,51 @@ +{ + "name": "laravel/serializable-closure", + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": ["laravel", "Serializable", "closure"], + "license": "MIT", + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/laravel/serializable-closure/src/Contracts/Serializable.php b/laravel/serializable-closure/src/Contracts/Serializable.php new file mode 100644 index 00000000..1a62922e --- /dev/null +++ b/laravel/serializable-closure/src/Contracts/Serializable.php @@ -0,0 +1,20 @@ +<?php + +namespace Laravel\SerializableClosure\Contracts; + +interface Serializable +{ + /** + * Resolve the closure with the given arguments. + * + * @return mixed + */ + public function __invoke(); + + /** + * Gets the closure that got serialized/unserialized. + * + * @return \Closure + */ + public function getClosure(); +} diff --git a/laravel/serializable-closure/src/Contracts/Signer.php b/laravel/serializable-closure/src/Contracts/Signer.php new file mode 100644 index 00000000..4d0f0fc6 --- /dev/null +++ b/laravel/serializable-closure/src/Contracts/Signer.php @@ -0,0 +1,22 @@ +<?php + +namespace Laravel\SerializableClosure\Contracts; + +interface Signer +{ + /** + * Sign the given serializable. + * + * @param string $serializable + * @return array + */ + public function sign($serializable); + + /** + * Verify the given signature. + * + * @param array $signature + * @return bool + */ + public function verify($signature); +} diff --git a/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php b/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php new file mode 100644 index 00000000..83d9e4fc --- /dev/null +++ b/laravel/serializable-closure/src/Exceptions/InvalidSignatureException.php @@ -0,0 +1,19 @@ +<?php + +namespace Laravel\SerializableClosure\Exceptions; + +use Exception; + +class InvalidSignatureException extends Exception +{ + /** + * Create a new exception instance. + * + * @param string $message + * @return void + */ + public function __construct($message = 'Your serialized closure might have been modified or it\'s unsafe to be unserialized.') + { + parent::__construct($message); + } +} diff --git a/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php b/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php new file mode 100644 index 00000000..b301a3a7 --- /dev/null +++ b/laravel/serializable-closure/src/Exceptions/MissingSecretKeyException.php @@ -0,0 +1,19 @@ +<?php + +namespace Laravel\SerializableClosure\Exceptions; + +use Exception; + +class MissingSecretKeyException extends Exception +{ + /** + * Create a new exception instance. + * + * @param string $message + * @return void + */ + public function __construct($message = 'No serializable closure secret key has been specified.') + { + parent::__construct($message); + } +} diff --git a/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php b/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php new file mode 100644 index 00000000..b664e00a --- /dev/null +++ b/laravel/serializable-closure/src/Exceptions/PhpVersionNotSupportedException.php @@ -0,0 +1,19 @@ +<?php + +namespace Laravel\SerializableClosure\Exceptions; + +use Exception; + +class PhpVersionNotSupportedException extends Exception +{ + /** + * Create a new exception instance. + * + * @param string $message + * @return void + */ + public function __construct($message = 'PHP 7.3 is not supported.') + { + parent::__construct($message); + } +} diff --git a/laravel/serializable-closure/src/SerializableClosure.php b/laravel/serializable-closure/src/SerializableClosure.php new file mode 100644 index 00000000..e7f9f0cf --- /dev/null +++ b/laravel/serializable-closure/src/SerializableClosure.php @@ -0,0 +1,128 @@ +<?php + +namespace Laravel\SerializableClosure; + +use Closure; +use Laravel\SerializableClosure\Exceptions\InvalidSignatureException; +use Laravel\SerializableClosure\Exceptions\PhpVersionNotSupportedException; +use Laravel\SerializableClosure\Serializers\Signed; +use Laravel\SerializableClosure\Signers\Hmac; + +class SerializableClosure +{ + /** + * The closure's serializable. + * + * @var \Laravel\SerializableClosure\Contracts\Serializable + */ + protected $serializable; + + /** + * Creates a new serializable closure instance. + * + * @param \Closure $closure + * @return void + */ + public function __construct(Closure $closure) + { + if (\PHP_VERSION_ID < 70400) { + throw new PhpVersionNotSupportedException(); + } + + $this->serializable = Serializers\Signed::$signer + ? new Serializers\Signed($closure) + : new Serializers\Native($closure); + } + + /** + * Resolve the closure with the given arguments. + * + * @return mixed + */ + public function __invoke() + { + if (\PHP_VERSION_ID < 70400) { + throw new PhpVersionNotSupportedException(); + } + + return call_user_func_array($this->serializable, func_get_args()); + } + + /** + * Gets the closure. + * + * @return \Closure + */ + public function getClosure() + { + if (\PHP_VERSION_ID < 70400) { + throw new PhpVersionNotSupportedException(); + } + + return $this->serializable->getClosure(); + } + + /** + * Sets the serializable closure secret key. + * + * @param string|null $secret + * @return void + */ + public static function setSecretKey($secret) + { + Serializers\Signed::$signer = $secret + ? new Hmac($secret) + : null; + } + + /** + * Sets the serializable closure secret key. + * + * @param \Closure|null $transformer + * @return void + */ + public static function transformUseVariablesUsing($transformer) + { + Serializers\Native::$transformUseVariables = $transformer; + } + + /** + * Sets the serializable closure secret key. + * + * @param \Closure|null $resolver + * @return void + */ + public static function resolveUseVariablesUsing($resolver) + { + Serializers\Native::$resolveUseVariables = $resolver; + } + + /** + * Get the serializable representation of the closure. + * + * @return array + */ + public function __serialize() + { + return [ + 'serializable' => $this->serializable, + ]; + } + + /** + * Restore the closure after serialization. + * + * @param array $data + * @return void + * + * @throws \Laravel\SerializableClosure\Exceptions\InvalidSignatureException + */ + public function __unserialize($data) + { + if (Signed::$signer && ! $data['serializable'] instanceof Signed) { + throw new InvalidSignatureException(); + } + + $this->serializable = $data['serializable']; + } +} diff --git a/laravel/serializable-closure/src/Serializers/Native.php b/laravel/serializable-closure/src/Serializers/Native.php new file mode 100644 index 00000000..c04ead03 --- /dev/null +++ b/laravel/serializable-closure/src/Serializers/Native.php @@ -0,0 +1,506 @@ +<?php + +namespace Laravel\SerializableClosure\Serializers; + +use Closure; +use Laravel\SerializableClosure\Contracts\Serializable; +use Laravel\SerializableClosure\SerializableClosure; +use Laravel\SerializableClosure\Support\ClosureScope; +use Laravel\SerializableClosure\Support\ClosureStream; +use Laravel\SerializableClosure\Support\ReflectionClosure; +use Laravel\SerializableClosure\Support\SelfReference; +use ReflectionObject; +use UnitEnum; + +class Native implements Serializable +{ + /** + * Transform the use variables before serialization. + * + * @var \Closure|null + */ + public static $transformUseVariables; + + /** + * Resolve the use variables after unserialization. + * + * @var \Closure|null + */ + public static $resolveUseVariables; + + /** + * The closure to be serialized/unserialized. + * + * @var \Closure + */ + protected $closure; + + /** + * The closure's reflection. + * + * @var \Laravel\SerializableClosure\Support\ReflectionClosure|null + */ + protected $reflector; + + /** + * The closure's code. + * + * @var array|null + */ + protected $code; + + /** + * The closure's reference. + * + * @var string + */ + protected $reference; + + /** + * The closure's scope. + * + * @var \Laravel\SerializableClosure\Support\ClosureScope|null + */ + protected $scope; + + /** + * The "key" that marks an array as recursive. + */ + const ARRAY_RECURSIVE_KEY = 'LARAVEL_SERIALIZABLE_RECURSIVE_KEY'; + + /** + * Creates a new serializable closure instance. + * + * @param \Closure $closure + * @return void + */ + public function __construct(Closure $closure) + { + $this->closure = $closure; + } + + /** + * Resolve the closure with the given arguments. + * + * @return mixed + */ + public function __invoke() + { + return call_user_func_array($this->closure, func_get_args()); + } + + /** + * Gets the closure. + * + * @return \Closure + */ + public function getClosure() + { + return $this->closure; + } + + /** + * Get the serializable representation of the closure. + * + * @return array + */ + public function __serialize() + { + if ($this->scope === null) { + $this->scope = new ClosureScope(); + $this->scope->toSerialize++; + } + + $this->scope->serializations++; + + $scope = $object = null; + $reflector = $this->getReflector(); + + if ($reflector->isBindingRequired()) { + $object = $reflector->getClosureThis(); + + static::wrapClosures($object, $this->scope); + } + + if ($scope = $reflector->getClosureScopeClass()) { + $scope = $scope->name; + } + + $this->reference = spl_object_hash($this->closure); + + $this->scope[$this->closure] = $this; + + $use = $reflector->getUseVariables(); + + if (static::$transformUseVariables) { + $use = call_user_func(static::$transformUseVariables, $reflector->getUseVariables()); + } + + $code = $reflector->getCode(); + + $this->mapByReference($use); + + $data = [ + 'use' => $use, + 'function' => $code, + 'scope' => $scope, + 'this' => $object, + 'self' => $this->reference, + ]; + + if (! --$this->scope->serializations && ! --$this->scope->toSerialize) { + $this->scope = null; + } + + return $data; + } + + /** + * Restore the closure after serialization. + * + * @param array $data + * @return void + */ + public function __unserialize($data) + { + ClosureStream::register(); + + $this->code = $data; + unset($data); + + $this->code['objects'] = []; + + if ($this->code['use']) { + $this->scope = new ClosureScope(); + + if (static::$resolveUseVariables) { + $this->code['use'] = call_user_func(static::$resolveUseVariables, $this->code['use']); + } + + $this->mapPointers($this->code['use']); + + extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); + + $this->scope = null; + } + + $this->closure = include ClosureStream::STREAM_PROTO.'://'.$this->code['function']; + + if ($this->code['this'] === $this) { + $this->code['this'] = null; + } + + $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); + + if (! empty($this->code['objects'])) { + foreach ($this->code['objects'] as $item) { + $item['property']->setValue($item['instance'], $item['object']->getClosure()); + } + } + + $this->code = $this->code['function']; + } + + /** + * Ensures the given closures are serializable. + * + * @param mixed $data + * @param \Laravel\SerializableClosure\Support\ClosureScope $storage + * @return void + */ + public static function wrapClosures(&$data, $storage) + { + if ($data instanceof Closure) { + $data = new static($data); + } elseif (is_array($data)) { + if (isset($data[self::ARRAY_RECURSIVE_KEY])) { + return; + } + + $data[self::ARRAY_RECURSIVE_KEY] = true; + + foreach ($data as $key => &$value) { + if ($key === self::ARRAY_RECURSIVE_KEY) { + continue; + } + static::wrapClosures($value, $storage); + } + + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif ($data instanceof \stdClass) { + if (isset($storage[$data])) { + $data = $storage[$data]; + + return; + } + + $data = $storage[$data] = clone $data; + + foreach ($data as &$value) { + static::wrapClosures($value, $storage); + } + + unset($value); + } elseif (is_object($data) && ! $data instanceof static && ! $data instanceof UnitEnum) { + if (isset($storage[$data])) { + $data = $storage[$data]; + + return; + } + + $instance = $data; + $reflection = new ReflectionObject($instance); + + if (! $reflection->isUserDefined()) { + $storage[$instance] = $data; + + return; + } + + $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); + + do { + if (! $reflection->isUserDefined()) { + break; + } + + foreach ($reflection->getProperties() as $property) { + if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { + continue; + } + + $property->setAccessible(true); + + if (PHP_VERSION >= 7.4 && ! $property->isInitialized($instance)) { + continue; + } + + $value = $property->getValue($instance); + + if (is_array($value) || is_object($value)) { + static::wrapClosures($value, $storage); + } + + $property->setValue($data, $value); + } + } while ($reflection = $reflection->getParentClass()); + } + } + + /** + * Gets the closure's reflector. + * + * @return \Laravel\SerializableClosure\Support\ReflectionClosure + */ + public function getReflector() + { + if ($this->reflector === null) { + $this->code = null; + $this->reflector = new ReflectionClosure($this->closure); + } + + return $this->reflector; + } + + /** + * Internal method used to map closure pointers. + * + * @param mixed $data + * @return void + */ + protected function mapPointers(&$data) + { + $scope = $this->scope; + + if ($data instanceof static) { + $data = &$data->closure; + } elseif (is_array($data)) { + if (isset($data[self::ARRAY_RECURSIVE_KEY])) { + return; + } + + $data[self::ARRAY_RECURSIVE_KEY] = true; + + foreach ($data as $key => &$value) { + if ($key === self::ARRAY_RECURSIVE_KEY) { + continue; + } elseif ($value instanceof static) { + $data[$key] = &$value->closure; + } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']) { + $data[$key] = &$this->closure; + } else { + $this->mapPointers($value); + } + } + + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif ($data instanceof \stdClass) { + if (isset($scope[$data])) { + return; + } + + $scope[$data] = true; + + foreach ($data as $key => &$value) { + if ($value instanceof SelfReference && $value->hash === $this->code['self']) { + $data->{$key} = &$this->closure; + } elseif (is_array($value) || is_object($value)) { + $this->mapPointers($value); + } + } + + unset($value); + } elseif (is_object($data) && ! ($data instanceof Closure)) { + if (isset($scope[$data])) { + return; + } + + $scope[$data] = true; + $reflection = new ReflectionObject($data); + + do { + if (! $reflection->isUserDefined()) { + break; + } + + foreach ($reflection->getProperties() as $property) { + if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { + continue; + } + + $property->setAccessible(true); + + if (PHP_VERSION >= 7.4 && ! $property->isInitialized($data)) { + continue; + } + + $item = $property->getValue($data); + + if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { + $this->code['objects'][] = [ + 'instance' => $data, + 'property' => $property, + 'object' => $item instanceof SelfReference ? $this : $item, + ]; + } elseif (is_array($item) || is_object($item)) { + $this->mapPointers($item); + $property->setValue($data, $item); + } + } + } while ($reflection = $reflection->getParentClass()); + } + } + + /** + * Internal method used to map closures by reference. + * + * @param mixed $data + * @return void + */ + protected function mapByReference(&$data) + { + if ($data instanceof Closure) { + if ($data === $this->closure) { + $data = new SelfReference($this->reference); + + return; + } + + if (isset($this->scope[$data])) { + $data = $this->scope[$data]; + + return; + } + + $instance = new static($data); + + $instance->scope = $this->scope; + + $data = $this->scope[$data] = $instance; + } elseif (is_array($data)) { + if (isset($data[self::ARRAY_RECURSIVE_KEY])) { + return; + } + + $data[self::ARRAY_RECURSIVE_KEY] = true; + + foreach ($data as $key => &$value) { + if ($key === self::ARRAY_RECURSIVE_KEY) { + continue; + } + + $this->mapByReference($value); + } + + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif ($data instanceof \stdClass) { + if (isset($this->scope[$data])) { + $data = $this->scope[$data]; + + return; + } + + $instance = $data; + $this->scope[$instance] = $data = clone $data; + + foreach ($data as &$value) { + $this->mapByReference($value); + } + + unset($value); + } elseif (is_object($data) && ! $data instanceof SerializableClosure) { + if (isset($this->scope[$data])) { + $data = $this->scope[$data]; + + return; + } + + $instance = $data; + + if ($data instanceof UnitEnum) { + $this->scope[$instance] = $data; + + return; + } + + $reflection = new ReflectionObject($data); + + if (! $reflection->isUserDefined()) { + $this->scope[$instance] = $data; + + return; + } + + $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); + + do { + if (! $reflection->isUserDefined()) { + break; + } + + foreach ($reflection->getProperties() as $property) { + if ($property->isStatic() || ! $property->getDeclaringClass()->isUserDefined()) { + continue; + } + + $property->setAccessible(true); + + if (PHP_VERSION >= 7.4 && ! $property->isInitialized($instance)) { + continue; + } + + $value = $property->getValue($instance); + + if (is_array($value) || is_object($value)) { + $this->mapByReference($value); + } + + $property->setValue($data, $value); + } + } while ($reflection = $reflection->getParentClass()); + } + } +} diff --git a/laravel/serializable-closure/src/Serializers/Signed.php b/laravel/serializable-closure/src/Serializers/Signed.php new file mode 100644 index 00000000..a47d367e --- /dev/null +++ b/laravel/serializable-closure/src/Serializers/Signed.php @@ -0,0 +1,88 @@ +<?php + +namespace Laravel\SerializableClosure\Serializers; + +use Laravel\SerializableClosure\Contracts\Serializable; +use Laravel\SerializableClosure\Exceptions\InvalidSignatureException; +use Laravel\SerializableClosure\Exceptions\MissingSecretKeyException; + +class Signed implements Serializable +{ + /** + * The signer that will sign and verify the closure's signature. + * + * @var \Laravel\SerializableClosure\Contracts\Signer|null + */ + public static $signer; + + /** + * The closure to be serialized/unserialized. + * + * @var \Closure + */ + protected $closure; + + /** + * Creates a new serializable closure instance. + * + * @param \Closure $closure + * @return void + */ + public function __construct($closure) + { + $this->closure = $closure; + } + + /** + * Resolve the closure with the given arguments. + * + * @return mixed + */ + public function __invoke() + { + return call_user_func_array($this->closure, func_get_args()); + } + + /** + * Gets the closure. + * + * @return \Closure + */ + public function getClosure() + { + return $this->closure; + } + + /** + * Get the serializable representation of the closure. + * + * @return array + */ + public function __serialize() + { + if (! static::$signer) { + throw new MissingSecretKeyException(); + } + + return static::$signer->sign( + serialize(new Native($this->closure)) + ); + } + + /** + * Restore the closure after serialization. + * + * @param array $signature + * @return void + * + * @throws \Laravel\SerializableClosure\Exceptions\InvalidSignatureException + */ + public function __unserialize($signature) + { + if (static::$signer && ! static::$signer->verify($signature)) { + throw new InvalidSignatureException(); + } + + $this->closure = unserialize($signature['serializable'])->getClosure(); + } +} diff --git a/laravel/serializable-closure/src/Signers/Hmac.php b/laravel/serializable-closure/src/Signers/Hmac.php new file mode 100644 index 00000000..d94b0a2a --- /dev/null +++ b/laravel/serializable-closure/src/Signers/Hmac.php @@ -0,0 +1,53 @@ +<?php + +namespace Laravel\SerializableClosure\Signers; + +use Laravel\SerializableClosure\Contracts\Signer; + +class Hmac implements Signer +{ + /** + * The secret key. + * + * @var string + */ + protected $secret; + + /** + * Creates a new signer instance. + * + * @param string $secret + * @return void + */ + public function __construct($secret) + { + $this->secret = $secret; + } + + /** + * Sign the given serializable. + * + * @param string $serialized + * @return array + */ + public function sign($serialized) + { + return [ + 'serializable' => $serialized, + 'hash' => base64_encode(hash_hmac('sha256', $serialized, $this->secret, true)), + ]; + } + + /** + * Verify the given signature. + * + * @param array $signature + * @return bool + */ + public function verify($signature) + { + return hash_equals(base64_encode( + hash_hmac('sha256', $signature['serializable'], $this->secret, true) + ), $signature['hash']); + } +} diff --git a/laravel/serializable-closure/src/Support/ClosureScope.php b/laravel/serializable-closure/src/Support/ClosureScope.php new file mode 100644 index 00000000..64ca19a3 --- /dev/null +++ b/laravel/serializable-closure/src/Support/ClosureScope.php @@ -0,0 +1,22 @@ +<?php + +namespace Laravel\SerializableClosure\Support; + +use SplObjectStorage; + +class ClosureScope extends SplObjectStorage +{ + /** + * The number of serializations in current scope. + * + * @var int + */ + public $serializations = 0; + + /** + * The number of closures that have to be serialized. + * + * @var int + */ + public $toSerialize = 0; +} diff --git a/laravel/serializable-closure/src/Support/ClosureStream.php b/laravel/serializable-closure/src/Support/ClosureStream.php new file mode 100644 index 00000000..b54558b8 --- /dev/null +++ b/laravel/serializable-closure/src/Support/ClosureStream.php @@ -0,0 +1,178 @@ +<?php + +namespace Laravel\SerializableClosure\Support; + +class ClosureStream +{ + /** + * The stream protocol. + */ + const STREAM_PROTO = 'laravel-serializable-closure'; + + /** + * Checks if this stream is registered. + * + * @var bool + */ + protected static $isRegistered = false; + + /** + * The stream content. + * + * @var string + */ + protected $content; + + /** + * The stream content. + * + * @var int + */ + protected $length; + + /** + * The stream pointer. + * + * @var int + */ + protected $pointer = 0; + + /** + * Opens file or URL. + * + * @param string $path + * @param string $mode + * @param string $options + * @param string|null $opened_path + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) + { + $this->content = "<?php\nreturn ".substr($path, strlen(static::STREAM_PROTO.'://')).';'; + $this->length = strlen($this->content); + + return true; + } + + /** + * Read from stream. + * + * @param int $count + * @return string + */ + public function stream_read($count) + { + $value = substr($this->content, $this->pointer, $count); + + $this->pointer += $count; + + return $value; + } + + /** + * Tests for end-of-file on a file pointer. + * + * @return bool + */ + public function stream_eof() + { + return $this->pointer >= $this->length; + } + + /** + * Change stream options. + * + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + */ + public function stream_set_option($option, $arg1, $arg2) + { + return false; + } + + /** + * Retrieve information about a file resource. + * + * @return array|bool + */ + public function stream_stat() + { + $stat = stat(__FILE__); + // @phpstan-ignore-next-line + $stat[7] = $stat['size'] = $this->length; + + return $stat; + } + + /** + * Retrieve information about a file. + * + * @param string $path + * @param int $flags + * @return array|bool + */ + public function url_stat($path, $flags) + { + $stat = stat(__FILE__); + // @phpstan-ignore-next-line + $stat[7] = $stat['size'] = $this->length; + + return $stat; + } + + /** + * Seeks to specific location in a stream. + * + * @param int $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence = SEEK_SET) + { + $crt = $this->pointer; + + switch ($whence) { + case SEEK_SET: + $this->pointer = $offset; + break; + case SEEK_CUR: + $this->pointer += $offset; + break; + case SEEK_END: + $this->pointer = $this->length + $offset; + break; + } + + if ($this->pointer < 0 || $this->pointer >= $this->length) { + $this->pointer = $crt; + + return false; + } + + return true; + } + + /** + * Retrieve the current position of a stream. + * + * @return int + */ + public function stream_tell() + { + return $this->pointer; + } + + /** + * Registers the stream. + * + * @return void + */ + public static function register() + { + if (! static::$isRegistered) { + static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__); + } + } +} diff --git a/opis/closure/src/ReflectionClosure.php b/laravel/serializable-closure/src/Support/ReflectionClosure.php index 1f6a8322..a0d37075 100644 --- a/opis/closure/src/ReflectionClosure.php +++ b/laravel/serializable-closure/src/Support/ReflectionClosure.php @@ -1,15 +1,11 @@ <?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ -namespace Opis\Closure; +namespace Laravel\SerializableClosure\Support; defined('T_NAME_QUALIFIED') || define('T_NAME_QUALIFIED', -4); defined('T_NAME_FULLY_QUALIFIED') || define('T_NAME_FULLY_QUALIFIED', -5); defined('T_FN') || define('T_FN', -6); +defined('T_NULLSAFE_OBJECT_OPERATOR') || define('T_NULLSAFE_OBJECT_OPERATOR', -7); use Closure; use ReflectionFunction; @@ -25,18 +21,18 @@ class ReflectionClosure extends ReflectionFunction protected $isBindingRequired; protected $isShortClosure; - protected static $files = array(); - protected static $classes = array(); - protected static $functions = array(); - protected static $constants = array(); - protected static $structures = array(); - + protected static $files = []; + protected static $classes = []; + protected static $functions = []; + protected static $constants = []; + protected static $structures = []; /** - * ReflectionClosure constructor. - * @param Closure $closure - * @param string|null $code This is ignored. Do not use it - * @throws \ReflectionException + * Creates a new reflection closure instance. + * + * @param \Closure $closure + * @param string|null $code + * @return void */ public function __construct(Closure $closure, $code = null) { @@ -44,9 +40,11 @@ class ReflectionClosure extends ReflectionFunction } /** + * Checks if the closure is "static". + * * @return bool */ - public function isStatic() + public function isStatic(): bool { if ($this->isStaticClosure === null) { $this->isStaticClosure = strtolower(substr($this->getCode(), 0, 6)) === 'static'; @@ -55,13 +53,20 @@ class ReflectionClosure extends ReflectionFunction return $this->isStaticClosure; } + /** + * Checks if the closure is a "short closure". + * + * @return bool + */ public function isShortClosure() { if ($this->isShortClosure === null) { $code = $this->getCode(); + if ($this->isStatic()) { $code = substr($code, 6); } + $this->isShortClosure = strtolower(substr(trim($code), 0, 2)) === 'fn'; } @@ -69,11 +74,13 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the closure's code. + * * @return string */ public function getCode() { - if($this->code !== null){ + if ($this->code !== null) { return $this->code; } @@ -83,21 +90,21 @@ class ReflectionClosure extends ReflectionFunction $className = null; if (null !== $className = $this->getClosureScopeClass()) { - $className = '\\' . trim($className->getName(), '\\'); + $className = '\\'.trim($className->getName(), '\\'); } $builtin_types = self::getBuiltinTypes(); $class_keywords = ['self', 'static', 'parent']; - $ns = $this->getNamespaceName(); - $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns); + $ns = $this->getClosureNamespaceName(); + $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\'.$ns); $_file = var_export($fileName, true); $_dir = var_export(dirname($fileName), true); $_namespace = var_export($ns, true); - $_class = var_export(trim($className, '\\'), true); - $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}'; - $_method = ($className == '' ? '' : trim($className, '\\') . '::') . $_function; + $_class = var_export(trim($className ?: '', '\\'), true); + $_function = $ns.($ns == '' ? '' : '\\').'{closure}'; + $_method = ($className == '' ? '' : trim($className, '\\').'::').$_function; $_function = var_export($_function, true); $_method = var_export($_method, true); $_trait = null; @@ -105,28 +112,35 @@ class ReflectionClosure extends ReflectionFunction $tokens = $this->getTokens(); $state = $lastState = 'start'; $inside_structure = false; + $isFirstClassCallable = false; $isShortClosure = false; + $inside_structure_mark = 0; $open = 0; $code = ''; $id_start = $id_start_ci = $id_name = $context = ''; $classes = $functions = $constants = null; - $use = array(); + $use = []; $lineAdd = 0; $isUsingScope = false; $isUsingThisObject = false; - for($i = 0, $l = count($tokens); $i < $l; $i++) { + for ($i = 0, $l = count($tokens); $i < $l; $i++) { $token = $tokens[$i]; + switch ($state) { case 'start': if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) { $code .= $token[1]; + $state = $token[0] === T_FUNCTION ? 'function' : 'static'; } elseif ($token[0] === T_FN) { $isShortClosure = true; $code .= $token[1]; $state = 'closure_args'; + } elseif ($token[0] === T_PUBLIC || $token[0] === T_PROTECTED || $token[0] === T_PRIVATE) { + $code = ''; + $isFirstClassCallable = true; } break; case 'static': @@ -145,8 +159,13 @@ class ReflectionClosure extends ReflectionFunction } break; case 'function': - switch ($token[0]){ + switch ($token[0]) { case T_STRING: + if ($isFirstClassCallable) { + $state = 'closure_args'; + break; + } + $code = ''; $state = 'named_function'; break; @@ -159,7 +178,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'named_function': - if($token[0] === T_FUNCTION || $token[0] === T_STATIC){ + if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) { $code = $token[1]; $state = $token[0] === T_FUNCTION ? 'function' : 'static'; } elseif ($token[0] === T_FN) { @@ -169,9 +188,9 @@ class ReflectionClosure extends ReflectionFunction } break; case 'closure_args': - switch ($token[0]){ + switch ($token[0]) { case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); + [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'args'; $state = 'id_name'; $lastState = 'closure_args'; @@ -209,7 +228,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'use': - switch ($token[0]){ + switch ($token[0]) { case T_VARIABLE: $use[] = substr($token[1], 1); $code .= $token[1]; @@ -229,7 +248,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'return': - switch ($token[0]){ + switch ($token[0]) { case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: @@ -245,7 +264,7 @@ class ReflectionClosure extends ReflectionFunction $lastState = 'return'; break 2; case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); + [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'return_type'; $state = 'id_name'; $lastState = 'return'; @@ -267,7 +286,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'closure': - switch ($token[0]){ + switch ($token[0]) { case T_CURLY_OPEN: case T_DOLLAR_OPEN_CURLY_BRACES: case '{': @@ -276,10 +295,10 @@ class ReflectionClosure extends ReflectionFunction break; case '}': $code .= '}'; - if(--$open === 0 && !$isShortClosure){ + if (--$open === 0 && ! $isShortClosure) { break 3; } elseif ($inside_structure) { - $inside_structure = !($open === $inside_structure_mark); + $inside_structure = ! ($open === $inside_structure_mark); } break; case '(': @@ -295,7 +314,7 @@ class ReflectionClosure extends ReflectionFunction if ($open === 0) { break 3; } - --$open; + $open--; } $code .= $token[0]; break; @@ -330,18 +349,18 @@ class ReflectionClosure extends ReflectionFunction case T_COMMENT: if (substr($token[1], 0, 8) === '#trackme') { $timestamp = time(); - $code .= '/**' . PHP_EOL; - $code .= '* Date : ' . date(DATE_W3C, $timestamp) . PHP_EOL; - $code .= '* Timestamp : ' . $timestamp . PHP_EOL; - $code .= '* Line : ' . ($line + 1) . PHP_EOL; - $code .= '* File : ' . $_file . PHP_EOL . '*/' . PHP_EOL; + $code .= '/**'.PHP_EOL; + $code .= '* Date : '.date(DATE_W3C, $timestamp).PHP_EOL; + $code .= '* Timestamp : '.$timestamp.PHP_EOL; + $code .= '* Line : '.($line + 1).PHP_EOL; + $code .= '* File : '.$_file.PHP_EOL.'*/'.PHP_EOL; $lineAdd += 5; } else { $code .= $token[1]; } break; case T_VARIABLE: - if($token[1] == '$this' && !$inside_structure){ + if ($token[1] == '$this' && ! $inside_structure) { $isUsingThisObject = true; } $code .= $token[1]; @@ -357,7 +376,7 @@ class ReflectionClosure extends ReflectionFunction $lastState = 'closure'; break 2; case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); + [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $context = 'root'; $state = 'id_name'; $lastState = 'closure'; @@ -382,6 +401,7 @@ class ReflectionClosure extends ReflectionFunction $lastState = 'closure'; break; case T_OBJECT_OPERATOR: + case T_NULLSAFE_OBJECT_OPERATOR: case T_DOUBLE_COLON: $code .= $token[1]; $lastState = 'closure'; @@ -390,7 +410,7 @@ class ReflectionClosure extends ReflectionFunction case T_FUNCTION: $code .= $token[1]; $state = 'closure_args'; - if (!$inside_structure) { + if (! $inside_structure) { $inside_structure = true; $inside_structure_mark = $open; } @@ -408,7 +428,7 @@ class ReflectionClosure extends ReflectionFunction $struct['start'] <= $startLine && $struct['end'] >= $endLine ) { - $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name']; + $_trait = ($ns == '' ? '' : $ns.'\\').$struct['name']; break; } } @@ -423,7 +443,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'ignore_next': - switch ($token[0]){ + switch ($token[0]) { case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: @@ -454,7 +474,7 @@ class ReflectionClosure extends ReflectionFunction } break; case 'id_start': - switch ($token[0]){ + switch ($token[0]) { case T_WHITESPACE: case T_COMMENT: case T_DOC_COMMENT: @@ -470,7 +490,7 @@ class ReflectionClosure extends ReflectionFunction $state = 'id_name'; break 2; case T_NAME_QUALIFIED: - list($id_start, $id_start_ci, $id_name) = $this->parseNameQualified($token[1]); + [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]); $state = 'id_name'; break 2; case T_VARIABLE: @@ -482,12 +502,21 @@ class ReflectionClosure extends ReflectionFunction $state = 'anonymous'; break; default: - $i--;//reprocess last + $i--; //reprocess last $state = 'id_name'; } break; case 'id_name': - switch ($token[0]){ + switch ($token[0]) { + // named arguments... + case ':': + if ($lastState === 'closure' && $context === 'root') { + $state = 'ignore_next'; + $lastState = 'closure'; + $code .= $id_start.$token; + } + + break; case T_NAME_QUALIFIED: case T_NS_SEPARATOR: case T_STRING: @@ -500,76 +529,76 @@ class ReflectionClosure extends ReflectionFunction if ($isShortClosure) { $open++; } - if($context === 'new' || false !== strpos($id_name, '\\')){ - if($id_start_ci === 'self' || $id_start_ci === 'static') { - if (!$inside_structure) { + if ($context === 'new' || false !== strpos($id_name, '\\')) { + if ($id_start_ci === 'self' || $id_start_ci === 'static') { + if (! $inside_structure) { $isUsingScope = true; } - } elseif ($id_start !== '\\' && !in_array($id_start_ci, $class_keywords)) { + } elseif ($id_start !== '\\' && ! in_array($id_start_ci, $class_keywords)) { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; + if ($id_start[0] !== '\\') { + $id_start = $nsf.'\\'.$id_start; } } } else { - if($id_start !== '\\'){ - if($functions === null){ + if ($id_start !== '\\') { + if ($functions === null) { $functions = $this->getFunctions(); } - if(isset($functions[$id_start_ci])){ + if (isset($functions[$id_start_ci])) { $id_start = $functions[$id_start_ci]; - } elseif ($nsf !== '\\' && function_exists($nsf . '\\' . $id_start)) { - $id_start = $nsf . '\\' . $id_start; + } elseif ($nsf !== '\\' && function_exists($nsf.'\\'.$id_start)) { + $id_start = $nsf.'\\'.$id_start; // Cache it to functions array $functions[$id_start_ci] = $id_start; } } } - $code .= $id_start . $id_name . '('; + $code .= $id_start.$id_name.'('; $state = $lastState; break; case T_VARIABLE: case T_DOUBLE_COLON: - if($id_start !== '\\') { - if($id_start_ci === 'self' || $id_start_ci === 'parent'){ - if (!$inside_structure) { + if ($id_start !== '\\') { + if ($id_start_ci === 'self' || $id_start_ci === 'parent') { + if (! $inside_structure) { $isUsingScope = true; } } elseif ($id_start_ci === 'static') { - if (!$inside_structure) { + if (! $inside_structure) { $isUsingScope = $token[0] === T_DOUBLE_COLON; } - } elseif (!(\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))){ + } elseif (! (\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))) { if ($classes === null) { $classes = $this->getClasses(); } if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; + if ($id_start[0] !== '\\') { + $id_start = $nsf.'\\'.$id_start; } } } - $code .= $id_start . $id_name . $token[1]; + $code .= $id_start.$id_name.$token[1]; $state = $token[0] === T_DOUBLE_COLON ? 'ignore_next' : $lastState; break; default: - if($id_start !== '\\' && !defined($id_start)){ - if($constants === null){ + if ($id_start !== '\\' && ! defined($id_start)) { + if ($constants === null) { $constants = $this->getConstants(); } - if(isset($constants[$id_start])){ + if (isset($constants[$id_start])) { $id_start = $constants[$id_start]; - } elseif($context === 'new'){ - if(in_array($id_start_ci, $class_keywords)) { - if (!$inside_structure) { + } elseif ($context === 'new') { + if (in_array($id_start_ci, $class_keywords)) { + if (! $inside_structure) { $isUsingScope = true; } } else { @@ -580,36 +609,36 @@ class ReflectionClosure extends ReflectionFunction $id_start = $classes[$id_start_ci]; } if ($id_start[0] !== '\\') { - $id_start = $nsf . '\\' . $id_start; + $id_start = $nsf.'\\'.$id_start; } } - } elseif($context === 'use' || + } elseif ($context === 'use' || $context === 'instanceof' || $context === 'args' || $context === 'return_type' || $context === 'extends' || $context === 'root' - ){ - if(in_array($id_start_ci, $class_keywords)){ - if (!$inside_structure && !$id_start_ci === 'static') { + ) { + if (in_array($id_start_ci, $class_keywords)) { + if (! $inside_structure && ! $id_start_ci === 'static') { $isUsingScope = true; } - } elseif (!(\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))){ - if($classes === null){ + } elseif (! (\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))) { + if ($classes === null) { $classes = $this->getClasses(); } - if(isset($classes[$id_start_ci])){ + if (isset($classes[$id_start_ci])) { $id_start = $classes[$id_start_ci]; } - if($id_start[0] !== '\\'){ - $id_start = $nsf . '\\' . $id_start; + if ($id_start[0] !== '\\') { + $id_start = $nsf.'\\'.$id_start; } } } } - $code .= $id_start . $id_name; + $code .= $id_start.$id_name; $state = $lastState; - $i--;//reprocess last token + $i--; //reprocess last token } break; case 'anonymous': @@ -625,7 +654,7 @@ class ReflectionClosure extends ReflectionFunction break; case '{': $state = 'closure'; - if (!$inside_structure) { + if (! $inside_structure) { $inside_structure = true; $inside_structure_mark = $open; } @@ -647,19 +676,45 @@ class ReflectionClosure extends ReflectionFunction $this->isShortClosure = $isShortClosure; $this->isBindingRequired = $isUsingThisObject; $this->isScopeRequired = $isUsingScope; + + if (PHP_VERSION_ID >= 80100) { + $attributesCode = array_map(function ($attribute) { + $arguments = $attribute->getArguments(); + + $name = $attribute->getName(); + $arguments = implode(', ', array_map(function ($argument, $key) { + $argument = sprintf("'%s'", str_replace("'", "\\'", $argument)); + + if (is_string($key)) { + $argument = sprintf('%s: %s', $key, $argument); + } + + return $argument; + }, $arguments, array_keys($arguments))); + + return "#[$name($arguments)]"; + }, $this->getAttributes()); + + if (! empty($attributesCode)) { + $code = implode("\n", array_merge($attributesCode, [$code])); + } + } + $this->code = $code; return $this->code; } /** + * Get PHP native built in types. + * * @return array */ - private static function getBuiltinTypes() + protected static function getBuiltinTypes() { - // PHP 5 - if (\PHP_MAJOR_VERSION === 5) { - return ['array', 'callable']; + // PHP 8.1 + if (PHP_VERSION_ID >= 80100) { + return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null', 'never']; } // PHP 8 @@ -679,16 +734,18 @@ class ReflectionClosure extends ReflectionFunction } /** + * Gets the use variables by the closure. + * * @return array */ public function getUseVariables() { - if($this->useVariables !== null){ + if ($this->useVariables !== null) { return $this->useVariables; } $tokens = $this->getTokens(); - $use = array(); + $use = []; $state = 'start'; foreach ($tokens as &$token) { @@ -718,11 +775,13 @@ class ReflectionClosure extends ReflectionFunction } /** - * return bool + * Checks if binding is required. + * + * @return bool */ public function isBindingRequired() { - if($this->isBindingRequired === null){ + if ($this->isBindingRequired === null) { $this->getCode(); } @@ -730,11 +789,13 @@ class ReflectionClosure extends ReflectionFunction } /** - * return bool + * Checks if access to the scope is required. + * + * @return bool */ public function isScopeRequired() { - if($this->isScopeRequired === null){ + if ($this->isScopeRequired === null) { $this->getCode(); } @@ -742,6 +803,8 @@ class ReflectionClosure extends ReflectionFunction } /** + * The the hash of the current file name. + * * @return string */ protected function getHashedFileName() @@ -754,13 +817,15 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the file tokens. + * * @return array */ protected function getFileTokens() { $key = $this->getHashedFileName(); - if (!isset(static::$files[$key])) { + if (! isset(static::$files[$key])) { static::$files[$key] = token_get_all(file_get_contents($this->getFileName())); } @@ -768,6 +833,8 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the tokens. + * * @return array */ protected function getTokens() @@ -776,11 +843,11 @@ class ReflectionClosure extends ReflectionFunction $tokens = $this->getFileTokens(); $startLine = $this->getStartLine(); $endLine = $this->getEndLine(); - $results = array(); + $results = []; $start = false; foreach ($tokens as &$token) { - if (!is_array($token)) { + if (! is_array($token)) { if ($start) { $results[] = $token; } @@ -809,13 +876,15 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the classes. + * * @return array */ protected function getClasses() { $key = $this->getHashedFileName(); - if (!isset(static::$classes[$key])) { + if (! isset(static::$classes[$key])) { $this->fetchItems(); } @@ -823,13 +892,15 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the functions. + * * @return array */ protected function getFunctions() { $key = $this->getHashedFileName(); - if (!isset(static::$functions[$key])) { + if (! isset(static::$functions[$key])) { $this->fetchItems(); } @@ -837,13 +908,15 @@ class ReflectionClosure extends ReflectionFunction } /** + * Gets the constants. + * * @return array */ protected function getConstants() { $key = $this->getHashedFileName(); - if (!isset(static::$constants[$key])) { + if (! isset(static::$constants[$key])) { $this->fetchItems(); } @@ -851,27 +924,34 @@ class ReflectionClosure extends ReflectionFunction } /** + * Get the structures. + * * @return array */ protected function getStructures() { $key = $this->getHashedFileName(); - if (!isset(static::$structures[$key])) { + if (! isset(static::$structures[$key])) { $this->fetchItems(); } return static::$structures[$key]; } + /** + * Fetch the items. + * + * @return void. + */ protected function fetchItems() { $key = $this->getHashedFileName(); - $classes = array(); - $functions = array(); - $constants = array(); - $structures = array(); + $classes = []; + $functions = []; + $constants = []; + $structures = []; $tokens = $this->getFileTokens(); $open = 0; @@ -887,7 +967,6 @@ class ReflectionClosure extends ReflectionFunction $structIgnore = false; foreach ($tokens as $token) { - switch ($state) { case 'start': switch ($token[0]) { @@ -950,7 +1029,7 @@ class ReflectionClosure extends ReflectionFunction case ',': case ';': if ($name === '' || $name[0] !== '\\') { - $name = '\\' . $name; + $name = '\\'.$name; } if ($alias !== '') { @@ -989,16 +1068,16 @@ class ReflectionClosure extends ReflectionFunction case '}': if ($prefix === '' || $prefix[0] !== '\\') { - $prefix = '\\' . $prefix; + $prefix = '\\'.$prefix; } if ($alias !== '') { if ($isFunc) { - $functions[strtolower($alias)] = $prefix . $name; + $functions[strtolower($alias)] = $prefix.$name; } elseif ($isConst) { - $constants[$alias] = $prefix . $name; + $constants[$alias] = $prefix.$name; } else { - $classes[strtolower($alias)] = $prefix . $name; + $classes[strtolower($alias)] = $prefix.$name; } } $name = $alias = ''; @@ -1051,13 +1130,13 @@ class ReflectionClosure extends ReflectionFunction break; case '}': if (--$open == 0) { - if(!$structIgnore){ - $structures[] = array( - 'type' => $structType, - 'name' => $structName, + if (! $structIgnore) { + $structures[] = [ + 'type' => $structType, + 'name' => $structName, 'start' => $startLine, - 'end' => $endLine, - ); + 'end' => $endLine, + ]; } $structIgnore = false; $state = 'start'; @@ -1078,7 +1157,30 @@ class ReflectionClosure extends ReflectionFunction static::$structures[$key] = $structures; } - private function parseNameQualified($token) + /** + * Returns the namespace associated to the closure. + * + * @return string + */ + protected function getClosureNamespaceName() + { + $ns = $this->getNamespaceName(); + + // First class callables... + if ($this->getName() !== '{closure}' && empty($ns) && ! is_null($this->getClosureScopeClass())) { + $ns = $this->getClosureScopeClass()->getNamespaceName(); + } + + return $ns; + } + + /** + * Parse the given token. + * + * @param string $token + * @return array + */ + protected function parseNameQualified($token) { $pieces = explode('\\', $token); @@ -1086,7 +1188,7 @@ class ReflectionClosure extends ReflectionFunction $id_start_ci = strtolower($id_start); - $id_name = '\\' . implode('\\', $pieces); + $id_name = '\\'.implode('\\', $pieces); return [$id_start, $id_start_ci, $id_name]; } diff --git a/laravel/serializable-closure/src/Support/SelfReference.php b/laravel/serializable-closure/src/Support/SelfReference.php new file mode 100644 index 00000000..58319504 --- /dev/null +++ b/laravel/serializable-closure/src/Support/SelfReference.php @@ -0,0 +1,24 @@ +<?php + +namespace Laravel\SerializableClosure\Support; + +class SelfReference +{ + /** + * The unique hash representing the object. + * + * @var string + */ + public $hash; + + /** + * Creates a new self reference instance. + * + * @param string $hash + * @return void + */ + public function __construct($hash) + { + $this->hash = $hash; + } +} diff --git a/opis/closure/CHANGELOG.md b/opis/closure/CHANGELOG.md deleted file mode 100644 index 16c9e3da..00000000 --- a/opis/closure/CHANGELOG.md +++ /dev/null @@ -1,260 +0,0 @@ -CHANGELOG ---------- - -### v3.6.2, 2021.04.09 - -- Fixed string interpolation - -### v3.6.1, 2020.11.07 - -- Fixed serialization error [#84](https://github.com/opis/closure/issues/84) - -### v3.6.0, 2020.10.12 - -- Initial PHP 8 Support [#67](https://github.com/opis/closure/issues/67). - -### v3.5.7, 2020.09.06 - -- Fixed issue [#76](https://github.com/opis/closure/issues/76). -- Fixed issue [#78](https://github.com/opis/closure/issues/78). - -### v3.5.6, 2020.08.11 - -- Fixed issue [#70](https://github.com/opis/closure/issues/70) - -### v3.5.5, 2020.06.17 - -- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method - -### v3.5.4, 2020.06.07 - -- Fixed a false-positive when using `Opis\Closure\ReflectionClosure::isScopeRequired` method -- Fixed a bug related to `T_STRING_VARNAME` - -### v3.5.3, 2020.05.25 - -- Improved parser -- The class scope optimisation is no longer used. We always bind now to the closure's original class scope. -When the class scope was `null`, the optimisation failed to work as expected and kept the wrong `SerializableClosure` scope. - -### v3.5.2, 2020.05.21 - -- Removed extra semicolon in short closures, since is not part of the closure's body. - -### v3.5.1, 2019.11.30 - -- Bugfix. See #47 - -### v3.5.0, 2019.11.29 - -- Added support for short closures (arrow functions) -- Added `isShortClosure` method to `Opis\Closure\ReflectionClosure` - -### v3.4.2, 2019.11.29 - -- Added `stream_set_option()` - -### v3.4.1, 2019.10.19 - -- Fixed a [bug](https://github.com/opis/closure/issues/40) that prevented serialization to work correctly. - -### v3.4.0, 2019.09.03 - -- Added `createClosure` static method in `Opis\Closure\SerializableClosure`. -This method creates a new closure from arbitrary code, emulating `create_function`, -but without using eval - -### v3.3.1, 2019.07.10 - -- Use `sha1` instead of `md5` for hashing file names in `Opis\Closure\ReflectionClosure` class - -### v3.3.0, 2019.05.31 - -- Fixed a bug that prevented signed closures to properly work when the serialized string -contains invalid UTF-8 chars. Starting with this version `json_encode` is no longer used -when signing a closure. Backward compatibility is maintained and all closures that were -previously signed using the old method will continue to work. - -### v3.2.0, 2019.05.05 - -- Since an unsigned closure can be unserialized when no security provider is set, -there is no reason to treat differently a signed closure in the same situation. -Therefore, the `Opis\Closure\SecurityException` exception is no longer thrown when -unserializing a signed closure, if no security provider is set. - -### v3.1.6, 2019.02.22 - -- Fixed a bug that occurred when trying to set properties of classes that were not defined in user-land. -Those properties are now ignored. - -### v3.1.5, 2019.01.14 - -- Improved parser - -### v3.1.4, 2019.01.14 - -- Added support for static methods that are named using PHP keywords or magic constants. -Ex: `A::new()`, `A::use()`, `A::if()`, `A::function()`, `A::__DIR__()`, etc. -- Used `@internal` to mark classes & methods that are for internal use only and -backward compatibility is not guaranteed. - -### v3.1.3, 2019.01.07 - -- Fixed a bug that prevented traits to be correctly resolved when used by an -anonymous class -- Fixed a bug that occurred when `$this` keyword was used inside an anonymous class - -### v3.1.2, 2018.12.16 - -* Fixed a bug regarding comma trail in group-use statements. See [issue 23](https://github.com/opis/closure/issues/23) - -### v3.1.1, 2018.10.02 - -* Fixed a bug where `parent` keyword was treated like a class-name and scope was not added to the -serialized closure -* Fixed a bug where return type was not properly handled for nested closures -* Support for anonymous classes was improved - -### v3.1.0, 2018.09.20 - -* Added `transformUseVariables` and `resolveUseVariables` to -`Opis\Closure\SerializableClosure` class. -* Added `removeSecurityProvider` static method to -`Opis\Closure\SerializableClosure` class. -* Fixed some security related issues where a user was able to unserialize an unsigned -closure, even when a security provider was in use. - -### v3.0.12, 2018.02.23 - -* Bugfix. See [issue 20](https://github.com/opis/closure/issues/20) - -### v3.0.11, 2018.01.22 - -* Bugfix. See [issue 18](https://github.com/opis/closure/issues/18) - -### v3.0.10, 2018.01.04 - -* Improved support for PHP 7.1 & 7.2 - -### v3.0.9, 2018.01.04 - -* Fixed a bug where the return type was not properly resolved. -See [issue 17](https://github.com/opis/closure/issues/17) -* Added more tests - -### v3.0.8, 2017.12.18 - -* Fixed a bug. See [issue 16](https://github.com/opis/closure/issues/16) - -### v3.0.7, 2017.10.31 - -* Bugfix: static properties are ignored now, since they are not serializable - -### v3.0.6, 2017.10.06 - -* Fixed a bug introduced by accident in 3.0.5 - -### v3.0.5, 2017.09.18 - -* Fixed a bug related to nested references - -### v3.0.4, 2017.09.18 - -* \[*internal*\] Refactored `SerializableClosure::mapPointers` method -* \[*internal*\] Added a new optional argument to `SerializableClosure::unwrapClosures` -* \[*internal*\] Removed `SerializableClosure::getClosurePointer` method -* Fixed various bugs - -### v3.0.3, 2017.09.06 - -* Fixed a bug related to nested object references -* \[*internal*\] `Opis\Closure\ClosureScope` now extends `SplObjectStorage` -* \[*internal*\] The `storage` property was removed from `Opis\Closure\ClosureScope` -* \[*internal*\] The `instances` and `objects` properties were removed from `Opis\Closure\ClosureContext` - -### v3.0.2, 2017.08.28 - -* Fixed a bug where `$this` object was not handled properly inside the -`SerializableClosre::serialize` method. - -### v3.0.1, 2017.04.13 - -* Fixed a bug in 'ignore_next' state - -### v3.0.0, 2017.04.07 - -* Dropped PHP 5.3 support -* Moved source files from `lib` to `src` folder -* Removed second parameter from `Opis\Closure\SerializableClosure::from` method and from constructor -* Removed `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` classes -* Refactored how signed closures were handled -* Added `wrapClosures` and `unwrapClosures` static methods to `Opis\Closure\SerializableClosure` class -* Added `Opis\Colosure\serialize` and `Opis\Closure\unserialize` functions -* Improved serialization. You can now serialize arbitrary objects and the library will automatically wrap all closures - -### v2.4.0, 2016.12.16 - -* The parser was refactored and improved -* Refactored `Opis\Closure\SerializableClosure::__invoke` method -* `Opis\Closure\{ISecurityProvider, SecurityProvider}` were added -* `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` were deprecated -and they will be removed in the next major version -* `setSecretKey` and `addSecurityProvider` static methods were added to `Opis\Closure\SerializableClosure` - -### v2.3.2, 2016.12.15 - -* Fixed a bug that prevented namespace resolution to be done properly - -### v2.3.1, 2016.12.13 - -* Hotfix. See [PR](https://github.com/opis/closure/pull/7) - -### v2.3.0, 2016.11.17 - -* Added `isBindingRequired` and `isScopeRequired` to the `Opis\Closure\ReflectionClosure` class -* Automatically detects when the scope and/or the bound object of a closure needs to be serialized. - -### v2.2.1, 2016.08.20 - -* Fixed a bug in `Opis\Closure\ReflectionClosure::fetchItems` - -### v2.2.0, 2016.07.26 - -* Fixed CS -* `Opis\Closure\ClosureContext`, `Opis\Closure\ClosureScope`, `Opis\Closure\SelfReference` - and `Opis\Closure\SecurityException` classes were moved into separate files -* Added support for PHP7 syntax -* Fixed some bugs in `Opis\Closure\ReflectionClosure` class -* Improved closure parser -* Added an analyzer for SuperClosure library - -### v2.1.0, 2015.09.30 - -* Added support for the missing `__METHOD__`, `__FUNCTION__` and `__TRAIT__` magic constants -* Added some security related classes and interfaces: `Opis\Closure\SecurityProviderInterface`, -`Opis\Closure\DefaultSecurityProvider`, `Opis\Closure\SecureClosure`, `Opis\Closure\SecurityException`. -* Fiexed a bug in `Opis\Closure\ReflectionClosure::getClasses` method -* Other minor bugfixes -* Added support for static closures -* Added public `isStatic` method to `Opis\Closure\ReflectionClosure` class - - -### v2.0.1, 2015.09.23 - -* Removed `branch-alias` property from `composer.json` -* Bugfix. See [issue #6](https://github.com/opis/closure/issues/6) - -### v2.0.0, 2015.07.31 - -* The closure parser was improved -* Class names are now automatically resolved -* Added support for the `#trackme` directive which allows tracking closure's residing source - -### v1.3.0, 2014.10.18 - -* Added autoload file -* Changed README file - -### Opis Closure 1.2.2 - -* Started changelog diff --git a/opis/closure/LICENSE b/opis/closure/LICENSE deleted file mode 100644 index 9c0a19ba..00000000 --- a/opis/closure/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018-2019 Zindex Software - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/opis/closure/NOTICE b/opis/closure/NOTICE deleted file mode 100644 index ae5caa62..00000000 --- a/opis/closure/NOTICE +++ /dev/null @@ -1,9 +0,0 @@ -Opis Closure -Copyright 2018-2019 Zindex Software - -This product includes software developed at -Zindex Software (http://zindex.software). - -This software was originally developed by Marius Sarca and Sorin Sarca -(Copyright 2014-2018). The copyright info was changed with the permission -of the original authors.
\ No newline at end of file diff --git a/opis/closure/README.md b/opis/closure/README.md deleted file mode 100644 index f5f3ad8c..00000000 --- a/opis/closure/README.md +++ /dev/null @@ -1,92 +0,0 @@ -Opis Closure -==================== -[![Tests](https://github.com/opis/closure/workflows/Tests/badge.svg)](https://github.com/opis/closure/actions) -[![Latest Stable Version](https://poser.pugx.org/opis/closure/v/stable.png)](https://packagist.org/packages/opis/closure) -[![Latest Unstable Version](https://poser.pugx.org/opis/closure/v/unstable.png)](https://packagist.org/packages/opis/closure) -[![License](https://poser.pugx.org/opis/closure/license.png)](https://packagist.org/packages/opis/closure) - -Serializable closures ---------------------- -**Opis Closure** is a library that aims to overcome PHP's limitations regarding closure -serialization by providing a wrapper that will make all closures serializable. - -**The library's key features:** - -- Serialize any closure -- Serialize arbitrary objects -- Doesn't use `eval` for closure serialization or unserialization -- Works with any PHP version that has support for closures -- Supports PHP 7 syntax -- Handles all variables referenced/imported in `use()` and automatically wraps all referenced/imported closures for -proper serialization -- Handles recursive closures -- Handles magic constants like `__FILE__`, `__DIR__`, `__LINE__`, `__NAMESPACE__`, `__CLASS__`, -`__TRAIT__`, `__METHOD__` and `__FUNCTION__`. -- Automatically resolves all class names, function names and constant names used inside the closure -- Track closure's residing source by using the `#trackme` directive -- Simple and very fast parser -- Any error or exception, that might occur when executing an unserialized closure, can be caught and treated properly -- You can serialize/unserialize any closure unlimited times, even those previously unserialized -(this is possible because `eval()` is not used for unserialization) -- Handles static closures -- Supports cryptographically signed closures -- Provides a reflector that can give you information about the serialized closure -- Provides an analyzer for *SuperClosure* library -- Automatically detects when the scope and/or the bound object of a closure needs to be serialized -in order for the closure to work after deserialization - -## Documentation - -The full documentation for this library can be found [here][documentation]. - -## License - -**Opis Closure** is licensed under the [MIT License (MIT)][license]. - -## Requirements - -* PHP ^5.4 || ^7.0 || ^8.0 - -## Installation - -**Opis Closure** is available on [Packagist] and it can be installed from a -command line interface by using [Composer]. - -```bash -composer require opis/closure -``` - -Or you could directly reference it into your `composer.json` file as a dependency - -```json -{ - "require": { - "opis/closure": "^3.5" - } -} -``` - -### Migrating from 2.x - -If your project needs to support PHP 5.3 you can continue using the `2.x` version -of **Opis Closure**. Otherwise, assuming you are not using one of the removed/refactored classes or features(see -[CHANGELOG]), migrating to version `3.x` is simply a matter of updating your `composer.json` file. - -### Semantic versioning - -**Opis Closure** follows [semantic versioning][SemVer] specifications. - -### Arbitrary object serialization - -We've added this feature in order to be able to support the serialization of a closure's bound object. -The implementation is far from being perfect, and it's really hard to make it work flawless. -We will try to improve this, but we can't guarantee anything. -So our advice regarding the `Opis\Closure\serialize|unserialize` functions is to use them with caution. - - -[documentation]: https://www.opis.io/closure "Opis Closure" -[license]: http://opensource.org/licenses/MIT "MIT License" -[Packagist]: https://packagist.org/packages/opis/closure "Packagist" -[Composer]: https://getcomposer.org "Composer" -[SemVer]: http://semver.org/ "Semantic versioning" -[CHANGELOG]: https://github.com/opis/closure/blob/master/CHANGELOG.md "Changelog" diff --git a/opis/closure/autoload.php b/opis/closure/autoload.php deleted file mode 100644 index 48b10f66..00000000 --- a/opis/closure/autoload.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -require_once 'functions.php'; - -spl_autoload_register(function($class){ - - $class = ltrim($class, '\\'); - $dir = __DIR__ . '/src'; - $namespace = 'Opis\Closure'; - - if(strpos($class, $namespace) === 0) - { - $class = substr($class, strlen($namespace)); - $path = ''; - if(($pos = strripos($class, '\\')) !== FALSE) - { - $path = str_replace('\\', '/', substr($class, 0, $pos)) . '/'; - $class = substr($class, $pos + 1); - } - $path .= str_replace('_', '/', $class) . '.php'; - $dir .= '/' . $path; - - if(file_exists($dir)) - { - include $dir; - return true; - } - - return false; - } - - return false; - -}); diff --git a/opis/closure/composer.json b/opis/closure/composer.json deleted file mode 100644 index 5d7d77ac..00000000 --- a/opis/closure/composer.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "opis/closure", - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "keywords": ["closure", "serialization", "function", "serializable", "serialize", "anonymous functions"], - "homepage": "https://opis.io/closure", - "license": "MIT", - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, - "files": ["functions.php"] - }, - "autoload-dev": { - "psr-4": { - "Opis\\Closure\\Test\\": "tests/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/opis/closure/functions.php b/opis/closure/functions.php deleted file mode 100644 index 38dcb91f..00000000 --- a/opis/closure/functions.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -/** - * Serialize - * - * @param mixed $data - * @return string - */ -function serialize($data) -{ - SerializableClosure::enterContext(); - SerializableClosure::wrapClosures($data); - $data = \serialize($data); - SerializableClosure::exitContext(); - return $data; -} - -/** - * Unserialize - * - * @param string $data - * @param array|null $options - * @return mixed - */ -function unserialize($data, array $options = null) -{ - SerializableClosure::enterContext(); - $data = ($options === null || \PHP_MAJOR_VERSION < 7) - ? \unserialize($data) - : \unserialize($data, $options); - SerializableClosure::unwrapClosures($data); - SerializableClosure::exitContext(); - return $data; -} diff --git a/opis/closure/src/Analyzer.php b/opis/closure/src/Analyzer.php deleted file mode 100644 index 9618b1c7..00000000 --- a/opis/closure/src/Analyzer.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -use Closure; -use SuperClosure\Analyzer\ClosureAnalyzer; - -/** - * @deprecated We'll remove this class - */ -class Analyzer extends ClosureAnalyzer -{ - /** - * Analyzer a given closure. - * - * @param Closure $closure - * - * @return array - */ - public function analyze(Closure $closure) - { - $reflection = new ReflectionClosure($closure); - $scope = $reflection->getClosureScopeClass(); - - $data = [ - 'reflection' => $reflection, - 'code' => $reflection->getCode(), - 'hasThis' => $reflection->isBindingRequired(), - 'context' => $reflection->getUseVariables(), - 'hasRefs' => false, - 'binding' => $reflection->getClosureThis(), - 'scope' => $scope ? $scope->getName() : null, - 'isStatic' => $reflection->isStatic(), - ]; - - return $data; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineCode(array &$data) - { - return null; - } - - /** - * @param array $data - * @return mixed - */ - protected function determineContext(array &$data) - { - return null; - } - -} diff --git a/opis/closure/src/ClosureContext.php b/opis/closure/src/ClosureContext.php deleted file mode 100644 index d8f13d9d..00000000 --- a/opis/closure/src/ClosureContext.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -/** - * Closure context class - * @internal - */ -class ClosureContext -{ - /** - * @var ClosureScope Closures scope - */ - public $scope; - - /** - * @var integer - */ - public $locks; - - /** - * Constructor - */ - public function __construct() - { - $this->scope = new ClosureScope(); - $this->locks = 0; - } -}
\ No newline at end of file diff --git a/opis/closure/src/ClosureScope.php b/opis/closure/src/ClosureScope.php deleted file mode 100644 index 3afd9b55..00000000 --- a/opis/closure/src/ClosureScope.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -/** - * Closure scope class - * @internal - */ -class ClosureScope extends \SplObjectStorage -{ - /** - * @var integer Number of serializations in current scope - */ - public $serializations = 0; - - /** - * @var integer Number of closures that have to be serialized - */ - public $toserialize = 0; -}
\ No newline at end of file diff --git a/opis/closure/src/ClosureStream.php b/opis/closure/src/ClosureStream.php deleted file mode 100644 index d77d97c8..00000000 --- a/opis/closure/src/ClosureStream.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -/** - * @internal - */ -class ClosureStream -{ - const STREAM_PROTO = 'closure'; - - protected static $isRegistered = false; - - protected $content; - - protected $length; - - protected $pointer = 0; - - function stream_open($path, $mode, $options, &$opened_path) - { - $this->content = "<?php\nreturn " . substr($path, strlen(static::STREAM_PROTO . '://')) . ";"; - $this->length = strlen($this->content); - return true; - } - - public function stream_read($count) - { - $value = substr($this->content, $this->pointer, $count); - $this->pointer += $count; - return $value; - } - - public function stream_eof() - { - return $this->pointer >= $this->length; - } - - public function stream_set_option($option, $arg1, $arg2) - { - return false; - } - - public function stream_stat() - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function url_stat($path, $flags) - { - $stat = stat(__FILE__); - $stat[7] = $stat['size'] = $this->length; - return $stat; - } - - public function stream_seek($offset, $whence = SEEK_SET) - { - $crt = $this->pointer; - - switch ($whence) { - case SEEK_SET: - $this->pointer = $offset; - break; - case SEEK_CUR: - $this->pointer += $offset; - break; - case SEEK_END: - $this->pointer = $this->length + $offset; - break; - } - - if ($this->pointer < 0 || $this->pointer >= $this->length) { - $this->pointer = $crt; - return false; - } - - return true; - } - - public function stream_tell() - { - return $this->pointer; - } - - public static function register() - { - if (!static::$isRegistered) { - static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__); - } - } - -} diff --git a/opis/closure/src/ISecurityProvider.php b/opis/closure/src/ISecurityProvider.php deleted file mode 100644 index 54e2e20a..00000000 --- a/opis/closure/src/ISecurityProvider.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -interface ISecurityProvider -{ - /** - * Sign serialized closure - * @param string $closure - * @return array - */ - public function sign($closure); - - /** - * Verify signature - * @param array $data - * @return bool - */ - public function verify(array $data); -}
\ No newline at end of file diff --git a/opis/closure/src/SecurityException.php b/opis/closure/src/SecurityException.php deleted file mode 100644 index b65f5cb8..00000000 --- a/opis/closure/src/SecurityException.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -use Exception; - -/** - * Security exception class - */ -class SecurityException extends Exception -{ - -}
\ No newline at end of file diff --git a/opis/closure/src/SecurityProvider.php b/opis/closure/src/SecurityProvider.php deleted file mode 100644 index 19529173..00000000 --- a/opis/closure/src/SecurityProvider.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -class SecurityProvider implements ISecurityProvider -{ - /** @var string */ - protected $secret; - - /** - * SecurityProvider constructor. - * @param string $secret - */ - public function __construct($secret) - { - $this->secret = $secret; - } - - /** - * @inheritdoc - */ - public function sign($closure) - { - return array( - 'closure' => $closure, - 'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)), - ); - } - - /** - * @inheritdoc - */ - public function verify(array $data) - { - return base64_encode(hash_hmac('sha256', $data['closure'], $this->secret, true)) === $data['hash']; - } -}
\ No newline at end of file diff --git a/opis/closure/src/SelfReference.php b/opis/closure/src/SelfReference.php deleted file mode 100644 index 425edf27..00000000 --- a/opis/closure/src/SelfReference.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - - -/** - * Helper class used to indicate a reference to an object - * @internal - */ -class SelfReference -{ - /** - * @var string An unique hash representing the object - */ - public $hash; - - /** - * Constructor - * - * @param string $hash - */ - public function __construct($hash) - { - $this->hash = $hash; - } -}
\ No newline at end of file diff --git a/opis/closure/src/SerializableClosure.php b/opis/closure/src/SerializableClosure.php deleted file mode 100644 index 1025ff51..00000000 --- a/opis/closure/src/SerializableClosure.php +++ /dev/null @@ -1,678 +0,0 @@ -<?php -/* =========================================================================== - * Copyright (c) 2018-2021 Zindex Software - * - * Licensed under the MIT License - * =========================================================================== */ - -namespace Opis\Closure; - -use Closure; -use Serializable; -use SplObjectStorage; -use ReflectionObject; - -/** - * Provides a wrapper for serialization of closures - */ -class SerializableClosure implements Serializable -{ - /** - * @var Closure Wrapped closure - * - * @see \Opis\Closure\SerializableClosure::getClosure() - */ - protected $closure; - - /** - * @var ReflectionClosure A reflection instance for closure - * - * @see \Opis\Closure\SerializableClosure::getReflector() - */ - protected $reflector; - - /** - * @var mixed Used at deserialization to hold variables - * - * @see \Opis\Closure\SerializableClosure::unserialize() - * @see \Opis\Closure\SerializableClosure::getReflector() - */ - protected $code; - - /** - * @var string Closure's ID - */ - protected $reference; - - /** - * @var string Closure scope - */ - protected $scope; - - /** - * @var ClosureContext Context of closure, used in serialization - */ - protected static $context; - - /** - * @var ISecurityProvider|null - */ - protected static $securityProvider; - - /** Array recursive constant*/ - const ARRAY_RECURSIVE_KEY = '¯\_(ツ)_/¯'; - - /** - * Constructor - * - * @param Closure $closure Closure you want to serialize - */ - public function __construct(Closure $closure) - { - $this->closure = $closure; - if (static::$context !== null) { - $this->scope = static::$context->scope; - $this->scope->toserialize++; - } - } - - /** - * Get the Closure object - * - * @return Closure The wrapped closure - */ - public function getClosure() - { - return $this->closure; - } - - /** - * Get the reflector for closure - * - * @return ReflectionClosure - */ - public function getReflector() - { - if ($this->reflector === null) { - $this->reflector = new ReflectionClosure($this->closure); - $this->code = null; - } - - return $this->reflector; - } - - /** - * Implementation of magic method __invoke() - */ - public function __invoke() - { - return call_user_func_array($this->closure, func_get_args()); - } - - /** - * Implementation of Serializable::serialize() - * - * @return string The serialized closure - */ - public function serialize() - { - if ($this->scope === null) { - $this->scope = new ClosureScope(); - $this->scope->toserialize++; - } - - $this->scope->serializations++; - - $scope = $object = null; - $reflector = $this->getReflector(); - - if($reflector->isBindingRequired()){ - $object = $reflector->getClosureThis(); - static::wrapClosures($object, $this->scope); - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } else { - if($scope = $reflector->getClosureScopeClass()){ - $scope = $scope->name; - } - } - - $this->reference = spl_object_hash($this->closure); - - $this->scope[$this->closure] = $this; - - $use = $this->transformUseVariables($reflector->getUseVariables()); - $code = $reflector->getCode(); - - $this->mapByReference($use); - - $ret = \serialize(array( - 'use' => $use, - 'function' => $code, - 'scope' => $scope, - 'this' => $object, - 'self' => $this->reference, - )); - - if (static::$securityProvider !== null) { - $data = static::$securityProvider->sign($ret); - $ret = '@' . $data['hash'] . '.' . $data['closure']; - } - - if (!--$this->scope->serializations && !--$this->scope->toserialize) { - $this->scope = null; - } - - return $ret; - } - - /** - * Transform the use variables before serialization. - * - * @param array $data The Closure's use variables - * @return array - */ - protected function transformUseVariables($data) - { - return $data; - } - - /** - * Implementation of Serializable::unserialize() - * - * @param string $data Serialized data - * @throws SecurityException - */ - public function unserialize($data) - { - ClosureStream::register(); - - if (static::$securityProvider !== null) { - if ($data[0] !== '@') { - throw new SecurityException("The serialized closure is not signed. ". - "Make sure you use a security provider for both serialization and unserialization."); - } - - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !static::$securityProvider->verify($data)) { - throw new SecurityException("Your serialized closure might have been modified and it's unsafe to be unserialized. " . - "Make sure you use the same security provider, with the same settings, " . - "both for serialization and unserialization."); - } - - $data = $data['closure']; - } elseif ($data[0] === '@') { - if ($data[1] !== '{') { - $separator = strpos($data, '.'); - if ($separator === false) { - throw new SecurityException('Invalid signed closure'); - } - $hash = substr($data, 1, $separator - 1); - $closure = substr($data, $separator + 1); - - $data = ['hash' => $hash, 'closure' => $closure]; - - unset($hash, $closure); - } else { - $data = json_decode(substr($data, 1), true); - } - - if (!is_array($data) || !isset($data['closure']) || !isset($data['hash'])) { - throw new SecurityException('Invalid signed closure'); - } - - $data = $data['closure']; - } - - $this->code = \unserialize($data); - - // unset data - unset($data); - - $this->code['objects'] = array(); - - if ($this->code['use']) { - $this->scope = new ClosureScope(); - $this->code['use'] = $this->resolveUseVariables($this->code['use']); - $this->mapPointers($this->code['use']); - extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); - $this->scope = null; - } - - $this->closure = include(ClosureStream::STREAM_PROTO . '://' . $this->code['function']); - - if($this->code['this'] === $this){ - $this->code['this'] = null; - } - - $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); - - if(!empty($this->code['objects'])){ - foreach ($this->code['objects'] as $item){ - $item['property']->setValue($item['instance'], $item['object']->getClosure()); - } - } - - $this->code = $this->code['function']; - } - - /** - * Resolve the use variables after unserialization. - * - * @param array $data The Closure's transformed use variables - * @return array - */ - protected function resolveUseVariables($data) - { - return $data; - } - - /** - * Wraps a closure and sets the serialization context (if any) - * - * @param Closure $closure Closure to be wrapped - * - * @return self The wrapped closure - */ - public static function from(Closure $closure) - { - if (static::$context === null) { - $instance = new static($closure); - } elseif (isset(static::$context->scope[$closure])) { - $instance = static::$context->scope[$closure]; - } else { - $instance = new static($closure); - static::$context->scope[$closure] = $instance; - } - - return $instance; - } - - /** - * Increments the context lock counter or creates a new context if none exist - */ - public static function enterContext() - { - if (static::$context === null) { - static::$context = new ClosureContext(); - } - - static::$context->locks++; - } - - /** - * Decrements the context lock counter and destroy the context when it reaches to 0 - */ - public static function exitContext() - { - if (static::$context !== null && !--static::$context->locks) { - static::$context = null; - } - } - - /** - * @param string $secret - */ - public static function setSecretKey($secret) - { - if(static::$securityProvider === null){ - static::$securityProvider = new SecurityProvider($secret); - } - } - - /** - * @param ISecurityProvider $securityProvider - */ - public static function addSecurityProvider(ISecurityProvider $securityProvider) - { - static::$securityProvider = $securityProvider; - } - - /** - * Remove security provider - */ - public static function removeSecurityProvider() - { - static::$securityProvider = null; - } - - /** - * @return null|ISecurityProvider - */ - public static function getSecurityProvider() - { - return static::$securityProvider; - } - - /** - * Wrap closures - * - * @internal - * @param $data - * @param ClosureScope|SplObjectStorage|null $storage - */ - public static function wrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof Closure){ - $data = static::from($data); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::wrapClosures($value, $storage); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif($data instanceof \stdClass){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $data = $storage[$data] = clone($data); - foreach ($data as &$value){ - static::wrapClosures($value, $storage); - } - unset($value); - } elseif (is_object($data) && ! $data instanceof static){ - if(isset($storage[$data])){ - $data = $storage[$data]; - return; - } - $instance = $data; - $reflection = new ReflectionObject($instance); - if(!$reflection->isUserDefined()){ - $storage[$instance] = $data; - return; - } - $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - static::wrapClosures($value, $storage); - } - $property->setValue($data, $value); - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Unwrap closures - * - * @internal - * @param $data - * @param SplObjectStorage|null $storage - */ - public static function unwrapClosures(&$data, SplObjectStorage $storage = null) - { - if($storage === null){ - $storage = static::$context->scope; - } - - if($data instanceof static){ - $data = $data->getClosure(); - } elseif (is_array($data)){ - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - static::unwrapClosures($value, $storage); - } - unset($data[self::ARRAY_RECURSIVE_KEY]); - }elseif ($data instanceof \stdClass){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - foreach ($data as &$property){ - static::unwrapClosures($property, $storage); - } - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($storage[$data])){ - return; - } - $storage[$data] = true; - $reflection = new ReflectionObject($data); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $value = $property->getValue($data); - if(is_array($value) || is_object($value)){ - static::unwrapClosures($value, $storage); - $property->setValue($data, $value); - } - }; - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Creates a new closure from arbitrary code, - * emulating create_function, but without using eval - * - * @param string$args - * @param string $code - * @return Closure - */ - public static function createClosure($args, $code) - { - ClosureStream::register(); - return include(ClosureStream::STREAM_PROTO . '://function(' . $args. '){' . $code . '};'); - } - - /** - * Internal method used to map closure pointers - * @internal - * @param $data - */ - protected function mapPointers(&$data) - { - $scope = $this->scope; - - if ($data instanceof static) { - $data = &$data->closure; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } elseif ($value instanceof static) { - $data[$key] = &$value->closure; - } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data[$key] = &$this->closure; - } else { - $this->mapPointers($value); - } - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - foreach ($data as $key => &$value){ - if ($value instanceof SelfReference && $value->hash === $this->code['self']){ - $data->{$key} = &$this->closure; - } elseif(is_array($value) || is_object($value)) { - $this->mapPointers($value); - } - } - unset($value); - } elseif (is_object($data) && !($data instanceof Closure)){ - if(isset($scope[$data])){ - return; - } - $scope[$data] = true; - $reflection = new ReflectionObject($data); - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($data)) { - continue; - } - $item = $property->getValue($data); - if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { - $this->code['objects'][] = array( - 'instance' => $data, - 'property' => $property, - 'object' => $item instanceof SelfReference ? $this : $item, - ); - } elseif (is_array($item) || is_object($item)) { - $this->mapPointers($item); - $property->setValue($data, $item); - } - } - } while($reflection = $reflection->getParentClass()); - } - } - - /** - * Internal method used to map closures by reference - * - * @internal - * @param mixed &$data - */ - protected function mapByReference(&$data) - { - if ($data instanceof Closure) { - if($data === $this->closure){ - $data = new SelfReference($this->reference); - return; - } - - if (isset($this->scope[$data])) { - $data = $this->scope[$data]; - return; - } - - $instance = new static($data); - - if (static::$context !== null) { - static::$context->scope->toserialize--; - } else { - $instance->scope = $this->scope; - } - - $data = $this->scope[$data] = $instance; - } elseif (is_array($data)) { - if(isset($data[self::ARRAY_RECURSIVE_KEY])){ - return; - } - $data[self::ARRAY_RECURSIVE_KEY] = true; - foreach ($data as $key => &$value){ - if($key === self::ARRAY_RECURSIVE_KEY){ - continue; - } - $this->mapByReference($value); - } - unset($value); - unset($data[self::ARRAY_RECURSIVE_KEY]); - } elseif ($data instanceof \stdClass) { - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - $instance = $data; - $this->scope[$instance] = $data = clone($data); - - foreach ($data as &$value){ - $this->mapByReference($value); - } - unset($value); - } elseif (is_object($data) && !$data instanceof SerializableClosure){ - if(isset($this->scope[$data])){ - $data = $this->scope[$data]; - return; - } - - $instance = $data; - $reflection = new ReflectionObject($data); - if(!$reflection->isUserDefined()){ - $this->scope[$instance] = $data; - return; - } - $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); - - do{ - if(!$reflection->isUserDefined()){ - break; - } - foreach ($reflection->getProperties() as $property){ - if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ - continue; - } - $property->setAccessible(true); - if (PHP_VERSION >= 7.4 && !$property->isInitialized($instance)) { - continue; - } - $value = $property->getValue($instance); - if(is_array($value) || is_object($value)){ - $this->mapByReference($value); - } - $property->setValue($data, $value); - } - } while($reflection = $reflection->getParentClass()); - } - } - -} |