diff --git a/data/web/inc/lib/composer.json b/data/web/inc/lib/composer.json index 91a50bcbf..3998065cb 100644 --- a/data/web/inc/lib/composer.json +++ b/data/web/inc/lib/composer.json @@ -11,6 +11,7 @@ "directorytree/ldaprecord": "^3.3", "twig/twig": "^3.0", "stevenmaguire/oauth2-keycloak": "^4.0", - "league/oauth2-client": "^2.7" + "league/oauth2-client": "^2.7", + "bacon/bacon-qr-code": "^2.0" } } diff --git a/data/web/inc/lib/composer.lock b/data/web/inc/lib/composer.lock index fb1c3903b..4254deffb 100644 --- a/data/web/inc/lib/composer.lock +++ b/data/web/inc/lib/composer.lock @@ -4,8 +4,62 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8f5a147cdb147b935a158b86f47a4747", + "content-hash": "50fb4a320500820e36f30eabc45222a0", "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "time": "2022-12-07T17:46:57+00:00" + }, { "name": "bshaffer/oauth2-server-php", "version": "v1.11.1", @@ -137,6 +191,56 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "time": "2025-09-16T12:23:56+00:00" + }, { "name": "ddeboer/imap", "version": "1.13.1", @@ -214,30 +318,32 @@ }, { "name": "directorytree/ldaprecord", - "version": "v2.20.5", + "version": "v3.8.5", "source": { "type": "git", "url": "https://github.com/DirectoryTree/LdapRecord.git", - "reference": "5bd0a5a9d257cf1049ae83055dbba4c3479ddf16" + "reference": "00e5f088f8c4028d5f398783cccc2e8119a27a65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/5bd0a5a9d257cf1049ae83055dbba4c3479ddf16", - "reference": "5bd0a5a9d257cf1049ae83055dbba4c3479ddf16", + "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/00e5f088f8c4028d5f398783cccc2e8119a27a65", + "reference": "00e5f088f8c4028d5f398783cccc2e8119a27a65", "shasum": "" }, "require": { + "ext-iconv": "*", "ext-json": "*", "ext-ldap": "*", - "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", - "nesbot/carbon": "^1.0|^2.0", - "php": ">=7.3", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0", - "symfony/polyfill-php80": "^1.25", - "tightenco/collect": "^5.6|^6.0|^7.0|^8.0|^9.0" + "illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", + "nesbot/carbon": "*", + "php": ">=8.1", + "psr/log": "*", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, "require-dev": { + "fakerphp/faker": "^1.21", + "laravel/pint": "^1.6", "mockery/mockery": "^1.0", "phpunit/phpunit": "^9.0", "spatie/ray": "^1.24" @@ -284,7 +390,7 @@ "type": "github" } ], - "time": "2023-10-11T16:34:34+00:00" + "time": "2025-10-06T02:22:34+00:00" }, { "name": "firebase/php-jwt", @@ -677,6 +783,107 @@ ], "time": "2023-04-17T16:00:45+00:00" }, + { + "name": "illuminate/collections", + "version": "v10.49.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/6ae9c74fa92d4e1824d1b346cd435e8eacdc3232", + "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232", + "shasum": "" + }, + "require": { + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "php": "^8.1" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^6.2)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2025-09-08T19:05:53+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v10.49.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/47c700320b7a419f0d188d111f3bbed978fcbd3f", + "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2025-03-24T11:47:24+00:00" + }, { "name": "illuminate/contracts", "version": "v10.44.0", @@ -725,6 +932,52 @@ }, "time": "2024-01-15T18:52:32+00:00" }, + { + "name": "illuminate/macroable", + "version": "v10.49.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-06-05T12:46:42+00:00" + }, { "name": "league/oauth2-client", "version": "2.7.0", @@ -2452,145 +2705,6 @@ ], "time": "2023-12-26T14:02:43+00:00" }, - { - "name": "symfony/var-dumper", - "version": "v6.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "0435a08f69125535336177c29d56af3abc1f69da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0435a08f69125535336177c29d56af3abc1f69da", - "reference": "0435a08f69125535336177c29d56af3abc1f69da", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/console": "<5.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-23T14:53:30+00:00" - }, - { - "name": "tightenco/collect", - "version": "v9.52.7", - "source": { - "type": "git", - "url": "https://github.com/tighten/collect.git", - "reference": "b15143cd11fe01a700fcc449df61adc64452fa6d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/b15143cd11fe01a700fcc449df61adc64452fa6d", - "reference": "b15143cd11fe01a700fcc449df61adc64452fa6d", - "shasum": "" - }, - "require": { - "php": "^8.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "nesbot/carbon": "^2.23.0", - "phpunit/phpunit": "^8.3" - }, - "type": "library", - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": [ - "collection", - "laravel" - ], - "support": { - "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v9.52.7" - }, - "time": "2023-04-14T21:51:36+00:00" - }, { "name": "twig/twig", "version": "v3.14.0", @@ -2674,10 +2788,10 @@ "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": {}, + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/LICENSE b/data/web/inc/lib/vendor/bacon/bacon-qr-code/LICENSE new file mode 100644 index 000000000..d45a35647 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017, Ben Scholzen 'DASPRiD' +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/README.md b/data/web/inc/lib/vendor/bacon/bacon-qr-code/README.md new file mode 100644 index 000000000..9c099fefd --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/README.md @@ -0,0 +1,39 @@ +# QR Code generator + +[![PHP CI](https://github.com/Bacon/BaconQrCode/actions/workflows/ci.yml/badge.svg)](https://github.com/Bacon/BaconQrCode/actions/workflows/ci.yml) +[![codecov](https://codecov.io/gh/Bacon/BaconQrCode/branch/master/graph/badge.svg?token=rD0HcAiEEx)](https://codecov.io/gh/Bacon/BaconQrCode) +[![Latest Stable Version](https://poser.pugx.org/bacon/bacon-qr-code/v/stable)](https://packagist.org/packages/bacon/bacon-qr-code) +[![Total Downloads](https://poser.pugx.org/bacon/bacon-qr-code/downloads)](https://packagist.org/packages/bacon/bacon-qr-code) +[![License](https://poser.pugx.org/bacon/bacon-qr-code/license)](https://packagist.org/packages/bacon/bacon-qr-code) + + +## Introduction +BaconQrCode is a port of QR code portion of the ZXing library. It currently +only features the encoder part, but could later receive the decoder part as +well. + +As the Reed Solomon codec implementation of the ZXing library performs quite +slow in PHP, it was exchanged with the implementation by Phil Karn. + + +## Example usage +```php +use BaconQrCode\Renderer\ImageRenderer; +use BaconQrCode\Renderer\Image\ImagickImageBackEnd; +use BaconQrCode\Renderer\RendererStyle\RendererStyle; +use BaconQrCode\Writer; + +$renderer = new ImageRenderer( + new RendererStyle(400), + new ImagickImageBackEnd() +); +$writer = new Writer($renderer); +$writer->writeFile('Hello World!', 'qrcode.png'); +``` + +## Available image renderer back ends +BaconQrCode comes with multiple back ends for rendering images. Currently included are the following: + +- `ImagickImageBackEnd`: renders raster images using the Imagick library +- `SvgImageBackEnd`: renders SVG files using XMLWriter +- `EpsImageBackEnd`: renders EPS files diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/composer.json b/data/web/inc/lib/vendor/bacon/bacon-qr-code/composer.json new file mode 100644 index 000000000..7f193daf0 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/composer.json @@ -0,0 +1,44 @@ +{ + "name": "bacon/bacon-qr-code", + "description": "BaconQrCode is a QR code generator for PHP.", + "license" : "BSD-2-Clause", + "homepage": "https://github.com/Bacon/BaconQrCode", + "require": { + "php": "^7.1 || ^8.0", + "ext-iconv": "*", + "dasprid/enum": "^1.0.3" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4", + "phly/keep-a-changelog": "^2.1" + }, + "config": { + "allow-plugins": { + "ocramius/package-versions": true + } + }, + "archive": { + "exclude": [ + "/test", + "/phpunit.xml.dist" + ] + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/phpunit.xml.dist b/data/web/inc/lib/vendor/bacon/bacon-qr-code/phpunit.xml.dist new file mode 100644 index 000000000..d9e4d57bc --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/phpunit.xml.dist @@ -0,0 +1,13 @@ + + + + + src + + + + + ./test + + + diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitArray.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitArray.php new file mode 100644 index 000000000..158384fe8 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitArray.php @@ -0,0 +1,372 @@ + + */ + private $bits; + + /** + * Size of the bit array in bits. + * + * @var int + */ + private $size; + + /** + * Creates a new bit array with a given size. + */ + public function __construct(int $size = 0) + { + $this->size = $size; + $this->bits = SplFixedArray::fromArray(array_fill(0, ($this->size + 31) >> 3, 0)); + } + + /** + * Gets the size in bits. + */ + public function getSize() : int + { + return $this->size; + } + + /** + * Gets the size in bytes. + */ + public function getSizeInBytes() : int + { + return ($this->size + 7) >> 3; + } + + /** + * Ensures that the array has a minimum capacity. + */ + public function ensureCapacity(int $size) : void + { + if ($size > count($this->bits) << 5) { + $this->bits->setSize(($size + 31) >> 5); + } + } + + /** + * Gets a specific bit. + */ + public function get(int $i) : bool + { + return 0 !== ($this->bits[$i >> 5] & (1 << ($i & 0x1f))); + } + + /** + * Sets a specific bit. + */ + public function set(int $i) : void + { + $this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f); + } + + /** + * Flips a specific bit. + */ + public function flip(int $i) : void + { + $this->bits[$i >> 5] ^= 1 << ($i & 0x1f); + } + + /** + * Gets the next set bit position from a given position. + */ + public function getNextSet(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = $this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = $this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return $result > $this->size ? $this->size : $result; + } + + /** + * Gets the next unset bit position from a given position. + */ + public function getNextUnset(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = ~$this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = ~$this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return $result > $this->size ? $this->size : $result; + } + + /** + * Sets a bulk of bits. + */ + public function setBulk(int $i, int $newBits) : void + { + $this->bits[$i >> 5] = $newBits; + } + + /** + * Sets a range of bits. + * + * @throws InvalidArgumentException if end is smaller than start + */ + public function setRange(int $start, int $end) : void + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j < $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + $this->bits[$i] = $this->bits[$i] | $mask; + } + } + + /** + * Clears the bit array, unsetting every bit. + */ + public function clear() : void + { + $bitsLength = count($this->bits); + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Checks if a range of bits is set or not set. + + * @throws InvalidArgumentException if end is smaller than start + */ + public function isRange(int $start, int $end, bool $value) : bool + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return true; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j <= $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) { + return false; + } + } + + return true; + } + + /** + * Appends a bit to the array. + */ + public function appendBit(bool $bit) : void + { + $this->ensureCapacity($this->size + 1); + + if ($bit) { + $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f)); + } + + ++$this->size; + } + + /** + * Appends a number of bits (up to 32) to the array. + + * @throws InvalidArgumentException if num bits is not between 0 and 32 + */ + public function appendBits(int $value, int $numBits) : void + { + if ($numBits < 0 || $numBits > 32) { + throw new InvalidArgumentException('Num bits must be between 0 and 32'); + } + + $this->ensureCapacity($this->size + $numBits); + + for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) { + $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1); + } + } + + /** + * Appends another bit array to this array. + */ + public function appendBitArray(self $other) : void + { + $otherSize = $other->getSize(); + $this->ensureCapacity($this->size + $other->getSize()); + + for ($i = 0; $i < $otherSize; ++$i) { + $this->appendBit($other->get($i)); + } + } + + /** + * Makes an exclusive-or comparision on the current bit array. + * + * @throws InvalidArgumentException if sizes don't match + */ + public function xorBits(self $other) : void + { + $bitsLength = count($this->bits); + $otherBits = $other->getBitArray(); + + if ($bitsLength !== count($otherBits)) { + throw new InvalidArgumentException('Sizes don\'t match'); + } + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i]; + } + } + + /** + * Converts the bit array to a byte array. + * + * @return SplFixedArray + */ + public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray + { + $bytes = new SplFixedArray($numBytes); + + for ($i = 0; $i < $numBytes; ++$i) { + $byte = 0; + + for ($j = 0; $j < 8; ++$j) { + if ($this->get($bitOffset)) { + $byte |= 1 << (7 - $j); + } + + ++$bitOffset; + } + + $bytes[$i] = $byte; + } + + return $bytes; + } + + /** + * Gets the internal bit array. + * + * @return SplFixedArray + */ + public function getBitArray() : SplFixedArray + { + return $this->bits; + } + + /** + * Reverses the array. + */ + public function reverse() : void + { + $newBits = new SplFixedArray(count($this->bits)); + + for ($i = 0; $i < $this->size; ++$i) { + if ($this->get($this->size - $i - 1)) { + $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f)); + } + } + + $this->bits = $newBits; + } + + /** + * Returns a string representation of the bit array. + */ + public function __toString() : string + { + $result = ''; + + for ($i = 0; $i < $this->size; ++$i) { + if (0 === ($i & 0x07)) { + $result .= ' '; + } + + $result .= $this->get($i) ? 'X' : '.'; + } + + return $result; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php new file mode 100644 index 000000000..10bf8fe20 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php @@ -0,0 +1,313 @@ + + */ + private $bits; + + /** + * @throws InvalidArgumentException if a dimension is smaller than zero + */ + public function __construct(int $width, int $height = null) + { + if (null === $height) { + $height = $width; + } + + if ($width < 1 || $height < 1) { + throw new InvalidArgumentException('Both dimensions must be greater than zero'); + } + + $this->width = $width; + $this->height = $height; + $this->rowSize = ($width + 31) >> 5; + $this->bits = SplFixedArray::fromArray(array_fill(0, $this->rowSize * $height, 0)); + } + + /** + * Gets the requested bit, where true means black. + */ + public function get(int $x, int $y) : bool + { + $offset = $y * $this->rowSize + ($x >> 5); + return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1); + } + + /** + * Sets the given bit to true. + */ + public function set(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f)); + } + + /** + * Flips the given bit. + */ + public function flip(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f)); + } + + /** + * Clears all bits (set to false). + */ + public function clear() : void + { + $max = count($this->bits); + + for ($i = 0; $i < $max; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Sets a square region of the bit matrix to true. + * + * @throws InvalidArgumentException if left or top are negative + * @throws InvalidArgumentException if width or height are smaller than 1 + * @throws InvalidArgumentException if region does not fit into the matix + */ + public function setRegion(int $left, int $top, int $width, int $height) : void + { + if ($top < 0 || $left < 0) { + throw new InvalidArgumentException('Left and top must be non-negative'); + } + + if ($height < 1 || $width < 1) { + throw new InvalidArgumentException('Width and height must be at least 1'); + } + + $right = $left + $width; + $bottom = $top + $height; + + if ($bottom > $this->height || $right > $this->width) { + throw new InvalidArgumentException('The region must fit inside the matrix'); + } + + for ($y = $top; $y < $bottom; ++$y) { + $offset = $y * $this->rowSize; + + for ($x = $left; $x < $right; ++$x) { + $index = $offset + ($x >> 5); + $this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f)); + } + } + } + + /** + * A fast method to retrieve one row of data from the matrix as a BitArray. + */ + public function getRow(int $y, BitArray $row = null) : BitArray + { + if (null === $row || $row->getSize() < $this->width) { + $row = new BitArray($this->width); + } + + $offset = $y * $this->rowSize; + + for ($x = 0; $x < $this->rowSize; ++$x) { + $row->setBulk($x << 5, $this->bits[$offset + $x]); + } + + return $row; + } + + /** + * Sets a row of data from a BitArray. + */ + public function setRow(int $y, BitArray $row) : void + { + $bits = $row->getBitArray(); + + for ($i = 0; $i < $this->rowSize; ++$i) { + $this->bits[$y * $this->rowSize + $i] = $bits[$i]; + } + } + + /** + * This is useful in detecting the enclosing rectangle of a 'pure' barcode. + * + * @return int[]|null + */ + public function getEnclosingRectangle() : ?array + { + $left = $this->width; + $top = $this->height; + $right = -1; + $bottom = -1; + + for ($y = 0; $y < $this->height; ++$y) { + for ($x32 = 0; $x32 < $this->rowSize; ++$x32) { + $bits = $this->bits[$y * $this->rowSize + $x32]; + + if (0 !== $bits) { + if ($y < $top) { + $top = $y; + } + + if ($y > $bottom) { + $bottom = $y; + } + + if ($x32 * 32 < $left) { + $bit = 0; + + while (($bits << (31 - $bit)) === 0) { + $bit++; + } + + if (($x32 * 32 + $bit) < $left) { + $left = $x32 * 32 + $bit; + } + } + } + + if ($x32 * 32 + 31 > $right) { + $bit = 31; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + if (($x32 * 32 + $bit) > $right) { + $right = $x32 * 32 + $bit; + } + } + } + } + + $width = $right - $left; + $height = $bottom - $top; + + if ($width < 0 || $height < 0) { + return null; + } + + return [$left, $top, $width, $height]; + } + + /** + * Gets the most top left set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getTopLeftOnBit() : ?array + { + $bitsOffset = 0; + + while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) { + ++$bitsOffset; + } + + if (count($this->bits) === $bitsOffset) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === ($bits << (31 - $bit))) { + ++$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the most bottom right set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getBottomRightOnBit() : ?array + { + $bitsOffset = count($this->bits) - 1; + + while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) { + --$bitsOffset; + } + + if ($bitsOffset < 0) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the width of the matrix, + */ + public function getWidth() : int + { + return $this->width; + } + + /** + * Gets the height of the matrix. + */ + public function getHeight() : int + { + return $this->height; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php new file mode 100644 index 000000000..0c575b493 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php @@ -0,0 +1,41 @@ +>>" in other + * languages. + */ + public static function unsignedRightShift(int $a, int $b) : int + { + return ( + $a >= 0 + ? $a >> $b + : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1)) + ); + } + + /** + * Gets the number of trailing zeros. + */ + public static function numberOfTrailingZeros(int $i) : int + { + $lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1'); + return $lastPos === false ? 32 : 31 - $lastPos; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php new file mode 100644 index 000000000..9049ccb30 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php @@ -0,0 +1,183 @@ +|null + */ + private static $valueToEci; + + /** + * @var array|null + */ + private static $nameToEci; + + /** + * @param int[] $values + */ + public function __construct(array $values, string ...$otherEncodingNames) + { + $this->values = $values; + $this->otherEncodingNames = $otherEncodingNames; + } + + /** + * Returns the primary value. + */ + public function getValue() : int + { + return $this->values[0]; + } + + /** + * Gets character set ECI by value. + * + * Returns the representing ECI of a given value, or null if it is legal but unsupported. + * + * @throws InvalidArgumentException if value is not between 0 and 900 + */ + public static function getCharacterSetEciByValue(int $value) : ?self + { + if ($value < 0 || $value >= 900) { + throw new InvalidArgumentException('Value must be between 0 and 900'); + } + + $valueToEci = self::valueToEci(); + + if (! array_key_exists($value, $valueToEci)) { + return null; + } + + return $valueToEci[$value]; + } + + /** + * Returns character set ECI by name. + * + * Returns the representing ECI of a given name, or null if it is legal but unsupported + */ + public static function getCharacterSetEciByName(string $name) : ?self + { + $nameToEci = self::nameToEci(); + $name = strtolower($name); + + if (! array_key_exists($name, $nameToEci)) { + return null; + } + + return $nameToEci[$name]; + } + + private static function valueToEci() : array + { + if (null !== self::$valueToEci) { + return self::$valueToEci; + } + + self::$valueToEci = []; + + foreach (self::values() as $eci) { + foreach ($eci->values as $value) { + self::$valueToEci[$value] = $eci; + } + } + + return self::$valueToEci; + } + + private static function nameToEci() : array + { + if (null !== self::$nameToEci) { + return self::$nameToEci; + } + + self::$nameToEci = []; + + foreach (self::values() as $eci) { + self::$nameToEci[strtolower($eci->name())] = $eci; + + foreach ($eci->otherEncodingNames as $name) { + self::$nameToEci[strtolower($name)] = $eci; + } + } + + return self::$nameToEci; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php new file mode 100644 index 000000000..a9a1d07d7 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php @@ -0,0 +1,49 @@ +count = $count; + $this->dataCodewords = $dataCodewords; + } + + /** + * Returns how many times the block is used. + */ + public function getCount() : int + { + return $this->count; + } + + /** + * Returns the number of data codewords. + */ + public function getDataCodewords() : int + { + return $this->dataCodewords; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php new file mode 100644 index 000000000..172b5f278 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php @@ -0,0 +1,74 @@ +ecCodewordsPerBlock = $ecCodewordsPerBlock; + $this->ecBlocks = $ecBlocks; + } + + /** + * Returns the number of EC codewords per block. + */ + public function getEcCodewordsPerBlock() : int + { + return $this->ecCodewordsPerBlock; + } + + /** + * Returns the total number of EC block appearances. + */ + public function getNumBlocks() : int + { + $total = 0; + + foreach ($this->ecBlocks as $ecBlock) { + $total += $ecBlock->getCount(); + } + + return $total; + } + + /** + * Returns the total count of EC codewords. + */ + public function getTotalEcCodewords() : int + { + return $this->ecCodewordsPerBlock * $this->getNumBlocks(); + } + + /** + * Returns the EC blocks included in this collection. + * + * @return EcBlock[] + */ + public function getEcBlocks() : array + { + return $this->ecBlocks; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php new file mode 100644 index 000000000..9bbf44068 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php @@ -0,0 +1,63 @@ +bits = $bits; + } + + /** + * @throws OutOfBoundsException if number of bits is invalid + */ + public static function forBits(int $bits) : self + { + switch ($bits) { + case 0: + return self::M(); + + case 1: + return self::L(); + + case 2: + return self::H(); + + case 3: + return self::Q(); + } + + throw new OutOfBoundsException('Invalid number of bits'); + } + + /** + * Returns the two bits used to encode this error correction level. + */ + public function getBits() : int + { + return $this->bits; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php new file mode 100644 index 000000000..38295fc69 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php @@ -0,0 +1,203 @@ +ecLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x3); + $this->dataMask = $formatInfo & 0x7; + } + + /** + * Checks how many bits are different between two integers. + */ + public static function numBitsDiffering(int $a, int $b) : int + { + $a ^= $b; + + return ( + self::BITS_SET_IN_HALF_BYTE[$a & 0xf] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 4) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 8) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 12) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 16) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 20) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 24) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 28) & 0xf)] + ); + } + + /** + * Decodes format information. + */ + public static function decodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2); + + if (null !== $formatInfo) { + return $formatInfo; + } + + // Should return null, but, some QR codes apparently do not mask this info. Try again by actually masking the + // pattern first. + return self::doDecodeFormatInformation( + $maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR, + $maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR + ); + } + + /** + * Internal method for decoding format information. + */ + private static function doDecodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $bestDifference = PHP_INT_MAX; + $bestFormatInfo = 0; + + foreach (self::FORMAT_INFO_DECODE_LOOKUP as $decodeInfo) { + $targetInfo = $decodeInfo[0]; + + if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) { + // Found an exact match + return new self($decodeInfo[1]); + } + + $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + + if ($maskedFormatInfo1 !== $maskedFormatInfo2) { + // Also try the other option + $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + } + } + + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match. + if ($bestDifference <= 3) { + return new self($bestFormatInfo); + } + + return null; + } + + /** + * Returns the error correction level. + */ + public function getErrorCorrectionLevel() : ErrorCorrectionLevel + { + return $this->ecLevel; + } + + /** + * Returns the data mask. + */ + public function getDataMask() : int + { + return $this->dataMask; + } + + /** + * Hashes the code of the EC level. + */ + public function hashCode() : int + { + return ($this->ecLevel->getBits() << 3) | $this->dataMask; + } + + /** + * Verifies if this instance equals another one. + */ + public function equals(self $other) : bool + { + return ( + $this->ecLevel === $other->ecLevel + && $this->dataMask === $other->dataMask + ); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Mode.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Mode.php new file mode 100644 index 000000000..af5a113f4 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Mode.php @@ -0,0 +1,79 @@ +characterCountBitsForVersions = $characterCountBitsForVersions; + $this->bits = $bits; + } + + /** + * Returns the number of bits used in a specific QR code version. + */ + public function getCharacterCountBits(Version $version) : int + { + $number = $version->getVersionNumber(); + + if ($number <= 9) { + $offset = 0; + } elseif ($number <= 26) { + $offset = 1; + } else { + $offset = 2; + } + + return $this->characterCountBitsForVersions[$offset]; + } + + /** + * Returns the four bits used to encode this mode. + */ + public function getBits() : int + { + return $this->bits; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php new file mode 100644 index 000000000..a5aad0b51 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php @@ -0,0 +1,468 @@ + 8) { + throw new InvalidArgumentException('Symbol size must be between 0 and 8'); + } + + if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) { + throw new InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize)); + } + + if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) { + throw new InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize)); + } + + if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) { + throw new InvalidArgumentException( + 'Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots) + ); + } + + $this->symbolSize = $symbolSize; + $this->blockSize = (1 << $symbolSize) - 1; + $this->padding = $padding; + $this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + $this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + + // Generate galous field lookup table + $this->indexOf[0] = $this->blockSize; + $this->alphaTo[$this->blockSize] = 0; + + $sr = 1; + + for ($i = 0; $i < $this->blockSize; ++$i) { + $this->indexOf[$sr] = $i; + $this->alphaTo[$i] = $sr; + + $sr <<= 1; + + if ($sr & (1 << $symbolSize)) { + $sr ^= $gfPoly; + } + + $sr &= $this->blockSize; + } + + if (1 !== $sr) { + throw new RuntimeException('Field generator polynomial is not primitive'); + } + + // Form RS code generator polynomial from its roots + $this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false); + $this->firstRoot = $firstRoot; + $this->primitive = $primitive; + $this->numRoots = $numRoots; + + // Find prim-th root of 1, used in decoding + for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize) { + } + + $this->iPrimitive = intdiv($iPrimitive, $primitive); + + $this->generatorPoly[0] = 1; + + for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; ++$i, $root += $primitive) { + $this->generatorPoly[$i + 1] = 1; + + for ($j = $i; $j > 0; $j--) { + if ($this->generatorPoly[$j] !== 0) { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root) + ]; + } else { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1]; + } + } + + $this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)]; + } + + // Convert generator poly to index form for quicker encoding + for ($i = 0; $i <= $numRoots; ++$i) { + $this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]]; + } + } + + /** + * Encodes data and writes result back into parity array. + */ + public function encode(SplFixedArray $data, SplFixedArray $parity) : void + { + for ($i = 0; $i < $this->numRoots; ++$i) { + $parity[$i] = 0; + } + + $iterations = $this->blockSize - $this->numRoots - $this->padding; + + for ($i = 0; $i < $iterations; ++$i) { + $feedback = $this->indexOf[$data[$i] ^ $parity[0]]; + + if ($feedback !== $this->blockSize) { + // Feedback term is non-zero + $feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback); + + for ($j = 1; $j < $this->numRoots; ++$j) { + $parity[$j] = $parity[$j] ^ $this->alphaTo[ + $this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j]) + ]; + } + } + + for ($j = 0; $j < $this->numRoots - 1; ++$j) { + $parity[$j] = $parity[$j + 1]; + } + + if ($feedback !== $this->blockSize) { + $parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])]; + } else { + $parity[$this->numRoots - 1] = 0; + } + } + } + + /** + * Decodes received data. + */ + public function decode(SplFixedArray $data, SplFixedArray $erasures = null) : ?int + { + // This speeds up the initialization a bit. + $numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false); + $numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false); + + $lambda = clone $numRootsPlusOne; + $b = clone $numRootsPlusOne; + $t = clone $numRootsPlusOne; + $omega = clone $numRootsPlusOne; + $root = clone $numRoots; + $loc = clone $numRoots; + + $numErasures = (null !== $erasures ? count($erasures) : 0); + + // Form the Syndromes; i.e., evaluate data(x) at roots of g(x) + $syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false); + + for ($i = 1; $i < $this->blockSize - $this->padding; ++$i) { + for ($j = 0; $j < $this->numRoots; ++$j) { + if ($syndromes[$j] === 0) { + $syndromes[$j] = $data[$i]; + } else { + $syndromes[$j] = $data[$i] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive) + ]; + } + } + } + + // Convert syndromes to index form, checking for nonzero conditions + $syndromeError = 0; + + for ($i = 0; $i < $this->numRoots; ++$i) { + $syndromeError |= $syndromes[$i]; + $syndromes[$i] = $this->indexOf[$syndromes[$i]]; + } + + if (! $syndromeError) { + // If syndrome is zero, data[] is a codeword and there are no errors to correct, so return data[] + // unmodified. + return 0; + } + + $lambda[0] = 1; + + if ($numErasures > 0) { + // Init lambda to be the erasure locator polynomial + $lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))]; + + for ($i = 1; $i < $numErasures; ++$i) { + $u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i])); + + for ($j = $i + 1; $j > 0; --$j) { + $tmp = $this->indexOf[$lambda[$j - 1]]; + + if ($tmp !== $this->blockSize) { + $lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)]; + } + } + } + } + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $b[$i] = $this->indexOf[$lambda[$i]]; + } + + // Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial + $r = $numErasures; + $el = $numErasures; + + while (++$r <= $this->numRoots) { + // Compute discrepancy at the r-th step in poly form + $discrepancyR = 0; + + for ($i = 0; $i < $r; ++$i) { + if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) { + $discrepancyR ^= $this->alphaTo[ + $this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1]) + ]; + } + } + + $discrepancyR = $this->indexOf[$discrepancyR]; + + if ($discrepancyR === $this->blockSize) { + $tmp = $b->toArray(); + array_unshift($tmp, $this->blockSize); + array_pop($tmp); + $b = SplFixedArray::fromArray($tmp, false); + continue; + } + + $t[0] = $lambda[0]; + + for ($i = 0; $i < $this->numRoots; ++$i) { + if ($b[$i] !== $this->blockSize) { + $t[$i + 1] = $lambda[$i + 1] ^ $this->alphaTo[$this->modNn($discrepancyR + $b[$i])]; + } else { + $t[$i + 1] = $lambda[$i + 1]; + } + } + + if (2 * $el <= $r + $numErasures - 1) { + $el = $r + $numErasures - $el; + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $b[$i] = ( + $lambda[$i] === 0 + ? $this->blockSize + : $this->modNn($this->indexOf[$lambda[$i]] - $discrepancyR + $this->blockSize) + ); + } + } else { + $tmp = $b->toArray(); + array_unshift($tmp, $this->blockSize); + array_pop($tmp); + $b = SplFixedArray::fromArray($tmp, false); + } + + $lambda = clone $t; + } + + // Convert lambda to index form and compute deg(lambda(x)) + $degLambda = 0; + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $lambda[$i] = $this->indexOf[$lambda[$i]]; + + if ($lambda[$i] !== $this->blockSize) { + $degLambda = $i; + } + } + + // Find roots of the error+erasure locator polynomial by Chien search. + $reg = clone $lambda; + $reg[0] = 0; + $count = 0; + $i = 1; + + for ($k = $this->iPrimitive - 1; $i <= $this->blockSize; ++$i, $k = $this->modNn($k + $this->iPrimitive)) { + $q = 1; + + for ($j = $degLambda; $j > 0; $j--) { + if ($reg[$j] !== $this->blockSize) { + $reg[$j] = $this->modNn($reg[$j] + $j); + $q ^= $this->alphaTo[$reg[$j]]; + } + } + + if ($q !== 0) { + // Not a root + continue; + } + + // Store root (index-form) and error location number + $root[$count] = $i; + $loc[$count] = $k; + + if (++$count === $degLambda) { + break; + } + } + + if ($degLambda !== $count) { + // deg(lambda) unequal to number of roots: uncorrectable error detected + return null; + } + + // Compute err+eras evaluate poly omega(x) = s(x)*lambda(x) (modulo x**numRoots). In index form. Also find + // deg(omega). + $degOmega = $degLambda - 1; + + for ($i = 0; $i <= $degOmega; ++$i) { + $tmp = 0; + + for ($j = $i; $j >= 0; --$j) { + if ($syndromes[$i - $j] !== $this->blockSize && $lambda[$j] !== $this->blockSize) { + $tmp ^= $this->alphaTo[$this->modNn($syndromes[$i - $j] + $lambda[$j])]; + } + } + + $omega[$i] = $this->indexOf[$tmp]; + } + + // Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(firstRoot-1) and + // den = lambda_pr(inv(X(l))) all in poly form. + for ($j = $count - 1; $j >= 0; --$j) { + $num1 = 0; + + for ($i = $degOmega; $i >= 0; $i--) { + if ($omega[$i] !== $this->blockSize) { + $num1 ^= $this->alphaTo[$this->modNn($omega[$i] + $i * $root[$j])]; + } + } + + $num2 = $this->alphaTo[$this->modNn($root[$j] * ($this->firstRoot - 1) + $this->blockSize)]; + $den = 0; + + // lambda[i+1] for i even is the formal derivativelambda_pr of lambda[i] + for ($i = min($degLambda, $this->numRoots - 1) & ~1; $i >= 0; $i -= 2) { + if ($lambda[$i + 1] !== $this->blockSize) { + $den ^= $this->alphaTo[$this->modNn($lambda[$i + 1] + $i * $root[$j])]; + } + } + + // Apply error to data + if ($num1 !== 0 && $loc[$j] >= $this->padding) { + $data[$loc[$j] - $this->padding] = $data[$loc[$j] - $this->padding] ^ ( + $this->alphaTo[ + $this->modNn( + $this->indexOf[$num1] + $this->indexOf[$num2] + $this->blockSize - $this->indexOf[$den] + ) + ] + ); + } + } + + if (null !== $erasures) { + if (count($erasures) < $count) { + $erasures->setSize($count); + } + + for ($i = 0; $i < $count; $i++) { + $erasures[$i] = $loc[$i]; + } + } + + return $count; + } + + /** + * Computes $x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, without a slow divide. + */ + private function modNn(int $x) : int + { + while ($x >= $this->blockSize) { + $x -= $this->blockSize; + $x = ($x >> $this->symbolSize) + ($x & $this->blockSize); + } + + return $x; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Version.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Version.php new file mode 100644 index 000000000..917d048df --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Common/Version.php @@ -0,0 +1,596 @@ +|null + */ + private static $versions; + + /** + * @param int[] $alignmentPatternCenters + */ + private function __construct( + int $versionNumber, + array $alignmentPatternCenters, + EcBlocks ...$ecBlocks + ) { + $this->versionNumber = $versionNumber; + $this->alignmentPatternCenters = $alignmentPatternCenters; + $this->ecBlocks = $ecBlocks; + + $totalCodewords = 0; + $ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock(); + + foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) { + $totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords); + } + + $this->totalCodewords = $totalCodewords; + } + + /** + * Returns the version number. + */ + public function getVersionNumber() : int + { + return $this->versionNumber; + } + + /** + * Returns the alignment pattern centers. + * + * @return int[] + */ + public function getAlignmentPatternCenters() : array + { + return $this->alignmentPatternCenters; + } + + /** + * Returns the total number of codewords. + */ + public function getTotalCodewords() : int + { + return $this->totalCodewords; + } + + /** + * Calculates the dimension for the current version. + */ + public function getDimensionForVersion() : int + { + return 17 + 4 * $this->versionNumber; + } + + /** + * Returns the number of EC blocks for a specific EC level. + */ + public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel) : EcBlocks + { + return $this->ecBlocks[$ecLevel->ordinal()]; + } + + /** + * Gets a provisional version number for a specific dimension. + * + * @throws InvalidArgumentException if dimension is not 1 mod 4 + */ + public static function getProvisionalVersionForDimension(int $dimension) : self + { + if (1 !== $dimension % 4) { + throw new InvalidArgumentException('Dimension is not 1 mod 4'); + } + + return self::getVersionForNumber(intdiv($dimension - 17, 4)); + } + + /** + * Gets a version instance for a specific version number. + * + * @throws InvalidArgumentException if version number is out of range + */ + public static function getVersionForNumber(int $versionNumber) : self + { + if ($versionNumber < 1 || $versionNumber > 40) { + throw new InvalidArgumentException('Version number must be between 1 and 40'); + } + + return self::versions()[$versionNumber - 1]; + } + + /** + * Decodes version information from an integer and returns the version. + */ + public static function decodeVersionInformation(int $versionBits) : ?self + { + $bestDifference = PHP_INT_MAX; + $bestVersion = 0; + + foreach (self::VERSION_DECODE_INFO as $i => $targetVersion) { + if ($targetVersion === $versionBits) { + return self::getVersionForNumber($i + 7); + } + + $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion); + + if ($bitsDifference < $bestDifference) { + $bestVersion = $i + 7; + $bestDifference = $bitsDifference; + } + } + + if ($bestDifference <= 3) { + return self::getVersionForNumber($bestVersion); + } + + return null; + } + + /** + * Builds the function pattern for the current version. + */ + public function buildFunctionPattern() : BitMatrix + { + $dimension = $this->getDimensionForVersion(); + $bitMatrix = new BitMatrix($dimension); + + // Top left finder pattern + separator + format + $bitMatrix->setRegion(0, 0, 9, 9); + // Top right finder pattern + separator + format + $bitMatrix->setRegion($dimension - 8, 0, 8, 9); + // Bottom left finder pattern + separator + format + $bitMatrix->setRegion(0, $dimension - 8, 9, 8); + + // Alignment patterns + $max = count($this->alignmentPatternCenters); + + for ($x = 0; $x < $max; ++$x) { + $i = $this->alignmentPatternCenters[$x] - 2; + + for ($y = 0; $y < $max; ++$y) { + if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) { + // No alignment patterns near the three finder paterns + continue; + } + + $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5); + } + } + + // Vertical timing pattern + $bitMatrix->setRegion(6, 9, 1, $dimension - 17); + // Horizontal timing pattern + $bitMatrix->setRegion(9, 6, $dimension - 17, 1); + + if ($this->versionNumber > 6) { + // Version info, top right + $bitMatrix->setRegion($dimension - 11, 0, 3, 6); + // Version info, bottom left + $bitMatrix->setRegion(0, $dimension - 11, 6, 3); + } + + return $bitMatrix; + } + + /** + * Returns a string representation for the version. + */ + public function __toString() : string + { + return (string) $this->versionNumber; + } + + /** + * Build and cache a specific version. + * + * See ISO 18004:2006 6.5.1 Table 9. + * + * @return array + */ + private static function versions() : array + { + if (null !== self::$versions) { + return self::$versions; + } + + return self::$versions = [ + new self( + 1, + [], + new EcBlocks(7, new EcBlock(1, 19)), + new EcBlocks(10, new EcBlock(1, 16)), + new EcBlocks(13, new EcBlock(1, 13)), + new EcBlocks(17, new EcBlock(1, 9)) + ), + new self( + 2, + [6, 18], + new EcBlocks(10, new EcBlock(1, 34)), + new EcBlocks(16, new EcBlock(1, 28)), + new EcBlocks(22, new EcBlock(1, 22)), + new EcBlocks(28, new EcBlock(1, 16)) + ), + new self( + 3, + [6, 22], + new EcBlocks(15, new EcBlock(1, 55)), + new EcBlocks(26, new EcBlock(1, 44)), + new EcBlocks(18, new EcBlock(2, 17)), + new EcBlocks(22, new EcBlock(2, 13)) + ), + new self( + 4, + [6, 26], + new EcBlocks(20, new EcBlock(1, 80)), + new EcBlocks(18, new EcBlock(2, 32)), + new EcBlocks(26, new EcBlock(3, 24)), + new EcBlocks(16, new EcBlock(4, 9)) + ), + new self( + 5, + [6, 30], + new EcBlocks(26, new EcBlock(1, 108)), + new EcBlocks(24, new EcBlock(2, 43)), + new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)), + new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12)) + ), + new self( + 6, + [6, 34], + new EcBlocks(18, new EcBlock(2, 68)), + new EcBlocks(16, new EcBlock(4, 27)), + new EcBlocks(24, new EcBlock(4, 19)), + new EcBlocks(28, new EcBlock(4, 15)) + ), + new self( + 7, + [6, 22, 38], + new EcBlocks(20, new EcBlock(2, 78)), + new EcBlocks(18, new EcBlock(4, 31)), + new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)), + new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14)) + ), + new self( + 8, + [6, 24, 42], + new EcBlocks(24, new EcBlock(2, 97)), + new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)), + new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)), + new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15)) + ), + new self( + 9, + [6, 26, 46], + new EcBlocks(30, new EcBlock(2, 116)), + new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)), + new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)), + new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13)) + ), + new self( + 10, + [6, 28, 50], + new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)), + new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)), + new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)), + new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16)) + ), + new self( + 11, + [6, 30, 54], + new EcBlocks(20, new EcBlock(4, 81)), + new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)), + new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)), + new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13)) + ), + new self( + 12, + [6, 32, 58], + new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)), + new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)), + new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)), + new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15)) + ), + new self( + 13, + [6, 34, 62], + new EcBlocks(26, new EcBlock(4, 107)), + new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)), + new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)), + new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12)) + ), + new self( + 14, + [6, 26, 46, 66], + new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)), + new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)), + new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)), + new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13)) + ), + new self( + 15, + [6, 26, 48, 70], + new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)), + new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)), + new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)), + new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13)) + ), + new self( + 16, + [6, 26, 50, 74], + new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)), + new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)), + new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)), + new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16)) + ), + new self( + 17, + [6, 30, 54, 78], + new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)), + new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)), + new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)), + new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15)) + ), + new self( + 18, + [6, 30, 56, 82], + new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)), + new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)), + new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)), + new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15)) + ), + new self( + 19, + [6, 30, 58, 86], + new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)), + new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)), + new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)), + new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14)) + ), + new self( + 20, + [6, 34, 62, 90], + new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)), + new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)), + new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)), + new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16)) + ), + new self( + 21, + [6, 28, 50, 72, 94], + new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)), + new EcBlocks(26, new EcBlock(17, 42)), + new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)), + new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17)) + ), + new self( + 22, + [6, 26, 50, 74, 98], + new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)), + new EcBlocks(28, new EcBlock(17, 46)), + new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)), + new EcBlocks(24, new EcBlock(34, 13)) + ), + new self( + 23, + [6, 30, 54, 78, 102], + new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)), + new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)), + new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16)) + ), + new self( + 24, + [6, 28, 54, 80, 106], + new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)), + new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)), + new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)), + new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17)) + ), + new self( + 25, + [6, 32, 58, 84, 110], + new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)), + new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)), + new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)), + new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16)) + ), + new self( + 26, + [6, 30, 58, 86, 114], + new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)), + new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)), + new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)), + new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17)) + ), + new self( + 27, + [6, 34, 62, 90, 118], + new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)), + new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)), + new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)), + new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16)) + ), + new self( + 28, + [6, 26, 50, 74, 98, 122], + new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)), + new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)), + new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)), + new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16)) + ), + new self( + 29, + [6, 30, 54, 78, 102, 126], + new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)), + new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)), + new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)), + new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16)) + ), + new self( + 30, + [6, 26, 52, 78, 104, 130], + new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)), + new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)), + new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)), + new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16)) + ), + new self( + 31, + [6, 30, 56, 82, 108, 134], + new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)), + new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)), + new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)), + new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16)) + ), + new self( + 32, + [6, 34, 60, 86, 112, 138], + new EcBlocks(30, new EcBlock(17, 115)), + new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)), + new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)), + new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16)) + ), + new self( + 33, + [6, 30, 58, 86, 114, 142], + new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)), + new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)), + new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)), + new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16)) + ), + new self( + 34, + [6, 34, 62, 90, 118, 146], + new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)), + new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)), + new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)), + new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17)) + ), + new self( + 35, + [6, 30, 54, 78, 102, 126, 150], + new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)), + new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)), + new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16)) + ), + new self( + 36, + [6, 24, 50, 76, 102, 128, 154], + new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)), + new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)), + new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)), + new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16)) + ), + new self( + 37, + [6, 28, 54, 80, 106, 132, 158], + new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)), + new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)), + new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)), + new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16)) + ), + new self( + 38, + [6, 32, 58, 84, 110, 136, 162], + new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)), + new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)), + new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16)) + ), + new self( + 39, + [6, 26, 54, 82, 110, 138, 166], + new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)), + new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)), + new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)), + new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16)) + ), + new self( + 40, + [6, 30, 58, 86, 114, 142, 170], + new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)), + new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)), + new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)), + new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16)) + ), + ]; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php new file mode 100644 index 000000000..be54afaa9 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php @@ -0,0 +1,58 @@ + + */ + private $dataBytes; + + /** + * Error correction bytes in the block. + * + * @var SplFixedArray + */ + private $errorCorrectionBytes; + + /** + * Creates a new block pair. + * + * @param SplFixedArray $data + * @param SplFixedArray $errorCorrection + */ + public function __construct(SplFixedArray $data, SplFixedArray $errorCorrection) + { + $this->dataBytes = $data; + $this->errorCorrectionBytes = $errorCorrection; + } + + /** + * Gets the data bytes. + * + * @return SplFixedArray + */ + public function getDataBytes() : SplFixedArray + { + return $this->dataBytes; + } + + /** + * Gets the error correction bytes. + * + * @return SplFixedArray + */ + public function getErrorCorrectionBytes() : SplFixedArray + { + return $this->errorCorrectionBytes; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php new file mode 100644 index 000000000..b58cc0ab2 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php @@ -0,0 +1,150 @@ +> + */ + private $bytes; + + /** + * Width of the matrix. + * + * @var int + */ + private $width; + + /** + * Height of the matrix. + * + * @var int + */ + private $height; + + public function __construct(int $width, int $height) + { + $this->height = $height; + $this->width = $width; + $this->bytes = new SplFixedArray($height); + + for ($y = 0; $y < $height; ++$y) { + $this->bytes[$y] = SplFixedArray::fromArray(array_fill(0, $width, 0)); + } + } + + /** + * Gets the width of the matrix. + */ + public function getWidth() : int + { + return $this->width; + } + + /** + * Gets the height of the matrix. + */ + public function getHeight() : int + { + return $this->height; + } + + /** + * Gets the internal representation of the matrix. + * + * @return SplFixedArray> + */ + public function getArray() : SplFixedArray + { + return $this->bytes; + } + + /** + * @return Traversable + */ + public function getBytes() : Traversable + { + foreach ($this->bytes as $row) { + foreach ($row as $byte) { + yield $byte; + } + } + } + + /** + * Gets the byte for a specific position. + */ + public function get(int $x, int $y) : int + { + return $this->bytes[$y][$x]; + } + + /** + * Sets the byte for a specific position. + */ + public function set(int $x, int $y, int $value) : void + { + $this->bytes[$y][$x] = $value; + } + + /** + * Clears the matrix with a specific value. + */ + public function clear(int $value) : void + { + for ($y = 0; $y < $this->height; ++$y) { + for ($x = 0; $x < $this->width; ++$x) { + $this->bytes[$y][$x] = $value; + } + } + } + + public function __clone() + { + $this->bytes = clone $this->bytes; + + foreach ($this->bytes as $index => $row) { + $this->bytes[$index] = clone $row; + } + } + + /** + * Returns a string representation of the matrix. + */ + public function __toString() : string + { + $result = ''; + + for ($y = 0; $y < $this->height; $y++) { + for ($x = 0; $x < $this->width; $x++) { + switch ($this->bytes[$y][$x]) { + case 0: + $result .= ' 0'; + break; + + case 1: + $result .= ' 1'; + break; + + default: + $result .= ' '; + break; + } + } + + $result .= "\n"; + } + + return $result; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php new file mode 100644 index 000000000..320846003 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php @@ -0,0 +1,668 @@ + + */ + private static $codecs = []; + + /** + * Encodes "content" with the error correction level "ecLevel". + */ + public static function encode( + string $content, + ErrorCorrectionLevel $ecLevel, + string $encoding = self::DEFAULT_BYTE_MODE_ECODING, + ?Version $forcedVersion = null + ) : QrCode { + // Pick an encoding mode appropriate for the content. Note that this + // will not attempt to use multiple modes / segments even if that were + // more efficient. Would be nice. + $mode = self::chooseMode($content, $encoding); + + // This will store the header information, like mode and length, as well + // as "header" segments like an ECI segment. + $headerBits = new BitArray(); + + // Append ECI segment if applicable + if (Mode::BYTE() === $mode && self::DEFAULT_BYTE_MODE_ECODING !== $encoding) { + $eci = CharacterSetEci::getCharacterSetEciByName($encoding); + + if (null !== $eci) { + self::appendEci($eci, $headerBits); + } + } + + // (With ECI in place,) Write the mode marker + self::appendModeInfo($mode, $headerBits); + + // Collect data within the main segment, separately, to count its size + // if needed. Don't add it to main payload yet. + $dataBits = new BitArray(); + self::appendBytes($content, $mode, $dataBits, $encoding); + + // Hard part: need to know version to know how many bits length takes. + // But need to know how many bits it takes to know version. First we + // take a guess at version by assuming version will be the minimum, 1: + $provisionalBitsNeeded = $headerBits->getSize() + + $mode->getCharacterCountBits(Version::getVersionForNumber(1)) + + $dataBits->getSize(); + $provisionalVersion = self::chooseVersion($provisionalBitsNeeded, $ecLevel); + + // Use that guess to calculate the right version. I am still not sure + // this works in 100% of cases. + $bitsNeeded = $headerBits->getSize() + + $mode->getCharacterCountBits($provisionalVersion) + + $dataBits->getSize(); + $version = self::chooseVersion($bitsNeeded, $ecLevel); + + if (null !== $forcedVersion) { + // Forced version check + if ($version->getVersionNumber() <= $forcedVersion->getVersionNumber()) { + // Calculated minimum version is same or equal as forced version + $version = $forcedVersion; + } else { + throw new WriterException( + 'Invalid version! Calculated version: ' + . $version->getVersionNumber() + . ', requested version: ' + . $forcedVersion->getVersionNumber() + ); + } + } + + $headerAndDataBits = new BitArray(); + $headerAndDataBits->appendBitArray($headerBits); + + // Find "length" of main segment and write it. + $numLetters = (Mode::BYTE() === $mode ? $dataBits->getSizeInBytes() : strlen($content)); + self::appendLengthInfo($numLetters, $version, $mode, $headerAndDataBits); + + // Put data together into the overall payload. + $headerAndDataBits->appendBitArray($dataBits); + $ecBlocks = $version->getEcBlocksForLevel($ecLevel); + $numDataBytes = $version->getTotalCodewords() - $ecBlocks->getTotalEcCodewords(); + + // Terminate the bits properly. + self::terminateBits($numDataBytes, $headerAndDataBits); + + // Interleave data bits with error correction code. + $finalBits = self::interleaveWithEcBytes( + $headerAndDataBits, + $version->getTotalCodewords(), + $numDataBytes, + $ecBlocks->getNumBlocks() + ); + + // Choose the mask pattern. + $dimension = $version->getDimensionForVersion(); + $matrix = new ByteMatrix($dimension, $dimension); + $maskPattern = self::chooseMaskPattern($finalBits, $ecLevel, $version, $matrix); + + // Build the matrix. + MatrixUtil::buildMatrix($finalBits, $ecLevel, $version, $maskPattern, $matrix); + + return new QrCode($mode, $ecLevel, $version, $maskPattern, $matrix); + } + + /** + * Gets the alphanumeric code for a byte. + */ + private static function getAlphanumericCode(int $code) : int + { + if (isset(self::ALPHANUMERIC_TABLE[$code])) { + return self::ALPHANUMERIC_TABLE[$code]; + } + + return -1; + } + + /** + * Chooses the best mode for a given content. + */ + private static function chooseMode(string $content, string $encoding = null) : Mode + { + if (null !== $encoding && 0 === strcasecmp($encoding, 'SHIFT-JIS')) { + return self::isOnlyDoubleByteKanji($content) ? Mode::KANJI() : Mode::BYTE(); + } + + $hasNumeric = false; + $hasAlphanumeric = false; + $contentLength = strlen($content); + + for ($i = 0; $i < $contentLength; ++$i) { + $char = $content[$i]; + + if (ctype_digit($char)) { + $hasNumeric = true; + } elseif (-1 !== self::getAlphanumericCode(ord($char))) { + $hasAlphanumeric = true; + } else { + return Mode::BYTE(); + } + } + + if ($hasAlphanumeric) { + return Mode::ALPHANUMERIC(); + } elseif ($hasNumeric) { + return Mode::NUMERIC(); + } + + return Mode::BYTE(); + } + + /** + * Calculates the mask penalty for a matrix. + */ + private static function calculateMaskPenalty(ByteMatrix $matrix) : int + { + return ( + MaskUtil::applyMaskPenaltyRule1($matrix) + + MaskUtil::applyMaskPenaltyRule2($matrix) + + MaskUtil::applyMaskPenaltyRule3($matrix) + + MaskUtil::applyMaskPenaltyRule4($matrix) + ); + } + + /** + * Checks if content only consists of double-byte kanji characters. + */ + private static function isOnlyDoubleByteKanji(string $content) : bool + { + $bytes = @iconv('utf-8', 'SHIFT-JIS', $content); + + if (false === $bytes) { + return false; + } + + $length = strlen($bytes); + + if (0 !== $length % 2) { + return false; + } + + for ($i = 0; $i < $length; $i += 2) { + $byte = $bytes[$i] & 0xff; + + if (($byte < 0x81 || $byte > 0x9f) && $byte < 0xe0 || $byte > 0xeb) { + return false; + } + } + + return true; + } + + /** + * Chooses the best mask pattern for a matrix. + */ + private static function chooseMaskPattern( + BitArray $bits, + ErrorCorrectionLevel $ecLevel, + Version $version, + ByteMatrix $matrix + ) : int { + $minPenalty = PHP_INT_MAX; + $bestMaskPattern = -1; + + for ($maskPattern = 0; $maskPattern < QrCode::NUM_MASK_PATTERNS; ++$maskPattern) { + MatrixUtil::buildMatrix($bits, $ecLevel, $version, $maskPattern, $matrix); + $penalty = self::calculateMaskPenalty($matrix); + + if ($penalty < $minPenalty) { + $minPenalty = $penalty; + $bestMaskPattern = $maskPattern; + } + } + + return $bestMaskPattern; + } + + /** + * Chooses the best version for the input. + * + * @throws WriterException if data is too big + */ + private static function chooseVersion(int $numInputBits, ErrorCorrectionLevel $ecLevel) : Version + { + for ($versionNum = 1; $versionNum <= 40; ++$versionNum) { + $version = Version::getVersionForNumber($versionNum); + $numBytes = $version->getTotalCodewords(); + + $ecBlocks = $version->getEcBlocksForLevel($ecLevel); + $numEcBytes = $ecBlocks->getTotalEcCodewords(); + + $numDataBytes = $numBytes - $numEcBytes; + $totalInputBytes = intdiv($numInputBits + 8, 8); + + if ($numDataBytes >= $totalInputBytes) { + return $version; + } + } + + throw new WriterException('Data too big'); + } + + /** + * Terminates the bits in a bit array. + * + * @throws WriterException if data bits cannot fit in the QR code + * @throws WriterException if bits size does not equal the capacity + */ + private static function terminateBits(int $numDataBytes, BitArray $bits) : void + { + $capacity = $numDataBytes << 3; + + if ($bits->getSize() > $capacity) { + throw new WriterException('Data bits cannot fit in the QR code'); + } + + for ($i = 0; $i < 4 && $bits->getSize() < $capacity; ++$i) { + $bits->appendBit(false); + } + + $numBitsInLastByte = $bits->getSize() & 0x7; + + if ($numBitsInLastByte > 0) { + for ($i = $numBitsInLastByte; $i < 8; ++$i) { + $bits->appendBit(false); + } + } + + $numPaddingBytes = $numDataBytes - $bits->getSizeInBytes(); + + for ($i = 0; $i < $numPaddingBytes; ++$i) { + $bits->appendBits(0 === ($i & 0x1) ? 0xec : 0x11, 8); + } + + if ($bits->getSize() !== $capacity) { + throw new WriterException('Bits size does not equal capacity'); + } + } + + /** + * Gets number of data- and EC bytes for a block ID. + * + * @return int[] + * @throws WriterException if block ID is too large + * @throws WriterException if EC bytes mismatch + * @throws WriterException if RS blocks mismatch + * @throws WriterException if total bytes mismatch + */ + private static function getNumDataBytesAndNumEcBytesForBlockId( + int $numTotalBytes, + int $numDataBytes, + int $numRsBlocks, + int $blockId + ) : array { + if ($blockId >= $numRsBlocks) { + throw new WriterException('Block ID too large'); + } + + $numRsBlocksInGroup2 = $numTotalBytes % $numRsBlocks; + $numRsBlocksInGroup1 = $numRsBlocks - $numRsBlocksInGroup2; + $numTotalBytesInGroup1 = intdiv($numTotalBytes, $numRsBlocks); + $numTotalBytesInGroup2 = $numTotalBytesInGroup1 + 1; + $numDataBytesInGroup1 = intdiv($numDataBytes, $numRsBlocks); + $numDataBytesInGroup2 = $numDataBytesInGroup1 + 1; + $numEcBytesInGroup1 = $numTotalBytesInGroup1 - $numDataBytesInGroup1; + $numEcBytesInGroup2 = $numTotalBytesInGroup2 - $numDataBytesInGroup2; + + if ($numEcBytesInGroup1 !== $numEcBytesInGroup2) { + throw new WriterException('EC bytes mismatch'); + } + + if ($numRsBlocks !== $numRsBlocksInGroup1 + $numRsBlocksInGroup2) { + throw new WriterException('RS blocks mismatch'); + } + + if ($numTotalBytes !== + (($numDataBytesInGroup1 + $numEcBytesInGroup1) * $numRsBlocksInGroup1) + + (($numDataBytesInGroup2 + $numEcBytesInGroup2) * $numRsBlocksInGroup2) + ) { + throw new WriterException('Total bytes mismatch'); + } + + if ($blockId < $numRsBlocksInGroup1) { + return [$numDataBytesInGroup1, $numEcBytesInGroup1]; + } else { + return [$numDataBytesInGroup2, $numEcBytesInGroup2]; + } + } + + /** + * Interleaves data with EC bytes. + * + * @throws WriterException if number of bits and data bytes does not match + * @throws WriterException if data bytes does not match offset + * @throws WriterException if an interleaving error occurs + */ + private static function interleaveWithEcBytes( + BitArray $bits, + int $numTotalBytes, + int $numDataBytes, + int $numRsBlocks + ) : BitArray { + if ($bits->getSizeInBytes() !== $numDataBytes) { + throw new WriterException('Number of bits and data bytes does not match'); + } + + $dataBytesOffset = 0; + $maxNumDataBytes = 0; + $maxNumEcBytes = 0; + + $blocks = new SplFixedArray($numRsBlocks); + + for ($i = 0; $i < $numRsBlocks; ++$i) { + list($numDataBytesInBlock, $numEcBytesInBlock) = self::getNumDataBytesAndNumEcBytesForBlockId( + $numTotalBytes, + $numDataBytes, + $numRsBlocks, + $i + ); + + $size = $numDataBytesInBlock; + $dataBytes = $bits->toBytes(8 * $dataBytesOffset, $size); + $ecBytes = self::generateEcBytes($dataBytes, $numEcBytesInBlock); + $blocks[$i] = new BlockPair($dataBytes, $ecBytes); + + $maxNumDataBytes = max($maxNumDataBytes, $size); + $maxNumEcBytes = max($maxNumEcBytes, count($ecBytes)); + $dataBytesOffset += $numDataBytesInBlock; + } + + if ($numDataBytes !== $dataBytesOffset) { + throw new WriterException('Data bytes does not match offset'); + } + + $result = new BitArray(); + + for ($i = 0; $i < $maxNumDataBytes; ++$i) { + foreach ($blocks as $block) { + $dataBytes = $block->getDataBytes(); + + if ($i < count($dataBytes)) { + $result->appendBits($dataBytes[$i], 8); + } + } + } + + for ($i = 0; $i < $maxNumEcBytes; ++$i) { + foreach ($blocks as $block) { + $ecBytes = $block->getErrorCorrectionBytes(); + + if ($i < count($ecBytes)) { + $result->appendBits($ecBytes[$i], 8); + } + } + } + + if ($numTotalBytes !== $result->getSizeInBytes()) { + throw new WriterException( + 'Interleaving error: ' . $numTotalBytes . ' and ' . $result->getSizeInBytes() . ' differ' + ); + } + + return $result; + } + + /** + * Generates EC bytes for given data. + * + * @param SplFixedArray $dataBytes + * @return SplFixedArray + */ + private static function generateEcBytes(SplFixedArray $dataBytes, int $numEcBytesInBlock) : SplFixedArray + { + $numDataBytes = count($dataBytes); + $toEncode = new SplFixedArray($numDataBytes + $numEcBytesInBlock); + + for ($i = 0; $i < $numDataBytes; $i++) { + $toEncode[$i] = $dataBytes[$i] & 0xff; + } + + $ecBytes = new SplFixedArray($numEcBytesInBlock); + $codec = self::getCodec($numDataBytes, $numEcBytesInBlock); + $codec->encode($toEncode, $ecBytes); + + return $ecBytes; + } + + /** + * Gets an RS codec and caches it. + */ + private static function getCodec(int $numDataBytes, int $numEcBytesInBlock) : ReedSolomonCodec + { + $cacheId = $numDataBytes . '-' . $numEcBytesInBlock; + + if (isset(self::$codecs[$cacheId])) { + return self::$codecs[$cacheId]; + } + + return self::$codecs[$cacheId] = new ReedSolomonCodec( + 8, + 0x11d, + 0, + 1, + $numEcBytesInBlock, + 255 - $numDataBytes - $numEcBytesInBlock + ); + } + + /** + * Appends mode information to a bit array. + */ + private static function appendModeInfo(Mode $mode, BitArray $bits) : void + { + $bits->appendBits($mode->getBits(), 4); + } + + /** + * Appends length information to a bit array. + * + * @throws WriterException if num letters is bigger than expected + */ + private static function appendLengthInfo(int $numLetters, Version $version, Mode $mode, BitArray $bits) : void + { + $numBits = $mode->getCharacterCountBits($version); + + if ($numLetters >= (1 << $numBits)) { + throw new WriterException($numLetters . ' is bigger than ' . ((1 << $numBits) - 1)); + } + + $bits->appendBits($numLetters, $numBits); + } + + /** + * Appends bytes to a bit array in a specific mode. + * + * @throws WriterException if an invalid mode was supplied + */ + private static function appendBytes(string $content, Mode $mode, BitArray $bits, string $encoding) : void + { + switch ($mode) { + case Mode::NUMERIC(): + self::appendNumericBytes($content, $bits); + break; + + case Mode::ALPHANUMERIC(): + self::appendAlphanumericBytes($content, $bits); + break; + + case Mode::BYTE(): + self::append8BitBytes($content, $bits, $encoding); + break; + + case Mode::KANJI(): + self::appendKanjiBytes($content, $bits); + break; + + default: + throw new WriterException('Invalid mode: ' . $mode); + } + } + + /** + * Appends numeric bytes to a bit array. + */ + private static function appendNumericBytes(string $content, BitArray $bits) : void + { + $length = strlen($content); + $i = 0; + + while ($i < $length) { + $num1 = (int) $content[$i]; + + if ($i + 2 < $length) { + // Encode three numeric letters in ten bits. + $num2 = (int) $content[$i + 1]; + $num3 = (int) $content[$i + 2]; + $bits->appendBits($num1 * 100 + $num2 * 10 + $num3, 10); + $i += 3; + } elseif ($i + 1 < $length) { + // Encode two numeric letters in seven bits. + $num2 = (int) $content[$i + 1]; + $bits->appendBits($num1 * 10 + $num2, 7); + $i += 2; + } else { + // Encode one numeric letter in four bits. + $bits->appendBits($num1, 4); + ++$i; + } + } + } + + /** + * Appends alpha-numeric bytes to a bit array. + * + * @throws WriterException if an invalid alphanumeric code was found + */ + private static function appendAlphanumericBytes(string $content, BitArray $bits) : void + { + $length = strlen($content); + $i = 0; + + while ($i < $length) { + $code1 = self::getAlphanumericCode(ord($content[$i])); + + if (-1 === $code1) { + throw new WriterException('Invalid alphanumeric code'); + } + + if ($i + 1 < $length) { + $code2 = self::getAlphanumericCode(ord($content[$i + 1])); + + if (-1 === $code2) { + throw new WriterException('Invalid alphanumeric code'); + } + + // Encode two alphanumeric letters in 11 bits. + $bits->appendBits($code1 * 45 + $code2, 11); + $i += 2; + } else { + // Encode one alphanumeric letter in six bits. + $bits->appendBits($code1, 6); + ++$i; + } + } + } + + /** + * Appends regular 8-bit bytes to a bit array. + * + * @throws WriterException if content cannot be encoded to target encoding + */ + private static function append8BitBytes(string $content, BitArray $bits, string $encoding) : void + { + $bytes = @iconv('utf-8', $encoding, $content); + + if (false === $bytes) { + throw new WriterException('Could not encode content to ' . $encoding); + } + + $length = strlen($bytes); + + for ($i = 0; $i < $length; $i++) { + $bits->appendBits(ord($bytes[$i]), 8); + } + } + + /** + * Appends KANJI bytes to a bit array. + * + * @throws WriterException if content does not seem to be encoded in SHIFT-JIS + * @throws WriterException if an invalid byte sequence occurs + */ + private static function appendKanjiBytes(string $content, BitArray $bits) : void + { + if (strlen($content) % 2 > 0) { + // We just do a simple length check here. The for loop will check + // individual characters. + throw new WriterException('Content does not seem to be encoded in SHIFT-JIS'); + } + + $length = strlen($content); + + for ($i = 0; $i < $length; $i += 2) { + $byte1 = ord($content[$i]) & 0xff; + $byte2 = ord($content[$i + 1]) & 0xff; + $code = ($byte1 << 8) | $byte2; + + if ($code >= 0x8140 && $code <= 0x9ffc) { + $subtracted = $code - 0x8140; + } elseif ($code >= 0xe040 && $code <= 0xebbf) { + $subtracted = $code - 0xc140; + } else { + throw new WriterException('Invalid byte sequence'); + } + + $encoded = (($subtracted >> 8) * 0xc0) + ($subtracted & 0xff); + + $bits->appendBits($encoded, 13); + } + } + + /** + * Appends ECI information to a bit array. + */ + private static function appendEci(CharacterSetEci $eci, BitArray $bits) : void + { + $mode = Mode::ECI(); + $bits->appendBits($mode->getBits(), 4); + $bits->appendBits($eci->getValue(), 8); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php new file mode 100644 index 000000000..ba97dfb79 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php @@ -0,0 +1,271 @@ +getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height - 1; ++$y) { + for ($x = 0; $x < $width - 1; ++$x) { + $value = $array[$y][$x]; + + if ($value === $array[$y][$x + 1] + && $value === $array[$y + 1][$x] + && $value === $array[$y + 1][$x + 1] + ) { + ++$penalty; + } + } + } + + return self::N2 * $penalty; + } + + /** + * Applies mask penalty rule 3 and returns the penalty. + * + * Finds consecutive cells of 00001011101 or 10111010000, and gives penalty + * to them. If we find patterns like 000010111010000, we give penalties + * twice (i.e. 40 * 2). + */ + public static function applyMaskPenaltyRule3(ByteMatrix $matrix) : int + { + $penalty = 0; + $array = $matrix->getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height; ++$y) { + for ($x = 0; $x < $width; ++$x) { + if ($x + 6 < $width + && 1 === $array[$y][$x] + && 0 === $array[$y][$x + 1] + && 1 === $array[$y][$x + 2] + && 1 === $array[$y][$x + 3] + && 1 === $array[$y][$x + 4] + && 0 === $array[$y][$x + 5] + && 1 === $array[$y][$x + 6] + && ( + ( + $x + 10 < $width + && 0 === $array[$y][$x + 7] + && 0 === $array[$y][$x + 8] + && 0 === $array[$y][$x + 9] + && 0 === $array[$y][$x + 10] + ) + || ( + $x - 4 >= 0 + && 0 === $array[$y][$x - 1] + && 0 === $array[$y][$x - 2] + && 0 === $array[$y][$x - 3] + && 0 === $array[$y][$x - 4] + ) + ) + ) { + $penalty += self::N3; + } + + if ($y + 6 < $height + && 1 === $array[$y][$x] + && 0 === $array[$y + 1][$x] + && 1 === $array[$y + 2][$x] + && 1 === $array[$y + 3][$x] + && 1 === $array[$y + 4][$x] + && 0 === $array[$y + 5][$x] + && 1 === $array[$y + 6][$x] + && ( + ( + $y + 10 < $height + && 0 === $array[$y + 7][$x] + && 0 === $array[$y + 8][$x] + && 0 === $array[$y + 9][$x] + && 0 === $array[$y + 10][$x] + ) + || ( + $y - 4 >= 0 + && 0 === $array[$y - 1][$x] + && 0 === $array[$y - 2][$x] + && 0 === $array[$y - 3][$x] + && 0 === $array[$y - 4][$x] + ) + ) + ) { + $penalty += self::N3; + } + } + } + + return $penalty; + } + + /** + * Applies mask penalty rule 4 and returns the penalty. + * + * Calculates the ratio of dark cells and gives penalty if the ratio is far + * from 50%. It gives 10 penalty for 5% distance. + */ + public static function applyMaskPenaltyRule4(ByteMatrix $matrix) : int + { + $numDarkCells = 0; + + $array = $matrix->getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height; ++$y) { + $arrayY = $array[$y]; + + for ($x = 0; $x < $width; ++$x) { + if (1 === $arrayY[$x]) { + ++$numDarkCells; + } + } + } + + $numTotalCells = $height * $width; + $darkRatio = $numDarkCells / $numTotalCells; + $fixedPercentVariances = (int) (abs($darkRatio - 0.5) * 20); + + return $fixedPercentVariances * self::N4; + } + + /** + * Returns the mask bit for "getMaskPattern" at "x" and "y". + * + * See 8.8 of JISX0510:2004 for mask pattern conditions. + * + * @throws InvalidArgumentException if an invalid mask pattern was supplied + */ + public static function getDataMaskBit(int $maskPattern, int $x, int $y) : bool + { + switch ($maskPattern) { + case 0: + $intermediate = ($y + $x) & 0x1; + break; + + case 1: + $intermediate = $y & 0x1; + break; + + case 2: + $intermediate = $x % 3; + break; + + case 3: + $intermediate = ($y + $x) % 3; + break; + + case 4: + $intermediate = (BitUtils::unsignedRightShift($y, 1) + (int) ($x / 3)) & 0x1; + break; + + case 5: + $temp = $y * $x; + $intermediate = ($temp & 0x1) + ($temp % 3); + break; + + case 6: + $temp = $y * $x; + $intermediate = (($temp & 0x1) + ($temp % 3)) & 0x1; + break; + + case 7: + $temp = $y * $x; + $intermediate = (($temp % 3) + (($y + $x) & 0x1)) & 0x1; + break; + + default: + throw new InvalidArgumentException('Invalid mask pattern: ' . $maskPattern); + } + + return 0 == $intermediate; + } + + /** + * Helper function for applyMaskPenaltyRule1. + * + * We need this for doing this calculation in both vertical and horizontal + * orders respectively. + */ + private static function applyMaskPenaltyRule1Internal(ByteMatrix $matrix, bool $isHorizontal) : int + { + $penalty = 0; + $iLimit = $isHorizontal ? $matrix->getHeight() : $matrix->getWidth(); + $jLimit = $isHorizontal ? $matrix->getWidth() : $matrix->getHeight(); + $array = $matrix->getArray(); + + for ($i = 0; $i < $iLimit; ++$i) { + $numSameBitCells = 0; + $prevBit = -1; + + for ($j = 0; $j < $jLimit; $j++) { + $bit = $isHorizontal ? $array[$i][$j] : $array[$j][$i]; + + if ($bit === $prevBit) { + ++$numSameBitCells; + } else { + if ($numSameBitCells >= 5) { + $penalty += self::N1 + ($numSameBitCells - 5); + } + + $numSameBitCells = 1; + $prevBit = $bit; + } + } + + if ($numSameBitCells >= 5) { + $penalty += self::N1 + ($numSameBitCells - 5); + } + } + + return $penalty; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php new file mode 100644 index 000000000..0967e298a --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php @@ -0,0 +1,513 @@ +clear(-1); + } + + /** + * Builds a complete matrix. + */ + public static function buildMatrix( + BitArray $dataBits, + ErrorCorrectionLevel $level, + Version $version, + int $maskPattern, + ByteMatrix $matrix + ) : void { + self::clearMatrix($matrix); + self::embedBasicPatterns($version, $matrix); + self::embedTypeInfo($level, $maskPattern, $matrix); + self::maybeEmbedVersionInfo($version, $matrix); + self::embedDataBits($dataBits, $maskPattern, $matrix); + } + + /** + * Removes the position detection patterns from a matrix. + * + * This can be useful if you need to render those patterns separately. + */ + public static function removePositionDetectionPatterns(ByteMatrix $matrix) : void + { + $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]); + + self::removePositionDetectionPattern(0, 0, $matrix); + self::removePositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix); + self::removePositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix); + } + + /** + * Embeds type information into a matrix. + */ + private static function embedTypeInfo(ErrorCorrectionLevel $level, int $maskPattern, ByteMatrix $matrix) : void + { + $typeInfoBits = new BitArray(); + self::makeTypeInfoBits($level, $maskPattern, $typeInfoBits); + + $typeInfoBitsSize = $typeInfoBits->getSize(); + + for ($i = 0; $i < $typeInfoBitsSize; ++$i) { + $bit = $typeInfoBits->get($typeInfoBitsSize - 1 - $i); + + $x1 = self::TYPE_INFO_COORDINATES[$i][0]; + $y1 = self::TYPE_INFO_COORDINATES[$i][1]; + + $matrix->set($x1, $y1, (int) $bit); + + if ($i < 8) { + $x2 = $matrix->getWidth() - $i - 1; + $y2 = 8; + } else { + $x2 = 8; + $y2 = $matrix->getHeight() - 7 + ($i - 8); + } + + $matrix->set($x2, $y2, (int) $bit); + } + } + + /** + * Generates type information bits and appends them to a bit array. + * + * @throws RuntimeException if bit array resulted in invalid size + */ + private static function makeTypeInfoBits(ErrorCorrectionLevel $level, int $maskPattern, BitArray $bits) : void + { + $typeInfo = ($level->getBits() << 3) | $maskPattern; + $bits->appendBits($typeInfo, 5); + + $bchCode = self::calculateBchCode($typeInfo, self::TYPE_INFO_POLY); + $bits->appendBits($bchCode, 10); + + $maskBits = new BitArray(); + $maskBits->appendBits(self::TYPE_INFO_MASK_PATTERN, 15); + $bits->xorBits($maskBits); + + if (15 !== $bits->getSize()) { + throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize()); + } + } + + /** + * Embeds version information if required. + */ + private static function maybeEmbedVersionInfo(Version $version, ByteMatrix $matrix) : void + { + if ($version->getVersionNumber() < 7) { + return; + } + + $versionInfoBits = new BitArray(); + self::makeVersionInfoBits($version, $versionInfoBits); + + $bitIndex = 6 * 3 - 1; + + for ($i = 0; $i < 6; ++$i) { + for ($j = 0; $j < 3; ++$j) { + $bit = $versionInfoBits->get($bitIndex); + --$bitIndex; + + $matrix->set($i, $matrix->getHeight() - 11 + $j, (int) $bit); + $matrix->set($matrix->getHeight() - 11 + $j, $i, (int) $bit); + } + } + } + + /** + * Generates version information bits and appends them to a bit array. + * + * @throws RuntimeException if bit array resulted in invalid size + */ + private static function makeVersionInfoBits(Version $version, BitArray $bits) : void + { + $bits->appendBits($version->getVersionNumber(), 6); + + $bchCode = self::calculateBchCode($version->getVersionNumber(), self::VERSION_INFO_POLY); + $bits->appendBits($bchCode, 12); + + if (18 !== $bits->getSize()) { + throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize()); + } + } + + /** + * Calculates the BCH code for a value and a polynomial. + */ + private static function calculateBchCode(int $value, int $poly) : int + { + $msbSetInPoly = self::findMsbSet($poly); + $value <<= $msbSetInPoly - 1; + + while (self::findMsbSet($value) >= $msbSetInPoly) { + $value ^= $poly << (self::findMsbSet($value) - $msbSetInPoly); + } + + return $value; + } + + /** + * Finds and MSB set. + */ + private static function findMsbSet(int $value) : int + { + $numDigits = 0; + + while (0 !== $value) { + $value >>= 1; + ++$numDigits; + } + + return $numDigits; + } + + /** + * Embeds basic patterns into a matrix. + */ + private static function embedBasicPatterns(Version $version, ByteMatrix $matrix) : void + { + self::embedPositionDetectionPatternsAndSeparators($matrix); + self::embedDarkDotAtLeftBottomCorner($matrix); + self::maybeEmbedPositionAdjustmentPatterns($version, $matrix); + self::embedTimingPatterns($matrix); + } + + /** + * Embeds position detection patterns and separators into a byte matrix. + */ + private static function embedPositionDetectionPatternsAndSeparators(ByteMatrix $matrix) : void + { + $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]); + + self::embedPositionDetectionPattern(0, 0, $matrix); + self::embedPositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix); + self::embedPositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix); + + $hspWidth = 8; + + self::embedHorizontalSeparationPattern(0, $hspWidth - 1, $matrix); + self::embedHorizontalSeparationPattern($matrix->getWidth() - $hspWidth, $hspWidth - 1, $matrix); + self::embedHorizontalSeparationPattern(0, $matrix->getWidth() - $hspWidth, $matrix); + + $vspSize = 7; + + self::embedVerticalSeparationPattern($vspSize, 0, $matrix); + self::embedVerticalSeparationPattern($matrix->getHeight() - $vspSize - 1, 0, $matrix); + self::embedVerticalSeparationPattern($vspSize, $matrix->getHeight() - $vspSize, $matrix); + } + + /** + * Embeds a single position detection pattern into a byte matrix. + */ + private static function embedPositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; ++$y) { + for ($x = 0; $x < 7; ++$x) { + $matrix->set($xStart + $x, $yStart + $y, self::POSITION_DETECTION_PATTERN[$y][$x]); + } + } + } + + private static function removePositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; ++$y) { + for ($x = 0; $x < 7; ++$x) { + $matrix->set($xStart + $x, $yStart + $y, 0); + } + } + } + + /** + * Embeds a single horizontal separation pattern. + * + * @throws RuntimeException if a byte was already set + */ + private static function embedHorizontalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($x = 0; $x < 8; $x++) { + if (-1 !== $matrix->get($xStart + $x, $yStart)) { + throw new RuntimeException('Byte already set'); + } + + $matrix->set($xStart + $x, $yStart, 0); + } + } + + /** + * Embeds a single vertical separation pattern. + * + * @throws RuntimeException if a byte was already set + */ + private static function embedVerticalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; $y++) { + if (-1 !== $matrix->get($xStart, $yStart + $y)) { + throw new RuntimeException('Byte already set'); + } + + $matrix->set($xStart, $yStart + $y, 0); + } + } + + /** + * Embeds a dot at the left bottom corner. + * + * @throws RuntimeException if a byte was already set to 0 + */ + private static function embedDarkDotAtLeftBottomCorner(ByteMatrix $matrix) : void + { + if (0 === $matrix->get(8, $matrix->getHeight() - 8)) { + throw new RuntimeException('Byte already set to 0'); + } + + $matrix->set(8, $matrix->getHeight() - 8, 1); + } + + /** + * Embeds position adjustment patterns if required. + */ + private static function maybeEmbedPositionAdjustmentPatterns(Version $version, ByteMatrix $matrix) : void + { + if ($version->getVersionNumber() < 2) { + return; + } + + $index = $version->getVersionNumber() - 1; + + $coordinates = self::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[$index]; + $numCoordinates = count($coordinates); + + for ($i = 0; $i < $numCoordinates; ++$i) { + for ($j = 0; $j < $numCoordinates; ++$j) { + $y = $coordinates[$i]; + $x = $coordinates[$j]; + + if (null === $x || null === $y) { + continue; + } + + if (-1 === $matrix->get($x, $y)) { + self::embedPositionAdjustmentPattern($x - 2, $y - 2, $matrix); + } + } + } + } + + /** + * Embeds a single position adjustment pattern. + */ + private static function embedPositionAdjustmentPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 5; $y++) { + for ($x = 0; $x < 5; $x++) { + $matrix->set($xStart + $x, $yStart + $y, self::POSITION_ADJUSTMENT_PATTERN[$y][$x]); + } + } + } + + /** + * Embeds timing patterns into a matrix. + */ + private static function embedTimingPatterns(ByteMatrix $matrix) : void + { + $matrixWidth = $matrix->getWidth(); + + for ($i = 8; $i < $matrixWidth - 8; ++$i) { + $bit = ($i + 1) % 2; + + if (-1 === $matrix->get($i, 6)) { + $matrix->set($i, 6, $bit); + } + + if (-1 === $matrix->get(6, $i)) { + $matrix->set(6, $i, $bit); + } + } + } + + /** + * Embeds "dataBits" using "getMaskPattern". + * + * For debugging purposes, it skips masking process if "getMaskPattern" is -1. See 8.7 of JISX0510:2004 (p.38) for + * how to embed data bits. + * + * @throws WriterException if not all bits could be consumed + */ + private static function embedDataBits(BitArray $dataBits, int $maskPattern, ByteMatrix $matrix) : void + { + $bitIndex = 0; + $direction = -1; + + // Start from the right bottom cell. + $x = $matrix->getWidth() - 1; + $y = $matrix->getHeight() - 1; + + while ($x > 0) { + // Skip vertical timing pattern. + if (6 === $x) { + --$x; + } + + while ($y >= 0 && $y < $matrix->getHeight()) { + for ($i = 0; $i < 2; $i++) { + $xx = $x - $i; + + // Skip the cell if it's not empty. + if (-1 !== $matrix->get($xx, $y)) { + continue; + } + + if ($bitIndex < $dataBits->getSize()) { + $bit = $dataBits->get($bitIndex); + ++$bitIndex; + } else { + // Padding bit. If there is no bit left, we'll fill the + // left cells with 0, as described in 8.4.9 of + // JISX0510:2004 (p. 24). + $bit = false; + } + + // Skip masking if maskPattern is -1. + if (-1 !== $maskPattern && MaskUtil::getDataMaskBit($maskPattern, $xx, $y)) { + $bit = ! $bit; + } + + $matrix->set($xx, $y, (int) $bit); + } + + $y += $direction; + } + + $direction = -$direction; + $y += $direction; + $x -= 2; + } + + // All bits should be consumed + if ($dataBits->getSize() !== $bitIndex) { + throw new WriterException('Not all bits consumed (' . $bitIndex . ' out of ' . $dataBits->getSize() .')'); + } + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php new file mode 100644 index 000000000..f568e88cf --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php @@ -0,0 +1,141 @@ +mode = $mode; + $this->errorCorrectionLevel = $errorCorrectionLevel; + $this->version = $version; + $this->maskPattern = $maskPattern; + $this->matrix = $matrix; + } + + /** + * Gets the mode. + */ + public function getMode() : Mode + { + return $this->mode; + } + + /** + * Gets the EC level. + */ + public function getErrorCorrectionLevel() : ErrorCorrectionLevel + { + return $this->errorCorrectionLevel; + } + + /** + * Gets the version. + */ + public function getVersion() : Version + { + return $this->version; + } + + /** + * Gets the mask pattern. + */ + public function getMaskPattern() : int + { + return $this->maskPattern; + } + + /** + * Gets the matrix. + * + * @return ByteMatrix + */ + public function getMatrix() + { + return $this->matrix; + } + + /** + * Validates whether a mask pattern is valid. + */ + public static function isValidMaskPattern(int $maskPattern) : bool + { + return $maskPattern > 0 && $maskPattern < self::NUM_MASK_PATTERNS; + } + + /** + * Returns a string representation of the QR code. + */ + public function __toString() : string + { + $result = "<<\n" + . ' mode: ' . $this->mode . "\n" + . ' ecLevel: ' . $this->errorCorrectionLevel . "\n" + . ' version: ' . $this->version . "\n" + . ' maskPattern: ' . $this->maskPattern . "\n"; + + if ($this->matrix === null) { + $result .= " matrix: null\n"; + } else { + $result .= " matrix:\n"; + $result .= $this->matrix; + } + + $result .= ">>\n"; + + return $result; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php new file mode 100644 index 000000000..6f70c2055 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php @@ -0,0 +1,10 @@ + 100) { + throw new Exception\InvalidArgumentException('Alpha must be between 0 and 100'); + } + + $this->alpha = $alpha; + $this->baseColor = $baseColor; + } + + public function getAlpha() : int + { + return $this->alpha; + } + + public function getBaseColor() : ColorInterface + { + return $this->baseColor; + } + + public function toRgb() : Rgb + { + return $this->baseColor->toRgb(); + } + + public function toCmyk() : Cmyk + { + return $this->baseColor->toCmyk(); + } + + public function toGray() : Gray + { + return $this->baseColor->toGray(); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php new file mode 100644 index 000000000..d6de390ad --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php @@ -0,0 +1,103 @@ + 100) { + throw new Exception\InvalidArgumentException('Cyan must be between 0 and 100'); + } + + if ($magenta < 0 || $magenta > 100) { + throw new Exception\InvalidArgumentException('Magenta must be between 0 and 100'); + } + + if ($yellow < 0 || $yellow > 100) { + throw new Exception\InvalidArgumentException('Yellow must be between 0 and 100'); + } + + if ($black < 0 || $black > 100) { + throw new Exception\InvalidArgumentException('Black must be between 0 and 100'); + } + + $this->cyan = $cyan; + $this->magenta = $magenta; + $this->yellow = $yellow; + $this->black = $black; + } + + public function getCyan() : int + { + return $this->cyan; + } + + public function getMagenta() : int + { + return $this->magenta; + } + + public function getYellow() : int + { + return $this->yellow; + } + + public function getBlack() : int + { + return $this->black; + } + + public function toRgb() : Rgb + { + $k = $this->black / 100; + $c = (-$k * $this->cyan + $k * 100 + $this->cyan) / 100; + $m = (-$k * $this->magenta + $k * 100 + $this->magenta) / 100; + $y = (-$k * $this->yellow + $k * 100 + $this->yellow) / 100; + + return new Rgb( + (int) (-$c * 255 + 255), + (int) (-$m * 255 + 255), + (int) (-$y * 255 + 255) + ); + } + + public function toCmyk() : Cmyk + { + return $this; + } + + public function toGray() : Gray + { + return $this->toRgb()->toGray(); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php new file mode 100644 index 000000000..b50d1cace --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php @@ -0,0 +1,22 @@ + 100) { + throw new Exception\InvalidArgumentException('Gray must be between 0 and 100'); + } + + $this->gray = (int) $gray; + } + + public function getGray() : int + { + return $this->gray; + } + + public function toRgb() : Rgb + { + return new Rgb((int) ($this->gray * 2.55), (int) ($this->gray * 2.55), (int) ($this->gray * 2.55)); + } + + public function toCmyk() : Cmyk + { + return new Cmyk(0, 0, 0, 100 - $this->gray); + } + + public function toGray() : Gray + { + return $this; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php new file mode 100644 index 000000000..793540621 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php @@ -0,0 +1,88 @@ + 255) { + throw new Exception\InvalidArgumentException('Red must be between 0 and 255'); + } + + if ($green < 0 || $green > 255) { + throw new Exception\InvalidArgumentException('Green must be between 0 and 255'); + } + + if ($blue < 0 || $blue > 255) { + throw new Exception\InvalidArgumentException('Blue must be between 0 and 255'); + } + + $this->red = $red; + $this->green = $green; + $this->blue = $blue; + } + + public function getRed() : int + { + return $this->red; + } + + public function getGreen() : int + { + return $this->green; + } + + public function getBlue() : int + { + return $this->blue; + } + + public function toRgb() : Rgb + { + return $this; + } + + public function toCmyk() : Cmyk + { + $c = 1 - ($this->red / 255); + $m = 1 - ($this->green / 255); + $y = 1 - ($this->blue / 255); + $k = min($c, $m, $y); + + return new Cmyk( + (int) (100 * ($c - $k) / (1 - $k)), + (int) (100 * ($m - $k) / (1 - $k)), + (int) (100 * ($y - $k) / (1 - $k)), + (int) (100 * $k) + ); + } + + public function toGray() : Gray + { + return new Gray((int) (($this->red * 0.21 + $this->green * 0.71 + $this->blue * 0.07) / 2.55)); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php new file mode 100644 index 000000000..0d0312590 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php @@ -0,0 +1,38 @@ +externalEye = $externalEye; + $this->internalEye = $internalEye; + } + + public function getExternalPath() : Path + { + return $this->externalEye->getExternalPath(); + } + + public function getInternalPath() : Path + { + return $this->internalEye->getInternalPath(); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php new file mode 100644 index 000000000..ab68f3cd1 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php @@ -0,0 +1,26 @@ +module = $module; + } + + public function getExternalPath() : Path + { + $matrix = new ByteMatrix(7, 7); + + for ($x = 0; $x < 7; ++$x) { + $matrix->set($x, 0, 1); + $matrix->set($x, 6, 1); + } + + for ($y = 1; $y < 6; ++$y) { + $matrix->set(0, $y, 1); + $matrix->set(6, $y, 1); + } + + return $this->module->createPath($matrix)->translate(-3.5, -3.5); + } + + public function getInternalPath() : Path + { + $matrix = new ByteMatrix(3, 3); + + for ($x = 0; $x < 3; ++$x) { + for ($y = 0; $y < 3; ++$y) { + $matrix->set($x, $y, 1); + } + } + + return $this->module->createPath($matrix)->translate(-1.5, -1.5); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php new file mode 100644 index 000000000..64d54ee28 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php @@ -0,0 +1,54 @@ +move(-3.5, -3.5) + ->line(3.5, -3.5) + ->line(3.5, 3.5) + ->line(-3.5, 3.5) + ->close() + ->move(-2.5, -2.5) + ->line(-2.5, 2.5) + ->line(2.5, 2.5) + ->line(2.5, -2.5) + ->close() + ; + } + + public function getInternalPath() : Path + { + return (new Path()) + ->move(1.5, 0) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., 1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, -1.5, 0.) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., -1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, 1.5, 0.) + ->close() + ; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php new file mode 100644 index 000000000..a3892b476 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php @@ -0,0 +1,53 @@ +move(-3.5, -3.5) + ->line(3.5, -3.5) + ->line(3.5, 3.5) + ->line(-3.5, 3.5) + ->close() + ->move(-2.5, -2.5) + ->line(-2.5, 2.5) + ->line(2.5, 2.5) + ->line(2.5, -2.5) + ->close() + ; + } + + public function getInternalPath() : Path + { + return (new Path()) + ->move(-1.5, -1.5) + ->line(1.5, -1.5) + ->line(1.5, 1.5) + ->line(-1.5, 1.5) + ->close() + ; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php new file mode 100644 index 000000000..b581b540d --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php @@ -0,0 +1,376 @@ +eps = "%!PS-Adobe-3.0 EPSF-3.0\n" + . "%%Creator: BaconQrCode\n" + . sprintf("%%%%BoundingBox: 0 0 %d %d \n", $size, $size) + . "%%BeginProlog\n" + . "save\n" + . "50 dict begin\n" + . "/q { gsave } bind def\n" + . "/Q { grestore } bind def\n" + . "/s { scale } bind def\n" + . "/t { translate } bind def\n" + . "/r { rotate } bind def\n" + . "/n { newpath } bind def\n" + . "/m { moveto } bind def\n" + . "/l { lineto } bind def\n" + . "/c { curveto } bind def\n" + . "/z { closepath } bind def\n" + . "/f { eofill } bind def\n" + . "/rgb { setrgbcolor } bind def\n" + . "/cmyk { setcmykcolor } bind def\n" + . "/gray { setgray } bind def\n" + . "%%EndProlog\n" + . "1 -1 s\n" + . sprintf("0 -%d t\n", $size); + + if ($backgroundColor instanceof Alpha && 0 === $backgroundColor->getAlpha()) { + return; + } + + $this->eps .= wordwrap( + '0 0 m' + . sprintf(' %s 0 l', (string) $size) + . sprintf(' %s %s l', (string) $size, (string) $size) + . sprintf(' 0 %s l', (string) $size) + . ' z' + . ' ' .$this->getColorSetString($backgroundColor) . " f\n", + 75, + "\n " + ); + } + + public function scale(float $size) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%1\$s %1\$s s\n", round($size, self::PRECISION)); + } + + public function translate(float $x, float $y) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%s %s t\n", round($x, self::PRECISION), round($y, self::PRECISION)); + } + + public function rotate(int $degrees) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%d r\n", $degrees); + } + + public function push() : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "q\n"; + } + + public function pop() : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "Q\n"; + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $fromX = 0; + $fromY = 0; + $this->eps .= wordwrap( + 'n ' + . $this->drawPathOperations($path, $fromX, $fromY) + . ' ' . $this->getColorSetString($color) . " f\n", + 75, + "\n " + ); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $fromX = 0; + $fromY = 0; + $this->eps .= wordwrap( + 'q n ' . $this->drawPathOperations($path, $fromX, $fromY) . "\n", + 75, + "\n " + ); + + $this->createGradientFill($gradient, $x, $y, $width, $height); + } + + public function done() : string + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "%%TRAILER\nend restore\n%%EOF"; + $blob = $this->eps; + $this->eps = null; + + return $blob; + } + + private function drawPathOperations(Iterable $ops, &$fromX, &$fromY) : string + { + $pathData = []; + + foreach ($ops as $op) { + switch (true) { + case $op instanceof Move: + $fromX = $toX = round($op->getX(), self::PRECISION); + $fromY = $toY = round($op->getY(), self::PRECISION); + $pathData[] = sprintf('%s %s m', $toX, $toY); + break; + + case $op instanceof Line: + $fromX = $toX = round($op->getX(), self::PRECISION); + $fromY = $toY = round($op->getY(), self::PRECISION); + $pathData[] = sprintf('%s %s l', $toX, $toY); + break; + + case $op instanceof EllipticArc: + $pathData[] = $this->drawPathOperations($op->toCurves($fromX, $fromY), $fromX, $fromY); + break; + + case $op instanceof Curve: + $x1 = round($op->getX1(), self::PRECISION); + $y1 = round($op->getY1(), self::PRECISION); + $x2 = round($op->getX2(), self::PRECISION); + $y2 = round($op->getY2(), self::PRECISION); + $fromX = $x3 = round($op->getX3(), self::PRECISION); + $fromY = $y3 = round($op->getY3(), self::PRECISION); + $pathData[] = sprintf('%s %s %s %s %s %s c', $x1, $y1, $x2, $y2, $x3, $y3); + break; + + case $op instanceof Close: + $pathData[] = 'z'; + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + return implode(' ', $pathData); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : void + { + $startColor = $gradient->getStartColor(); + $endColor = $gradient->getEndColor(); + + if ($startColor instanceof Alpha) { + $startColor = $startColor->getBaseColor(); + } + + $startColorType = get_class($startColor); + + if (! in_array($startColorType, [Rgb::class, Cmyk::class, Gray::class])) { + $startColorType = Cmyk::class; + $startColor = $startColor->toCmyk(); + } + + if (get_class($endColor) !== $startColorType) { + switch ($startColorType) { + case Cmyk::class: + $endColor = $endColor->toCmyk(); + break; + + case Rgb::class: + $endColor = $endColor->toRgb(); + break; + + case Gray::class: + $endColor = $endColor->toGray(); + break; + } + } + + $this->eps .= "eoclip\n<<\n"; + + if ($gradient->getType() === GradientType::RADIAL()) { + $this->eps .= " /ShadingType 3\n"; + } else { + $this->eps .= " /ShadingType 2\n"; + } + + $this->eps .= " /Extend [ true true ]\n" + . " /AntiAlias true\n"; + + switch ($startColorType) { + case Cmyk::class: + $this->eps .= " /ColorSpace /DeviceCMYK\n"; + break; + + case Rgb::class: + $this->eps .= " /ColorSpace /DeviceRGB\n"; + break; + + case Gray::class: + $this->eps .= " /ColorSpace /DeviceGray\n"; + break; + } + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ); + break; + + case GradientType::VERTICAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x, self::PRECISION), + round($y + $height, self::PRECISION) + ); + break; + + case GradientType::DIAGONAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y + $height, self::PRECISION) + ); + break; + + case GradientType::INVERSE_DIAGONAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y + $height, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ); + break; + + case GradientType::RADIAL(): + $centerX = ($x + $width) / 2; + $centerY = ($y + $height) / 2; + + $this->eps .= sprintf( + " /Coords [ %s %s 0 %s %s %s ]\n", + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round(max($width, $height) / 2, self::PRECISION) + ); + break; + } + + $this->eps .= " /Function\n" + . " <<\n" + . " /FunctionType 2\n" + . " /Domain [ 0 1 ]\n" + . sprintf(" /C0 [ %s ]\n", $this->getColorString($startColor)) + . sprintf(" /C1 [ %s ]\n", $this->getColorString($endColor)) + . " /N 1\n" + . " >>\n>>\nshfill\nQ\n"; + } + + private function getColorSetString(ColorInterface $color) : string + { + if ($color instanceof Rgb) { + return $this->getColorString($color) . ' rgb'; + } + + if ($color instanceof Cmyk) { + return $this->getColorString($color) . ' cmyk'; + } + + if ($color instanceof Gray) { + return $this->getColorString($color) . ' gray'; + } + + return $this->getColorSetString($color->toCmyk()); + } + + private function getColorString(ColorInterface $color) : string + { + if ($color instanceof Rgb) { + return sprintf('%s %s %s', $color->getRed() / 255, $color->getGreen() / 255, $color->getBlue() / 255); + } + + if ($color instanceof Cmyk) { + return sprintf( + '%s %s %s %s', + $color->getCyan() / 100, + $color->getMagenta() / 100, + $color->getYellow() / 100, + $color->getBlack() / 100 + ); + } + + if ($color instanceof Gray) { + return sprintf('%s', $color->getGray() / 100); + } + + return $this->getColorString($color->toCmyk()); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php new file mode 100644 index 000000000..0935819a8 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php @@ -0,0 +1,87 @@ +imageFormat = $imageFormat; + $this->compressionQuality = $compressionQuality; + } + + public function new(int $size, ColorInterface $backgroundColor) : void + { + $this->image = new Imagick(); + $this->image->newImage($size, $size, $this->getColorPixel($backgroundColor)); + $this->image->setImageFormat($this->imageFormat); + $this->image->setCompressionQuality($this->compressionQuality); + $this->draw = new ImagickDraw(); + $this->gradientCount = 0; + $this->matrices = [new TransformationMatrix()]; + $this->matrixIndex = 0; + } + + public function scale(float $size) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->scale($size, $size); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::scale($size)); + } + + public function translate(float $x, float $y) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->translate($x, $y); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::translate($x, $y)); + } + + public function rotate(int $degrees) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->rotate($degrees); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::rotate($degrees)); + } + + public function push() : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->push(); + $this->matrices[++$this->matrixIndex] = $this->matrices[$this->matrixIndex - 1]; + } + + public function pop() : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->pop(); + unset($this->matrices[$this->matrixIndex--]); + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->setFillColor($this->getColorPixel($color)); + $this->drawPath($path); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->setFillPatternURL('#' . $this->createGradientFill($gradient, $x, $y, $width, $height)); + $this->drawPath($path); + } + + public function done() : string + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->image->drawImage($this->draw); + $blob = $this->image->getImageBlob(); + $this->draw->clear(); + $this->image->clear(); + $this->draw = null; + $this->image = null; + $this->gradientCount = null; + + return $blob; + } + + private function drawPath(Path $path) : void + { + $this->draw->pathStart(); + + foreach ($path as $op) { + switch (true) { + case $op instanceof Move: + $this->draw->pathMoveToAbsolute($op->getX(), $op->getY()); + break; + + case $op instanceof Line: + $this->draw->pathLineToAbsolute($op->getX(), $op->getY()); + break; + + case $op instanceof EllipticArc: + $this->draw->pathEllipticArcAbsolute( + $op->getXRadius(), + $op->getYRadius(), + $op->getXAxisAngle(), + $op->isLargeArc(), + $op->isSweep(), + $op->getX(), + $op->getY() + ); + break; + + case $op instanceof Curve: + $this->draw->pathCurveToAbsolute( + $op->getX1(), + $op->getY1(), + $op->getX2(), + $op->getY2(), + $op->getX3(), + $op->getY3() + ); + break; + + case $op instanceof Close: + $this->draw->pathClose(); + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + $this->draw->pathFinish(); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string + { + list($width, $height) = $this->matrices[$this->matrixIndex]->apply($width, $height); + + $startColor = $this->getColorPixel($gradient->getStartColor())->getColorAsString(); + $endColor = $this->getColorPixel($gradient->getEndColor())->getColorAsString(); + $gradientImage = new Imagick(); + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $gradientImage->newPseudoImage((int) $height, (int) $width, sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + $gradientImage->rotateImage('transparent', -90); + break; + + case GradientType::VERTICAL(): + $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + break; + + case GradientType::DIAGONAL(): + case GradientType::INVERSE_DIAGONAL(): + $gradientImage->newPseudoImage((int) ($width * sqrt(2)), (int) ($height * sqrt(2)), sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + + if (GradientType::DIAGONAL() === $gradient->getType()) { + $gradientImage->rotateImage('transparent', -45); + } else { + $gradientImage->rotateImage('transparent', -135); + } + + $rotatedWidth = $gradientImage->getImageWidth(); + $rotatedHeight = $gradientImage->getImageHeight(); + + $gradientImage->setImagePage($rotatedWidth, $rotatedHeight, 0, 0); + $gradientImage->cropImage( + intdiv($rotatedWidth, 2) - 2, + intdiv($rotatedHeight, 2) - 2, + intdiv($rotatedWidth, 4) + 1, + intdiv($rotatedWidth, 4) + 1 + ); + break; + + case GradientType::RADIAL(): + $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( + 'radial-gradient:%s-%s', + $startColor, + $endColor + )); + break; + } + + $id = sprintf('g%d', ++$this->gradientCount); + $this->draw->pushPattern($id, 0, 0, $width, $height); + $this->draw->composite(Imagick::COMPOSITE_COPY, 0, 0, $width, $height, $gradientImage); + $this->draw->popPattern(); + return $id; + } + + private function getColorPixel(ColorInterface $color) : ImagickPixel + { + $alpha = 100; + + if ($color instanceof Alpha) { + $alpha = $color->getAlpha(); + $color = $color->getBaseColor(); + } + + if ($color instanceof Rgb) { + return new ImagickPixel(sprintf( + 'rgba(%d, %d, %d, %F)', + $color->getRed(), + $color->getGreen(), + $color->getBlue(), + $alpha / 100 + )); + } + + if ($color instanceof Cmyk) { + return new ImagickPixel(sprintf( + 'cmyka(%d, %d, %d, %d, %F)', + $color->getCyan(), + $color->getMagenta(), + $color->getYellow(), + $color->getBlack(), + $alpha / 100 + )); + } + + if ($color instanceof Gray) { + return new ImagickPixel(sprintf( + 'graya(%d%%, %F)', + $color->getGray(), + $alpha / 100 + )); + } + + return $this->getColorPixel(new Alpha($alpha, $color->toRgb())); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php new file mode 100644 index 000000000..cb37a9ff8 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php @@ -0,0 +1,369 @@ +xmlWriter = new XMLWriter(); + $this->xmlWriter->openMemory(); + + $this->xmlWriter->startDocument('1.0', 'UTF-8'); + $this->xmlWriter->startElement('svg'); + $this->xmlWriter->writeAttribute('xmlns', 'http://www.w3.org/2000/svg'); + $this->xmlWriter->writeAttribute('version', '1.1'); + $this->xmlWriter->writeAttribute('width', (string) $size); + $this->xmlWriter->writeAttribute('height', (string) $size); + $this->xmlWriter->writeAttribute('viewBox', '0 0 '. $size . ' ' . $size); + + $this->gradientCount = 0; + $this->currentStack = 0; + $this->stack[0] = 0; + + $alpha = 1; + + if ($backgroundColor instanceof Alpha) { + $alpha = $backgroundColor->getAlpha() / 100; + } + + if (0 === $alpha) { + return; + } + + $this->xmlWriter->startElement('rect'); + $this->xmlWriter->writeAttribute('x', '0'); + $this->xmlWriter->writeAttribute('y', '0'); + $this->xmlWriter->writeAttribute('width', (string) $size); + $this->xmlWriter->writeAttribute('height', (string) $size); + $this->xmlWriter->writeAttribute('fill', $this->getColorString($backgroundColor)); + + if ($alpha < 1) { + $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha); + } + + $this->xmlWriter->endElement(); + } + + public function scale(float $size) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute( + 'transform', + sprintf('scale(%s)', round($size, self::PRECISION)) + ); + ++$this->stack[$this->currentStack]; + } + + public function translate(float $x, float $y) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute( + 'transform', + sprintf('translate(%s,%s)', round($x, self::PRECISION), round($y, self::PRECISION)) + ); + ++$this->stack[$this->currentStack]; + } + + public function rotate(int $degrees) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute('transform', sprintf('rotate(%d)', $degrees)); + ++$this->stack[$this->currentStack]; + } + + public function push() : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->stack[] = 1; + ++$this->currentStack; + } + + public function pop() : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + for ($i = 0; $i < $this->stack[$this->currentStack]; ++$i) { + $this->xmlWriter->endElement(); + } + + array_pop($this->stack); + --$this->currentStack; + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $alpha = 1; + + if ($color instanceof Alpha) { + $alpha = $color->getAlpha() / 100; + } + + $this->startPathElement($path); + $this->xmlWriter->writeAttribute('fill', $this->getColorString($color)); + + if ($alpha < 1) { + $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha); + } + + $this->xmlWriter->endElement(); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $gradientId = $this->createGradientFill($gradient, $x, $y, $width, $height); + $this->startPathElement($path); + $this->xmlWriter->writeAttribute('fill', 'url(#' . $gradientId . ')'); + $this->xmlWriter->endElement(); + } + + public function done() : string + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + foreach ($this->stack as $openElements) { + for ($i = $openElements; $i > 0; --$i) { + $this->xmlWriter->endElement(); + } + } + + $this->xmlWriter->endDocument(); + $blob = $this->xmlWriter->outputMemory(true); + $this->xmlWriter = null; + $this->stack = null; + $this->currentStack = null; + $this->gradientCount = null; + + return $blob; + } + + private function startPathElement(Path $path) : void + { + $pathData = []; + + foreach ($path as $op) { + switch (true) { + case $op instanceof Move: + $pathData[] = sprintf( + 'M%s %s', + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof Line: + $pathData[] = sprintf( + 'L%s %s', + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof EllipticArc: + $pathData[] = sprintf( + 'A%s %s %s %u %u %s %s', + round($op->getXRadius(), self::PRECISION), + round($op->getYRadius(), self::PRECISION), + round($op->getXAxisAngle(), self::PRECISION), + $op->isLargeArc(), + $op->isSweep(), + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof Curve: + $pathData[] = sprintf( + 'C%s %s %s %s %s %s', + round($op->getX1(), self::PRECISION), + round($op->getY1(), self::PRECISION), + round($op->getX2(), self::PRECISION), + round($op->getY2(), self::PRECISION), + round($op->getX3(), self::PRECISION), + round($op->getY3(), self::PRECISION) + ); + break; + + case $op instanceof Close: + $pathData[] = 'Z'; + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + $this->xmlWriter->startElement('path'); + $this->xmlWriter->writeAttribute('fill-rule', 'evenodd'); + $this->xmlWriter->writeAttribute('d', implode('', $pathData)); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string + { + $this->xmlWriter->startElement('defs'); + + $startColor = $gradient->getStartColor(); + $endColor = $gradient->getEndColor(); + + if ($gradient->getType() === GradientType::RADIAL()) { + $this->xmlWriter->startElement('radialGradient'); + } else { + $this->xmlWriter->startElement('linearGradient'); + } + + $this->xmlWriter->writeAttribute('gradientUnits', 'userSpaceOnUse'); + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); + break; + + case GradientType::VERTICAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); + break; + + case GradientType::DIAGONAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); + break; + + case GradientType::INVERSE_DIAGONAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y + $height, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); + break; + + case GradientType::RADIAL(): + $this->xmlWriter->writeAttribute('cx', (string) round(($x + $width) / 2, self::PRECISION)); + $this->xmlWriter->writeAttribute('cy', (string) round(($y + $height) / 2, self::PRECISION)); + $this->xmlWriter->writeAttribute('r', (string) round(max($width, $height) / 2, self::PRECISION)); + break; + } + + $id = sprintf('g%d', ++$this->gradientCount); + $this->xmlWriter->writeAttribute('id', $id); + + $this->xmlWriter->startElement('stop'); + $this->xmlWriter->writeAttribute('offset', '0%'); + $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($startColor)); + + if ($startColor instanceof Alpha) { + $this->xmlWriter->writeAttribute('stop-opacity', (string) $startColor->getAlpha()); + } + + $this->xmlWriter->endElement(); + + $this->xmlWriter->startElement('stop'); + $this->xmlWriter->writeAttribute('offset', '100%'); + $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($endColor)); + + if ($endColor instanceof Alpha) { + $this->xmlWriter->writeAttribute('stop-opacity', (string) $endColor->getAlpha()); + } + + $this->xmlWriter->endElement(); + + $this->xmlWriter->endElement(); + $this->xmlWriter->endElement(); + + return $id; + } + + private function getColorString(ColorInterface $color) : string + { + $color = $color->toRgb(); + + return sprintf( + '#%02x%02x%02x', + $color->getRed(), + $color->getGreen(), + $color->getBlue() + ); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php new file mode 100644 index 000000000..7e88da6df --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php @@ -0,0 +1,68 @@ +values = [1, 0, 0, 1, 0, 0]; + } + + public function multiply(self $other) : self + { + $matrix = new self(); + $matrix->values[0] = $this->values[0] * $other->values[0] + $this->values[2] * $other->values[1]; + $matrix->values[1] = $this->values[1] * $other->values[0] + $this->values[3] * $other->values[1]; + $matrix->values[2] = $this->values[0] * $other->values[2] + $this->values[2] * $other->values[3]; + $matrix->values[3] = $this->values[1] * $other->values[2] + $this->values[3] * $other->values[3]; + $matrix->values[4] = $this->values[0] * $other->values[4] + $this->values[2] * $other->values[5] + + $this->values[4]; + $matrix->values[5] = $this->values[1] * $other->values[4] + $this->values[3] * $other->values[5] + + $this->values[5]; + + return $matrix; + } + + public static function scale(float $size) : self + { + $matrix = new self(); + $matrix->values = [$size, 0, 0, $size, 0, 0]; + return $matrix; + } + + public static function translate(float $x, float $y) : self + { + $matrix = new self(); + $matrix->values = [1, 0, 0, 1, $x, $y]; + return $matrix; + } + + public static function rotate(int $degrees) : self + { + $matrix = new self(); + $rad = deg2rad($degrees); + $matrix->values = [cos($rad), sin($rad), -sin($rad), cos($rad), 0, 0]; + return $matrix; + } + + + /** + * Applies this matrix onto a point and returns the resulting viewport point. + * + * @return float[] + */ + public function apply(float $x, float $y) : array + { + return [ + $x * $this->values[0] + $y * $this->values[2] + $this->values[4], + $x * $this->values[1] + $y * $this->values[3] + $this->values[5], + ]; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php new file mode 100644 index 000000000..ab16276c9 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php @@ -0,0 +1,152 @@ +rendererStyle = $rendererStyle; + $this->imageBackEnd = $imageBackEnd; + } + + /** + * @throws InvalidArgumentException if matrix width doesn't match height + */ + public function render(QrCode $qrCode) : string + { + $size = $this->rendererStyle->getSize(); + $margin = $this->rendererStyle->getMargin(); + $matrix = $qrCode->getMatrix(); + $matrixSize = $matrix->getWidth(); + + if ($matrixSize !== $matrix->getHeight()) { + throw new InvalidArgumentException('Matrix must have the same width and height'); + } + + $totalSize = $matrixSize + ($margin * 2); + $moduleSize = $size / $totalSize; + $fill = $this->rendererStyle->getFill(); + + $this->imageBackEnd->new($size, $fill->getBackgroundColor()); + $this->imageBackEnd->scale((float) $moduleSize); + $this->imageBackEnd->translate((float) $margin, (float) $margin); + + $module = $this->rendererStyle->getModule(); + $moduleMatrix = clone $matrix; + MatrixUtil::removePositionDetectionPatterns($moduleMatrix); + $modulePath = $this->drawEyes($matrixSize, $module->createPath($moduleMatrix)); + + if ($fill->hasGradientFill()) { + $this->imageBackEnd->drawPathWithGradient( + $modulePath, + $fill->getForegroundGradient(), + 0, + 0, + $matrixSize, + $matrixSize + ); + } else { + $this->imageBackEnd->drawPathWithColor($modulePath, $fill->getForegroundColor()); + } + + return $this->imageBackEnd->done(); + } + + private function drawEyes(int $matrixSize, Path $modulePath) : Path + { + $fill = $this->rendererStyle->getFill(); + + $eye = $this->rendererStyle->getEye(); + $externalPath = $eye->getExternalPath(); + $internalPath = $eye->getInternalPath(); + + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getTopLeftEyeFill(), + 3.5, + 3.5, + 0, + $modulePath + ); + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getTopRightEyeFill(), + $matrixSize - 3.5, + 3.5, + 90, + $modulePath + ); + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getBottomLeftEyeFill(), + 3.5, + $matrixSize - 3.5, + -90, + $modulePath + ); + + return $modulePath; + } + + private function drawEye( + Path $externalPath, + Path $internalPath, + EyeFill $fill, + float $xTranslation, + float $yTranslation, + int $rotation, + Path $modulePath + ) : Path { + if ($fill->inheritsBothColors()) { + return $modulePath + ->append($externalPath->translate($xTranslation, $yTranslation)) + ->append($internalPath->translate($xTranslation, $yTranslation)); + } + + $this->imageBackEnd->push(); + $this->imageBackEnd->translate($xTranslation, $yTranslation); + + if (0 !== $rotation) { + $this->imageBackEnd->rotate($rotation); + } + + if ($fill->inheritsExternalColor()) { + $modulePath = $modulePath->append($externalPath->translate($xTranslation, $yTranslation)); + } else { + $this->imageBackEnd->drawPathWithColor($externalPath, $fill->getExternalColor()); + } + + if ($fill->inheritsInternalColor()) { + $modulePath = $modulePath->append($internalPath->translate($xTranslation, $yTranslation)); + } else { + $this->imageBackEnd->drawPathWithColor($internalPath, $fill->getInternalColor()); + } + + $this->imageBackEnd->pop(); + + return $modulePath; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php new file mode 100644 index 000000000..f536e5ab3 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php @@ -0,0 +1,63 @@ + 1) { + throw new InvalidArgumentException('Size must between 0 (exclusive) and 1 (inclusive)'); + } + + $this->size = $size; + } + + public function createPath(ByteMatrix $matrix) : Path + { + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + $path = new Path(); + $halfSize = $this->size / 2; + $margin = (1 - $this->size) / 2; + + for ($y = 0; $y < $height; ++$y) { + for ($x = 0; $x < $width; ++$x) { + if (! $matrix->get($x, $y)) { + continue; + } + + $pathX = $x + $margin; + $pathY = $y + $margin; + + $path = $path + ->move($pathX + $this->size, $pathY + $halfSize) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY + $this->size) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX, $pathY + $halfSize) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $this->size, $pathY + $halfSize) + ->close() + ; + } + } + + return $path; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php new file mode 100644 index 000000000..90482f21d --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php @@ -0,0 +1,100 @@ + + */ + private $points = []; + + /** + * @var array|null + */ + private $simplifiedPoints; + + /** + * @var int + */ + private $minX = PHP_INT_MAX; + + /** + * @var int + */ + private $minY = PHP_INT_MAX; + + /** + * @var int + */ + private $maxX = -1; + + /** + * @var int + */ + private $maxY = -1; + + public function __construct(bool $positive) + { + $this->positive = $positive; + } + + public function addPoint(int $x, int $y) : void + { + $this->points[] = [$x, $y]; + $this->minX = min($this->minX, $x); + $this->minY = min($this->minY, $y); + $this->maxX = max($this->maxX, $x); + $this->maxY = max($this->maxY, $y); + } + + public function isPositive() : bool + { + return $this->positive; + } + + /** + * @return array + */ + public function getPoints() : array + { + return $this->points; + } + + public function getMaxX() : int + { + return $this->maxX; + } + + public function getSimplifiedPoints() : array + { + if (null !== $this->simplifiedPoints) { + return $this->simplifiedPoints; + } + + $points = []; + $length = count($this->points); + + for ($i = 0; $i < $length; ++$i) { + $previousPoint = $this->points[(0 === $i ? $length : $i) - 1]; + $nextPoint = $this->points[($length - 1 === $i ? -1 : $i) + 1]; + $currentPoint = $this->points[$i]; + + if (($previousPoint[0] === $currentPoint[0] && $currentPoint[0] === $nextPoint[0]) + || ($previousPoint[1] === $currentPoint[1] && $currentPoint[1] === $nextPoint[1]) + ) { + continue; + } + + $points[] = $currentPoint; + } + + return $this->simplifiedPoints = $points; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php new file mode 100644 index 000000000..eb29dc60a --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php @@ -0,0 +1,169 @@ +bytes = iterator_to_array($matrix->getBytes()); + $this->size = count($this->bytes); + $this->width = $matrix->getWidth(); + $this->height = $matrix->getHeight(); + } + + /** + * @return Traversable + */ + public function getIterator() : Traversable + { + $originalBytes = $this->bytes; + $point = $this->findNext(0, 0); + + while (null !== $point) { + $edge = $this->findEdge($point[0], $point[1]); + $this->xorEdge($edge); + + yield $edge; + + $point = $this->findNext($point[0], $point[1]); + } + + $this->bytes = $originalBytes; + } + + /** + * @return int[]|null + */ + private function findNext(int $x, int $y) : ?array + { + $i = $this->width * $y + $x; + + while ($i < $this->size && 1 !== $this->bytes[$i]) { + ++$i; + } + + if ($i < $this->size) { + return $this->pointOf($i); + } + + return null; + } + + private function findEdge(int $x, int $y) : Edge + { + $edge = new Edge($this->isSet($x, $y)); + $startX = $x; + $startY = $y; + $dirX = 0; + $dirY = 1; + + while (true) { + $edge->addPoint($x, $y); + $x += $dirX; + $y += $dirY; + + if ($x === $startX && $y === $startY) { + break; + } + + $left = $this->isSet($x + ($dirX + $dirY - 1 ) / 2, $y + ($dirY - $dirX - 1) / 2); + $right = $this->isSet($x + ($dirX - $dirY - 1) / 2, $y + ($dirY + $dirX - 1) / 2); + + if ($right && ! $left) { + $tmp = $dirX; + $dirX = -$dirY; + $dirY = $tmp; + } elseif ($right) { + $tmp = $dirX; + $dirX = -$dirY; + $dirY = $tmp; + } elseif (! $left) { + $tmp = $dirX; + $dirX = $dirY; + $dirY = -$tmp; + } + } + + return $edge; + } + + private function xorEdge(Edge $path) : void + { + $points = $path->getPoints(); + $y1 = $points[0][1]; + $length = count($points); + $maxX = $path->getMaxX(); + + for ($i = 1; $i < $length; ++$i) { + $y = $points[$i][1]; + + if ($y === $y1) { + continue; + } + + $x = $points[$i][0]; + $minY = min($y1, $y); + + for ($j = $x; $j < $maxX; ++$j) { + $this->flip($j, $minY); + } + + $y1 = $y; + } + } + + private function isSet(int $x, int $y) : bool + { + return ( + $x >= 0 + && $x < $this->width + && $y >= 0 + && $y < $this->height + ) && 1 === $this->bytes[$this->width * $y + $x]; + } + + /** + * @return int[] + */ + private function pointOf(int $i) : array + { + $y = intdiv($i, $this->width); + return [$i - $y * $this->width, $y]; + } + + private function flip(int $x, int $y) : void + { + $this->bytes[$this->width * $y + $x] = ( + $this->isSet($x, $y) ? 0 : 1 + ); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php new file mode 100644 index 000000000..0ccb0e0fe --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php @@ -0,0 +1,18 @@ + 1) { + throw new InvalidArgumentException('Intensity must between 0 (exclusive) and 1 (inclusive)'); + } + + $this->intensity = $intensity / 2; + } + + public function createPath(ByteMatrix $matrix) : Path + { + $path = new Path(); + + foreach (new EdgeIterator($matrix) as $edge) { + $points = $edge->getSimplifiedPoints(); + $length = count($points); + + $currentPoint = $points[0]; + $nextPoint = $points[1]; + $horizontal = ($currentPoint[1] === $nextPoint[1]); + + if ($horizontal) { + $right = $nextPoint[0] > $currentPoint[0]; + $path = $path->move( + $currentPoint[0] + ($right ? $this->intensity : -$this->intensity), + $currentPoint[1] + ); + } else { + $up = $nextPoint[0] < $currentPoint[0]; + $path = $path->move( + $currentPoint[0], + $currentPoint[1] + ($up ? -$this->intensity : $this->intensity) + ); + } + + for ($i = 1; $i <= $length; ++$i) { + if ($i === $length) { + $previousPoint = $points[$length - 1]; + $currentPoint = $points[0]; + $nextPoint = $points[1]; + } else { + $previousPoint = $points[(0 === $i ? $length : $i) - 1]; + $currentPoint = $points[$i]; + $nextPoint = $points[($length - 1 === $i ? -1 : $i) + 1]; + } + + $horizontal = ($previousPoint[1] === $currentPoint[1]); + + if ($horizontal) { + $right = $previousPoint[0] < $currentPoint[0]; + $up = $nextPoint[1] < $currentPoint[1]; + $sweep = ($up xor $right); + + if ($this->intensity < 0.5 + || ($right && $previousPoint[0] !== $currentPoint[0] - 1) + || (! $right && $previousPoint[0] - 1 !== $currentPoint[0]) + ) { + $path = $path->line( + $currentPoint[0] + ($right ? -$this->intensity : $this->intensity), + $currentPoint[1] + ); + } + + $path = $path->ellipticArc( + $this->intensity, + $this->intensity, + 0, + false, + $sweep, + $currentPoint[0], + $currentPoint[1] + ($up ? -$this->intensity : $this->intensity) + ); + } else { + $up = $previousPoint[1] > $currentPoint[1]; + $right = $nextPoint[0] > $currentPoint[0]; + $sweep = ! ($up xor $right); + + if ($this->intensity < 0.5 + || ($up && $previousPoint[1] !== $currentPoint[1] + 1) + || (! $up && $previousPoint[0] + 1 !== $currentPoint[0]) + ) { + $path = $path->line( + $currentPoint[0], + $currentPoint[1] + ($up ? $this->intensity : -$this->intensity) + ); + } + + $path = $path->ellipticArc( + $this->intensity, + $this->intensity, + 0, + false, + $sweep, + $currentPoint[0] + ($right ? $this->intensity : -$this->intensity), + $currentPoint[1] + ); + } + } + + $path = $path->close(); + } + + return $path; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php new file mode 100644 index 000000000..9ab460766 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php @@ -0,0 +1,47 @@ +getSimplifiedPoints(); + $length = count($points); + $path = $path->move($points[0][0], $points[0][1]); + + for ($i = 1; $i < $length; ++$i) { + $path = $path->line($points[$i][0], $points[$i][1]); + } + + $path = $path->close(); + } + + return $path; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php new file mode 100644 index 000000000..b07feb02d --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php @@ -0,0 +1,29 @@ +x1 = $x1; + $this->y1 = $y1; + $this->x2 = $x2; + $this->y2 = $y2; + $this->x3 = $x3; + $this->y3 = $y3; + } + + public function getX1() : float + { + return $this->x1; + } + + public function getY1() : float + { + return $this->y1; + } + + public function getX2() : float + { + return $this->x2; + } + + public function getY2() : float + { + return $this->y2; + } + + public function getX3() : float + { + return $this->x3; + } + + public function getY3() : float + { + return $this->y3; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self( + $this->x1 + $x, + $this->y1 + $y, + $this->x2 + $x, + $this->y2 + $y, + $this->x3 + $x, + $this->y3 + $y + ); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php new file mode 100644 index 000000000..9f2385abb --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php @@ -0,0 +1,278 @@ +xRadius = abs($xRadius); + $this->yRadius = abs($yRadius); + $this->xAxisAngle = $xAxisAngle % 360; + $this->largeArc = $largeArc; + $this->sweep = $sweep; + $this->x = $x; + $this->y = $y; + } + + public function getXRadius() : float + { + return $this->xRadius; + } + + public function getYRadius() : float + { + return $this->yRadius; + } + + public function getXAxisAngle() : float + { + return $this->xAxisAngle; + } + + public function isLargeArc() : bool + { + return $this->largeArc; + } + + public function isSweep() : bool + { + return $this->sweep; + } + + public function getX() : float + { + return $this->x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self( + $this->xRadius, + $this->yRadius, + $this->xAxisAngle, + $this->largeArc, + $this->sweep, + $this->x + $x, + $this->y + $y + ); + } + + /** + * Converts the elliptic arc to multiple curves. + * + * Since not all image back ends support elliptic arcs, this method allows to convert the arc into multiple curves + * resembling the same result. + * + * @see https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ + * @return array + */ + public function toCurves(float $fromX, float $fromY) : array + { + if (sqrt(($fromX - $this->x) ** 2 + ($fromY - $this->y) ** 2) < self::ZERO_TOLERANCE) { + return []; + } + + if ($this->xRadius < self::ZERO_TOLERANCE || $this->yRadius < self::ZERO_TOLERANCE) { + return [new Line($this->x, $this->y)]; + } + + return $this->createCurves($fromX, $fromY); + } + + /** + * @return Curve[] + */ + private function createCurves(float $fromX, float $fromY) : array + { + $xAngle = deg2rad($this->xAxisAngle); + list($centerX, $centerY, $radiusX, $radiusY, $startAngle, $deltaAngle) = + $this->calculateCenterPointParameters($fromX, $fromY, $xAngle); + + $s = $startAngle; + $e = $s + $deltaAngle; + $sign = ($e < $s) ? -1 : 1; + $remain = abs($e - $s); + $p1 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s); + $curves = []; + + while ($remain > self::ZERO_TOLERANCE) { + $step = min($remain, pi() / 2); + $signStep = $step * $sign; + $p2 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s + $signStep); + + $alphaT = tan($signStep / 2); + $alpha = sin($signStep) * (sqrt(4 + 3 * $alphaT ** 2) - 1) / 3; + $d1 = self::derivative($radiusX, $radiusY, $xAngle, $s); + $d2 = self::derivative($radiusX, $radiusY, $xAngle, $s + $signStep); + + $curves[] = new Curve( + $p1[0] + $alpha * $d1[0], + $p1[1] + $alpha * $d1[1], + $p2[0] - $alpha * $d2[0], + $p2[1] - $alpha * $d2[1], + $p2[0], + $p2[1] + ); + + $s += $signStep; + $remain -= $step; + $p1 = $p2; + } + + return $curves; + } + + /** + * @return float[] + */ + private function calculateCenterPointParameters(float $fromX, float $fromY, float $xAngle) + { + $rX = $this->xRadius; + $rY = $this->yRadius; + + // F.6.5.1 + $dx2 = ($fromX - $this->x) / 2; + $dy2 = ($fromY - $this->y) / 2; + $x1p = cos($xAngle) * $dx2 + sin($xAngle) * $dy2; + $y1p = -sin($xAngle) * $dx2 + cos($xAngle) * $dy2; + + // F.6.5.2 + $rxs = $rX ** 2; + $rys = $rY ** 2; + $x1ps = $x1p ** 2; + $y1ps = $y1p ** 2; + $cr = $x1ps / $rxs + $y1ps / $rys; + + if ($cr > 1) { + $s = sqrt($cr); + $rX *= $s; + $rY *= $s; + $rxs = $rX ** 2; + $rys = $rY ** 2; + } + + $dq = ($rxs * $y1ps + $rys * $x1ps); + $pq = ($rxs * $rys - $dq) / $dq; + $q = sqrt(max(0, $pq)); + + if ($this->largeArc === $this->sweep) { + $q = -$q; + } + + $cxp = $q * $rX * $y1p / $rY; + $cyp = -$q * $rY * $x1p / $rX; + + // F.6.5.3 + $cx = cos($xAngle) * $cxp - sin($xAngle) * $cyp + ($fromX + $this->x) / 2; + $cy = sin($xAngle) * $cxp + cos($xAngle) * $cyp + ($fromY + $this->y) / 2; + + // F.6.5.5 + $theta = self::angle(1, 0, ($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY); + + // F.6.5.6 + $delta = self::angle(($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY, (-$x1p - $cxp) / $rX, (-$y1p - $cyp) / $rY); + $delta = fmod($delta, pi() * 2); + + if (! $this->sweep) { + $delta -= 2 * pi(); + } + + return [$cx, $cy, $rX, $rY, $theta, $delta]; + } + + private static function angle(float $ux, float $uy, float $vx, float $vy) : float + { + // F.6.5.4 + $dot = $ux * $vx + $uy * $vy; + $length = sqrt($ux ** 2 + $uy ** 2) * sqrt($vx ** 2 + $vy ** 2); + $angle = acos(min(1, max(-1, $dot / $length))); + + if (($ux * $vy - $uy * $vx) < 0) { + return -$angle; + } + + return $angle; + } + + /** + * @return float[] + */ + private static function point( + float $centerX, + float $centerY, + float $radiusX, + float $radiusY, + float $xAngle, + float $angle + ) : array { + return [ + $centerX + $radiusX * cos($xAngle) * cos($angle) - $radiusY * sin($xAngle) * sin($angle), + $centerY + $radiusX * sin($xAngle) * cos($angle) + $radiusY * cos($xAngle) * sin($angle), + ]; + } + + /** + * @return float[] + */ + private static function derivative(float $radiusX, float $radiusY, float $xAngle, float $angle) : array + { + return [ + -$radiusX * cos($xAngle) * sin($angle) - $radiusY * sin($xAngle) * cos($angle), + -$radiusX * sin($xAngle) * sin($angle) + $radiusY * cos($xAngle) * cos($angle), + ]; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php new file mode 100644 index 000000000..3149a39bc --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php @@ -0,0 +1,41 @@ +x = $x; + $this->y = $y; + } + + public function getX() : float + { + return $this->x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self($this->x + $x, $this->y + $y); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php new file mode 100644 index 000000000..481d0dd15 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php @@ -0,0 +1,41 @@ +x = $x; + $this->y = $y; + } + + public function getX() : float + { + return $this->x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self($this->x + $x, $this->y + $y); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php new file mode 100644 index 000000000..a5fa0edc4 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php @@ -0,0 +1,12 @@ +operations[] = new Move($x, $y); + return $path; + } + + /** + * Draws a line from the current position to another position. + */ + public function line(float $x, float $y) : self + { + $path = clone $this; + $path->operations[] = new Line($x, $y); + return $path; + } + + /** + * Draws an elliptic arc from the current position to another position. + */ + public function ellipticArc( + float $xRadius, + float $yRadius, + float $xAxisRotation, + bool $largeArc, + bool $sweep, + float $x, + float $y + ) : self { + $path = clone $this; + $path->operations[] = new EllipticArc($xRadius, $yRadius, $xAxisRotation, $largeArc, $sweep, $x, $y); + return $path; + } + + /** + * Draws a curve from the current position to another position. + */ + public function curve(float $x1, float $y1, float $x2, float $y2, float $x3, float $y3) : self + { + $path = clone $this; + $path->operations[] = new Curve($x1, $y1, $x2, $y2, $x3, $y3); + return $path; + } + + /** + * Closes a sub-path. + */ + public function close() : self + { + $path = clone $this; + $path->operations[] = Close::instance(); + return $path; + } + + /** + * Appends another path to this one. + */ + public function append(self $other) : self + { + $path = clone $this; + $path->operations = array_merge($this->operations, $other->operations); + return $path; + } + + public function translate(float $x, float $y) : self + { + $path = new self(); + + foreach ($this->operations as $operation) { + $path->operations[] = $operation->translate($x, $y); + } + + return $path; + } + + /** + * @return OperationInterface[]|Traversable + */ + public function getIterator() : Traversable + { + foreach ($this->operations as $operation) { + yield $operation; + } + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php new file mode 100644 index 000000000..8aa76528b --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php @@ -0,0 +1,86 @@ +margin = $margin; + } + + /** + * @throws InvalidArgumentException if matrix width doesn't match height + */ + public function render(QrCode $qrCode) : string + { + $matrix = $qrCode->getMatrix(); + $matrixSize = $matrix->getWidth(); + + if ($matrixSize !== $matrix->getHeight()) { + throw new InvalidArgumentException('Matrix must have the same width and height'); + } + + $rows = $matrix->getArray()->toArray(); + + if (0 !== $matrixSize % 2) { + $rows[] = array_fill(0, $matrixSize, 0); + } + + $horizontalMargin = str_repeat(self::EMPTY_BLOCK, $this->margin); + $result = str_repeat("\n", (int) ceil($this->margin / 2)); + + for ($i = 0; $i < $matrixSize; $i += 2) { + $result .= $horizontalMargin; + + $upperRow = $rows[$i]; + $lowerRow = $rows[$i + 1]; + + for ($j = 0; $j < $matrixSize; ++$j) { + $upperBit = $upperRow[$j]; + $lowerBit = $lowerRow[$j]; + + if ($upperBit) { + $result .= $lowerBit ? self::FULL_BLOCK : self::UPPER_HALF_BLOCK; + } else { + $result .= $lowerBit ? self::LOWER_HALF_BLOCK : self::EMPTY_BLOCK; + } + } + + $result .= $horizontalMargin . "\n"; + } + + $result .= str_repeat("\n", (int) ceil($this->margin / 2)); + + return $result; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php new file mode 100644 index 000000000..b0aae390d --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php @@ -0,0 +1,11 @@ +externalColor = $externalColor; + $this->internalColor = $internalColor; + } + + public static function uniform(ColorInterface $color) : self + { + return new self($color, $color); + } + + public static function inherit() : self + { + return self::$inherit ?: self::$inherit = new self(null, null); + } + + public function inheritsBothColors() : bool + { + return null === $this->externalColor && null === $this->internalColor; + } + + public function inheritsExternalColor() : bool + { + return null === $this->externalColor; + } + + public function inheritsInternalColor() : bool + { + return null === $this->internalColor; + } + + public function getExternalColor() : ColorInterface + { + if (null === $this->externalColor) { + throw new RuntimeException('External eye color inherits foreground color'); + } + + return $this->externalColor; + } + + public function getInternalColor() : ColorInterface + { + if (null === $this->internalColor) { + throw new RuntimeException('Internal eye color inherits foreground color'); + } + + return $this->internalColor; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php new file mode 100644 index 000000000..d54268e63 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php @@ -0,0 +1,168 @@ +backgroundColor = $backgroundColor; + $this->foregroundColor = $foregroundColor; + $this->foregroundGradient = $foregroundGradient; + $this->topLeftEyeFill = $topLeftEyeFill; + $this->topRightEyeFill = $topRightEyeFill; + $this->bottomLeftEyeFill = $bottomLeftEyeFill; + } + + public static function default() : self + { + return self::$default ?: self::$default = self::uniformColor(new Gray(100), new Gray(0)); + } + + public static function withForegroundColor( + ColorInterface $backgroundColor, + ColorInterface $foregroundColor, + EyeFill $topLeftEyeFill, + EyeFill $topRightEyeFill, + EyeFill $bottomLeftEyeFill + ) : self { + return new self( + $backgroundColor, + $foregroundColor, + null, + $topLeftEyeFill, + $topRightEyeFill, + $bottomLeftEyeFill + ); + } + + public static function withForegroundGradient( + ColorInterface $backgroundColor, + Gradient $foregroundGradient, + EyeFill $topLeftEyeFill, + EyeFill $topRightEyeFill, + EyeFill $bottomLeftEyeFill + ) : self { + return new self( + $backgroundColor, + null, + $foregroundGradient, + $topLeftEyeFill, + $topRightEyeFill, + $bottomLeftEyeFill + ); + } + + public static function uniformColor(ColorInterface $backgroundColor, ColorInterface $foregroundColor) : self + { + return new self( + $backgroundColor, + $foregroundColor, + null, + EyeFill::inherit(), + EyeFill::inherit(), + EyeFill::inherit() + ); + } + + public static function uniformGradient(ColorInterface $backgroundColor, Gradient $foregroundGradient) : self + { + return new self( + $backgroundColor, + null, + $foregroundGradient, + EyeFill::inherit(), + EyeFill::inherit(), + EyeFill::inherit() + ); + } + + public function hasGradientFill() : bool + { + return null !== $this->foregroundGradient; + } + + public function getBackgroundColor() : ColorInterface + { + return $this->backgroundColor; + } + + public function getForegroundColor() : ColorInterface + { + if (null === $this->foregroundColor) { + throw new RuntimeException('Fill uses a gradient, thus no foreground color is available'); + } + + return $this->foregroundColor; + } + + public function getForegroundGradient() : Gradient + { + if (null === $this->foregroundGradient) { + throw new RuntimeException('Fill uses a single color, thus no foreground gradient is available'); + } + + return $this->foregroundGradient; + } + + public function getTopLeftEyeFill() : EyeFill + { + return $this->topLeftEyeFill; + } + + public function getTopRightEyeFill() : EyeFill + { + return $this->topRightEyeFill; + } + + public function getBottomLeftEyeFill() : EyeFill + { + return $this->bottomLeftEyeFill; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php new file mode 100644 index 000000000..3813dfd17 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php @@ -0,0 +1,46 @@ +startColor = $startColor; + $this->endColor = $endColor; + $this->type = $type; + } + + public function getStartColor() : ColorInterface + { + return $this->startColor; + } + + public function getEndColor() : ColorInterface + { + return $this->endColor; + } + + public function getType() : GradientType + { + return $this->type; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php new file mode 100644 index 000000000..c1ca75471 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php @@ -0,0 +1,22 @@ +margin = $margin; + $this->size = $size; + $this->module = $module ?: SquareModule::instance(); + $this->eye = $eye ?: new ModuleEye($this->module); + $this->fill = $fill ?: Fill::default(); + } + + public function withSize(int $size) : self + { + $style = clone $this; + $style->size = $size; + return $style; + } + + public function withMargin(int $margin) : self + { + $style = clone $this; + $style->margin = $margin; + return $style; + } + + public function getSize() : int + { + return $this->size; + } + + public function getMargin() : int + { + return $this->margin; + } + + public function getModule() : ModuleInterface + { + return $this->module; + } + + public function getEye() : EyeInterface + { + return $this->eye; + } + + public function getFill() : Fill + { + return $this->fill; + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Writer.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Writer.php new file mode 100644 index 000000000..d5bdc5c35 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/src/Writer.php @@ -0,0 +1,71 @@ +renderer = $renderer; + } + + /** + * Writes QR code and returns it as string. + * + * Content is a string which *should* be encoded in UTF-8, in case there are + * non ASCII-characters present. + * + * @throws InvalidArgumentException if the content is empty + */ + public function writeString( + string $content, + string $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING, + ?ErrorCorrectionLevel $ecLevel = null, + ?Version $forcedVersion = null + ) : string { + if (strlen($content) === 0) { + throw new InvalidArgumentException('Found empty contents'); + } + + if (null === $ecLevel) { + $ecLevel = ErrorCorrectionLevel::L(); + } + + return $this->renderer->render(Encoder::encode($content, $ecLevel, $encoding, $forcedVersion)); + } + + /** + * Writes QR code to a file. + * + * @see Writer::writeString() + */ + public function writeFile( + string $content, + string $filename, + string $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING, + ?ErrorCorrectionLevel $ecLevel = null, + ?Version $forcedVersion = null + ) : void { + file_put_contents($filename, $this->writeString($content, $encoding, $ecLevel, $forcedVersion)); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitArrayTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitArrayTest.php new file mode 100644 index 000000000..add798b1b --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitArrayTest.php @@ -0,0 +1,222 @@ +assertFalse($array->get($i)); + $array->set($i); + $this->assertTrue($array->get($i)); + } + } + + public function testGetNextSet1() : void + { + $array = new BitArray(32); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, 32, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, 32, $array->getNextSet($i)); + } + } + + $array = new BitArray(33); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, 33, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, 33, $array->getNextSet($i)); + } + } + } + + public function testGetNextSet2() : void + { + $array = new BitArray(33); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, $i <= 31 ? 31 : 33, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, $i <= 31 ? 31 : 33, $array->getNextSet($i)); + } + } + + $array = new BitArray(33); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, 32, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, 32, $array->getNextSet($i)); + } + } + } + + public function testGetNextSet3() : void + { + $array = new BitArray(63); + $array->set(31); + $array->set(32); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($i <= 31) { + $expected = 31; + } elseif ($i <= 32) { + $expected = 32; + } else { + $expected = 63; + } + + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, $expected, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, $expected, $array->getNextSet($i)); + } + } + } + + public function testGetNextSet4() : void + { + $array = new BitArray(63); + $array->set(33); + $array->set(40); + + for ($i = 0; $i < $array->getSize(); ++$i) { + if ($i <= 33) { + $expected = 33; + } elseif ($i <= 40) { + $expected = 40; + } else { + $expected = 63; + } + + if ($this->getPhpUnitMajorVersion() === 7) { + $this->assertEquals($i, $expected, '', $array->getNextSet($i)); + } else { + $this->assertEqualsWithDelta($i, $expected, $array->getNextSet($i)); + } + } + } + + public function testGetNextSet5() : void + { + mt_srand(0xdeadbeef, MT_RAND_PHP); + + for ($i = 0; $i < 10; ++$i) { + $array = new BitArray(mt_rand(1, 100)); + $numSet = mt_rand(0, 19); + + for ($j = 0; $j < $numSet; ++$j) { + $array->set(mt_rand(0, $array->getSize() - 1)); + } + + $numQueries = mt_rand(0, 19); + + for ($j = 0; $j < $numQueries; ++$j) { + $query = mt_rand(0, $array->getSize() - 1); + $expected = $query; + + while ($expected < $array->getSize() && ! $array->get($expected)) { + ++$expected; + } + + $actual = $array->getNextSet($query); + + if ($actual !== $expected) { + $array->getNextSet($query); + } + + $this->assertEquals($expected, $actual); + } + } + } + + public function testSetBulk() : void + { + $array = new BitArray(64); + $array->setBulk(32, 0xFFFF0000); + + for ($i = 0; $i < 48; ++$i) { + $this->assertFalse($array->get($i)); + } + + for ($i = 48; $i < 64; ++$i) { + $this->assertTrue($array->get($i)); + } + } + + public function testClear() : void + { + $array = new BitArray(32); + + for ($i = 0; $i < 32; ++$i) { + $array->set($i); + } + + $array->clear(); + + for ($i = 0; $i < 32; ++$i) { + $this->assertFalse($array->get($i)); + } + } + + public function testGetArray() : void + { + $array = new BitArray(64); + $array->set(0); + $array->set(63); + + $ints = $array->getBitArray(); + + $this->assertSame(1, $ints[0]); + $this->assertSame(0x80000000, $ints[1]); + } + + public function testIsRange() : void + { + $array = new BitArray(64); + $this->assertTrue($array->isRange(0, 64, false)); + $this->assertFalse($array->isRange(0, 64, true)); + + $array->set(32); + $this->assertTrue($array->isRange(32, 33, true)); + + $array->set(31); + $this->assertTrue($array->isRange(31, 33, true)); + + $array->set(34); + $this->assertFalse($array->isRange(31, 35, true)); + + for ($i = 0; $i < 31; ++$i) { + $array->set($i); + } + + $this->assertTrue($array->isRange(0, 33, true)); + + for ($i = 33; $i < 64; ++$i) { + $array->set($i); + } + + $this->assertTrue($array->isRange(0, 64, true)); + $this->assertFalse($array->isRange(0, 64, false)); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitMatrixTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitMatrixTest.php new file mode 100644 index 000000000..8ad86d4c2 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitMatrixTest.php @@ -0,0 +1,115 @@ +assertEquals(33, $matrix->getHeight()); + + for ($y = 0; $y < 33; ++$y) { + for ($x = 0; $x < 33; ++$x) { + if ($y * $x % 3 === 0) { + $matrix->set($x, $y); + } + } + } + + for ($y = 0; $y < 33; $y++) { + for ($x = 0; $x < 33; ++$x) { + $this->assertSame(0 === $x * $y % 3, $matrix->get($x, $y)); + } + } + } + + public function testSetRegion() : void + { + $matrix = new BitMatrix(5); + $matrix->setRegion(1, 1, 3, 3); + + for ($y = 0; $y < 5; ++$y) { + for ($x = 0; $x < 5; ++$x) { + $this->assertSame($y >= 1 && $y <= 3 && $x >= 1 && $x <= 3, $matrix->get($x, $y)); + } + } + } + + public function testRectangularMatrix() : void + { + $matrix = new BitMatrix(75, 20); + $this->assertSame(75, $matrix->getWidth()); + $this->assertSame(20, $matrix->getHeight()); + + $matrix->set(10, 0); + $matrix->set(11, 1); + $matrix->set(50, 2); + $matrix->set(51, 3); + $matrix->flip(74, 4); + $matrix->flip(0, 5); + + $this->assertTrue($matrix->get(10, 0)); + $this->assertTrue($matrix->get(11, 1)); + $this->assertTrue($matrix->get(50, 2)); + $this->assertTrue($matrix->get(51, 3)); + $this->assertTrue($matrix->get(74, 4)); + $this->assertTrue($matrix->get(0, 5)); + + $matrix->flip(50, 2); + $matrix->flip(51, 3); + + $this->assertFalse($matrix->get(50, 2)); + $this->assertFalse($matrix->get(51, 3)); + } + + public function testRectangularSetRegion() : void + { + $matrix = new BitMatrix(320, 240); + $this->assertSame(320, $matrix->getWidth()); + $this->assertSame(240, $matrix->getHeight()); + + $matrix->setRegion(105, 22, 80, 12); + + for ($y = 0; $y < 240; ++$y) { + for ($x = 0; $x < 320; ++$x) { + $this->assertEquals($y >= 22 && $y < 34 && $x >= 105 && $x < 185, $matrix->get($x, $y)); + } + } + } + + public function testGetRow() : void + { + $matrix = new BitMatrix(102, 5); + + for ($x = 0; $x < 102; ++$x) { + if (0 === ($x & 3)) { + $matrix->set($x, 2); + } + } + + $array1 = $matrix->getRow(2, null); + $this->assertSame(102, $array1->getSize()); + + $array2 = new BitArray(60); + $array2 = $matrix->getRow(2, $array2); + $this->assertSame(102, $array2->getSize()); + + $array3 = new BitArray(200); + $array3 = $matrix->getRow(2, $array3); + $this->assertSame(200, $array3->getSize()); + + for ($x = 0; $x < 102; ++$x) { + $on = (0 === ($x & 3)); + + $this->assertSame($on, $array1->get($x)); + $this->assertSame($on, $array2->get($x)); + $this->assertSame($on, $array3->get($x)); + } + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitUtilsTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitUtilsTest.php new file mode 100644 index 000000000..2904d312f --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/BitUtilsTest.php @@ -0,0 +1,25 @@ +assertSame(1, BitUtils::unsignedRightShift(1, 0)); + $this->assertSame(1, BitUtils::unsignedRightShift(10, 3)); + $this->assertSame(536870910, BitUtils::unsignedRightShift(-10, 3)); + } + + public function testNumberOfTrailingZeros() : void + { + $this->assertSame(32, BitUtils::numberOfTrailingZeros(0)); + $this->assertSame(1, BitUtils::numberOfTrailingZeros(10)); + $this->assertSame(0, BitUtils::numberOfTrailingZeros(15)); + $this->assertSame(2, BitUtils::numberOfTrailingZeros(20)); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ErrorCorrectionLevelTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ErrorCorrectionLevelTest.php new file mode 100644 index 000000000..369b5d917 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ErrorCorrectionLevelTest.php @@ -0,0 +1,25 @@ +assertSame(0x0, ErrorCorrectionLevel::M()->getBits()); + $this->assertSame(0x1, ErrorCorrectionLevel::L()->getBits()); + $this->assertSame(0x2, ErrorCorrectionLevel::H()->getBits()); + $this->assertSame(0x3, ErrorCorrectionLevel::Q()->getBits()); + } + + public function testInvalidErrorCorrectionLevelThrowsException() : void + { + $this->expectException(OutOfBoundsException::class); + ErrorCorrectionLevel::forBits(4); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/FormatInformationTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/FormatInformationTest.php new file mode 100644 index 000000000..39534a24a --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/FormatInformationTest.php @@ -0,0 +1,94 @@ +assertSame(0, FormatInformation::numBitsDiffering(1, 1)); + $this->assertSame(1, FormatInformation::numBitsDiffering(0, 2)); + $this->assertSame(2, FormatInformation::numBitsDiffering(1, 2)); + $this->assertEquals(32, FormatInformation::numBitsDiffering(-1, 0)); + } + + public function testDecode() : void + { + $expected = FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO, + self::MASKED_TEST_FORMAT_INFO + ); + + $this->assertNotNull($expected); + $this->assertSame(7, $expected->getDataMask()); + $this->assertSame(ErrorCorrectionLevel::Q(), $expected->getErrorCorrectionLevel()); + + $this->assertEquals( + $expected, + FormatInformation::decodeFormatInformation( + self::UNMAKSED_TEST_FORMAT_INFO, + self::MASKED_TEST_FORMAT_INFO + ) + ); + } + + public function testDecodeWithBitDifference() : void + { + $expected = FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO, + self::MASKED_TEST_FORMAT_INFO + ); + + $this->assertEquals( + $expected, + FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO ^ 0x1, + self::MASKED_TEST_FORMAT_INFO ^ 0x1 + ) + ); + $this->assertEquals( + $expected, + FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO ^ 0x3, + self::MASKED_TEST_FORMAT_INFO ^ 0x3 + ) + ); + $this->assertEquals( + $expected, + FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO ^ 0x7, + self::MASKED_TEST_FORMAT_INFO ^ 0x7 + ) + ); + $this->assertNull( + FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO ^ 0xf, + self::MASKED_TEST_FORMAT_INFO ^ 0xf + ) + ); + } + + public function testDecodeWithMisRead() : void + { + $expected = FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO, + self::MASKED_TEST_FORMAT_INFO + ); + + $this->assertEquals( + $expected, + FormatInformation::decodeFormatInformation( + self::MASKED_TEST_FORMAT_INFO ^ 0x3, + self::MASKED_TEST_FORMAT_INFO ^ 0xf + ) + ); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ModeTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ModeTest.php new file mode 100644 index 000000000..51fcb3eb4 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ModeTest.php @@ -0,0 +1,19 @@ +assertSame(0x0, Mode::TERMINATOR()->getBits()); + $this->assertSame(0x1, Mode::NUMERIC()->getBits()); + $this->assertSame(0x2, Mode::ALPHANUMERIC()->getBits()); + $this->assertSame(0x4, Mode::BYTE()->getBits()); + $this->assertSame(0x8, Mode::KANJI()->getBits()); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ReedSolomonCodecTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ReedSolomonCodecTest.php new file mode 100644 index 000000000..47975b523 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/ReedSolomonCodecTest.php @@ -0,0 +1,96 @@ +encode($block, $parity); + + // Copy parity into test blocks + for ($i = 0; $i < $numRoots; ++$i) { + $block[$i + $dataSize] = $parity[$i]; + $tBlock[$i + $dataSize] = $parity[$i]; + } + + // Seed with errors + for ($i = 0; $i < $errors; ++$i) { + $errorValue = mt_rand(1, $blockSize); + + do { + $errorLocation = mt_rand(0, $blockSize); + } while (0 !== $errorLocations[$errorLocation]); + + $errorLocations[$errorLocation] = 1; + + if (mt_rand(0, 1)) { + $erasures[] = $errorLocation; + } + + $tBlock[$errorLocation] ^= $errorValue; + } + + $erasures = SplFixedArray::fromArray($erasures, false); + + // Decode the errored block + $foundErrors = $codec->decode($tBlock, $erasures); + + if ($errors > 0 && null === $foundErrors) { + $this->assertSame($block, $tBlock, 'Decoder failed to correct errors'); + } + + $this->assertSame($errors, $foundErrors, 'Found errors do not equal expected errors'); + + for ($i = 0; $i < $foundErrors; ++$i) { + if (0 === $errorLocations[$erasures[$i]]) { + $this->fail(sprintf('Decoder indicates error in location %d without error', $erasures[$i])); + } + } + + $this->assertEquals($block, $tBlock, 'Decoder did not correct errors'); + } + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/VersionTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/VersionTest.php new file mode 100644 index 000000000..f6f038ba0 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Common/VersionTest.php @@ -0,0 +1,78 @@ +assertNotNull($version); + $this->assertEquals($versionNumber, $version->getVersionNumber()); + $this->assertNotNull($version->getAlignmentPatternCenters()); + + if ($versionNumber > 1) { + $this->assertTrue(count($version->getAlignmentPatternCenters()) > 0); + } + + $this->assertEquals($dimension, $version->getDimensionForVersion()); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::H())); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::L())); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::M())); + $this->assertNotNull($version->getEcBlocksForLevel(ErrorCorrectionLevel::Q())); + $this->assertNotNull($version->buildFunctionPattern()); + } + + /** + * @dataProvider versions + */ + public function testGetProvisionalVersionForDimension(int $versionNumber, int $dimension) : void + { + $this->assertSame( + $versionNumber, + Version::getProvisionalVersionForDimension($dimension)->getVersionNumber() + ); + } + + /** + * @dataProvider decodeInformation + */ + public function testDecodeVersionInformation(int $expectedVersion, int $mask) : void + { + $version = Version::decodeVersionInformation($mask); + $this->assertNotNull($version); + $this->assertSame($expectedVersion, $version->getVersionNumber()); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/EncoderTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/EncoderTest.php new file mode 100644 index 000000000..9baa66b16 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/EncoderTest.php @@ -0,0 +1,487 @@ +getMethods(ReflectionMethod::IS_STATIC) as $method) { + $method->setAccessible(true); + $this->methods[$method->getName()] = $method; + } + } + + public function testGetAlphanumericCode() : void + { + // The first ten code points are numbers. + for ($i = 0; $i < 10; ++$i) { + $this->assertSame($i, $this->methods['getAlphanumericCode']->invoke(null, ord('0') + $i)); + } + + // The next 26 code points are capital alphabet letters. + for ($i = 10; $i < 36; ++$i) { + // The first ten code points are numbers + $this->assertSame($i, $this->methods['getAlphanumericCode']->invoke(null, ord('A') + $i - 10)); + } + + // Others are symbol letters. + $this->assertSame(36, $this->methods['getAlphanumericCode']->invoke(null, ord(' '))); + $this->assertSame(37, $this->methods['getAlphanumericCode']->invoke(null, ord('$'))); + $this->assertSame(38, $this->methods['getAlphanumericCode']->invoke(null, ord('%'))); + $this->assertSame(39, $this->methods['getAlphanumericCode']->invoke(null, ord('*'))); + $this->assertSame(40, $this->methods['getAlphanumericCode']->invoke(null, ord('+'))); + $this->assertSame(41, $this->methods['getAlphanumericCode']->invoke(null, ord('-'))); + $this->assertSame(42, $this->methods['getAlphanumericCode']->invoke(null, ord('.'))); + $this->assertSame(43, $this->methods['getAlphanumericCode']->invoke(null, ord('/'))); + $this->assertSame(44, $this->methods['getAlphanumericCode']->invoke(null, ord(':'))); + + // Should return -1 for other letters. + $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord('a'))); + $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord('#'))); + $this->assertSame(-1, $this->methods['getAlphanumericCode']->invoke(null, ord("\0"))); + } + + public function testChooseMode() : void + { + // Numeric mode + $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0')); + $this->assertSame(Mode::NUMERIC(), $this->methods['chooseMode']->invoke(null, '0123456789')); + + // Alphanumeric mode + $this->assertSame(Mode::ALPHANUMERIC(), $this->methods['chooseMode']->invoke(null, 'A')); + $this->assertSame( + Mode::ALPHANUMERIC(), + $this->methods['chooseMode']->invoke(null, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:') + ); + + // 8-bit byte mode + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, 'a')); + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '#')); + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, '')); + + // AIUE in Hiragana in SHIFT-JIS + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x8\xa\x8\xa\x8\xa\x8\xa6")); + + // Nihon in Kanji in SHIFT-JIS + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\x9\xf\x9\x7b")); + + // Sou-Utso-Byou in Kanji in SHIFT-JIS + $this->assertSame(Mode::BYTE(), $this->methods['chooseMode']->invoke(null, "\xe\x4\x9\x5\x9\x61")); + } + + public function testEncode() : void + { + $qrCode = Encoder::encode('ABCDEF', ErrorCorrectionLevel::H()); + $expected = "<<\n" + . " mode: ALPHANUMERIC\n" + . " ecLevel: H\n" + . " version: 1\n" + . " maskPattern: 0\n" + . " matrix:\n" + . " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0\n" + . " 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1\n" + . " 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0\n" + . " 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0\n" + . " 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0\n" + . " 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0\n" + . " 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 0 0 0\n" + . " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 1\n" + . " 1 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0\n" + . " 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 0 0 1 1\n" + . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1\n" + . ">>\n"; + + $this->assertSame($expected, (string) $qrCode); + } + + public function testSimpleUtf8Eci() : void + { + $qrCode = Encoder::encode('hello', ErrorCorrectionLevel::H(), 'utf-8'); + $expected = "<<\n" + . " mode: BYTE\n" + . " ecLevel: H\n" + . " version: 1\n" + . " maskPattern: 3\n" + . " matrix:\n" + . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0\n" + . " 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0\n" + . " 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1\n" + . " 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0\n" + . " 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0\n" + . " 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0\n" + . " 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0\n" + . " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0\n" + . " 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0\n" + . " 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0\n" + . " 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0\n" + . ">>\n"; + + $this->assertSame($expected, (string) $qrCode); + } + + public function testAppendModeInfo() : void + { + $bits = new BitArray(); + $this->methods['appendModeInfo']->invoke(null, Mode::NUMERIC(), $bits); + $this->assertSame(' ...X', (string) $bits); + } + + public function testAppendLengthInfo() : void + { + // 1 letter (1/1), 10 bits. + $bits = new BitArray(); + $this->methods['appendLengthInfo']->invoke( + null, + 1, + Version::getVersionForNumber(1), + Mode::NUMERIC(), + $bits + ); + $this->assertSame(' ........ .X', (string) $bits); + + // 2 letters (2/1), 11 bits. + $bits = new BitArray(); + $this->methods['appendLengthInfo']->invoke( + null, + 2, + Version::getVersionForNumber(10), + Mode::ALPHANUMERIC(), + $bits + ); + $this->assertSame(' ........ .X.', (string) $bits); + + // 255 letters (255/1), 16 bits. + $bits = new BitArray(); + $this->methods['appendLengthInfo']->invoke( + null, + 255, + Version::getVersionForNumber(27), + Mode::BYTE(), + $bits + ); + $this->assertSame(' ........ XXXXXXXX', (string) $bits); + + // 512 letters (1024/2), 12 bits. + $bits = new BitArray(); + $this->methods['appendLengthInfo']->invoke( + null, + 512, + Version::getVersionForNumber(40), + Mode::KANJI(), + $bits + ); + $this->assertSame(' ..X..... ....', (string) $bits); + } + + public function testAppendBytes() : void + { + // Should use appendNumericBytes. + // 1 = 01 = 0001 in 4 bits. + $bits = new BitArray(); + $this->methods['appendBytes']->invoke( + null, + '1', + Mode::NUMERIC(), + $bits, + Encoder::DEFAULT_BYTE_MODE_ECODING + ); + $this->assertSame(' ...X', (string) $bits); + + // Should use appendAlphaNumericBytes. + // A = 10 = 0xa = 001010 in 6 bits. + $bits = new BitArray(); + $this->methods['appendBytes']->invoke( + null, + 'A', + Mode::ALPHANUMERIC(), + $bits, + Encoder::DEFAULT_BYTE_MODE_ECODING + ); + $this->assertSame(' ..X.X.', (string) $bits); + + // Should use append8BitBytes. + // 0x61, 0x62, 0x63 + $bits = new BitArray(); + $this->methods['appendBytes']->invoke( + null, + 'abc', + Mode::BYTE(), + $bits, + Encoder::DEFAULT_BYTE_MODE_ECODING + ); + $this->assertSame(' .XX....X .XX...X. .XX...XX', (string) $bits); + + // Should use appendKanjiBytes. + // 0x93, 0x5f + $bits = new BitArray(); + $this->methods['appendBytes']->invoke( + null, + "\x93\x5f", + Mode::KANJI(), + $bits, + Encoder::DEFAULT_BYTE_MODE_ECODING + ); + $this->assertSame(' .XX.XX.. XXXXX', (string) $bits); + + // Lower letters such as 'a' cannot be encoded in alphanumeric mode. + $this->expectException(WriterException::class); + $this->methods['appendBytes']->invoke( + null, + 'a', + Mode::ALPHANUMERIC(), + $bits, + Encoder::DEFAULT_BYTE_MODE_ECODING + ); + } + + public function testTerminateBits() : void + { + $bits = new BitArray(); + $this->methods['terminateBits']->invoke(null, 0, $bits); + $this->assertSame('', (string) $bits); + + $bits = new BitArray(); + $this->methods['terminateBits']->invoke(null, 1, $bits); + $this->assertSame(' ........', (string) $bits); + + $bits = new BitArray(); + $bits->appendBits(0, 3); + $this->methods['terminateBits']->invoke(null, 1, $bits); + $this->assertSame(' ........', (string) $bits); + + $bits = new BitArray(); + $bits->appendBits(0, 5); + $this->methods['terminateBits']->invoke(null, 1, $bits); + $this->assertSame(' ........', (string) $bits); + + $bits = new BitArray(); + $bits->appendBits(0, 8); + $this->methods['terminateBits']->invoke(null, 1, $bits); + $this->assertSame(' ........', (string) $bits); + + $bits = new BitArray(); + $this->methods['terminateBits']->invoke(null, 2, $bits); + $this->assertSame(' ........ XXX.XX..', (string) $bits); + + $bits = new BitArray(); + $bits->appendBits(0, 1); + $this->methods['terminateBits']->invoke(null, 3, $bits); + $this->assertSame(' ........ XXX.XX.. ...X...X', (string) $bits); + } + + public function testGetNumDataBytesAndNumEcBytesForBlockId() : void + { + // Version 1-H. + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 26, 9, 1, 0); + $this->assertSame(9, $numDataBytes); + $this->assertSame(17, $numEcBytes); + + // Version 3-H. 2 blocks. + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 70, 26, 2, 0); + $this->assertSame(13, $numDataBytes); + $this->assertSame(22, $numEcBytes); + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 70, 26, 2, 1); + $this->assertSame(13, $numDataBytes); + $this->assertSame(22, $numEcBytes); + + // Version 7-H. (4 + 1) blocks. + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 196, 66, 5, 0); + $this->assertSame(13, $numDataBytes); + $this->assertSame(26, $numEcBytes); + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 196, 66, 5, 4); + $this->assertSame(14, $numDataBytes); + $this->assertSame(26, $numEcBytes); + + // Version 40-H. (20 + 61) blocks. + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 3706, 1276, 81, 0); + $this->assertSame(15, $numDataBytes); + $this->assertSame(30, $numEcBytes); + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 3706, 1276, 81, 20); + $this->assertSame(16, $numDataBytes); + $this->assertSame(30, $numEcBytes); + list($numDataBytes, $numEcBytes) = $this->methods['getNumDataBytesAndNumEcBytesForBlockId'] + ->invoke(null, 3706, 1276, 81, 80); + $this->assertSame(16, $numDataBytes); + $this->assertSame(30, $numEcBytes); + } + + public function testInterleaveWithEcBytes() : void + { + $dataBytes = SplFixedArray::fromArray([32, 65, 205, 69, 41, 220, 46, 128, 236], false); + $in = new BitArray(); + + foreach ($dataBytes as $dataByte) { + $in->appendBits($dataByte, 8); + } + + $outBits = $this->methods['interleaveWithEcBytes']->invoke(null, $in, 26, 9, 1); + $expected = SplFixedArray::fromArray([ + // Data bytes. + 32, 65, 205, 69, 41, 220, 46, 128, 236, + // Error correction bytes. + 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61, + ], false); + + $out = $outBits->toBytes(0, count($expected)); + + $this->assertEquals($expected, $out); + } + + public function testAppendNumericBytes() : void + { + // 1 = 01 = 0001 in 4 bits. + $bits = new BitArray(); + $this->methods['appendNumericBytes']->invoke(null, '1', $bits); + $this->assertSame(' ...X', (string) $bits); + + // 12 = 0xc = 0001100 in 7 bits. + $bits = new BitArray(); + $this->methods['appendNumericBytes']->invoke(null, '12', $bits); + $this->assertSame(' ...XX..', (string) $bits); + + // 123 = 0x7b = 0001111011 in 10 bits. + $bits = new BitArray(); + $this->methods['appendNumericBytes']->invoke(null, '123', $bits); + $this->assertSame(' ...XXXX. XX', (string) $bits); + + // 1234 = "123" + "4" = 0001111011 + 0100 in 14 bits. + $bits = new BitArray(); + $this->methods['appendNumericBytes']->invoke(null, '1234', $bits); + $this->assertSame(' ...XXXX. XX.X..', (string) $bits); + + // Empty + $bits = new BitArray(); + $this->methods['appendNumericBytes']->invoke(null, '', $bits); + $this->assertSame('', (string) $bits); + } + + public function testAppendAlphanumericBytes() : void + { + $bits = new BitArray(); + $this->methods['appendAlphanumericBytes']->invoke(null, 'A', $bits); + $this->assertSame(' ..X.X.', (string) $bits); + + $bits = new BitArray(); + $this->methods['appendAlphanumericBytes']->invoke(null, 'AB', $bits); + $this->assertSame(' ..XXX..X X.X', (string) $bits); + + $bits = new BitArray(); + $this->methods['appendAlphanumericBytes']->invoke(null, 'ABC', $bits); + $this->assertSame(' ..XXX..X X.X..XX. .', (string) $bits); + + // Empty + $bits = new BitArray(); + $this->methods['appendAlphanumericBytes']->invoke(null, '', $bits); + $this->assertSame('', (string) $bits); + + // Invalid data + $this->expectException(WriterException::class); + $bits = new BitArray(); + $this->methods['appendAlphanumericBytes']->invoke(null, 'abc', $bits); + } + + public function testAppend8BitBytes() : void + { + // 0x61, 0x62, 0x63 + $bits = new BitArray(); + $this->methods['append8BitBytes']->invoke(null, 'abc', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING); + $this->assertSame(' .XX....X .XX...X. .XX...XX', (string) $bits); + + // Empty + $bits = new BitArray(); + $this->methods['append8BitBytes']->invoke(null, '', $bits, Encoder::DEFAULT_BYTE_MODE_ECODING); + $this->assertSame('', (string) $bits); + } + + public function testAppendKanjiBytes() : void + { + // Numbers are from page 21 of JISX0510:2004 + $bits = new BitArray(); + $this->methods['appendKanjiBytes']->invoke(null, "\x93\x5f", $bits); + $this->assertSame(' .XX.XX.. XXXXX', (string) $bits); + + $this->methods['appendKanjiBytes']->invoke(null, "\xe4\xaa", $bits); + $this->assertSame(' .XX.XX.. XXXXXXX. X.X.X.X. X.', (string) $bits); + } + + public function testGenerateEcBytes() : void + { + // Numbers are from http://www.swetake.com/qr/qr3.html and + // http://www.swetake.com/qr/qr9.html + $dataBytes = SplFixedArray::fromArray([32, 65, 205, 69, 41, 220, 46, 128, 236], false); + $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17); + $expected = SplFixedArray::fromArray( + [42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61], + false + ); + $this->assertEquals($expected, $ecBytes); + + $dataBytes = SplFixedArray::fromArray( + [67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214], + false + ); + $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 18); + $expected = SplFixedArray::fromArray( + [175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187], + false + ); + $this->assertEquals($expected, $ecBytes); + + // High-order zero coefficient case. + $dataBytes = SplFixedArray::fromArray([32, 49, 205, 69, 42, 20, 0, 236, 17], false); + $ecBytes = $this->methods['generateEcBytes']->invoke(null, $dataBytes, 17); + $expected = SplFixedArray::fromArray( + [0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213], + false + ); + $this->assertEquals($expected, $ecBytes); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MaskUtilTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MaskUtilTest.php new file mode 100644 index 000000000..46670fce7 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MaskUtilTest.php @@ -0,0 +1,251 @@ +assertSame( + 1 === $expected[$y][$x], + MaskUtil::getDataMaskBit($maskPattern, $x, $y) + ); + } + } + } + + public function testApplyMaskPenaltyRule1() : void + { + $matrix = new ByteMatrix(4, 1); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(2, 0, 0); + $matrix->set(3, 0, 0); + + $this->assertSame(0, MaskUtil::applyMaskPenaltyRule1($matrix)); + + // Horizontal + $matrix = new ByteMatrix(6, 1); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(2, 0, 0); + $matrix->set(3, 0, 0); + $matrix->set(4, 0, 0); + $matrix->set(5, 0, 1); + $this->assertSame(3, MaskUtil::applyMaskPenaltyRule1($matrix)); + $matrix->set(5, 0, 0); + $this->assertSame(4, MaskUtil::applyMaskPenaltyRule1($matrix)); + + // Vertical + $matrix = new ByteMatrix(1, 6); + $matrix->set(0, 0, 0); + $matrix->set(0, 1, 0); + $matrix->set(0, 2, 0); + $matrix->set(0, 3, 0); + $matrix->set(0, 4, 0); + $matrix->set(0, 5, 1); + $this->assertSame(3, MaskUtil::applyMaskPenaltyRule1($matrix)); + $matrix->set(0, 5, 0); + $this->assertSame(4, MaskUtil::applyMaskPenaltyRule1($matrix)); + } + + public function testApplyMaskPenaltyRule2() : void + { + $matrix = new ByteMatrix(1, 1); + $matrix->set(0, 0, 0); + $this->assertSame(0, MaskUtil::applyMaskPenaltyRule2($matrix)); + + $matrix = new ByteMatrix(2, 2); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(0, 1, 0); + $matrix->set(1, 1, 1); + $this->assertSame(0, MaskUtil::applyMaskPenaltyRule2($matrix)); + + $matrix = new ByteMatrix(2, 2); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(0, 1, 0); + $matrix->set(1, 1, 0); + $this->assertSame(3, MaskUtil::applyMaskPenaltyRule2($matrix)); + + $matrix = new ByteMatrix(3, 3); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(2, 0, 0); + $matrix->set(0, 1, 0); + $matrix->set(1, 1, 0); + $matrix->set(2, 1, 0); + $matrix->set(0, 2, 0); + $matrix->set(1, 2, 0); + $matrix->set(2, 2, 0); + $this->assertSame(3 * 4, MaskUtil::applyMaskPenaltyRule2($matrix)); + } + + public function testApplyMaskPenalty3() : void + { + // Horizontal 00001011101 + $matrix = new ByteMatrix(11, 1); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 0); + $matrix->set(2, 0, 0); + $matrix->set(3, 0, 0); + $matrix->set(4, 0, 1); + $matrix->set(5, 0, 0); + $matrix->set(6, 0, 1); + $matrix->set(7, 0, 1); + $matrix->set(8, 0, 1); + $matrix->set(9, 0, 0); + $matrix->set(10, 0, 1); + $this->assertSame(40, MaskUtil::applyMaskPenaltyRule3($matrix)); + + // Horizontal 10111010000 + $matrix = new ByteMatrix(11, 1); + $matrix->set(0, 0, 1); + $matrix->set(1, 0, 0); + $matrix->set(2, 0, 1); + $matrix->set(3, 0, 1); + $matrix->set(4, 0, 1); + $matrix->set(5, 0, 0); + $matrix->set(6, 0, 1); + $matrix->set(7, 0, 0); + $matrix->set(8, 0, 0); + $matrix->set(9, 0, 0); + $matrix->set(10, 0, 0); + $this->assertSame(40, MaskUtil::applyMaskPenaltyRule3($matrix)); + + // Vertical 00001011101 + $matrix = new ByteMatrix(1, 11); + $matrix->set(0, 0, 0); + $matrix->set(0, 1, 0); + $matrix->set(0, 2, 0); + $matrix->set(0, 3, 0); + $matrix->set(0, 4, 1); + $matrix->set(0, 5, 0); + $matrix->set(0, 6, 1); + $matrix->set(0, 7, 1); + $matrix->set(0, 8, 1); + $matrix->set(0, 9, 0); + $matrix->set(0, 10, 1); + $this->assertSame(40, MaskUtil::applyMaskPenaltyRule3($matrix)); + + // Vertical 10111010000 + $matrix = new ByteMatrix(1, 11); + $matrix->set(0, 0, 1); + $matrix->set(0, 1, 0); + $matrix->set(0, 2, 1); + $matrix->set(0, 3, 1); + $matrix->set(0, 4, 1); + $matrix->set(0, 5, 0); + $matrix->set(0, 6, 1); + $matrix->set(0, 7, 0); + $matrix->set(0, 8, 0); + $matrix->set(0, 9, 0); + $matrix->set(0, 10, 0); + $this->assertSame(40, MaskUtil::applyMaskPenaltyRule3($matrix)); + } + + public function testApplyMaskPenaltyRule4() : void + { + // Dark cell ratio = 0% + $matrix = new ByteMatrix(1, 1); + $matrix->set(0, 0, 0); + $this->assertSame(100, MaskUtil::applyMaskPenaltyRule4($matrix)); + + // Dark cell ratio = 5% + $matrix = new ByteMatrix(2, 1); + $matrix->set(0, 0, 0); + $matrix->set(0, 0, 1); + $this->assertSame(0, MaskUtil::applyMaskPenaltyRule4($matrix)); + + // Dark cell ratio = 66.67% + $matrix = new ByteMatrix(6, 1); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 1); + $matrix->set(2, 0, 1); + $matrix->set(3, 0, 1); + $matrix->set(4, 0, 1); + $matrix->set(5, 0, 0); + $this->assertSame(30, MaskUtil::applyMaskPenaltyRule4($matrix)); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MatrixUtilTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MatrixUtilTest.php new file mode 100644 index 000000000..106ceaaf5 --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Encoder/MatrixUtilTest.php @@ -0,0 +1,335 @@ +getMethods(ReflectionMethod::IS_STATIC) as $method) { + $method->setAccessible(true); + $this->methods[$method->getName()] = $method; + } + } + + public function testToString() : void + { + $matrix = new ByteMatrix(3, 3); + $matrix->set(0, 0, 0); + $matrix->set(1, 0, 1); + $matrix->set(2, 0, 0); + $matrix->set(0, 1, 1); + $matrix->set(1, 1, 0); + $matrix->set(2, 1, 1); + $matrix->set(0, 2, -1); + $matrix->set(1, 2, -1); + $matrix->set(2, 2, -1); + + $expected = " 0 1 0\n 1 0 1\n \n"; + $this->assertSame($expected, (string) $matrix); + } + + public function testClearMatrix() : void + { + $matrix = new ByteMatrix(2, 2); + MatrixUtil::clearMatrix($matrix); + + $this->assertSame(-1, $matrix->get(0, 0)); + $this->assertSame(-1, $matrix->get(1, 0)); + $this->assertSame(-1, $matrix->get(0, 1)); + $this->assertSame(-1, $matrix->get(1, 1)); + } + + public function testEmbedBasicPatterns1() : void + { + $matrix = new ByteMatrix(21, 21); + MatrixUtil::clearMatrix($matrix); + $this->methods['embedBasicPatterns']->invoke( + null, + Version::getVersionForNumber(1), + $matrix + ); + $expected = " 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 \n" + . " 0 \n" + . " 1 \n" + . " 0 \n" + . " 1 \n" + . " 0 0 0 0 0 0 0 0 1 \n" + . " 1 1 1 1 1 1 1 0 \n" + . " 1 0 0 0 0 0 1 0 \n" + . " 1 0 1 1 1 0 1 0 \n" + . " 1 0 1 1 1 0 1 0 \n" + . " 1 0 1 1 1 0 1 0 \n" + . " 1 0 0 0 0 0 1 0 \n" + . " 1 1 1 1 1 1 1 0 \n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testEmbedBasicPatterns2() : void + { + $matrix = new ByteMatrix(25, 25); + MatrixUtil::clearMatrix($matrix); + $this->methods['embedBasicPatterns']->invoke( + null, + Version::getVersionForNumber(2), + $matrix + ); + $expected = " 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 \n" + . " 0 \n" + . " 1 \n" + . " 0 \n" + . " 1 \n" + . " 0 \n" + . " 1 \n" + . " 0 \n" + . " 1 1 1 1 1 1 \n" + . " 0 0 0 0 0 0 0 0 1 1 0 0 0 1 \n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 \n" + . " 1 0 0 0 0 0 1 0 1 0 0 0 1 \n" + . " 1 0 1 1 1 0 1 0 1 1 1 1 1 \n" + . " 1 0 1 1 1 0 1 0 \n" + . " 1 0 1 1 1 0 1 0 \n" + . " 1 0 0 0 0 0 1 0 \n" + . " 1 1 1 1 1 1 1 0 \n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testEmbedTypeInfo() : void + { + $matrix = new ByteMatrix(21, 21); + MatrixUtil::clearMatrix($matrix); + $this->methods['embedTypeInfo']->invoke( + null, + ErrorCorrectionLevel::M(), + 5, + $matrix + ); + $expected = " 0 \n" + . " 1 \n" + . " 1 \n" + . " 1 \n" + . " 0 \n" + . " 0 \n" + . " \n" + . " 1 \n" + . " 1 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0\n" + . " \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " 0 \n" + . " 0 \n" + . " 0 \n" + . " 0 \n" + . " 0 \n" + . " 0 \n" + . " 1 \n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testEmbedVersionInfo() : void + { + $matrix = new ByteMatrix(21, 21); + MatrixUtil::clearMatrix($matrix); + $this->methods['maybeEmbedVersionInfo']->invoke( + null, + Version::getVersionForNumber(7), + $matrix + ); + $expected = " 0 0 1 \n" + . " 0 1 0 \n" + . " 0 1 0 \n" + . " 0 1 1 \n" + . " 1 1 1 \n" + . " 0 0 0 \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " 0 0 0 0 1 0 \n" + . " 0 1 1 1 1 0 \n" + . " 1 0 0 1 1 0 \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " \n" + . " \n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testEmbedDataBits() : void + { + $matrix = new ByteMatrix(21, 21); + MatrixUtil::clearMatrix($matrix); + $this->methods['embedBasicPatterns']->invoke( + null, + Version::getVersionForNumber(1), + $matrix + ); + + $bits = new BitArray(); + $this->methods['embedDataBits']->invoke( + null, + $bits, + -1, + $matrix + ); + + $expected = " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" + . " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testBuildMatrix() : void + { + $bytes = [ + 32, 65, 205, 69, 41, 220, 46, 128, 236, 42, 159, 74, 221, 244, 169, + 239, 150, 138, 70, 237, 85, 224, 96, 74, 219 , 61 + ]; + $bits = new BitArray(); + + foreach ($bytes as $byte) { + $bits->appendBits($byte, 8); + } + + $matrix = new ByteMatrix(21, 21); + MatrixUtil::buildMatrix( + $bits, + ErrorCorrectionLevel::H(), + Version::getVersionForNumber(1), + 3, + $matrix + ); + + $expected = " 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" + . " 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1\n" + . " 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1\n" + . " 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1\n" + . " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0\n" + . " 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0\n" + . " 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0\n" + . " 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0\n" + . " 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0\n" + . " 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1\n" + . " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1\n" + . " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0\n" + . " 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0\n" + . " 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1\n" + . " 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0\n" + . " 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0\n" + . " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0\n" + . " 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0\n"; + + $this->assertSame($expected, (string) $matrix); + } + + public function testFindMsbSet() : void + { + $this->assertSame(0, $this->methods['findMsbSet']->invoke(null, 0)); + $this->assertSame(1, $this->methods['findMsbSet']->invoke(null, 1)); + $this->assertSame(8, $this->methods['findMsbSet']->invoke(null, 0x80)); + $this->assertSame(32, $this->methods['findMsbSet']->invoke(null, 0x80000000)); + } + + public function testCalculateBchCode() : void + { + // Encoding of type information. + // From Appendix C in JISX0510:2004 (p 65) + $this->assertSame(0xdc, $this->methods['calculateBchCode']->invoke(null, 5, 0x537)); + // From http://www.swetake.com/qr/qr6.html + $this->assertSame(0x1c2, $this->methods['calculateBchCode']->invoke(null, 0x13, 0x537)); + // From http://www.swetake.com/qr/qr11.html + $this->assertSame(0x214, $this->methods['calculateBchCode']->invoke(null, 0x1b, 0x537)); + + // Encoding of version information. + // From Appendix D in JISX0510:2004 (p 68) + $this->assertSame(0xc94, $this->methods['calculateBchCode']->invoke(null, 7, 0x1f25)); + $this->assertSame(0x5bc, $this->methods['calculateBchCode']->invoke(null, 8, 0x1f25)); + $this->assertSame(0xa99, $this->methods['calculateBchCode']->invoke(null, 9, 0x1f25)); + $this->assertSame(0x4d3, $this->methods['calculateBchCode']->invoke(null, 10, 0x1f25)); + $this->assertSame(0x9a6, $this->methods['calculateBchCode']->invoke(null, 20, 0x1f25)); + $this->assertSame(0xd75, $this->methods['calculateBchCode']->invoke(null, 30, 0x1f25)); + $this->assertSame(0xc69, $this->methods['calculateBchCode']->invoke(null, 40, 0x1f25)); + } + + public function testMakeVersionInfoBits() : void + { + // From Appendix D in JISX0510:2004 (p 68) + $bits = new BitArray(); + $this->methods['makeVersionInfoBits']->invoke(null, Version::getVersionForNumber(7), $bits); + $this->assertSame(' ...XXXXX ..X..X.X ..', (string) $bits); + } + + public function testMakeTypeInfoBits() : void + { + // From Appendix D in JISX0510:2004 (p 68) + $bits = new BitArray(); + $this->methods['makeTypeInfoBits']->invoke(null, ErrorCorrectionLevel::M(), 5, $bits); + $this->assertSame(' X......X X..XXX.', (string) $bits); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/ImagickRenderingTest.php b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/ImagickRenderingTest.php new file mode 100644 index 000000000..3df8687ec --- /dev/null +++ b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/ImagickRenderingTest.php @@ -0,0 +1,72 @@ +writeFile('Hello World!', $tempName); + + $this->assertMatchesFileSnapshot($tempName); + unlink($tempName); + } + + /** + * @requires extension imagick + */ + public function testIssue79() : void + { + $eye = SquareEye::instance(); + $squareModule = SquareModule::instance(); + + $eyeFill = new EyeFill(new Rgb(100, 100, 55), new Rgb(100, 100, 255)); + $gradient = new Gradient(new Rgb(100, 100, 55), new Rgb(100, 100, 255), GradientType::HORIZONTAL()); + + $renderer = new ImageRenderer( + new RendererStyle( + 400, + 2, + $squareModule, + $eye, + Fill::withForegroundGradient(new Rgb(255, 255, 255), $gradient, $eyeFill, $eyeFill, $eyeFill) + ), + new ImagickImageBackEnd() + ); + $writer = new Writer($renderer); + $tempName = tempnam(sys_get_temp_dir(), 'test') . '.png'; + $writer->writeFile('https://apiroad.net/very-long-url', $tempName); + + $this->assertMatchesFileSnapshot($tempName); + unlink($tempName); + } +} diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testGenericQrCode__1.png b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testGenericQrCode__1.png new file mode 100644 index 000000000..9a429edc8 Binary files /dev/null and b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testGenericQrCode__1.png differ diff --git a/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue79__1.png b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue79__1.png new file mode 100644 index 000000000..47e3b1a29 Binary files /dev/null and b/data/web/inc/lib/vendor/bacon/bacon-qr-code/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue79__1.png differ diff --git a/data/web/inc/lib/vendor/bin/var-dump-server b/data/web/inc/lib/vendor/bin/var-dump-server deleted file mode 100755 index 18db1c1eb..000000000 --- a/data/web/inc/lib/vendor/bin/var-dump-server +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server'); - } -} - -return include __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server'; diff --git a/data/web/inc/lib/vendor/composer/InstalledVersions.php b/data/web/inc/lib/vendor/composer/InstalledVersions.php index 51e734a77..6d29bff66 100644 --- a/data/web/inc/lib/vendor/composer/InstalledVersions.php +++ b/data/web/inc/lib/vendor/composer/InstalledVersions.php @@ -32,6 +32,11 @@ class InstalledVersions */ private static $installed; + /** + * @var bool + */ + private static $installedIsLocalDir; + /** * @var bool|null */ @@ -309,6 +314,12 @@ class InstalledVersions { self::$installed = $data; self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; } /** @@ -322,19 +333,27 @@ class InstalledVersions } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { + $selfDir = strtr(__DIR__, '\\', '/'); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { /** @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} $required */ $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; } } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } } } @@ -350,7 +369,7 @@ class InstalledVersions } } - if (self::$installed !== array()) { + if (self::$installed !== array() && !$copiedLocalDir) { $installed[] = self::$installed; } diff --git a/data/web/inc/lib/vendor/composer/autoload_classmap.php b/data/web/inc/lib/vendor/composer/autoload_classmap.php index 8e4b7d313..3885b22a6 100644 --- a/data/web/inc/lib/vendor/composer/autoload_classmap.php +++ b/data/web/inc/lib/vendor/composer/autoload_classmap.php @@ -9,6 +9,7 @@ return array( 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', diff --git a/data/web/inc/lib/vendor/composer/autoload_files.php b/data/web/inc/lib/vendor/composer/autoload_files.php index c426e71df..e2cabb90d 100644 --- a/data/web/inc/lib/vendor/composer/autoload_files.php +++ b/data/web/inc/lib/vendor/composer/autoload_files.php @@ -10,15 +10,12 @@ return array( '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', - '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + '60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', - 'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php', - 'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php', '04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php', '89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php', 'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php', diff --git a/data/web/inc/lib/vendor/composer/autoload_psr4.php b/data/web/inc/lib/vendor/composer/autoload_psr4.php index eca85b846..236034cf0 100644 --- a/data/web/inc/lib/vendor/composer/autoload_psr4.php +++ b/data/web/inc/lib/vendor/composer/autoload_psr4.php @@ -7,13 +7,11 @@ $baseDir = dirname($vendorDir); return array( 'Twig\\' => array($vendorDir . '/twig/twig/src'), - 'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'), 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'), - 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), 'Stevenmaguire\\OAuth2\\Client\\' => array($vendorDir . '/stevenmaguire/oauth2-keycloak/src'), 'RobThree\\Auth\\' => array($vendorDir . '/robthree/twofactorauth/lib'), @@ -29,6 +27,7 @@ return array( 'MatthiasMullie\\Minify\\' => array($vendorDir . '/matthiasmullie/minify/src'), 'League\\OAuth2\\Client\\' => array($vendorDir . '/league/oauth2-client/src'), 'LdapRecord\\' => array($vendorDir . '/directorytree/ldaprecord/src'), + 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/conditionable'), 'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'), 'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), @@ -36,6 +35,8 @@ return array( 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), 'Ddeboer\\Imap\\' => array($vendorDir . '/ddeboer/imap/src'), + 'DASPRiD\\Enum\\' => array($vendorDir . '/dasprid/enum/src'), 'Carbon\\Doctrine\\' => array($vendorDir . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine'), 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'), + 'BaconQrCode\\' => array($vendorDir . '/bacon/bacon-qr-code/src'), ); diff --git a/data/web/inc/lib/vendor/composer/autoload_static.php b/data/web/inc/lib/vendor/composer/autoload_static.php index 5375b0bea..f66ad0c71 100644 --- a/data/web/inc/lib/vendor/composer/autoload_static.php +++ b/data/web/inc/lib/vendor/composer/autoload_static.php @@ -11,15 +11,12 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', - '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', - 'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php', - 'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php', '04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php', '89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php', 'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php', @@ -28,27 +25,25 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b ); public static $prefixLengthsPsr4 = array ( - 'T' => + 'T' => array ( 'Twig\\' => 5, - 'Tightenco\\Collect\\' => 18, ), - 'S' => + 'S' => array ( 'Symfony\\Polyfill\\Php81\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Contracts\\Translation\\' => 30, - 'Symfony\\Component\\VarDumper\\' => 28, 'Symfony\\Component\\Translation\\' => 30, 'Stevenmaguire\\OAuth2\\Client\\' => 28, ), - 'R' => + 'R' => array ( 'RobThree\\Auth\\' => 14, ), - 'P' => + 'P' => array ( 'Psr\\SimpleCache\\' => 16, 'Psr\\Log\\' => 8, @@ -59,181 +54,193 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b 'PhpMimeMailParser\\' => 18, 'PHPMailer\\PHPMailer\\' => 20, ), - 'M' => + 'M' => array ( 'MatthiasMullie\\PathConverter\\' => 29, 'MatthiasMullie\\Minify\\' => 22, ), - 'L' => + 'L' => array ( 'League\\OAuth2\\Client\\' => 21, 'LdapRecord\\' => 11, ), - 'I' => + 'I' => array ( + 'Illuminate\\Support\\' => 19, 'Illuminate\\Contracts\\' => 21, ), - 'H' => + 'H' => array ( 'Html2Text\\' => 10, ), - 'G' => + 'G' => array ( 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, ), - 'F' => + 'F' => array ( 'Firebase\\JWT\\' => 13, ), - 'D' => + 'D' => array ( 'Ddeboer\\Imap\\' => 13, + 'DASPRiD\\Enum\\' => 13, ), - 'C' => + 'C' => array ( 'Carbon\\Doctrine\\' => 16, 'Carbon\\' => 7, ), + 'B' => + array ( + 'BaconQrCode\\' => 12, + ), ); public static $prefixDirsPsr4 = array ( - 'Twig\\' => + 'Twig\\' => array ( 0 => __DIR__ . '/..' . '/twig/twig/src', ), - 'Tightenco\\Collect\\' => - array ( - 0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect', - ), - 'Symfony\\Polyfill\\Php81\\' => + 'Symfony\\Polyfill\\Php81\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php81', ), - 'Symfony\\Polyfill\\Php80\\' => + 'Symfony\\Polyfill\\Php80\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), - 'Symfony\\Polyfill\\Mbstring\\' => + 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), - 'Symfony\\Polyfill\\Ctype\\' => + 'Symfony\\Polyfill\\Ctype\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', ), - 'Symfony\\Contracts\\Translation\\' => + 'Symfony\\Contracts\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation-contracts', ), - 'Symfony\\Component\\VarDumper\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/var-dumper', - ), - 'Symfony\\Component\\Translation\\' => + 'Symfony\\Component\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation', ), - 'Stevenmaguire\\OAuth2\\Client\\' => + 'Stevenmaguire\\OAuth2\\Client\\' => array ( 0 => __DIR__ . '/..' . '/stevenmaguire/oauth2-keycloak/src', ), - 'RobThree\\Auth\\' => + 'RobThree\\Auth\\' => array ( 0 => __DIR__ . '/..' . '/robthree/twofactorauth/lib', ), - 'Psr\\SimpleCache\\' => + 'Psr\\SimpleCache\\' => array ( 0 => __DIR__ . '/..' . '/psr/simple-cache/src', ), - 'Psr\\Log\\' => + 'Psr\\Log\\' => array ( 0 => __DIR__ . '/..' . '/psr/log/src', ), - 'Psr\\Http\\Message\\' => + 'Psr\\Http\\Message\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src', ), - 'Psr\\Http\\Client\\' => + 'Psr\\Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-client/src', ), - 'Psr\\Container\\' => + 'Psr\\Container\\' => array ( 0 => __DIR__ . '/..' . '/psr/container/src', ), - 'Psr\\Clock\\' => + 'Psr\\Clock\\' => array ( 0 => __DIR__ . '/..' . '/psr/clock/src', ), - 'PhpMimeMailParser\\' => + 'PhpMimeMailParser\\' => array ( 0 => __DIR__ . '/..' . '/php-mime-mail-parser/php-mime-mail-parser/src', ), - 'PHPMailer\\PHPMailer\\' => + 'PHPMailer\\PHPMailer\\' => array ( 0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src', ), - 'MatthiasMullie\\PathConverter\\' => + 'MatthiasMullie\\PathConverter\\' => array ( 0 => __DIR__ . '/..' . '/matthiasmullie/path-converter/src', ), - 'MatthiasMullie\\Minify\\' => + 'MatthiasMullie\\Minify\\' => array ( 0 => __DIR__ . '/..' . '/matthiasmullie/minify/src', ), - 'League\\OAuth2\\Client\\' => + 'League\\OAuth2\\Client\\' => array ( 0 => __DIR__ . '/..' . '/league/oauth2-client/src', ), - 'LdapRecord\\' => + 'LdapRecord\\' => array ( 0 => __DIR__ . '/..' . '/directorytree/ldaprecord/src', ), - 'Illuminate\\Contracts\\' => + 'Illuminate\\Support\\' => + array ( + 0 => __DIR__ . '/..' . '/illuminate/collections', + 1 => __DIR__ . '/..' . '/illuminate/macroable', + 2 => __DIR__ . '/..' . '/illuminate/conditionable', + ), + 'Illuminate\\Contracts\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/contracts', ), - 'Html2Text\\' => + 'Html2Text\\' => array ( 0 => __DIR__ . '/..' . '/soundasleep/html2text/src', ), - 'GuzzleHttp\\Psr7\\' => + 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', ), - 'GuzzleHttp\\Promise\\' => + 'GuzzleHttp\\Promise\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/promises/src', ), - 'GuzzleHttp\\' => + 'GuzzleHttp\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', ), - 'Firebase\\JWT\\' => + 'Firebase\\JWT\\' => array ( 0 => __DIR__ . '/..' . '/firebase/php-jwt/src', ), - 'Ddeboer\\Imap\\' => + 'Ddeboer\\Imap\\' => array ( 0 => __DIR__ . '/..' . '/ddeboer/imap/src', ), - 'Carbon\\Doctrine\\' => + 'DASPRiD\\Enum\\' => + array ( + 0 => __DIR__ . '/..' . '/dasprid/enum/src', + ), + 'Carbon\\Doctrine\\' => array ( 0 => __DIR__ . '/..' . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine', ), - 'Carbon\\' => + 'Carbon\\' => array ( 0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon', ), + 'BaconQrCode\\' => + array ( + 0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src', + ), ); public static $prefixesPsr0 = array ( - 'O' => + 'O' => array ( - 'OAuth2' => + 'OAuth2' => array ( 0 => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src', ), @@ -244,6 +251,7 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', diff --git a/data/web/inc/lib/vendor/composer/installed.json b/data/web/inc/lib/vendor/composer/installed.json index 26e8bc42b..e2d7113bc 100644 --- a/data/web/inc/lib/vendor/composer/installed.json +++ b/data/web/inc/lib/vendor/composer/installed.json @@ -1,5 +1,62 @@ { "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "version_normalized": "2.0.8.0", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "time": "2022-12-07T17:46:57+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "install-path": "../bacon/bacon-qr-code" + }, { "name": "bshaffer/oauth2-server-php", "version": "v1.11.1", @@ -133,6 +190,59 @@ ], "install-path": "../carbonphp/carbon-doctrine-types" }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "version_normalized": "1.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "time": "2025-09-16T12:23:56+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "install-path": "../dasprid/enum" + }, { "name": "ddeboer/imap", "version": "1.13.1", @@ -213,36 +323,38 @@ }, { "name": "directorytree/ldaprecord", - "version": "v2.20.5", - "version_normalized": "2.20.5.0", + "version": "v3.8.5", + "version_normalized": "3.8.5.0", "source": { "type": "git", "url": "https://github.com/DirectoryTree/LdapRecord.git", - "reference": "5bd0a5a9d257cf1049ae83055dbba4c3479ddf16" + "reference": "00e5f088f8c4028d5f398783cccc2e8119a27a65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/5bd0a5a9d257cf1049ae83055dbba4c3479ddf16", - "reference": "5bd0a5a9d257cf1049ae83055dbba4c3479ddf16", + "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/00e5f088f8c4028d5f398783cccc2e8119a27a65", + "reference": "00e5f088f8c4028d5f398783cccc2e8119a27a65", "shasum": "" }, "require": { + "ext-iconv": "*", "ext-json": "*", "ext-ldap": "*", - "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", - "nesbot/carbon": "^1.0|^2.0", - "php": ">=7.3", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0", - "symfony/polyfill-php80": "^1.25", - "tightenco/collect": "^5.6|^6.0|^7.0|^8.0|^9.0" + "illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", + "nesbot/carbon": "*", + "php": ">=8.1", + "psr/log": "*", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, "require-dev": { + "fakerphp/faker": "^1.21", + "laravel/pint": "^1.6", "mockery/mockery": "^1.0", "phpunit/phpunit": "^9.0", "spatie/ray": "^1.24" }, - "time": "2023-10-11T16:34:34+00:00", + "time": "2025-10-06T02:22:34+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -691,6 +803,113 @@ ], "install-path": "../guzzlehttp/psr7" }, + { + "name": "illuminate/collections", + "version": "v10.49.0", + "version_normalized": "10.49.0.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/6ae9c74fa92d4e1824d1b346cd435e8eacdc3232", + "reference": "6ae9c74fa92d4e1824d1b346cd435e8eacdc3232", + "shasum": "" + }, + "require": { + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "php": "^8.1" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^6.2)." + }, + "time": "2025-09-08T19:05:53+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/collections" + }, + { + "name": "illuminate/conditionable", + "version": "v10.49.0", + "version_normalized": "10.49.0.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/47c700320b7a419f0d188d111f3bbed978fcbd3f", + "reference": "47c700320b7a419f0d188d111f3bbed978fcbd3f", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "time": "2025-03-24T11:47:24+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/conditionable" + }, { "name": "illuminate/contracts", "version": "v10.44.0", @@ -742,6 +961,55 @@ }, "install-path": "../illuminate/contracts" }, + { + "name": "illuminate/macroable", + "version": "v10.49.0", + "version_normalized": "10.49.0.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "time": "2023-06-05T12:46:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/macroable" + }, { "name": "league/oauth2-client", "version": "2.7.0", @@ -2538,151 +2806,6 @@ ], "install-path": "../symfony/translation-contracts" }, - { - "name": "symfony/var-dumper", - "version": "v6.4.3", - "version_normalized": "6.4.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "0435a08f69125535336177c29d56af3abc1f69da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0435a08f69125535336177c29d56af3abc1f69da", - "reference": "0435a08f69125535336177c29d56af3abc1f69da", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/console": "<5.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" - }, - "time": "2024-01-23T14:53:30+00:00", - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/var-dumper" - }, - { - "name": "tightenco/collect", - "version": "v9.52.7", - "version_normalized": "9.52.7.0", - "source": { - "type": "git", - "url": "https://github.com/tighten/collect.git", - "reference": "b15143cd11fe01a700fcc449df61adc64452fa6d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/b15143cd11fe01a700fcc449df61adc64452fa6d", - "reference": "b15143cd11fe01a700fcc449df61adc64452fa6d", - "shasum": "" - }, - "require": { - "php": "^8.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "nesbot/carbon": "^2.23.0", - "phpunit/phpunit": "^8.3" - }, - "time": "2023-04-14T21:51:36+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": [ - "collection", - "laravel" - ], - "support": { - "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v9.52.7" - }, - "install-path": "../tightenco/collect" - }, { "name": "twig/twig", "version": "v3.14.0", diff --git a/data/web/inc/lib/vendor/composer/installed.php b/data/web/inc/lib/vendor/composer/installed.php index 074ec9f80..15a1aa89f 100644 --- a/data/web/inc/lib/vendor/composer/installed.php +++ b/data/web/inc/lib/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => '__root__', - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '220fdbb168792c07493db330d898b345cc902055', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,14 +11,23 @@ ), 'versions' => array( '__root__' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '220fdbb168792c07493db330d898b345cc902055', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), + 'bacon/bacon-qr-code' => array( + 'pretty_version' => '2.0.8', + 'version' => '2.0.8.0', + 'reference' => '8674e51bb65af933a5ffaf1c308a660387c35c22', + 'type' => 'library', + 'install_path' => __DIR__ . '/../bacon/bacon-qr-code', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'bshaffer/oauth2-server-php' => array( 'pretty_version' => 'v1.11.1', 'version' => '1.11.1.0', @@ -37,6 +46,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'dasprid/enum' => array( + 'pretty_version' => '1.0.7', + 'version' => '1.0.7.0', + 'reference' => 'b5874fa9ed0043116c72162ec7f4fb50e02e7cce', + 'type' => 'library', + 'install_path' => __DIR__ . '/../dasprid/enum', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'ddeboer/imap' => array( 'pretty_version' => '1.13.1', 'version' => '1.13.1.0', @@ -47,9 +65,9 @@ 'dev_requirement' => false, ), 'directorytree/ldaprecord' => array( - 'pretty_version' => 'v2.20.5', - 'version' => '2.20.5.0', - 'reference' => '5bd0a5a9d257cf1049ae83055dbba4c3479ddf16', + 'pretty_version' => 'v3.8.5', + 'version' => '3.8.5.0', + 'reference' => '00e5f088f8c4028d5f398783cccc2e8119a27a65', 'type' => 'library', 'install_path' => __DIR__ . '/../directorytree/ldaprecord', 'aliases' => array(), @@ -97,6 +115,24 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'illuminate/collections' => array( + 'pretty_version' => 'v10.49.0', + 'version' => '10.49.0.0', + 'reference' => '6ae9c74fa92d4e1824d1b346cd435e8eacdc3232', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/collections', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'illuminate/conditionable' => array( + 'pretty_version' => 'v10.49.0', + 'version' => '10.49.0.0', + 'reference' => '47c700320b7a419f0d188d111f3bbed978fcbd3f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/conditionable', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'illuminate/contracts' => array( 'pretty_version' => 'v10.44.0', 'version' => '10.44.0.0', @@ -106,6 +142,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'illuminate/macroable' => array( + 'pretty_version' => 'v10.49.0', + 'version' => '10.49.0.0', + 'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/macroable', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'league/oauth2-client' => array( 'pretty_version' => '2.7.0', 'version' => '2.7.0.0', @@ -376,24 +421,6 @@ 0 => '2.3|3.0', ), ), - 'symfony/var-dumper' => array( - 'pretty_version' => 'v6.4.3', - 'version' => '6.4.3.0', - 'reference' => '0435a08f69125535336177c29d56af3abc1f69da', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/var-dumper', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'tightenco/collect' => array( - 'pretty_version' => 'v9.52.7', - 'version' => '9.52.7.0', - 'reference' => 'b15143cd11fe01a700fcc449df61adc64452fa6d', - 'type' => 'library', - 'install_path' => __DIR__ . '/../tightenco/collect', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'twig/twig' => array( 'pretty_version' => 'v3.14.0', 'version' => '3.14.0.0', diff --git a/data/web/inc/lib/vendor/dasprid/enum/LICENSE b/data/web/inc/lib/vendor/dasprid/enum/LICENSE new file mode 100644 index 000000000..d45a35647 --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017, Ben Scholzen 'DASPRiD' +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/data/web/inc/lib/vendor/dasprid/enum/README.md b/data/web/inc/lib/vendor/dasprid/enum/README.md new file mode 100644 index 000000000..da37045e3 --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/README.md @@ -0,0 +1,164 @@ +# PHP 7.1 enums + +[![Build Status](https://github.com/DASPRiD/Enum/actions/workflows/tests.yml/badge.svg)](https://github.com/DASPRiD/Enum/actions?query=workflow%3Atests) +[![Coverage Status](https://coveralls.io/repos/github/DASPRiD/Enum/badge.svg?branch=master)](https://coveralls.io/github/DASPRiD/Enum?branch=master) +[![Latest Stable Version](https://poser.pugx.org/dasprid/enum/v/stable)](https://packagist.org/packages/dasprid/enum) +[![Total Downloads](https://poser.pugx.org/dasprid/enum/downloads)](https://packagist.org/packages/dasprid/enum) +[![License](https://poser.pugx.org/dasprid/enum/license)](https://packagist.org/packages/dasprid/enum) + +It is a well known fact that PHP is missing a basic enum type, ignoring the rather incomplete `SplEnum` implementation +which is only available as a PECL extension. There are also quite a few other userland enum implementations around, +but all of them have one or another compromise. This library tries to close that gap as far as PHP allows it to. + +## Usage + +### Basics + +At its core, there is the `DASPRiD\Enum\AbstractEnum` class, which by default will work with constants like any other +enum implementation you might know. The first clear difference is that you should define all the constants as protected +(so nobody outside your class can read them but the `AbstractEnum` can still do so). The other even mightier difference +is that, for simple enums, the value of the constant doesn't matter at all. Let's have a look at a simple example: + +```php +use DASPRiD\Enum\AbstractEnum; + +/** + * @method static self MONDAY() + * @method static self TUESDAY() + * @method static self WEDNESDAY() + * @method static self THURSDAY() + * @method static self FRIDAY() + * @method static self SATURDAY() + * @method static self SUNDAY() + */ +final class WeekDay extends AbstractEnum +{ + protected const MONDAY = null; + protected const TUESDAY = null; + protected const WEDNESDAY = null; + protected const THURSDAY = null; + protected const FRIDAY = null; + protected const SATURDAY = null; + protected const SUNDAY = null; +} +``` + +If you need to provide constants for either internal use or public use, you can mark them as either private or public, +in which case they will be ignored by the enum, which only considers protected constants as valid values. As you can +see, we specifically defined the generated magic methods in a class level doc block, so anyone using this class will +automatically have proper auto-completion in their IDE. Now since you have defined the enum, you can simply use it like +that: + +```php +function tellItLikeItIs(WeekDay $weekDay) +{ + switch ($weekDay) { + case WeekDay::MONDAY(): + echo 'Mondays are bad.'; + break; + + case WeekDay::FRIDAY(): + echo 'Fridays are better.'; + break; + + case WeekDay::SATURDAY(): + case WeekDay::SUNDAY(): + echo 'Weekends are best.'; + break; + + default: + echo 'Midweek days are so-so.'; + } +} + +tellItLikeItIs(WeekDay::MONDAY()); +tellItLikeItIs(WeekDay::WEDNESDAY()); +tellItLikeItIs(WeekDay::FRIDAY()); +tellItLikeItIs(WeekDay::SATURDAY()); +tellItLikeItIs(WeekDay::SUNDAY()); +``` + +### More complex example + +Of course, all enums are singletons, which are not cloneable or serializable. Thus you can be sure that there is always +just one instance of the same type. Of course, the values of constants are not completely useless, let's have a look at +a more complex example: + +```php +use DASPRiD\Enum\AbstractEnum; + +/** + * @method static self MERCURY() + * @method static self VENUS() + * @method static self EARTH() + * @method static self MARS() + * @method static self JUPITER() + * @method static self SATURN() + * @method static self URANUS() + * @method static self NEPTUNE() + */ +final class Planet extends AbstractEnum +{ + protected const MERCURY = [3.303e+23, 2.4397e6]; + protected const VENUS = [4.869e+24, 6.0518e6]; + protected const EARTH = [5.976e+24, 6.37814e6]; + protected const MARS = [6.421e+23, 3.3972e6]; + protected const JUPITER = [1.9e+27, 7.1492e7]; + protected const SATURN = [5.688e+26, 6.0268e7]; + protected const URANUS = [8.686e+25, 2.5559e7]; + protected const NEPTUNE = [1.024e+26, 2.4746e7]; + + /** + * Universal gravitational constant. + * + * @var float + */ + private const G = 6.67300E-11; + + /** + * Mass in kilograms. + * + * @var float + */ + private $mass; + + /** + * Radius in meters. + * + * @var float + */ + private $radius; + + protected function __construct(float $mass, float $radius) + { + $this->mass = $mass; + $this->radius = $radius; + } + + public function mass() : float + { + return $this->mass; + } + + public function radius() : float + { + return $this->radius; + } + + public function surfaceGravity() : float + { + return self::G * $this->mass / ($this->radius * $this->radius); + } + + public function surfaceWeight(float $otherMass) : float + { + return $otherMass * $this->surfaceGravity(); + } +} + +$myMass = 80; + +foreach (Planet::values() as $planet) { + printf("Your weight on %s is %f\n", $planet, $planet->surfaceWeight($myMass)); +} +``` diff --git a/data/web/inc/lib/vendor/dasprid/enum/composer.json b/data/web/inc/lib/vendor/dasprid/enum/composer.json new file mode 100644 index 000000000..a099aba54 --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/composer.json @@ -0,0 +1,34 @@ +{ + "name": "dasprid/enum", + "description": "PHP 7.1 enum implementation", + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "keywords": [ + "enum", + "map" + ], + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "DASPRiD\\EnumTest\\": "test/" + } + } +} diff --git a/data/web/inc/lib/vendor/dasprid/enum/src/AbstractEnum.php b/data/web/inc/lib/vendor/dasprid/enum/src/AbstractEnum.php new file mode 100644 index 000000000..43006dce6 --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/src/AbstractEnum.php @@ -0,0 +1,261 @@ +> + */ + private static $values = []; + + /** + * @var array + */ + private static $allValuesLoaded = []; + + /** + * @var array + */ + private static $constants = []; + + /** + * The constructor is private by default to avoid arbitrary enum creation. + * + * When creating your own constructor for a parameterized enum, make sure to declare it as protected, so that + * the static methods are able to construct it. Avoid making it public, as that would allow creation of + * non-singleton enum instances. + */ + private function __construct() + { + } + + /** + * Magic getter which forwards all calls to {@see self::valueOf()}. + * + * @return static + */ + final public static function __callStatic(string $name, array $arguments) : self + { + return static::valueOf($name); + } + + /** + * Returns an enum with the specified name. + * + * The name must match exactly an identifier used to declare an enum in this type (extraneous whitespace characters + * are not permitted). + * + * @return static + * @throws IllegalArgumentException if the enum has no constant with the specified name + */ + final public static function valueOf(string $name) : self + { + if (isset(self::$values[static::class][$name])) { + return self::$values[static::class][$name]; + } + + $constants = self::constants(); + + if (array_key_exists($name, $constants)) { + return self::createValue($name, $constants[$name][0], $constants[$name][1]); + } + + throw new IllegalArgumentException(sprintf('No enum constant %s::%s', static::class, $name)); + } + + /** + * @return static + */ + private static function createValue(string $name, int $ordinal, array $arguments) : self + { + $instance = new static(...$arguments); + $instance->name = $name; + $instance->ordinal = $ordinal; + self::$values[static::class][$name] = $instance; + return $instance; + } + + /** + * Obtains all possible types defined by this enum. + * + * @return static[] + */ + final public static function values() : array + { + if (isset(self::$allValuesLoaded[static::class])) { + return self::$values[static::class]; + } + + if (! isset(self::$values[static::class])) { + self::$values[static::class] = []; + } + + foreach (self::constants() as $name => $constant) { + if (array_key_exists($name, self::$values[static::class])) { + continue; + } + + static::createValue($name, $constant[0], $constant[1]); + } + + uasort(self::$values[static::class], function (self $a, self $b) { + return $a->ordinal() <=> $b->ordinal(); + }); + + self::$allValuesLoaded[static::class] = true; + return self::$values[static::class]; + } + + private static function constants() : array + { + if (isset(self::$constants[static::class])) { + return self::$constants[static::class]; + } + + self::$constants[static::class] = []; + $reflectionClass = new ReflectionClass(static::class); + $ordinal = -1; + + foreach ($reflectionClass->getReflectionConstants() as $reflectionConstant) { + if (! $reflectionConstant->isProtected()) { + continue; + } + + $value = $reflectionConstant->getValue(); + + self::$constants[static::class][$reflectionConstant->name] = [ + ++$ordinal, + is_array($value) ? $value : [] + ]; + } + + return self::$constants[static::class]; + } + + /** + * Returns the name of this enum constant, exactly as declared in its enum declaration. + * + * Most programmers should use the {@see self::__toString()} method in preference to this one, as the toString + * method may return a more user-friendly name. This method is designed primarily for use in specialized situations + * where correctness depends on getting the exact name, which will not vary from release to release. + */ + final public function name() : string + { + return $this->name; + } + + /** + * Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial + * constant is assigned an ordinal of zero). + * + * Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data + * structures. + */ + final public function ordinal() : int + { + return $this->ordinal; + } + + /** + * Compares this enum with the specified object for order. + * + * Returns negative integer, zero or positive integer as this object is less than, equal to or greater than the + * specified object. + * + * Enums are only comparable to other enums of the same type. The natural order implemented by this method is the + * order in which the constants are declared. + * + * @throws MismatchException if the passed enum is not of the same type + */ + final public function compareTo(self $other) : int + { + if (! $other instanceof static) { + throw new MismatchException(sprintf( + 'The passed enum %s is not of the same type as %s', + get_class($other), + static::class + )); + } + + return $this->ordinal - $other->ordinal; + } + + /** + * Forbid cloning enums. + * + * @throws CloneNotSupportedException + */ + final public function __clone() + { + throw new CloneNotSupportedException(); + } + + /** + * Forbid serializing enums. + * + * @throws SerializeNotSupportedException + */ + final public function __sleep() : array + { + throw new SerializeNotSupportedException(); + } + + /** + * Forbid serializing enums. + * + * @throws SerializeNotSupportedException + */ + final public function __serialize() : array + { + throw new SerializeNotSupportedException(); + } + + /** + * Forbid unserializing enums. + * + * @throws UnserializeNotSupportedException + */ + final public function __wakeup() : void + { + throw new UnserializeNotSupportedException(); + } + + /** + * Forbid unserializing enums. + * + * @throws UnserializeNotSupportedException + */ + final public function __unserialize($arg) : void + { + throw new UnserializeNotSupportedException(); + } + + /** + * Turns the enum into a string representation. + * + * You may override this method to give a more user-friendly version. + */ + public function __toString() : string + { + return $this->name; + } +} diff --git a/data/web/inc/lib/vendor/dasprid/enum/src/EnumMap.php b/data/web/inc/lib/vendor/dasprid/enum/src/EnumMap.php new file mode 100644 index 000000000..95b88568d --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/src/EnumMap.php @@ -0,0 +1,385 @@ + + */ + private $keyUniverse; + + /** + * Array representation of this map. The ith element is the value to which universe[i] is currently mapped, or null + * if it isn't mapped to anything, or NullValue if it's mapped to null. + * + * @var array + */ + private $values; + + /** + * @var int + */ + private $size = 0; + + /** + * Creates a new enum map. + * + * @param string $keyType the type of the keys, must extend AbstractEnum + * @param string $valueType the type of the values + * @param bool $allowNullValues whether to allow null values + * @throws IllegalArgumentException when key type does not extend AbstractEnum + */ + public function __construct(string $keyType, string $valueType, bool $allowNullValues) + { + if (! is_subclass_of($keyType, AbstractEnum::class)) { + throw new IllegalArgumentException(sprintf( + 'Class %s does not extend %s', + $keyType, + AbstractEnum::class + )); + } + + $this->keyType = $keyType; + $this->valueType = $valueType; + $this->allowNullValues = $allowNullValues; + $this->keyUniverse = $keyType::values(); + $this->values = array_fill(0, count($this->keyUniverse), null); + } + + public function __serialize(): array + { + $values = []; + + foreach ($this->values as $ordinal => $value) { + if (null === $value) { + continue; + } + + $values[$ordinal] = $this->unmaskNull($value); + } + + return [ + 'keyType' => $this->keyType, + 'valueType' => $this->valueType, + 'allowNullValues' => $this->allowNullValues, + 'values' => $values, + ]; + } + + public function __unserialize(array $data): void + { + $this->unserialize(serialize($data)); + } + + /** + * Checks whether the map types match the supplied ones. + * + * You should call this method when an EnumMap is passed to you and you want to ensure that it's made up of the + * correct types. + * + * @throws ExpectationException when supplied key type mismatches local key type + * @throws ExpectationException when supplied value type mismatches local value type + * @throws ExpectationException when the supplied map allows null values, abut should not + */ + public function expect(string $keyType, string $valueType, bool $allowNullValues) : void + { + if ($keyType !== $this->keyType) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with key type %s, but got %s', + $keyType, + $this->keyType + )); + } + + if ($valueType !== $this->valueType) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with value type %s, but got %s', + $keyType, + $this->keyType + )); + } + + if ($allowNullValues !== $this->allowNullValues) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with nullable flag %s, but got %s', + ($allowNullValues ? 'true' : 'false'), + ($this->allowNullValues ? 'true' : 'false') + )); + } + } + + /** + * Returns the number of key-value mappings in this map. + */ + public function size() : int + { + return $this->size; + } + + /** + * Returns true if this map maps one or more keys to the specified value. + */ + public function containsValue($value) : bool + { + return in_array($this->maskNull($value), $this->values, true); + } + + /** + * Returns true if this map contains a mapping for the specified key. + */ + public function containsKey(AbstractEnum $key) : bool + { + $this->checkKeyType($key); + return null !== $this->values[$key->ordinal()]; + } + + /** + * Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. + * + * More formally, if this map contains a mapping from a key to a value, then this method returns the value; + * otherwise it returns null (there can be at most one such mapping). + * + * A return value of null does not necessarily indicate that the map contains no mapping for the key; it's also + * possible that hte map explicitly maps the key to null. The {@see self::containsKey()} operation may be used to + * distinguish these two cases. + * + * @return mixed + */ + public function get(AbstractEnum $key) + { + $this->checkKeyType($key); + return $this->unmaskNull($this->values[$key->ordinal()]); + } + + /** + * Associates the specified value with the specified key in this map. + * + * If the map previously contained a mapping for this key, the old value is replaced. + * + * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key. + * (a null return can also indicate that the map previously associated null with the specified key.) + * @throws IllegalArgumentException when the passed values does not match the internal value type + */ + public function put(AbstractEnum $key, $value) + { + $this->checkKeyType($key); + + if (! $this->isValidValue($value)) { + throw new IllegalArgumentException(sprintf('Value is not of type %s', $this->valueType)); + } + + $index = $key->ordinal(); + $oldValue = $this->values[$index]; + $this->values[$index] = $this->maskNull($value); + + if (null === $oldValue) { + ++$this->size; + } + + return $this->unmaskNull($oldValue); + } + + /** + * Removes the mapping for this key frm this map if present. + * + * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key. + * (a null return can also indicate that the map previously associated null with the specified key.) + */ + public function remove(AbstractEnum $key) + { + $this->checkKeyType($key); + + $index = $key->ordinal(); + $oldValue = $this->values[$index]; + $this->values[$index] = null; + + if (null !== $oldValue) { + --$this->size; + } + + return $this->unmaskNull($oldValue); + } + + /** + * Removes all mappings from this map. + */ + public function clear() : void + { + $this->values = array_fill(0, count($this->keyUniverse), null); + $this->size = 0; + } + + /** + * Compares the specified map with this map for quality. + * + * Returns true if the two maps represent the same mappings. + */ + public function equals(self $other) : bool + { + if ($this === $other) { + return true; + } + + if ($this->size !== $other->size) { + return false; + } + + return $this->values === $other->values; + } + + /** + * Returns the values contained in this map. + * + * The array will contain the values in the order their corresponding keys appear in the map, which is their natural + * order (the order in which the num constants are declared). + */ + public function values() : array + { + return array_values(array_map(function ($value) { + return $this->unmaskNull($value); + }, array_filter($this->values, function ($value) : bool { + return null !== $value; + }))); + } + + public function serialize() : string + { + return serialize($this->__serialize()); + } + + public function unserialize($serialized) : void + { + $data = unserialize($serialized); + $this->__construct($data['keyType'], $data['valueType'], $data['allowNullValues']); + + foreach ($this->keyUniverse as $key) { + if (array_key_exists($key->ordinal(), $data['values'])) { + $this->put($key, $data['values'][$key->ordinal()]); + } + } + } + + public function getIterator() : Traversable + { + foreach ($this->keyUniverse as $key) { + if (null === $this->values[$key->ordinal()]) { + continue; + } + + yield $key => $this->unmaskNull($this->values[$key->ordinal()]); + } + } + + private function maskNull($value) + { + if (null === $value) { + return NullValue::instance(); + } + + return $value; + } + + private function unmaskNull($value) + { + if ($value instanceof NullValue) { + return null; + } + + return $value; + } + + /** + * @throws IllegalArgumentException when the passed key does not match the internal key type + */ + private function checkKeyType(AbstractEnum $key) : void + { + if (get_class($key) !== $this->keyType) { + throw new IllegalArgumentException(sprintf( + 'Object of type %s is not the same type as %s', + get_class($key), + $this->keyType + )); + } + } + + private function isValidValue($value) : bool + { + if (null === $value) { + if ($this->allowNullValues) { + return true; + } + + return false; + } + + switch ($this->valueType) { + case 'mixed': + return true; + + case 'bool': + case 'boolean': + return is_bool($value); + + case 'int': + case 'integer': + return is_int($value); + + case 'float': + case 'double': + return is_float($value); + + case 'string': + return is_string($value); + + case 'object': + return is_object($value); + + case 'array': + return is_array($value); + } + + return $value instanceof $this->valueType; + } +} diff --git a/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php b/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php new file mode 100644 index 000000000..4b37dbebe --- /dev/null +++ b/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php @@ -0,0 +1,10 @@ + **Environment:** - LDAP Server Type: [e.g. ActiveDirectory / OpenLDAP / FreeIPA] - - PHP Version: [e.g. 7.3 / 7.4 / 8.0] + - PHP Version: [e.g. 8.1 / 8.2] **Describe the bug:** diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md index 731d5cea0..b97a977cb 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md @@ -17,4 +17,4 @@ assignees: '' --> **Environment:** - LDAP Server Type: [e.g. ActiveDirectory / OpenLDAP / FreeIPA] - - PHP Version: [e.g. 7.3 / 7.4 / 8.0] + - PHP Version: [e.g. 8.1 / 8.2] diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml new file mode 100644 index 000000000..80cd34d61 --- /dev/null +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml @@ -0,0 +1,34 @@ +name: run-cs-fix + +on: + push: + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + php: [8.3] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: json, dom, curl, libxml, mbstring + coverage: none + + - name: Install Pint + run: composer global require laravel/pint + + - name: Run Pint + run: pint + + - name: Commit linted files + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "Fix code style" diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml index 6a6b2f9e5..de67e91c9 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml @@ -1,62 +1,62 @@ name: run-integration-tests on: - push: - pull_request: - schedule: - - cron: "0 0 * * *" + push: + pull_request: + schedule: + - cron: "0 0 * * *" jobs: - run-tests: - runs-on: ${{ matrix.os }} + run-tests: + runs-on: ${{ matrix.os }} - services: - ldap: - image: osixia/openldap:1.4.0 - env: - LDAP_TLS_VERIFY_CLIENT: try - LDAP_OPENLDAP_UID: 1000 - LDAP_OPENLDAP_GID: 1000 - LDAP_ORGANISATION: Local - LDAP_DOMAIN: local.com - LDAP_ADMIN_PASSWORD: secret - ports: - - 389:389 - - 636:636 + services: + ldap: + image: osixia/openldap:1.4.0 + env: + LDAP_TLS_VERIFY_CLIENT: try + LDAP_OPENLDAP_UID: 1000 + LDAP_OPENLDAP_GID: 1000 + LDAP_ORGANISATION: Local + LDAP_DOMAIN: local.com + LDAP_ADMIN_PASSWORD: secret + ports: + - 389:389 + - 636:636 - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - php: [8.1, 8.0, 7.4] + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + php: [8.1, 8.2, 8.3] - name: ${{ matrix.os }} - P${{ matrix.php }} + name: ${{ matrix.os }} - P${{ matrix.php }} - steps: - - name: Checkout code - uses: actions/checkout@v2 + steps: + - name: Checkout code + uses: actions/checkout@v2 - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ~/.composer/cache/files - key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache/files + key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - - name: Set ldap.conf file permissions - run: sudo chown -R $USER:$USER /etc/ldap/ldap.conf + - name: Set ldap.conf file permissions + run: sudo chown -R $USER:$USER /etc/ldap/ldap.conf - - name: Create ldap.conf file disabling TLS verification - run: sudo echo "TLS_REQCERT never" > "/etc/ldap/ldap.conf" + - name: Create ldap.conf file disabling TLS verification + run: sudo echo "TLS_REQCERT never" > "/etc/ldap/ldap.conf" - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: ldap, json - coverage: none + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ldap, json + coverage: none - - name: Install dependencies - run: composer update --prefer-dist --no-interaction + - name: Install dependencies + run: composer update --prefer-dist --no-interaction - - name: Execute tests - run: vendor/bin/phpunit --testsuite Integration + - name: Execute tests + run: vendor/bin/phpunit --testsuite Integration diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml index 6aaa3fd4a..8781e918a 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml @@ -1,41 +1,41 @@ name: run-tests on: - push: - pull_request: - schedule: - - cron: "0 0 * * *" + push: + pull_request: + schedule: + - cron: "0 0 * * *" jobs: - run-tests: - runs-on: ${{ matrix.os }} - name: ${{ matrix.os }} - P${{ matrix.php }} + run-tests: + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} - P${{ matrix.php }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest] - php: [8.1, 8.0, 7.4, 7.3] + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + php: [8.1, 8.2, 8.3, 8.4] - steps: - - name: Checkout code - uses: actions/checkout@v2 + steps: + - name: Checkout code + uses: actions/checkout@v2 - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ~/.composer/cache/files - key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache/files + key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: ldap, json - coverage: none + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ldap, json + coverage: none - - name: Install dependencies - run: composer update --prefer-dist --no-interaction + - name: Install dependencies + run: composer update --prefer-dist --no-interaction - - name: Execute tests - run: vendor/bin/phpunit --testsuite Unit + - name: Execute tests + run: vendor/bin/phpunit --testsuite Unit diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml deleted file mode 100644 index b3f8f88b2..000000000 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml +++ /dev/null @@ -1,9 +0,0 @@ -filter: - excluded_paths: - - tests/* -build: - nodes: - analysis: - tests: - override: - - command: php-scrutinizer-run diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml deleted file mode 100644 index 0285f1790..000000000 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml +++ /dev/null @@ -1 +0,0 @@ -preset: laravel diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json b/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json index 65d7dd8f6..97e84cd5e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json @@ -29,20 +29,22 @@ } ], "require": { - "php": ">=7.3", + "php": ">=8.1", "ext-ldap": "*", "ext-json": "*", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0", - "nesbot/carbon": "^1.0|^2.0", - "tightenco/collect": "^5.6|^6.0|^7.0|^8.0|^9.0", - "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0", - "symfony/polyfill-php80": "^1.25" + "ext-iconv": "*", + "psr/log": "*", + "nesbot/carbon": "*", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0" }, "require-dev": { "phpunit/phpunit": "^9.0", "mockery/mockery": "^1.0", - "spatie/ray": "^1.24" + "spatie/ray": "^1.24", + "laravel/pint": "^1.6", + "fakerphp/faker": "^1.21" }, "archive": { "exclude": [ diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml index de96b1398..1abf0979d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3' - services: ldap: image: osixia/openldap:1.4.0 diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md b/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md index e00f8ef69..4e34bd727 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md @@ -1,25 +1,12 @@ - -

- +

- - - - - - - - - - - - - - - + + + +

@@ -32,9 +19,9 @@

- Quickstart + Quickstart · - Documentation + Documentation · Laravel Integration · @@ -67,15 +54,15 @@ Active Directory Features 🚪 **Enable / Disable Accounts** -Detect and assign User Account Control values on accounts with the fluent [Account Control builder](https://ldaprecord.com/docs/core/v2/active-directory/users/#uac). +Detect and assign User Account Control values on accounts with the fluent [Account Control builder](https://ldaprecord.com/docs/core/v3/active-directory/users/#uac). 🔑 **Reset / Change Passwords** -Built-in support for [changing](https://ldaprecord.com/docs/core/v2/active-directory/users/#changing-passwords) and [resetting](https://ldaprecord.com/docs/core/v2/active-directory/users/#resetting-passwords) passwords on Active Directory accounts. +Built-in support for [changing](https://ldaprecord.com/docs/core/v3/active-directory/users/#changing-passwords) and [resetting](https://ldaprecord.com/docs/core/v3/active-directory/users/#resetting-passwords) passwords on Active Directory accounts. 🗑 **Restore Deleted Objects** -We've all been there -- accidentally deleting a user or group in Active Directory. [Restore them](https://ldaprecord.com/docs/core/v2/models/#restoring-deleted-models) by seamlessly accessing your directory's recycle bin. +Seamlessly access your Active Directory recycle bin and [restore deleted objects](https://ldaprecord.com/docs/core/v3/models/#restoring-deleted-models). --- diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php index 7c1bb3c87..29687dbf2 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php @@ -8,33 +8,23 @@ abstract class Event { /** * The connection that the username and password is being bound on. - * - * @var LdapInterface */ - protected $connection; + protected LdapInterface $connection; /** * The username that is being used for binding. - * - * @var string */ - protected $username; + protected ?string $username; /** * The password that is being used for binding. - * - * @var string */ - protected $password; + protected ?string $password; /** * Constructor. - * - * @param LdapInterface $connection - * @param string $username - * @param string $password */ - public function __construct(LdapInterface $connection, $username, $password) + public function __construct(LdapInterface $connection, ?string $username = null, ?string $password = null) { $this->connection = $connection; $this->username = $username; @@ -42,31 +32,25 @@ abstract class Event } /** - * Returns the events connection. - * - * @return LdapInterface + * Get the event's connection. */ - public function getConnection() + public function getConnection(): LdapInterface { return $this->connection; } /** - * Returns the authentication events username. - * - * @return string + * Get the authentication event's username. */ - public function getUsername() + public function getUsername(): ?string { return $this->username; } /** - * Returns the authentication events password. - * - * @return string + * Get the authentication event's password. */ - public function getPassword() + public function getPassword(): ?string { return $this->password; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php index 7133e4390..b26049169 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php @@ -2,7 +2,32 @@ namespace LdapRecord\Auth\Events; +use Exception; +use LdapRecord\Auth\BindException; +use LdapRecord\LdapInterface; + class Failed extends Event { - // + /** + * The exception that was thrown during the bind attempt. + */ + protected BindException $exception; + + /** + * Constructor. + */ + public function __construct(LdapInterface $connection, ?string $username, ?string $password, BindException $exception) + { + parent::__construct($connection, $username, $password); + + $this->exception = $exception; + } + + /** + * Get the exception that was thrown during the bind attempt. + */ + public function getException(): BindException + { + return $this->exception; + } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php index c00989ae6..d560098b7 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php @@ -3,11 +3,6 @@ namespace LdapRecord\Auth; use Exception; -use LdapRecord\Auth\Events\Attempting; -use LdapRecord\Auth\Events\Binding; -use LdapRecord\Auth\Events\Bound; -use LdapRecord\Auth\Events\Failed; -use LdapRecord\Auth\Events\Passed; use LdapRecord\Configuration\DomainConfiguration; use LdapRecord\Events\DispatcherInterface; use LdapRecord\LdapInterface; @@ -16,30 +11,21 @@ class Guard { /** * The connection to bind to. - * - * @var LdapInterface */ - protected $connection; + protected LdapInterface $connection; /** * The domain configuration to utilize. - * - * @var DomainConfiguration */ - protected $configuration; + protected DomainConfiguration $configuration; /** * The event dispatcher. - * - * @var DispatcherInterface */ - protected $events; + protected ?DispatcherInterface $events = null; /** * Constructor. - * - * @param LdapInterface $connection - * @param DomainConfiguration $configuration */ public function __construct(LdapInterface $connection, DomainConfiguration $configuration) { @@ -50,15 +36,10 @@ class Guard /** * Attempt binding a user to the LDAP server. * - * @param string $username - * @param string $password - * @param bool $stayBound - * @return bool - * * @throws UsernameRequiredException * @throws PasswordRequiredException */ - public function attempt($username, $password, $stayBound = false) + public function attempt(string $username, string $password, bool $stayBound = false): bool { switch (true) { case empty($username): @@ -67,58 +48,73 @@ class Guard throw new PasswordRequiredException('A password must be specified.'); } - $this->fireAttemptingEvent($username, $password); + $this->fireAuthEvent('attempting', $username, $password); try { $this->bind($username, $password); - $authenticated = true; + $bound = true; - $this->firePassedEvent($username, $password); - } catch (BindException $e) { - $authenticated = false; + $this->fireAuthEvent('passed', $username, $password); + } catch (BindException) { + $bound = false; } if (! $stayBound) { $this->bindAsConfiguredUser(); } - return $authenticated; + return $bound; } /** - * Attempt binding a user to the LDAP server. Supports anonymous binding. - * - * @param string|null $username - * @param string|null $password + * Attempt binding a user to the LDAP server. Supports sasl and anonymous binding. * * @throws BindException * @throws \LdapRecord\ConnectionException */ - public function bind($username = null, $password = null) + public function bind(?string $username = null, ?string $password = null): void { - $this->fireBindingEvent($username, $password); + $this->fireAuthEvent('binding', $username, $password); // Prior to binding, we will upgrade our connectivity to TLS on our current // connection and ensure we are not already bound before upgrading. // This is to prevent subsequent upgrading on several binds. - if ($this->connection->isUsingTLS() && ! $this->connection->isBound()) { + if ($this->connection->isUsingTLS() && ! $this->connection->isSecure()) { $this->connection->startTLS(); } try { - if (! $this->connection->bind($username, $password)) { + if (! $this->authenticate($username, $password)) { throw new Exception($this->connection->getLastError(), $this->connection->errNo()); } - $this->fireBoundEvent($username, $password); + $this->fireAuthEvent('bound', $username, $password); } catch (Exception $e) { - $this->fireFailedEvent($username, $password); + $exception = BindException::withDetailedError($e, $this->connection->getDetailedError()); - throw BindException::withDetailedError($e, $this->connection->getDetailedError()); + $this->fireAuthEvent('failed', $username, $password, $exception); + + throw $exception; } } + /** + * Authenticate by binding to the LDAP server. + * + * @throws \LdapRecord\ConnectionException + */ + protected function authenticate(?string $username = null, ?string $password = null): bool + { + if ($this->configuration->get('use_sasl') ?? false) { + return $this->connection->saslBind( + $username, $password, $this->configuration->get('sasl_options') + ); + } + + return $this->connection->bind($username, $password)->successful(); + } + /** * Bind to the LDAP server using the configured username and password. * @@ -126,7 +122,7 @@ class Guard * @throws \LdapRecord\ConnectionException * @throws \LdapRecord\Configuration\ConfigurationException */ - public function bindAsConfiguredUser() + public function bindAsConfiguredUser(): void { $this->bind( $this->configuration->get('username'), @@ -136,92 +132,29 @@ class Guard /** * Get the event dispatcher instance. - * - * @return DispatcherInterface */ - public function getDispatcher() + public function getDispatcher(): ?DispatcherInterface { return $this->events; } /** * Set the event dispatcher instance. - * - * @param DispatcherInterface $dispatcher - * @return void */ - public function setDispatcher(DispatcherInterface $dispatcher) + public function setDispatcher(?DispatcherInterface $dispatcher = null): void { $this->events = $dispatcher; } /** - * Fire the attempting event. - * - * @param string $username - * @param string $password - * @return void + * Fire an authentication event. */ - protected function fireAttemptingEvent($username, $password) + protected function fireAuthEvent(string $name, ?string $username = null, ?string $password = null, ...$args): void { if (isset($this->events)) { - $this->events->fire(new Attempting($this->connection, $username, $password)); - } - } + $event = implode('\\', [Events::class, ucfirst($name)]); - /** - * Fire the passed event. - * - * @param string $username - * @param string $password - * @return void - */ - protected function firePassedEvent($username, $password) - { - if (isset($this->events)) { - $this->events->fire(new Passed($this->connection, $username, $password)); - } - } - - /** - * Fire the failed event. - * - * @param string $username - * @param string $password - * @return void - */ - protected function fireFailedEvent($username, $password) - { - if (isset($this->events)) { - $this->events->fire(new Failed($this->connection, $username, $password)); - } - } - - /** - * Fire the binding event. - * - * @param string $username - * @param string $password - * @return void - */ - protected function fireBindingEvent($username, $password) - { - if (isset($this->events)) { - $this->events->fire(new Binding($this->connection, $username, $password)); - } - } - - /** - * Fire the bound event. - * - * @param string $username - * @param string $password - * @return void - */ - protected function fireBoundEvent($username, $password) - { - if (isset($this->events)) { - $this->events->fire(new Bound($this->connection, $username, $password)); + $this->events->fire(new $event($this->connection, $username, $password, ...$args)); } } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php index f71f63d87..425fbd9ed 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php @@ -8,19 +8,15 @@ class DomainConfiguration { /** * The extended configuration options. - * - * @var array */ - protected static $extended = []; + protected static array $extended = []; /** * The configuration options array. * * The default values for each key indicate the type of value it requires. - * - * @var array */ - protected $options = [ + protected array $options = [ // An array of LDAP hosts. 'hosts' => [], @@ -33,6 +29,9 @@ class DomainConfiguration // The port to use for connecting to your hosts. 'port' => LdapInterface::PORT, + // The protocol to use for connecting to your hosts (ldap:// or ldaps://). + 'protocol' => null, + // The base distinguished name of your domain. 'base_dn' => '', @@ -42,13 +41,28 @@ class DomainConfiguration // The password to use for binding. 'password' => '', - // Whether or not to use SSL when connecting. + // Whether to use SSL when connecting. 'use_ssl' => false, - // Whether or not to use TLS when connecting. + // Whether to use TLS when connecting. 'use_tls' => false, - // Whether or not follow referrals is enabled when performing LDAP operations. + // Whether to use SASL when connecting. + 'use_sasl' => false, + + // Whether to allow password changes over plaintext. + 'allow_insecure_password_changes' => false, + + // SASL options + 'sasl_options' => [ + 'mech' => null, + 'realm' => null, + 'authc_id' => null, + 'authz_id' => null, + 'props' => null, + ], + + // Whether follow referrals is enabled when performing LDAP operations. 'follow_referrals' => false, // Custom LDAP options. @@ -58,8 +72,6 @@ class DomainConfiguration /** * Constructor. * - * @param array $options - * * @throws ConfigurationException When an option value given is an invalid type. */ public function __construct(array $options = []) @@ -73,32 +85,24 @@ class DomainConfiguration /** * Extend the configuration with a custom option, or override an existing. - * - * @param string $option - * @param mixed $default - * @return void */ - public static function extend($option, $default = null) + public static function extend(string $option, mixed $default = null): void { static::$extended[$option] = $default; } /** * Flush the extended configuration options. - * - * @return void */ - public static function flushExtended() + public static function flushExtended(): void { static::$extended = []; } /** * Get all configuration options. - * - * @return array */ - public function all() + public function all(): array { return $this->options; } @@ -106,12 +110,9 @@ class DomainConfiguration /** * Set a configuration option. * - * @param string $key - * @param mixed $value - * * @throws ConfigurationException When an option value given is an invalid type. */ - public function set($key, $value) + public function set(string $key, mixed $value): void { if ($this->validate($key, $value)) { $this->options[$key] = $value; @@ -119,17 +120,14 @@ class DomainConfiguration } /** - * Returns the value for the specified configuration options. - * - * @param string $key - * @return mixed + * Get the value for the specified configuration options. * * @throws ConfigurationException When the option specified does not exist. */ - public function get($key) + public function get(string $key): mixed { if (! $this->has($key)) { - throw new ConfigurationException("Option {$key} does not exist."); + throw new ConfigurationException("Option $key does not exist."); } return $this->options[$key]; @@ -137,11 +135,8 @@ class DomainConfiguration /** * Checks if a configuration option exists. - * - * @param string $key - * @return bool */ - public function has($key) + public function has(string $key): bool { return array_key_exists($key, $this->options); } @@ -149,13 +144,9 @@ class DomainConfiguration /** * Validate the configuration option. * - * @param string $key - * @param mixed $value - * @return bool - * * @throws ConfigurationException When an option value given is an invalid type. */ - protected function validate($key, $value) + protected function validate(string $key, mixed $value): bool { $default = $this->get($key); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php index 4aa43ed46..1324d1681 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php @@ -6,15 +6,13 @@ class ArrayValidator extends Validator { /** * The validation exception message. - * - * @var string */ - protected $message = 'Option [:option] must be an array.'; + protected string $message = 'Option [:option] must be an array.'; /** - * @inheritdoc + * {@inheritdoc} */ - public function passes() + public function passes(): bool { return is_array($this->value); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php index 1d25a4b25..1156859d3 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php @@ -6,15 +6,13 @@ class BooleanValidator extends Validator { /** * The validation exception message. - * - * @var string */ - protected $message = 'Option [:option] must be a boolean.'; + protected string $message = 'Option [:option] must be a boolean.'; /** - * @inheritdoc + * {@inheritdoc} */ - public function passes() + public function passes(): bool { return is_bool($this->value); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php index 5c4f0f95e..d7015888e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php @@ -6,15 +6,13 @@ class IntegerValidator extends Validator { /** * The validation exception message. - * - * @var string */ - protected $message = 'Option [:option] must be an integer.'; + protected string $message = 'Option [:option] must be an integer.'; /** - * @inheritdoc + * {@inheritdoc} */ - public function passes() + public function passes(): bool { return is_numeric($this->value); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php index bc2337245..5ca453c74 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php @@ -6,15 +6,13 @@ class StringOrNullValidator extends Validator { /** * The validation exception message. - * - * @var string */ - protected $message = 'Option [:option] must be a string or null.'; + protected string $message = 'Option [:option] must be a string or null.'; /** - * @inheritdoc + * {@inheritdoc} */ - public function passes() + public function passes(): bool { return is_string($this->value) || is_null($this->value); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php index d107314d5..25aedcbfa 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php @@ -8,32 +8,23 @@ abstract class Validator { /** * The configuration key under validation. - * - * @var string */ - protected $key; + protected string $key; /** * The configuration value under validation. - * - * @var mixed */ - protected $value; + protected mixed $value; /** * The validation exception message. - * - * @var string */ - protected $message; + protected string $message; /** * Constructor. - * - * @param string $key - * @param mixed $value */ - public function __construct($key, $value) + public function __construct(string $key, mixed $value) { $this->key = $key; $this->value = $value; @@ -41,19 +32,15 @@ abstract class Validator /** * Determine if the validation rule passes. - * - * @return bool */ - abstract public function passes(); + abstract public function passes(): bool; /** * Validate the configuration value. * - * @return bool - * * @throws ConfigurationException */ - public function validate() + public function validate(): bool { if (! $this->passes()) { $this->fail(); @@ -65,11 +52,9 @@ abstract class Validator /** * Throw a configuration exception. * - * @return void - * * @throws ConfigurationException */ - protected function fail() + protected function fail(): void { throw new ConfigurationException( str_replace(':option', $this->key, $this->message) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php index 6e55cffc9..e04393a27 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php @@ -5,6 +5,7 @@ namespace LdapRecord; use Carbon\Carbon; use Closure; use LdapRecord\Auth\Guard; +use LdapRecord\Configuration\ConfigurationException; use LdapRecord\Configuration\DomainConfiguration; use LdapRecord\Events\DispatcherInterface; use LdapRecord\Query\Builder; @@ -17,85 +18,64 @@ class Connection /** * The underlying LDAP connection. - * - * @var Ldap */ - protected $ldap; + protected LdapInterface $ldap; /** * The cache driver. - * - * @var Cache|null */ - protected $cache; + protected ?Cache $cache = null; /** * The domain configuration. - * - * @var DomainConfiguration */ - protected $configuration; + protected DomainConfiguration $configuration; /** - * The event dispatcher;. - * - * @var DispatcherInterface|null + * The event dispatcher. */ - protected $dispatcher; + protected ?DispatcherInterface $dispatcher = null; /** - * The current host connected to. - * - * @var string + * The currently connected host. */ - protected $host; + protected string $host; /** * The configured domain hosts. - * - * @var array */ - protected $hosts = []; + protected array $hosts = []; /** * The attempted hosts that failed connecting to. - * - * @var array */ - protected $attempted = []; + protected array $attempted = []; /** * The callback to execute upon total connection failure. - * - * @var Closure */ - protected $failed; + protected Closure $failed; /** * The authentication guard resolver. - * - * @var Closure */ - protected $authGuardResolver; + protected Closure $authGuardResolver; /** * Whether the connection is retrying the initial connection attempt. - * - * @var bool */ - protected $retryingInitialConnection = false; + protected bool $retryingInitialConnection = false; /** * Constructor. * - * @param array|DomainConfiguration $config - * @param LdapInterface|null $ldap + * @throws ConfigurationException */ - public function __construct($config = [], LdapInterface $ldap = null) + public function __construct(DomainConfiguration|array $config = [], ?LdapInterface $ldap = null) { $this->setConfiguration($config); - $this->setLdapConnection($ldap ?? new Ldap()); + $this->setLdapConnection($ldap ?? new Ldap); $this->failed = function () { $this->dispatch(new Events\ConnectionFailed($this)); @@ -109,12 +89,9 @@ class Connection /** * Set the connection configuration. * - * @param array|DomainConfiguration $config - * @return $this - * * @throws Configuration\ConfigurationException */ - public function setConfiguration($config = []) + public function setConfiguration(DomainConfiguration|array $config = []): void { if (! $config instanceof DomainConfiguration) { $config = new DomainConfiguration($config); @@ -125,54 +102,50 @@ class Connection $this->hosts = $this->configuration->get('hosts'); $this->host = reset($this->hosts); - - return $this; } /** * Set the LDAP connection. - * - * @param LdapInterface $ldap - * @return $this */ - public function setLdapConnection(LdapInterface $ldap) + public function setLdapConnection(LdapInterface $ldap): void { $this->ldap = $ldap; - - return $this; } /** * Set the event dispatcher. - * - * @param DispatcherInterface $dispatcher - * @return $this */ - public function setDispatcher(DispatcherInterface $dispatcher) + public function setDispatcher(DispatcherInterface $dispatcher): void { $this->dispatcher = $dispatcher; - - return $this; } /** - * Initializes the LDAP connection. - * - * @return void + * Get the event dispatcher. */ - public function initialize() + public function getDispatcher(): ?DispatcherInterface + { + return $this->dispatcher; + } + + /** + * Initialize the LDAP connection. + */ + public function initialize(): void { $this->configure(); - $this->ldap->connect($this->host, $this->configuration->get('port')); + $this->ldap->connect( + $this->host, + $this->configuration->get('port'), + $this->configuration->get('protocol') + ); } /** * Configure the LDAP connection. - * - * @return void */ - protected function configure() + protected function configure(): void { if ($this->configuration->get('use_ssl')) { $this->ldap->ssl(); @@ -192,60 +165,53 @@ class Connection /** * Set the cache store. - * - * @param CacheInterface $store - * @return $this */ - public function setCache(CacheInterface $store) + public function setCache(CacheInterface $store): void { $this->cache = new Cache($store); - - return $this; } /** * Get the cache store. - * - * @return Cache|null */ - public function getCache() + public function getCache(): ?Cache { return $this->cache; } /** * Get the LDAP configuration instance. - * - * @return DomainConfiguration */ - public function getConfiguration() + public function getConfiguration(): DomainConfiguration { return $this->configuration; } /** * Get the LDAP connection instance. - * - * @return Ldap */ - public function getLdapConnection() + public function getLdapConnection(): LdapInterface { return $this->ldap; } + /** + * Set the auth guard resolver callback. + */ + public function setGuardResolver(Closure $callback): void + { + $this->authGuardResolver = $callback; + } + /** * Bind to the LDAP server. * * If no username or password is specified, then the configured credentials are used. * - * @param string|null $username - * @param string|null $password - * @return Connection - * * @throws Auth\BindException * @throws LdapRecordException */ - public function connect($username = null, $password = null) + public function connect(?string $username = null, ?string $password = null): void { $attempt = function () use ($username, $password) { $this->dispatch(new Events\Connecting($this)); @@ -266,19 +232,16 @@ class Connection $this->retryOnNextHost($e, $attempt); } - - return $this; } /** * Reconnect to the LDAP server. * - * @return void - * * @throws Auth\BindException * @throws ConnectionException + * @throws LdapRecordException */ - public function reconnect() + public function reconnect(): void { $this->reinitialize(); @@ -287,10 +250,8 @@ class Connection /** * Reinitialize the connection. - * - * @return void */ - protected function reinitialize() + protected function reinitialize(): void { $this->disconnect(); @@ -299,31 +260,24 @@ class Connection /** * Clone the connection. - * - * @return static */ - public function replicate() + public function replicate(): static { return new static($this->configuration, new $this->ldap); } /** * Disconnect from the LDAP server. - * - * @return void */ - public function disconnect() + public function disconnect(): void { $this->ldap->close(); } /** * Dispatch an event. - * - * @param object $event - * @return void */ - public function dispatch($event) + public function dispatch(object $event): void { if (isset($this->dispatcher)) { $this->dispatcher->dispatch($event); @@ -332,25 +286,20 @@ class Connection /** * Get the attempted hosts that failed connecting to. - * - * @return array */ - public function attempted() + public function attempted(): array { return $this->attempted; } /** * Perform the operation on the LDAP connection. - * - * @param Closure $operation - * @return mixed */ - public function run(Closure $operation) + public function run(Closure $operation): mixed { try { // Before running the operation, we will check if the current - // connection is bound and connect if necessary. Otherwise + // connection is bound and connect if necessary. Otherwise, // some LDAP operations will not be executed properly. if (! $this->isConnected()) { $this->connect(); @@ -368,11 +317,8 @@ class Connection /** * Perform the operation on an isolated LDAP connection. - * - * @param Closure $operation - * @return mixed */ - public function isolate(Closure $operation) + public function isolate(Closure $operation): mixed { $connection = $this->replicate(); @@ -385,11 +331,8 @@ class Connection /** * Attempt to get an exception for the cause of failure. - * - * @param LdapRecordException $e - * @return mixed */ - protected function getExceptionForCauseOfFailure(LdapRecordException $e) + protected function getExceptionForCauseOfFailure(LdapRecordException $e): ?LdapRecordException { switch (true) { case $this->errorContainsMessage($e->getMessage(), 'Already exists'): @@ -399,29 +342,22 @@ class Connection case $this->errorContainsMessage($e->getMessage(), 'Constraint violation'): return Exceptions\ConstraintViolationException::withDetailedError($e, $e->getDetailedError()); default: - return; + return null; } } /** * Run the operation callback on the current LDAP connection. - * - * @param Closure $operation - * @return mixed - * - * @throws LdapRecordException */ - protected function runOperationCallback(Closure $operation) + protected function runOperationCallback(Closure $operation): mixed { return $operation($this->ldap); } /** * Get a new auth guard instance. - * - * @return Auth\Guard */ - public function auth() + public function auth(): Guard { if (! $this->ldap->isConnected()) { $this->initialize(); @@ -430,7 +366,7 @@ class Connection $guard = call_user_func($this->authGuardResolver); $guard->setDispatcher( - Container::getInstance()->getEventDispatcher() + Container::getInstance()->getDispatcher() ); return $guard; @@ -438,10 +374,8 @@ class Connection /** * Get a new query builder for the connection. - * - * @return Query\Builder */ - public function query() + public function query(): Builder { return (new Builder($this)) ->setCache($this->cache) @@ -450,10 +384,8 @@ class Connection /** * Determine if the LDAP connection is bound. - * - * @return bool */ - public function isConnected() + public function isConnected(): bool { return $this->ldap->isBound(); } @@ -461,13 +393,9 @@ class Connection /** * Attempt to retry an LDAP operation if due to a lost connection. * - * @param LdapRecordException $e - * @param Closure $operation - * @return mixed - * * @throws LdapRecordException */ - protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation) + protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation): mixed { // If the operation failed due to a lost or failed connection, // we'll attempt reconnecting and running the operation again @@ -482,12 +410,9 @@ class Connection /** * Retry the operation on the current host. * - * @param Closure $operation - * @return mixed - * * @throws LdapRecordException */ - protected function retry(Closure $operation) + protected function retry(Closure $operation): mixed { try { $this->retryingInitialConnection @@ -503,13 +428,9 @@ class Connection /** * Attempt the operation again on the next host. * - * @param LdapRecordException $e - * @param Closure $operation - * @return mixed - * * @throws LdapRecordException */ - protected function retryOnNextHost(LdapRecordException $e, Closure $operation) + protected function retryOnNextHost(LdapRecordException $e, Closure $operation): mixed { $this->attempted[$this->host] = Carbon::now(); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php index 0597f1f68..8bef8d150 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php @@ -2,7 +2,6 @@ namespace LdapRecord; -use BadMethodCallException; use LdapRecord\Events\Dispatcher; use LdapRecord\Events\DispatcherInterface; use LdapRecord\Events\Logger; @@ -10,148 +9,83 @@ use Psr\Log\LoggerInterface; class ConnectionManager { - /** - * The logger instance. - * - * @var LoggerInterface|null - */ - protected $logger; - - /** - * The event dispatcher instance. - * - * @var DispatcherInterface|null - */ - protected $dispatcher; - /** * The added LDAP connections. * * @var Connection[] */ - protected $connections = []; + protected array $connections = []; /** * The name of the default connection. - * - * @var string */ - protected $default = 'default'; + protected string $default = 'default'; /** * The events to register listeners for during initialization. - * - * @var array */ - protected $listen = [ + protected array $listen = [ 'LdapRecord\Auth\Events\*', 'LdapRecord\Query\Events\*', 'LdapRecord\Models\Events\*', ]; /** - * The method calls to proxy for compatibility. - * - * To be removed in the next major version. - * - * @var array + * The logger instance. */ - protected $proxy = [ - 'reset' => 'flush', - 'addConnection' => 'add', - 'getConnection' => 'get', - 'allConnections' => 'all', - 'removeConnection' => 'remove', - 'getDefaultConnection' => 'getDefault', - 'setDefaultConnection' => 'setDefault', - 'getEventDispatcher' => 'dispatcher', - 'setEventDispatcher' => 'setDispatcher', - ]; + protected ?LoggerInterface $logger = null; + + /** + * The event dispatcher instance. + */ + protected ?DispatcherInterface $dispatcher = null; /** * Constructor. - * - * @return void */ - public function __construct() + public function __construct($dispatcher = new Dispatcher) { - $this->dispatcher = new Dispatcher(); - } - - /** - * Forward missing method calls onto the instance. - * - * @param string $method - * @param mixed $args - * @return mixed - */ - public function __call($method, $args) - { - $method = $this->proxy[$method] ?? $method; - - if (! method_exists($this, $method)) { - throw new BadMethodCallException(sprintf( - 'Call to undefined method %s::%s()', - static::class, - $method - )); - } - - return $this->{$method}(...$args); + $this->dispatcher = $dispatcher; } /** * Add a new connection. - * - * @param Connection $connection - * @param string|null $name - * @return $this */ - public function add(Connection $connection, $name = null) + public function addConnection(Connection $connection, ?string $name = null): void { $this->connections[$name ?? $this->default] = $connection; if ($this->dispatcher) { $connection->setDispatcher($this->dispatcher); } - - return $this; } /** - * Remove a connection. - * - * @param $name - * @return $this + * Remove a connection by its name. */ - public function remove($name) + public function removeConnection(string $name): void { unset($this->connections[$name]); - - return $this; } /** - * Get all of the connections. + * Get all the registered connections. * * @return Connection[] */ - public function all() + public function getConnections(): array { return $this->connections; } /** - * Get a connection by name or return the default. - * - * @param string|null $name - * @return Connection + * Get a connection by its name or return the default. * * @throws ContainerException If the given connection does not exist. */ - public function get($name = null) + public function getConnection(?string $name = null): Connection { - if ($this->exists($name = $name ?? $this->default)) { + if ($this->hasConnection($name = $name ?? $this->default)) { return $this->connections[$name]; } @@ -159,82 +93,61 @@ class ConnectionManager } /** - * Return the default connection. - * - * @return Connection + * Get the default connection. */ - public function getDefault() + public function getDefaultConnection(): Connection { - return $this->get($this->default); + return $this->getConnection($this->default); + } + + /** + * Set the default connection by its name. + */ + public function setDefaultConnection(string $name): void + { + $this->default = $name; } /** * Get the default connection name. - * - * @return string */ - public function getDefaultConnectionName() + public function getDefaultConnectionName(): string { return $this->default; } /** - * Checks if the connection exists. - * - * @param string $name - * @return bool + * Determine if a connection exists. */ - public function exists($name) + public function hasConnection(string $name): bool { return array_key_exists($name, $this->connections); } - /** - * Set the default connection name. - * - * @param string $name - * @return $this - */ - public function setDefault($name = null) - { - $this->default = $name; - - return $this; - } - /** * Flush the manager of all instances and connections. - * - * @return $this */ - public function flush() + public function flush(): void { $this->logger = null; $this->connections = []; - $this->dispatcher = new Dispatcher(); - - return $this; + $this->dispatcher->forgetAll(); } /** * Get the logger instance. - * - * @return LoggerInterface|null */ - public function getLogger() + public function getLogger(): ?LoggerInterface { return $this->logger; } /** * Set the event logger to use. - * - * @param LoggerInterface $logger - * @return void */ - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { $this->logger = $logger; @@ -243,10 +156,8 @@ class ConnectionManager /** * Initialize the event logger. - * - * @return void */ - public function initEventLogger() + protected function initEventLogger(): void { $logger = $this->newEventLogger(); @@ -261,51 +172,40 @@ class ConnectionManager /** * Make a new event logger instance. - * - * @return Logger */ - protected function newEventLogger() + protected function newEventLogger(): Logger { return new Logger($this->logger); } /** * Unset the logger instance. - * - * @return void */ - public function unsetLogger() + public function unsetLogger(): void { $this->logger = null; } /** * Get the event dispatcher. - * - * @return DispatcherInterface|null */ - public function dispatcher() + public function getDispatcher(): ?DispatcherInterface { return $this->dispatcher; } /** * Set the event dispatcher. - * - * @param DispatcherInterface $dispatcher - * @return void */ - public function setDispatcher(DispatcherInterface $dispatcher) + public function setDispatcher(DispatcherInterface $dispatcher): void { $this->dispatcher = $dispatcher; } /** * Unset the event dispatcher. - * - * @return void */ - public function unsetEventDispatcher() + public function unsetDispatcher(): void { $this->dispatcher = null; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php index 0c125593d..5a3bd7f4c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php @@ -2,122 +2,79 @@ namespace LdapRecord; -/** - * @method static $this reset() - * @method static Connection[] all() - * @method static Connection[] allConnections() - * @method static Connection getDefaultConnection() - * @method static Connection get(string|null $name = null) - * @method static Connection getConnection(string|null $name = null) - * @method static bool exists(string $name) - * @method static $this remove(string|null $name = null) - * @method static $this removeConnection(string|null $name = null) - * @method static $this setDefault(string|null $name = null) - * @method static $this setDefaultConnection(string|null $name = null) - * @method static $this add(Connection $connection, string|null $name = null) - * @method static $this addConnection(Connection $connection, string|null $name = null) - */ +/** @mixin ConnectionManager */ class Container { /** * The current container instance. - * - * @var Container */ - protected static $instance; + protected static Container $instance; /** * The connection manager instance. - * - * @var ConnectionManager */ - protected $manager; - - /** - * The methods to passthru, for compatibility. - * - * @var array - */ - protected $passthru = [ - 'reset', 'flush', - 'add', 'addConnection', - 'remove', 'removeConnection', - 'setDefault', 'setDefaultConnection', - ]; - - /** - * Forward missing static calls onto the current instance. - * - * @param string $method - * @param mixed $args - * @return mixed - */ - public static function __callStatic($method, $args) - { - return static::getInstance()->{$method}(...$args); - } + protected ConnectionManager $manager; /** * Get or set the current instance of the container. - * - * @return Container */ - public static function getInstance() + public static function getInstance(): static { return static::$instance ?? static::getNewInstance(); } /** * Set the container instance. - * - * @param Container|null $container - * @return Container|null */ - public static function setInstance(self $container = null) + public static function setInstance(?self $container = null): ?static { return static::$instance = $container; } /** * Set and get a new instance of the container. - * - * @return Container */ - public static function getNewInstance() + public static function getNewInstance(): static { - return static::setInstance(new static()); + return static::setInstance(new static); + } + + /** + * Forward missing static calls onto the current instance. + */ + public static function __callStatic(string $method, array $parameters): mixed + { + return static::getInstance()->{$method}(...$parameters); } /** * Constructor. - * - * @return void */ - public function __construct() + public function __construct(ConnectionManager $manager = new ConnectionManager) { - $this->manager = new ConnectionManager(); + $this->manager = $manager; } /** * Forward missing method calls onto the connection manager. - * - * @param string $method - * @param mixed $args - * @return mixed */ - public function __call($method, $args) + public function __call(string $method, array $parameters): mixed { - $value = $this->manager->{$method}(...$args); + return $this->manager->{$method}(...$parameters); + } - return in_array($method, $this->passthru) ? $this : $value; + /** + * Set the current container instance available globally. + */ + public function setAsGlobal(): void + { + static::setInstance($this); } /** * Get the connection manager. - * - * @return ConnectionManager */ - public function manager() + public function getConnectionManager(): ConnectionManager { return $this->manager; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php index fff528c98..e9d9609dc 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php @@ -4,67 +4,35 @@ namespace LdapRecord; class DetailedError { - /** - * The error code from ldap_errno. - * - * @var int|null - */ - protected $errorCode; - - /** - * The error message from ldap_error. - * - * @var string|null - */ - protected $errorMessage; - - /** - * The diagnostic message when retrieved after an ldap_error. - * - * @var string|null - */ - protected $diagnosticMessage; - /** * Constructor. - * - * @param int $errorCode - * @param string $errorMessage - * @param string $diagnosticMessage */ - public function __construct($errorCode, $errorMessage, $diagnosticMessage) - { - $this->errorCode = $errorCode; - $this->errorMessage = $errorMessage; - $this->diagnosticMessage = $diagnosticMessage; - } + public function __construct( + protected int $errorCode, + protected string $errorMessage, + protected ?string $diagnosticMessage + ) {} /** - * Returns the LDAP error code. - * - * @return int + * Get the LDAP error code. */ - public function getErrorCode() + public function getErrorCode(): int { return $this->errorCode; } /** - * Returns the LDAP error message. - * - * @return string + * Get the LDAP error message. */ - public function getErrorMessage() + public function getErrorMessage(): string { return $this->errorMessage; } /** - * Returns the LDAP diagnostic message. - * - * @return string + * Get the LDAP diagnostic message. */ - public function getDiagnosticMessage() + public function getDiagnosticMessage(): ?string { return $this->diagnosticMessage; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php index 61fc4a02e..bb6f675f0 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php @@ -6,59 +6,43 @@ trait DetectsErrors { /** * Determine if the error was caused by a lost connection. - * - * @param string $error - * @return bool */ - protected function causedByLostConnection($error) + protected function causedByLostConnection(string $error): bool { return $this->errorContainsMessage($error, ["Can't contact LDAP server", 'Operations error']); } /** * Determine if the error was caused by lack of pagination support. - * - * @param string $error - * @return bool */ - protected function causedByPaginationSupport($error) + protected function causedByPaginationSupport(string $error): bool { return $this->errorContainsMessage($error, 'No server controls in result'); } /** * Determine if the error was caused by a size limit warning. - * - * @param $error - * @return bool */ - protected function causedBySizeLimit($error) + protected function causedBySizeLimit(string $error): bool { return $this->errorContainsMessage($error, ['Partial search results returned', 'Size limit exceeded']); } /** * Determine if the error was caused by a "No such object" warning. - * - * @param string $error - * @return bool */ - protected function causedByNoSuchObject($error) + protected function causedByNoSuchObject(string $error): bool { return $this->errorContainsMessage($error, ['No such object']); } /** - * Determine if the error contains the any of the messages. - * - * @param string $error - * @param string|array $messages - * @return bool + * Determine if the error contains any of the messages. */ - protected function errorContainsMessage($error, $messages = []) + protected function errorContainsMessage(string $error, string|array $messages = []): bool { foreach ((array) $messages as $message) { - if (str_contains((string) $error, $message)) { + if (str_contains($error, $message)) { return true; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php index ea53a2f93..088b50013 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php @@ -8,13 +8,8 @@ trait EscapesValues { /** * Prepare a value to be escaped. - * - * @param string $value - * @param string $ignore - * @param int $flags - * @return EscapedValue */ - public function escape($value, $ignore = '', $flags = 0) + public function escape(mixed $value = null, string $ignore = '', int $flags = 0): EscapedValue { return new EscapedValue($value, $ignore, $flags); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php index d2d77e2fc..99a6e6f1c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php @@ -8,15 +8,11 @@ abstract class ConnectionEvent { /** * The LDAP connection. - * - * @var Connection */ - protected $connection; + protected Connection $connection; /** * Constructor. - * - * @param Connection $connection */ public function __construct(Connection $connection) { @@ -25,10 +21,8 @@ abstract class ConnectionEvent /** * Get the connection pertaining to the event. - * - * @return Connection */ - public function getConnection() + public function getConnection(): Connection { return $this->connection; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php index 4fedbc2ef..304e15ccd 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php @@ -2,7 +2,9 @@ namespace LdapRecord\Events; +use Closure; use LdapRecord\Support\Arr; +use LdapRecord\Support\Str; /** * Class Dispatcher. @@ -21,29 +23,23 @@ class Dispatcher implements DispatcherInterface { /** * The registered event listeners. - * - * @var array */ - protected $listeners = []; + protected array $listeners = []; /** * The wildcard listeners. - * - * @var array */ - protected $wildcards = []; + protected array $wildcards = []; /** * The cached wildcard listeners. - * - * @var array */ - protected $wildcardsCache = []; + protected array $wildcardsCache = []; /** - * @inheritdoc + * {@inheritdoc} */ - public function listen($events, $listener) + public function listen(string|array $events, mixed $listener): void { foreach ((array) $events as $event) { if (str_contains((string) $event, '*')) { @@ -56,12 +52,8 @@ class Dispatcher implements DispatcherInterface /** * Setup a wildcard listener callback. - * - * @param string $event - * @param mixed $listener - * @return void */ - protected function setupWildcardListen($event, $listener) + protected function setupWildcardListen(string $event, mixed $listener): void { $this->wildcards[$event][] = $this->makeListener($listener, true); @@ -69,33 +61,33 @@ class Dispatcher implements DispatcherInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function hasListeners($eventName) + public function hasListeners(string $event): bool { - return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]); + return isset($this->listeners[$event]) || isset($this->wildcards[$event]); } /** - * @inheritdoc + * {@inheritdoc} */ - public function until($event, $payload = []) + public function until(string|object $event, mixed $payload = []): mixed { return $this->dispatch($event, $payload, true); } /** - * @inheritdoc + * {@inheritdoc} */ - public function fire($event, $payload = [], $halt = false) + public function fire(string|object $event, mixed $payload = [], bool $halt = false): void { - return $this->dispatch($event, $payload, $halt); + $this->dispatch($event, $payload, $halt); } /** - * @inheritdoc + * {@inheritdoc} */ - public function dispatch($event, $payload = [], $halt = false) + public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed { // When the given "event" is actually an object we will assume it is an event // object and use the class as the event name and this event itself as the @@ -132,12 +124,8 @@ class Dispatcher implements DispatcherInterface /** * Parse the given event and payload and prepare them for dispatching. - * - * @param mixed $event - * @param mixed $payload - * @return array */ - protected function parseEventAndPayload($event, $payload) + protected function parseEventAndPayload(string|object $event, mixed $payload): array { if (is_object($event)) { [$payload, $event] = [[$event], get_class($event)]; @@ -147,89 +135,42 @@ class Dispatcher implements DispatcherInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function getListeners($eventName) + public function getListeners(string $event): array { - $listeners = $this->listeners[$eventName] ?? []; + $listeners = $this->listeners[$event] ?? []; $listeners = array_merge( $listeners, - $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName) + $this->wildcardsCache[$event] ?? $this->getWildcardListeners($event) ); - return class_exists($eventName, false) - ? $this->addInterfaceListeners($eventName, $listeners) + return class_exists($event, false) + ? $this->addInterfaceListeners($event, $listeners) : $listeners; } /** * Get the wildcard listeners for the event. - * - * @param string $eventName - * @return array */ - protected function getWildcardListeners($eventName) + protected function getWildcardListeners(string $event): array { $wildcards = []; foreach ($this->wildcards as $key => $listeners) { - if ($this->wildcardContainsEvent($key, $eventName)) { + if (Str::is($key, $event)) { $wildcards = array_merge($wildcards, $listeners); } } - return $this->wildcardsCache[$eventName] = $wildcards; - } - - /** - * Determine if the wildcard matches or contains the given event. - * - * This function is a direct excerpt from Laravel's Str::is(). - * - * @param string $wildcard - * @param string $eventName - * @return bool - */ - protected function wildcardContainsEvent($wildcard, $eventName) - { - $patterns = Arr::wrap($wildcard); - - if (empty($patterns)) { - return false; - } - - foreach ($patterns as $pattern) { - // If the given event is an exact match we can of course return true right - // from the beginning. Otherwise, we will translate asterisks and do an - // actual pattern match against the two strings to see if they match. - if ($pattern == $eventName) { - return true; - } - - $pattern = preg_quote($pattern, '#'); - - // Asterisks are translated into zero-or-more regular expression wildcards - // to make it convenient to check if the strings starts with the given - // pattern such as "library/*", making any string check convenient. - $pattern = str_replace('\*', '.*', $pattern); - - if (preg_match('#^'.$pattern.'\z#u', $eventName) === 1) { - return true; - } - } - - return false; + return $this->wildcardsCache[$event] = $wildcards; } /** * Add the listeners for the event's interfaces to the given array. - * - * @param string $eventName - * @param array $listeners - * @return array */ - protected function addInterfaceListeners($eventName, array $listeners = []) + protected function addInterfaceListeners(string $eventName, array $listeners = []): array { foreach (class_implements($eventName) as $interface) { if (isset($this->listeners[$interface])) { @@ -244,12 +185,8 @@ class Dispatcher implements DispatcherInterface /** * Register an event listener with the dispatcher. - * - * @param \Closure|string $listener - * @param bool $wildcard - * @return \Closure */ - public function makeListener($listener, $wildcard = false) + public function makeListener(Closure|string $listener, bool $wildcard = false): Closure { if (is_string($listener)) { return $this->createClassListener($listener, $wildcard); @@ -266,12 +203,8 @@ class Dispatcher implements DispatcherInterface /** * Create a class based listener. - * - * @param string $listener - * @param bool $wildcard - * @return \Closure */ - protected function createClassListener($listener, $wildcard = false) + protected function createClassListener(string $listener, bool $wildcard = false): Closure { return function ($event, $payload) use ($listener, $wildcard) { if ($wildcard) { @@ -287,39 +220,53 @@ class Dispatcher implements DispatcherInterface /** * Create the class based event callable. - * - * @param string $listener - * @return callable */ - protected function createClassCallable($listener) + protected function createClassCallable(string $listener): callable { [$class, $method] = $this->parseListenerCallback($listener); - return [new $class(), $method]; + return [new $class, $method]; } /** * Parse the class listener into class and method. - * - * @param string $listener - * @return array */ - protected function parseListenerCallback($listener) + protected function parseListenerCallback(string $listener): array { - return str_contains((string) $listener, '@') + return str_contains($listener, '@') ? explode('@', $listener, 2) : [$listener, 'handle']; } /** - * @inheritdoc + * {@inheritdoc} */ - public function forget($event) + public function forget(string $event): void { - if (str_contains((string) $event, '*')) { + if (str_contains($event, '*')) { unset($this->wildcards[$event]); } else { unset($this->listeners[$event]); } + + foreach ($this->wildcardsCache as $key => $listeners) { + if (Str::is($event, $key)) { + unset($this->wildcardsCache[$key]); + } + } + } + + /** + * Remove all the listeners from the dispatcher. + */ + public function forgetAll(): void + { + $listeners = array_merge( + $this->listeners, $this->wildcards + ); + + foreach (array_keys($listeners) as $listener) { + $this->forget($listener); + } } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php index 590328f09..71de892c0 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php @@ -6,63 +6,41 @@ interface DispatcherInterface { /** * Register an event listener with the dispatcher. - * - * @param string|array $events - * @param mixed $listener - * @return void */ - public function listen($events, $listener); + public function listen(string|array $events, mixed $listener): void; /** * Determine if a given event has listeners. - * - * @param string $eventName - * @return bool */ - public function hasListeners($eventName); + public function hasListeners(string $event): bool; /** * Fire an event until the first non-null response is returned. - * - * @param string|object $event - * @param mixed $payload - * @return array|null */ - public function until($event, $payload = []); + public function until(string|object $event, mixed $payload = []): mixed; /** * Fire an event and call the listeners. - * - * @param string|object $event - * @param mixed $payload - * @param bool $halt - * @return mixed */ - public function fire($event, $payload = [], $halt = false); + public function fire(string|object $event, mixed $payload = [], bool $halt = false): void; /** * Fire an event and call the listeners. - * - * @param string|object $event - * @param mixed $payload - * @param bool $halt - * @return array|null */ - public function dispatch($event, $payload = [], $halt = false); + public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed; /** - * Get all of the listeners for a given event name. - * - * @param string $eventName - * @return array + * Get all the listeners for a given event name. */ - public function getListeners($eventName); + public function getListeners(string $event): array; /** * Remove a set of listeners from the dispatcher. - * - * @param string $event - * @return void */ - public function forget($event); + public function forget(string $event): void; + + /** + * Remove all the listeners from the dispatcher. + */ + public function forgetAll(): void; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php index b8a849169..5ac66f278 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php @@ -13,28 +13,21 @@ class Logger { /** * The logger instance. - * - * @var LoggerInterface|null */ - protected $logger; + protected ?LoggerInterface $logger; /** * Constructor. - * - * @param LoggerInterface|null $logger */ - public function __construct(LoggerInterface $logger = null) + public function __construct(?LoggerInterface $logger = null) { $this->logger = $logger; } /** * Logs the given event. - * - * @param mixed $event - * @return void */ - public function log($event) + public function log($event): void { switch (true) { case $event instanceof AuthEvent: @@ -51,11 +44,8 @@ class Logger /** * Logs an authentication event. - * - * @param AuthEvent $event - * @return void */ - public function auth(AuthEvent $event) + public function auth(AuthEvent $event): void { if (isset($this->logger)) { $connection = $event->getConnection(); @@ -78,11 +68,8 @@ class Logger /** * Logs a model event. - * - * @param ModelEvent $event - * @return void */ - public function model(ModelEvent $event) + public function model(ModelEvent $event): void { if (isset($this->logger)) { $model = $event->getModel(); @@ -102,11 +89,8 @@ class Logger /** * Logs a query event. - * - * @param QueryEvent $event - * @return void */ - public function query(QueryEvent $event) + public function query(QueryEvent $event): void { if (isset($this->logger)) { $query = $event->getQuery(); @@ -127,12 +111,9 @@ class Logger } /** - * Returns the operational name of the given event. - * - * @param mixed $event - * @return string + * Get the operational name of the given event. */ - protected function getOperationName($event) + protected function getOperationName($event): string { return (new ReflectionClass($event))->getShortName(); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php index 7683d1f80..31f95cb77 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php @@ -6,15 +6,11 @@ class NullDispatcher implements DispatcherInterface { /** * The underlying dispatcher instance. - * - * @var DispatcherInterface */ - protected $dispatcher; + protected DispatcherInterface $dispatcher; /** * Constructor. - * - * @param DispatcherInterface $dispatcher */ public function __construct(DispatcherInterface $dispatcher) { @@ -23,84 +19,62 @@ class NullDispatcher implements DispatcherInterface /** * Register an event listener with the dispatcher. - * - * @param string|array $events - * @param mixed $listener - * @return void */ - public function listen($events, $listener) + public function listen(string|array $events, mixed $listener): void { $this->dispatcher->listen($events, $listener); } /** * Determine if a given event has listeners. - * - * @param string $eventName - * @return bool */ - public function hasListeners($eventName) + public function hasListeners(string $event): bool { - return $this->dispatcher->hasListeners($eventName); + return $this->dispatcher->hasListeners($event); } /** * Fire an event until the first non-null response is returned. - * - * @param string|object $event - * @param mixed $payload - * @return null */ - public function until($event, $payload = []) + public function until(string|object $event, mixed $payload = []): ?array { return null; } /** * Fire an event and call the listeners. - * - * @param string|object $event - * @param mixed $payload - * @param bool $halt - * @return null */ - public function fire($event, $payload = [], $halt = false) - { - return null; - } + public function fire(string|object $event, mixed $payload = [], bool $halt = false): void {} /** * Fire an event and call the listeners. - * - * @param string|object $event - * @param mixed $payload - * @param bool $halt - * @return null */ - public function dispatch($event, $payload = [], $halt = false) + public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed { return null; } /** - * Get all of the listeners for a given event name. - * - * @param string $eventName - * @return array + * Get all the listeners for a given event name. */ - public function getListeners($eventName) + public function getListeners(string $event): array { - return $this->dispatcher->getListeners($eventName); + return $this->dispatcher->getListeners($event); } /** * Remove a set of listeners from the dispatcher. - * - * @param string $event - * @return void */ - public function forget($event) + public function forget(string $event): void { $this->dispatcher->forget($event); } + + /** + * Remove all the listeners from the dispatcher. + */ + public function forgetAll(): void + { + $this->dispatcher->forgetAll(); + } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php index 641843a9b..b5d30a739 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php @@ -11,25 +11,17 @@ class ConstraintViolationException extends LdapRecordException /** * Determine if the exception was generated due to the password policy. - * - * @return bool */ - public function causedByPasswordPolicy() + public function causedByPasswordPolicy(): bool { - return isset($this->detailedError) - ? $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '0000052D') - : false; + return isset($this->detailedError) && $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '0000052D'); } /** * Determine if the exception was generated due to an incorrect password. - * - * @return bool */ - public function causedByIncorrectPassword() + public function causedByIncorrectPassword(): bool { - return isset($this->detailedError) - ? $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '00000056') - : false; + return isset($this->detailedError) && $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '00000056'); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php index 4a2e27598..e47904d8b 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php @@ -5,88 +5,100 @@ namespace LdapRecord; use Closure; use ErrorException; use Exception; +use LDAP\Connection; +/** @mixin Ldap */ trait HandlesConnection { /** * The LDAP host that is currently connected. - * - * @var string|null */ - protected $host; + protected ?string $host = null; + + /** + * The LDAP protocol to use (ldap:// or ldaps://). + */ + protected ?string $protocol = null; /** * The LDAP connection resource. * - * @var resource|null + * @var Connection */ - protected $connection; + protected mixed $connection = null; /** - * The bound status of the connection. - * - * @var bool + * Whether the connection is bound. */ - protected $bound = false; + protected bool $bound = false; + + /** + * Whether the connection is secured over TLS or SSL. + */ + protected bool $secure = false; /** * Whether the connection must be bound over SSL. - * - * @var bool */ - protected $useSSL = false; + protected bool $useSSL = false; /** * Whether the connection must be bound over TLS. - * - * @var bool */ - protected $useTLS = false; + protected bool $useTLS = false; /** - * @inheritdoc + * {@inheritdoc} */ - public function isUsingSSL() + public function isUsingSSL(): bool { return $this->useSSL; } /** - * @inheritdoc + * {@inheritdoc} */ - public function isUsingTLS() + public function isUsingTLS(): bool { return $this->useTLS; } /** - * @inheritdoc + * {@inheritdoc} */ - public function isBound() + public function isBound(): bool { return $this->bound; } /** - * @inheritdoc + * {@inheritdoc} */ - public function isConnected() + public function isSecure(): bool + { + return $this->secure; + } + + /** + * {@inheritdoc} + */ + public function isConnected(): bool { return ! is_null($this->connection); } /** - * @inheritdoc + * {@inheritdoc} */ - public function canChangePasswords() + public function canChangePasswords(): bool { return $this->isUsingSSL() || $this->isUsingTLS(); } /** - * @inheritdoc + * {@inheritdoc} */ - public function ssl($enabled = true) + public function ssl(bool $enabled = true): static { $this->useSSL = $enabled; @@ -94,9 +106,9 @@ trait HandlesConnection } /** - * @inheritdoc + * {@inheritdoc} */ - public function tls($enabled = true) + public function tls(bool $enabled = true): static { $this->useTLS = $enabled; @@ -104,9 +116,9 @@ trait HandlesConnection } /** - * @inheritdoc + * {@inheritdoc} */ - public function setOptions(array $options = []) + public function setOptions(array $options = []): void { foreach ($options as $option => $value) { $this->setOption($option, $value); @@ -114,46 +126,57 @@ trait HandlesConnection } /** - * @inheritdoc + * {@inheritdoc} */ - public function getHost() + public function getHost(): ?string { return $this->host; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getConnection() + public function getConnection(): ?Connection { return $this->connection; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getProtocol() + public function getProtocol(): string { - return $this->isUsingSSL() ? LdapInterface::PROTOCOL_SSL : LdapInterface::PROTOCOL; + return $this->protocol ?: ( + $this->isUsingSSL() + ? LdapInterface::PROTOCOL_SSL + : LdapInterface::PROTOCOL + ); } /** - * @inheritdoc + * {@inheritdoc} */ - public function getExtendedError() + public function getExtendedError(): ?string { return $this->getDiagnosticMessage(); } + /** + * Handle the bind response. + */ + protected function handleBindResponse(LdapResultResponse $response): void + { + $this->bound = $response->successful(); + + $this->secure = $this->secure ?: $this->bound && $this->isUsingSSL(); + } + /** * Convert warnings to exceptions for the given operation. * - * @param Closure $operation - * @return mixed - * * @throws LdapRecordException */ - protected function executeFailableOperation(Closure $operation) + protected function executeFailableOperation(Closure $operation): mixed { // If some older versions of PHP, errors are reported instead of throwing // exceptions, which could be a significant detriment to our application. @@ -172,8 +195,8 @@ trait HandlesConnection } // If the failed query operation was a based on a query being executed - // -- such as a search, read, or listing, then we can safely return - // the failed response here and prevent throwning an exception. + // -- such as a search, read, or list, then we can safely return + // the failed response here and prevent throwing an exception. if ($this->shouldBypassFailure($method = debug_backtrace()[1]['function'])) { return $result; } @@ -188,46 +211,24 @@ trait HandlesConnection /** * Determine if the failed operation should be bypassed. - * - * @param string $method - * @return bool */ - protected function shouldBypassFailure($method) + protected function shouldBypassFailure(string $method): bool { - return in_array($method, ['search', 'read', 'listing']); + return in_array($method, ['search', 'read', 'list']); } /** * Determine if the error should be bypassed. - * - * @param string $error - * @return bool */ - protected function shouldBypassError($error) + protected function shouldBypassError(string $error): bool { return $this->causedByPaginationSupport($error) || $this->causedBySizeLimit($error) || $this->causedByNoSuchObject($error); } - /** - * Determine if the current PHP version supports server controls. - * - * @deprecated since v2.5.0 - * - * @return bool - */ - public function supportsServerControlsInMethods() - { - return version_compare(PHP_VERSION, '7.3.0') >= 0; - } - /** * Generates an LDAP connection string for each host given. - * - * @param string|array $hosts - * @param string $port - * @return string */ - protected function makeConnectionUris($hosts, $port) + protected function makeConnectionUris(array|string $hosts, string|int $port): string { // If an attempt to connect via SSL protocol is being performed, // and we are still using the default port, we will swap it @@ -244,15 +245,9 @@ trait HandlesConnection /** * Assemble the host URI strings. - * - * @param array|string $hosts - * @param string $port - * @return array */ - protected function assembleHostUris($hosts, $port) + protected function assembleHostUris(array|string $hosts, string|int $port): array { - return array_map(function ($host) use ($port) { - return "{$this->getProtocol()}{$host}:{$port}"; - }, (array) $hosts); + return array_map(fn ($host) => "{$this->getProtocol()}{$host}:{$port}", (array) $hosts); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php index 76c372040..7f2be60b6 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php @@ -6,15 +6,16 @@ use LDAP\Connection as RawLdapConnection; class Ldap implements LdapInterface { - use HandlesConnection, DetectsErrors; + use DetectsErrors; + use HandlesConnection; /** - * @inheritdoc + * {@inheritdoc} */ - public function getEntries($searchResults) + public function getEntries(mixed $result): array { - return $this->executeFailableOperation(function () use ($searchResults) { - return ldap_get_entries($this->connection, $searchResults); + return $this->executeFailableOperation(function () use ($result) { + return ldap_get_entries($this->connection, $result); }); } @@ -23,13 +24,12 @@ class Ldap implements LdapInterface * * @see http://php.net/manual/en/function.ldap-first-entry.php * - * @param resource $searchResults - * @return resource + * @param \Ldap\Result $result */ - public function getFirstEntry($searchResults) + public function getFirstEntry(mixed $result): mixed { - return $this->executeFailableOperation(function () use ($searchResults) { - return ldap_first_entry($this->connection, $searchResults); + return $this->executeFailableOperation(function () use ($result) { + return ldap_first_entry($this->connection, $result); }); } @@ -38,10 +38,9 @@ class Ldap implements LdapInterface * * @see http://php.net/manual/en/function.ldap-next-entry.php * - * @param resource $entry - * @return resource + * @param \Ldap\ResultEntry $entry */ - public function getNextEntry($entry) + public function getNextEntry(mixed $entry): mixed { return $this->executeFailableOperation(function () use ($entry) { return ldap_next_entry($this->connection, $entry); @@ -53,10 +52,9 @@ class Ldap implements LdapInterface * * @see http://php.net/manual/en/function.ldap-get-attributes.php * - * @param resource $entry - * @return array|false + * @param \Ldap\ResultEntry $entry */ - public function getAttributes($entry) + public function getAttributes(mixed $entry): array|false { return $this->executeFailableOperation(function () use ($entry) { return ldap_get_attributes($this->connection, $entry); @@ -64,41 +62,29 @@ class Ldap implements LdapInterface } /** - * Returns the number of entries from a search result. - * - * @see http://php.net/manual/en/function.ldap-count-entries.php - * - * @param resource $searchResults - * @return int + * {@inheritDoc} */ - public function countEntries($searchResults) + public function countEntries(mixed $result): int { - return $this->executeFailableOperation(function () use ($searchResults) { - return ldap_count_entries($this->connection, $searchResults); + return $this->executeFailableOperation(function () use ($result) { + return ldap_count_entries($this->connection, $result); }); } /** - * Compare value of attribute found in entry specified with DN. - * - * @see http://php.net/manual/en/function.ldap-compare.php - * - * @param string $dn - * @param string $attribute - * @param string $value - * @return mixed + * {@inheritDoc} */ - public function compare($dn, $attribute, $value) + public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int { - return $this->executeFailableOperation(function () use ($dn, $attribute, $value) { - return ldap_compare($this->connection, $dn, $attribute, $value); + return $this->executeFailableOperation(function () use ($dn, $attribute, $value, $controls) { + return ldap_compare($this->connection, $dn, $attribute, $value, $controls); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function getLastError() + public function getLastError(): ?string { if (! $this->connection) { return null; @@ -108,9 +94,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function getDetailedError() + public function getDetailedError(): ?DetailedError { if (! $number = $this->errNo()) { return null; @@ -122,15 +108,9 @@ class Ldap implements LdapInterface } /** - * Get all binary values from the specified result entry. - * - * @see http://php.net/manual/en/function.ldap-get-values-len.php - * - * @param $entry - * @param $attribute - * @return array + * {@inheritDoc} */ - public function getValuesLen($entry, $attribute) + public function getValuesLen(mixed $entry, string $attribute): array|false { return $this->executeFailableOperation(function () use ($entry, $attribute) { return ldap_get_values_len($this->connection, $entry, $attribute); @@ -138,17 +118,17 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function setOption($option, $value) + public function setOption(int $option, mixed $value): bool { return ldap_set_option($this->connection, $option, $value); } /** - * @inheritdoc + * {@inheritdoc} */ - public function getOption($option, &$value = null) + public function getOption(int $option, mixed &$value = null): mixed { ldap_get_option($this->connection, $option, $value); @@ -159,59 +139,63 @@ class Ldap implements LdapInterface * Set a callback function to do re-binds on referral chasing. * * @see http://php.net/manual/en/function.ldap-set-rebind-proc.php - * - * @param callable $callback - * @return bool */ - public function setRebindCallback(callable $callback) + public function setRebindCallback(callable $callback): bool { return ldap_set_rebind_proc($this->connection, $callback); } /** - * @inheritdoc + * {@inheritdoc} */ - public function startTLS() + public function startTLS(): bool { - return $this->executeFailableOperation(function () { + return $this->secure = $this->executeFailableOperation(function () { return ldap_start_tls($this->connection); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function connect($hosts = [], $port = 389) + public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool { $this->bound = false; - + $this->protocol = $protocol; $this->host = $this->makeConnectionUris($hosts, $port); - return $this->connection = $this->executeFailableOperation(function () { + $this->connection = $this->executeFailableOperation(function () { return ldap_connect($this->host); }); + + return $this->connection instanceof RawLdapConnection; } /** - * @inheritdoc + * {@inheritdoc} */ - public function close() + public function close(): bool { - $result = (is_resource($this->connection) || $this->connection instanceof RawLdapConnection) - ? @ldap_close($this->connection) - : false; + $result = false; + + if ($this->connection instanceof RawLdapConnection) { + $result = @ldap_close($this->connection); + } - $this->connection = null; $this->bound = false; + $this->secure = false; + $this->host = null; + $this->protocol = null; + $this->connection = null; return $result; } /** - * @inheritdoc + * {@inheritdoc} */ - public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { return $this->executeFailableOperation(function () use ( $dn, @@ -221,18 +205,16 @@ class Ldap implements LdapInterface $size, $time, $deref, - $serverControls + $controls ) { - return empty($serverControls) - ? ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref) - : ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls); + return ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { return $this->executeFailableOperation(function () use ( $dn, @@ -242,18 +224,16 @@ class Ldap implements LdapInterface $size, $time, $deref, - $serverControls + $controls ) { - return empty($serverControls) - ? ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref) - : ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls); + return ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { return $this->executeFailableOperation(function () use ( $dn, @@ -263,47 +243,78 @@ class Ldap implements LdapInterface $size, $time, $deref, - $serverControls + $controls ) { - return empty($serverControls) - ? ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref) - : ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls); + return ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = []) + public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false { - return $this->executeFailableOperation(function () use ( - $result, - &$errorCode, - &$dn, - &$errorMessage, - &$referrals, - &$serverControls - ) { - return empty($serverControls) - ? ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals) - : ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals, $serverControls); - }); + if (ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals, $controls)) { + return new LdapResultResponse( + $errorCode, + $dn, + $errorMessage, + $referrals, + $controls + ); + } + + return false; } /** - * @inheritdoc + * {@inheritdoc} */ - public function bind($username, $password) + public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse { - return $this->bound = $this->executeFailableOperation(function () use ($username, $password) { - return ldap_bind($this->connection, $username, $password ? html_entity_decode($password) : null); + /** @var \LDAP\Result $result */ + $result = $this->executeFailableOperation(function () use ($dn, $password, $controls) { + return ldap_bind_ext($this->connection, $dn, $password ? html_entity_decode($password) : null, $controls); + }); + + $response = $this->parseResult($result); + + $this->handleBindResponse($response); + + return $response; + } + + /** + * {@inheritDoc} + */ + public function saslBind(?string $dn = null, ?string $password = null, array $options = []): bool + { + return $this->executeFailableOperation(function () use ($dn, $password, $options) { + $options = array_merge([ + 'mech' => null, + 'realm' => null, + 'authc_id' => null, + 'authz_id' => null, + 'props' => null, + ], $options); + + return $this->bound = ldap_sasl_bind( + $this->connection, + $dn, + $password ? html_entity_decode($password) : null, + $options['mech'], + $options['realm'], + $options['authc_id'], + $options['authz_id'], + $options['props'], + ); }); } /** - * @inheritdoc + * {@inheritdoc} */ - public function add($dn, array $entry) + public function add(string $dn, array $entry): bool { return $this->executeFailableOperation(function () use ($dn, $entry) { return ldap_add($this->connection, $dn, $entry); @@ -311,9 +322,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function delete($dn) + public function delete(string $dn): bool { return $this->executeFailableOperation(function () use ($dn) { return ldap_delete($this->connection, $dn); @@ -321,9 +332,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false) + public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool { return $this->executeFailableOperation(function () use ( $dn, @@ -336,9 +347,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function modify($dn, array $entry) + public function modify(string $dn, array $entry): bool { return $this->executeFailableOperation(function () use ($dn, $entry) { return ldap_modify($this->connection, $dn, $entry); @@ -346,9 +357,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function modifyBatch($dn, array $values) + public function modifyBatch(string $dn, array $values): bool { return $this->executeFailableOperation(function () use ($dn, $values) { return ldap_modify_batch($this->connection, $dn, $values); @@ -356,9 +367,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function modAdd($dn, array $entry) + public function modAdd(string $dn, array $entry): bool { return $this->executeFailableOperation(function () use ($dn, $entry) { return ldap_mod_add($this->connection, $dn, $entry); @@ -366,9 +377,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function modReplace($dn, array $entry) + public function modReplace(string $dn, array $entry): bool { return $this->executeFailableOperation(function () use ($dn, $entry) { return ldap_mod_replace($this->connection, $dn, $entry); @@ -376,9 +387,9 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function modDelete($dn, array $entry) + public function modDelete(string $dn, array $entry): bool { return $this->executeFailableOperation(function () use ($dn, $entry) { return ldap_mod_del($this->connection, $dn, $entry); @@ -386,88 +397,63 @@ class Ldap implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '') - { - return $this->executeFailableOperation(function () use ($pageSize, $isCritical, $cookie) { - return ldap_control_paged_result($this->connection, $pageSize, $isCritical, $cookie); - }); - } - - /** - * @inheritdoc - */ - public function controlPagedResultResponse($result, &$cookie, &$estimated = null) - { - return $this->executeFailableOperation(function () use ($result, &$cookie, &$estimated) { - return ldap_control_paged_result_response($this->connection, $result, $cookie, $estimated); - }); - } - - /** - * @inheritdoc - */ - public function freeResult($result) + public function freeResult(mixed $result): bool { return ldap_free_result($result); } /** - * @inheritdoc + * {@inheritdoc} */ - public function errNo() + public function errNo(): ?int { return $this->connection ? ldap_errno($this->connection) : null; } /** - * @inheritdoc + * {@inheritdoc} */ - public function err2Str($number) + public function err2Str(int $number): string { return ldap_err2str($number); } /** - * Returns the extended error hex code of the last command. - * - * @return string|null + * Get the extended error hex code of the last command. */ - public function getExtendedErrorHex() + public function getExtendedErrorHex(): ?string { if (preg_match("/(?<=data\s).*?(?=,)/", $this->getExtendedError(), $code)) { return $code[0]; } + + return null; } /** - * Returns the extended error code of the last command. - * - * @return bool|string + * Get the extended error code of the last command. */ - public function getExtendedErrorCode() + public function getExtendedErrorCode(): string|false { return $this->extractDiagnosticCode($this->getExtendedError()); } /** * Extract the diagnostic code from the message. - * - * @param string $message - * @return string|bool */ - public function extractDiagnosticCode($message) + public function extractDiagnosticCode(string $message): string|false { preg_match('/^([\da-fA-F]+):/', $message, $matches); - return isset($matches[1]) ? $matches[1] : false; + return $matches[1] ?? false; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getDiagnosticMessage() + public function getDiagnosticMessage(): ?string { $this->getOption(LDAP_OPT_ERROR_STRING, $message); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php index fcff57f48..735f858ca 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php @@ -2,15 +2,15 @@ namespace LdapRecord; +use LDAP\Connection; + +/** + * @see https://ldap.com/ldap-oid-reference-guide + * @see http://msdn.microsoft.com/en-us/library/cc223359.aspx + * @see https://help.univention.com/t/openldap-debug-level/19301 + */ interface LdapInterface { - /** - * The SSL LDAP protocol string. - * - * @var string - */ - public const PROTOCOL_SSL = 'ldaps://'; - /** * The standard LDAP protocol string. * @@ -19,136 +19,370 @@ interface LdapInterface public const PROTOCOL = 'ldap://'; /** - * The LDAP SSL port number. + * The SSL LDAP protocol string. * * @var string */ - public const PORT_SSL = 636; + public const PROTOCOL_SSL = 'ldaps://'; /** * The standard LDAP port number. * - * @var string + * @var int */ public const PORT = 389; /** - * Various useful server control OID's. + * The LDAP SSL port number. * - * @see https://ldap.com/ldap-oid-reference-guide/ - * @see http://msdn.microsoft.com/en-us/library/cc223359.aspx + * @var int + */ + public const PORT_SSL = 636; + + /** + * Print entry and exit from routines. + * + * @var int + */ + public const DEBUG_TRACE = 1; + + /** + * Print packet activity. + * + * @var int + */ + public const DEBUG_PACKETS = 2; + + /** + * Print data arguments from requests. + * + * @var int + */ + public const DEBUG_ARGS = 4; + + /** + * Print connection activity. + * + * @var int + */ + public const DEBUG_CONNS = 8; + + /** + * Print encoding and decoding of data. + * + * @var int + */ + public const DEBUG_BER = 16; + + /** + * Print search filters. + * + * @var int + */ + public const DEBUG_FILTER = 32; + + /** + * Print configuration file processing. + * + * @var int + */ + public const DEBUG_CONFIG = 64; + + /** + * Print Access Control List activities. + * + * @var int + */ + public const DEBUG_ACL = 128; + + /** + * Print operational statistics. + * + * @var int + */ + public const DEBUG_STATS = 256; + + /** + * Print more detailed statistics. + * + * @var int + */ + public const DEBUG_STATS2 = 512; + + /** + * Print communication with shell backends. + * + * @var int + */ + public const DEBUG_SHELL = 1024; + + /** + * Print entry parsing. + * + * @var int + */ + public const DEBUG_PARSE = 2048; + + /** + * Print LDAPSync replication. + * + * @var int + */ + public const DEBUG_SYNC = 16384; + + /** + * Print referral activities. + * + * @var int + */ + public const DEBUG_REFERRAL = 32768; + + /** + * Print error conditions. + * + * @var int + */ + public const DEBUG_ERROR = 32768; + + /** + * Print all levels of debug. + * + * @var int + */ + public const DEBUG_ANY = 65535; + + /** + * OID for StartTLS extended operation. Signals the server to initiate a TLS connection. + * + * @var string */ public const OID_SERVER_START_TLS = '1.3.6.1.4.1.1466.20037'; + + /** + * OID for Paged Results Control. Used to retrieve search results in pages. + * + * @var string + */ public const OID_SERVER_PAGED_RESULTS = '1.2.840.113556.1.4.319'; + + /** + * OID for Show Deleted Control. Includes deleted entries in the search results. + * + * @var string + */ public const OID_SERVER_SHOW_DELETED = '1.2.840.113556.1.4.417'; + + /** + * OID for Server Side Sort Control. Requests the server to sort the search results. + * + * @var string + */ public const OID_SERVER_SORT = '1.2.840.113556.1.4.473'; + + /** + * OID for Cross-Domain Move Target Control. Used in cross-domain move operations. + * + * @var string + */ public const OID_SERVER_CROSSDOM_MOVE_TARGET = '1.2.840.113556.1.4.521'; + + /** + * OID for LDAP Notification Control. Used to register for change notifications. + * + * @var string + */ public const OID_SERVER_NOTIFICATION = '1.2.840.113556.1.4.528'; + + /** + * OID for Extended DN Control. Requests extended DN information in search results. + * + * @var string + */ public const OID_SERVER_EXTENDED_DN = '1.2.840.113556.1.4.529'; + + /** + * OID for Lazy Commit Control. Delays the actual commit of changes until requested. + * + * @var string + */ public const OID_SERVER_LAZY_COMMIT = '1.2.840.113556.1.4.619'; + + /** + * OID for Security Descriptor Flags Control. Used to manipulate security descriptor flags. + * + * @var string + */ public const OID_SERVER_SD_FLAGS = '1.2.840.113556.1.4.801'; + + /** + * OID for Tree Delete Control. Enables the deletion of an entire subtree. + * + * @var string + */ public const OID_SERVER_TREE_DELETE = '1.2.840.113556.1.4.805'; + + /** + * OID for DirSync Control. Used for directory synchronization operations. + * + * @var string + */ public const OID_SERVER_DIRSYNC = '1.2.840.113556.1.4.841'; + + /** + * OID for Verify Name Control. Allows verification of an entry without retrieving attributes. + * + * @var string + */ public const OID_SERVER_VERIFY_NAME = '1.2.840.113556.1.4.1338'; + + /** + * OID for Domain Scope Control. Limits a search to the current domain. + * + * @var string + */ public const OID_SERVER_DOMAIN_SCOPE = '1.2.840.113556.1.4.1339'; + + /** + * OID for Search Options Control. Used to set various search options. + * + * @var string + */ public const OID_SERVER_SEARCH_OPTIONS = '1.2.840.113556.1.4.1340'; + + /** + * OID for Permissive Modify Control. Allows modifications even if some attributes are missing. + * + * @var string + */ public const OID_SERVER_PERMISSIVE_MODIFY = '1.2.840.113556.1.4.1413'; + + /** + * OID for Authentication Service Queries (ASQ) Control. Used to perform ASQ operations. + * + * @var string + */ public const OID_SERVER_ASQ = '1.2.840.113556.1.4.1504'; + + /** + * OID for Fast Bind Control. Optimizes the bind process for faster authentication. + * + * @var string + */ public const OID_SERVER_FAST_BIND = '1.2.840.113556.1.4.1781'; + + /** + * OID for Virtual List View (VLV) Request Control. Used to request a specific range of entries. + * + * @var string + */ public const OID_SERVER_CONTROL_VLVREQUEST = '2.16.840.1.113730.3.4.9'; /** - * Query OID's. - * - * @see https://ldapwiki.com/wiki/LDAP_MATCHING_RULE_IN_CHAIN + * OID for the 'matchingRuleInChain' matching rule. Used for substring searches in multi-valued attributes. */ public const OID_MATCHING_RULE_IN_CHAIN = '1.2.840.113556.1.4.1941'; /** * Set the current connection to use SSL. - * - * @param bool $enabled - * @return $this */ - public function ssl(); + public function ssl(): static; /** * Determine if the current connection instance is using SSL. - * - * @return bool */ - public function isUsingSSL(); + public function isUsingSSL(): bool; /** * Set the current connection to use TLS. - * - * @param bool $enabled - * @return $this */ - public function tls(); + public function tls(): static; /** * Determine if the current connection instance is using TLS. - * - * @return bool */ - public function isUsingTLS(); + public function isUsingTLS(): bool; /** * Determine if the connection is bound. - * - * @return bool */ - public function isBound(); + public function isBound(): bool; + + /** + * Determine if the connection is secure over TLS or SSL. + */ + public function isSecure(): bool; /** * Determine if the connection has been created. - * - * @return bool */ - public function isConnected(); + public function isConnected(): bool; /** * Determine the connection is able to modify passwords. - * - * @return bool */ - public function canChangePasswords(); + public function canChangePasswords(): bool; /** - * Returns the full LDAP host URL. + * Get the full LDAP host URL. * * Ex: ldap://192.168.1.1:386 - * - * @return string|null */ - public function getHost(); + public function getHost(): ?string; /** - * Get the underlying connection resource. - * - * @return resource|null + * Get the underlying raw LDAP connection. */ - public function getConnection(); + public function getConnection(): ?Connection; /** * Retrieve the entries from a search result. * * @see http://php.net/manual/en/function.ldap-get-entries.php * - * @param resource $searchResults - * @return array + * @param \LDAP\Result $result */ - public function getEntries($searchResults); + public function getEntries(mixed $result): array; + + /** + * Get the entry identifier for first entry in the result. + * + * @see https://www.php.net/manual/en/function.ldap-first-entry.php + * + * @param \LDAP\Result $result + */ + public function getFirstEntry(mixed $result): mixed; + + /** + * Retrieve the next result entry. + * + * @see https://www.php.net/manual/en/function.ldap-next-entry.php + * + * @param \LDAP\Result $entry + */ + public function getNextEntry(mixed $entry): mixed; + + /** + * Reads attributes and values from an entry in the search result. + * + * @see https://www.php.net/manual/en/function.ldap-get-attributes.php + * + * @param \LDAP\Result $entry + */ + public function getAttributes(mixed $entry): array|false; + + /** + * Reads all the values of the attribute in the entry in the result. + * + * @param \LDAP\Result $entry + */ + public function getValuesLen(mixed $entry, string $attribute): array|false; /** * Retrieve the last error on the current connection. * * @see http://php.net/manual/en/function.ldap-error.php - * - * @return string|null */ - public function getLastError(); + public function getLastError(): ?string; /** * Return detailed information about an error. @@ -156,62 +390,64 @@ interface LdapInterface * Returns null when there was a successful last request. * * Returns DetailedError when there was an error. - * - * @return DetailedError|null */ - public function getDetailedError(); + public function getDetailedError(): ?DetailedError; + + /** + * Count the number of entries in a search. + * + * @see https://www.php.net/manual/en/function.ldap-count-entries.php + * + * @param \LDAP\Result $result + */ + public function countEntries(mixed $result): int; + + /** + * Compare value of attribute found in entry specified with DN. + */ + public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int; /** * Set an option on the current connection. * * @see http://php.net/manual/en/function.ldap-set-option.php - * - * @param int $option - * @param mixed $value - * @return bool */ - public function setOption($option, $value); + public function setOption(int $option, mixed $value): bool; /** - * Set options on the current connection. - * - * @param array $options - * @return void + * Set multiple options on the current connection. */ - public function setOptions(array $options = []); + public function setOptions(array $options = []): void; + + /** + * Set a callback function to do re-binds on referral chasing. + * + * @see https://www.php.net/manual/en/function.ldap-set-rebind-proc.php + */ + public function setRebindCallback(callable $callback): bool; /** * Get the value for the LDAP option. * * @see https://www.php.net/manual/en/function.ldap-get-option.php - * - * @param int $option - * @param mixed $value - * @return mixed */ - public function getOption($option, &$value = null); + public function getOption(int $option, mixed &$value = null): mixed; /** * Starts a connection using TLS. * * @see http://php.net/manual/en/function.ldap-start-tls.php * - * @return bool - * * @throws LdapRecordException */ - public function startTLS(); + public function startTLS(): bool; /** * Connects to the specified hostname using the specified port. * * @see http://php.net/manual/en/function.ldap-start-tls.php - * - * @param string|array $hosts - * @param int $port - * @return resource|false */ - public function connect($hosts = [], $port = 389); + public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool; /** * Closes the current connection. @@ -219,275 +455,176 @@ interface LdapInterface * Returns false if no connection is present. * * @see http://php.net/manual/en/function.ldap-close.php - * - * @return bool */ - public function close(); + public function close(): bool; /** * Performs a search on the current connection. * * @see http://php.net/manual/en/function.ldap-search.php * - * @param string $dn - * @param string $filter - * @param array $fields - * @param bool $onlyAttributes - * @param int $size - * @param int $time - * @param int $deref - * @param array $serverControls - * @return resource + * @return \LDAP\Result */ - public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []); + public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed; /** * Performs a single level search on the current connection. * * @see http://php.net/manual/en/function.ldap-list.php * - * @param string $dn - * @param string $filter - * @param array $fields - * @param bool $onlyAttributes - * @param int $size - * @param int $time - * @param int $deref - * @param array $serverControls - * @return resource + * @return \LDAP\Result */ - public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []); + public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed; /** * Reads an entry on the current connection. * * @see http://php.net/manual/en/function.ldap-read.php * - * @param string $dn - * @param string $filter - * @param array $fields - * @param bool $onlyAttributes - * @param int $size - * @param int $time - * @param int $deref - * @param array $serverControls - * @return resource + * @return \LDAP\Result */ - public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []); + public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed; /** * Extract information from an LDAP result. * * @see https://www.php.net/manual/en/function.ldap-parse-result.php * - * @param resource $result - * @param int $errorCode - * @param ?string $dn - * @param ?string $errorMessage - * @param ?array $referrals - * @param ?array $serverControls - * @return bool + * @param \LDAP\Result $result */ - public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = []); + public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false; /** - * Binds to the current connection using the specified username and password. - * If sasl is true, the current connection is bound using SASL. + * Bind to the LDAP directory. * * @see http://php.net/manual/en/function.ldap-bind.php * - * @param string $username - * @param string $password - * @return bool - * * @throws LdapRecordException */ - public function bind($username, $password); + public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse; + + /** + * Bind to the LDAP directory using SASL. + * + * SASL options: + * - mech: Mechanism (Defaults: null) + * - realm: Realm (Defaults: null) + * - authc_id: Verification Identity (Defaults: null) + * - authz_id: Authorization Identity (Defaults: null) + * - props: Options for Authorization Identity (Defaults: null) + * + * @see https://php.net/manual/en/function.ldap-sasl-bind.php + * @see https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml + */ + public function saslBind(?string $dn = null, ?string $password = null, array $options = []): bool; /** * Adds an entry to the current connection. * * @see http://php.net/manual/en/function.ldap-add.php * - * @param string $dn - * @param array $entry - * @return bool - * * @throws LdapRecordException */ - public function add($dn, array $entry); + public function add(string $dn, array $entry): bool; /** * Deletes an entry on the current connection. * * @see http://php.net/manual/en/function.ldap-delete.php * - * @param string $dn - * @return bool - * * @throws LdapRecordException */ - public function delete($dn); + public function delete(string $dn): bool; /** * Modify the name of an entry on the current connection. * * @see http://php.net/manual/en/function.ldap-rename.php * - * @param string $dn - * @param string $newRdn - * @param string $newParent - * @param bool $deleteOldRdn - * @return bool - * * @throws LdapRecordException */ - public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false); + public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool; /** * Modifies an existing entry on the current connection. * * @see http://php.net/manual/en/function.ldap-modify.php * - * @param string $dn - * @param array $entry - * @return bool - * * @throws LdapRecordException */ - public function modify($dn, array $entry); + public function modify(string $dn, array $entry): bool; /** * Batch modifies an existing entry on the current connection. * * @see http://php.net/manual/en/function.ldap-modify-batch.php * - * @param string $dn - * @param array $values - * @return bool - * * @throws LdapRecordException */ - public function modifyBatch($dn, array $values); + public function modifyBatch(string $dn, array $values): bool; /** * Add attribute values to current attributes. * * @see http://php.net/manual/en/function.ldap-mod-add.php * - * @param string $dn - * @param array $entry - * @return bool - * * @throws LdapRecordException */ - public function modAdd($dn, array $entry); + public function modAdd(string $dn, array $entry): bool; /** * Replaces attribute values with new ones. * * @see http://php.net/manual/en/function.ldap-mod-replace.php * - * @param string $dn - * @param array $entry - * @return bool - * * @throws LdapRecordException */ - public function modReplace($dn, array $entry); + public function modReplace(string $dn, array $entry): bool; /** * Delete attribute values from current attributes. * * @see http://php.net/manual/en/function.ldap-mod-del.php * - * @param string $dn - * @param array $entry - * @return bool - * * @throws LdapRecordException */ - public function modDelete($dn, array $entry); - - /** - * Send LDAP pagination control. - * - * @see http://php.net/manual/en/function.ldap-control-paged-result.php - * - * @param int $pageSize - * @param bool $isCritical - * @param string $cookie - * @return bool - */ - public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = ''); - - /** - * Retrieve the LDAP pagination cookie. - * - * @see http://php.net/manual/en/function.ldap-control-paged-result-response.php - * - * @param resource $result - * @param string $cookie - * @return bool - */ - public function controlPagedResultResponse($result, &$cookie); + public function modDelete(string $dn, array $entry): bool; /** * Frees up the memory allocated internally to store the result. * * @see https://www.php.net/manual/en/function.ldap-free-result.php * - * @param resource $result - * @return bool + * @param \LDAP\Result $result */ - public function freeResult($result); + public function freeResult(mixed $result): bool; /** - * Returns the error number of the last command executed. + * Get the error number of the last command executed. * * @see http://php.net/manual/en/function.ldap-errno.php - * - * @return int|null */ - public function errNo(); + public function errNo(): ?int; /** - * Returns the error string of the specified error number. + * Get the error string of the specified error number. * * @see http://php.net/manual/en/function.ldap-err2str.php - * - * @param int $number - * @return string */ - public function err2Str($number); + public function err2Str(int $number): string; /** - * Returns the LDAP protocol to utilize for the current connection. - * - * @return string + * Get the LDAP protocol to utilize for the current connection. */ - public function getProtocol(); + public function getProtocol(): string; /** - * Returns the extended error code of the last command. - * - * @return string + * Get the extended error code of the last command. */ - public function getExtendedError(); + public function getExtendedError(): ?string; /** - * Return the diagnostic Message. - * - * @return string + * Get the diagnostic message. */ - public function getDiagnosticMessage(); - - /** - * Determine if the current PHP version supports server controls. - * - * @deprecated since v2.5.0 - * - * @return bool - */ - public function supportsServerControlsInMethods(); + public function getDiagnosticMessage(): ?string; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php index 0669b4c65..f574b9bc4 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php @@ -8,30 +8,21 @@ class LdapRecordException extends Exception { /** * The detailed LDAP error (if available). - * - * @var DetailedError|null */ - protected $detailedError; + protected ?DetailedError $detailedError = null; /** * Create a new Bind Exception with a detailed connection error. - * - * @param Exception $e - * @param DetailedError|null $error - * @return $this */ - public static function withDetailedError(Exception $e, DetailedError $error = null) + public static function withDetailedError(Exception $e, ?DetailedError $error = null): static { return (new static($e->getMessage(), $e->getCode(), $e))->setDetailedError($error); } /** * Set the detailed error. - * - * @param DetailedError|null $error - * @return $this */ - public function setDetailedError(DetailedError $error = null) + public function setDetailedError(?DetailedError $error = null): static { $this->detailedError = $error; @@ -39,11 +30,9 @@ class LdapRecordException extends Exception } /** - * Returns the detailed error. - * - * @return DetailedError|null + * Get the detailed error. */ - public function getDetailedError() + public function getDetailedError(): ?DetailedError { return $this->detailedError; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php new file mode 100644 index 000000000..c0c1e8306 --- /dev/null +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php @@ -0,0 +1,33 @@ +errorCode === 0; + } + + /** + * Determine if the LDAP response indicates a failed status. + */ + public function failed(): bool + { + return ! $this->successful(); + } +} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php index 72db0a0d8..3900c61a9 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php @@ -2,18 +2,21 @@ namespace LdapRecord\Models\ActiveDirectory; +use LdapRecord\Models\ActiveDirectory\Concerns\HasAccountControl; use LdapRecord\Models\ActiveDirectory\Concerns\HasPrimaryGroup; +use LdapRecord\Models\ActiveDirectory\Relations\HasOnePrimaryGroup; +use LdapRecord\Models\Relations\HasMany; +use LdapRecord\Models\Relations\HasOne; class Computer extends Entry { + use HasAccountControl; use HasPrimaryGroup; /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'person', 'organizationalperson', @@ -23,32 +26,24 @@ class Computer extends Entry /** * The groups relationship. - * - * Retrieves groups that the current computer is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function groups() + public function groups(): HasMany { return $this->hasMany(Group::class, 'member')->with($this->primaryGroup()); } /** * The primary group relationship. - * - * @return Relations\HasOnePrimaryGroup */ - public function primaryGroup() + public function primaryGroup(): HasOnePrimaryGroup { return $this->hasOnePrimaryGroup(Group::class, 'primarygroupid'); } /** * The managed by relationship. - * - * @return \LdapRecord\Models\Relations\HasOne */ - public function managedBy() + public function managedBy(): HasOne { return $this->hasOne([Contact::class, Group::class, User::class], 'managedby'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php new file mode 100644 index 000000000..425cc548f --- /dev/null +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php @@ -0,0 +1,46 @@ +isDisabled(); + } + + /** + * Determine if the user's account is disabled. + */ + public function isDisabled(): bool + { + return $this->accountControl()->hasFlag(AccountControl::ACCOUNTDISABLE); + } + + /** + * Get the user's account control. + */ + public function accountControl(): AccountControl + { + return new AccountControl( + $this->getFirstAttribute('userAccountControl') + ); + } + + /** + * Set the user's account control attribute. + */ + public function setUserAccountControlAttribute(mixed $value): void + { + if ($value instanceof AccountControl) { + $value = $value->getValue(); + } + + $this->attributes['useraccountcontrol'] = [(int) $value]; + } +} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php index b7138d30c..c8e69915a 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php @@ -8,13 +8,8 @@ trait HasPrimaryGroup { /** * Returns a new has one primary group relationship. - * - * @param mixed $related - * @param string $relationKey - * @param string $foreignKey - * @return HasOnePrimaryGroup */ - public function hasOnePrimaryGroup($related, $relationKey, $foreignKey = 'primarygroupid') + public function hasOnePrimaryGroup(string $related, string $relationKey, string $foreignKey = 'primarygroupid'): HasOnePrimaryGroup { return new HasOnePrimaryGroup($this->newQuery(), $this, $related, $relationKey, $foreignKey); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php index 52c451fe4..9087f058e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php @@ -2,14 +2,14 @@ namespace LdapRecord\Models\ActiveDirectory; +use LdapRecord\Models\Relations\HasMany; + class Contact extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'person', 'organizationalperson', @@ -18,12 +18,8 @@ class Contact extends Entry /** * The groups relationship. - * - * Retrieves groups that the current contact is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function groups() + public function groups(): HasMany { return $this->hasMany(Group::class, 'member'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php index 1636cf393..e17fb1f70 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php @@ -6,10 +6,8 @@ class Container extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'container', ]; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php index e1a0233cc..e9924f433 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php @@ -16,10 +16,8 @@ class Entry extends BaseEntry implements ActiveDirectory { /** * The default attributes that should be mutated to dates. - * - * @var array */ - protected $defaultDates = [ + protected array $defaultDates = [ 'whenchanged' => 'windows', 'whencreated' => 'windows', 'dscorepropagationdata' => 'windows', @@ -27,83 +25,73 @@ class Entry extends BaseEntry implements ActiveDirectory /** * The attribute key that contains the Object SID. - * - * @var string */ - protected $sidKey = 'objectsid'; + protected string $sidKey = 'objectsid'; /** - * @inheritdoc + * {@inheritdoc} */ - public function getObjectSidKey() + public function getObjectSidKey(): string { return $this->sidKey; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getObjectSid() + public function getObjectSid(): ?string { return $this->getFirstAttribute($this->sidKey); } /** - * @inheritdoc + * {@inheritdoc} */ - public function getConvertedSid($sid = null) + public function getConvertedSid($sid = null): ?string { try { - return (string) $this->newObjectSid( - $sid ?? $this->getObjectSid() + return $this->newObjectSid( + (string) ($sid ?? $this->getObjectSid()) ); - } catch (InvalidArgumentException $e) { - return; + } catch (InvalidArgumentException) { + return null; } } /** - * @inheritdoc + * {@inheritdoc} */ - public function getBinarySid($sid = null) + public function getBinarySid($sid = null): ?string { try { return $this->newObjectSid( $sid ?? $this->getObjectSid() )->getBinary(); - } catch (InvalidArgumentException $e) { - return; + } catch (InvalidArgumentException) { + return null; } } /** * Make a new object Sid instance. - * - * @param string $value - * @return Sid */ - protected function newObjectSid($value) + protected function newObjectSid(string $value): Sid { return new Sid($value); } /** * Create a new query builder. - * - * @param Connection $connection - * @return ActiveDirectoryBuilder */ - public function newQueryBuilder(Connection $connection) + public function newQueryBuilder(Connection $connection): ActiveDirectoryBuilder { return new ActiveDirectoryBuilder($connection); } /** * Determine if the object is deleted. - * - * @return bool */ - public function isDeleted() + public function isDeleted(): bool { return strtoupper((string) $this->getFirstAttribute('isDeleted')) === 'TRUE'; } @@ -111,12 +99,9 @@ class Entry extends BaseEntry implements ActiveDirectory /** * Restore a deleted object. * - * @param string|null $newParentDn - * @return bool - * * @throws \LdapRecord\LdapRecordException */ - public function restore($newParentDn = null) + public function restore(?string $newParentDn = null): bool { if (! $this->isDeleted()) { return false; @@ -138,30 +123,27 @@ class Entry extends BaseEntry implements ActiveDirectory $this->setRawAttribute('distinguishedname', $newDn); $this->save(['isDeleted' => null]); + + return true; } /** * Get the objects restore location. - * - * @return string */ - protected function getDefaultRestoreLocation() + protected function getDefaultRestoreLocation(): ?string { return $this->getFirstAttribute('lastKnownParent') ?? $this->getParentDn($this->getParentDn($this->getDn())); } /** * Convert the attributes for JSON serialization. - * - * @param array $attributes - * @return array */ - protected function convertAttributesForJson(array $attributes = []) + protected function convertAttributesForJson(array $attributes = []): array { $attributes = parent::convertAttributesForJson($attributes); // If the model has a SID set, we need to convert it to its - // string format, due to it being in binary. Otherwise + // string format, due to it being in binary. Otherwise, // we will receive a JSON serialization exception. if (isset($attributes[$this->sidKey])) { $attributes[$this->sidKey] = [$this->getConvertedSid( @@ -174,23 +156,11 @@ class Entry extends BaseEntry implements ActiveDirectory /** * Convert the attributes from JSON serialization. - * - * @param array $attributes - * @return array */ - protected function convertAttributesFromJson(array $attributes = []) + protected function convertAttributesFromJson(array $attributes = []): array { $attributes = parent::convertAttributesFromJson($attributes); - // Here we are converting the model's GUID and SID attributes - // back to their original values from serialization, so that - // their original value may be used and compared against. - if (isset($attributes[$this->guidKey])) { - $attributes[$this->guidKey] = [$this->getBinaryGuid( - Arr::first($attributes[$this->guidKey]) - )]; - } - if (isset($attributes[$this->sidKey])) { $attributes[$this->sidKey] = [$this->getBinarySid( Arr::first($attributes[$this->sidKey]) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php index 77abbbcf5..e32f82009 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php @@ -5,17 +5,17 @@ namespace LdapRecord\Models\ActiveDirectory; class ExchangeDatabase extends Entry { /** - * @inheritdoc + * {@inheritdoc} */ - public static $objectClasses = ['msExchMDB']; + public static array $objectClasses = ['msExchMDB']; /** - * @inheritdoc + * {@inheritdoc} */ - public static function boot() + public static function boot(): void { parent::boot(); - static::addGlobalScope(new Scopes\InConfigurationContext()); + static::addGlobalScope(new Scopes\InConfigurationContext); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php index d304876ab..5e13d405d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php @@ -5,18 +5,18 @@ namespace LdapRecord\Models\ActiveDirectory; class ExchangeServer extends Entry { /** - * @inheritdoc + * {@inheritdoc} */ - public static $objectClasses = ['msExchExchangeServer']; + public static array $objectClasses = ['msExchExchangeServer']; /** - * @inheritdoc + * {@inheritdoc} */ - public static function boot() + public static function boot(): void { parent::boot(); - static::addGlobalScope(new Scopes\HasServerRoleAttribute()); - static::addGlobalScope(new Scopes\InConfigurationContext()); + static::addGlobalScope(new Scopes\HasServerRoleAttribute); + static::addGlobalScope(new Scopes\InConfigurationContext); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php index 25287ae4a..34e6c3358 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php @@ -2,23 +2,23 @@ namespace LdapRecord\Models\ActiveDirectory; +use LdapRecord\Models\Relations\HasMany; + class ForeignSecurityPrincipal extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = ['foreignsecurityprincipal']; + public static array $objectClasses = [ + 'foreignsecurityprincipal', + ]; /** * The groups relationship. * - * Retrieves groups that the current security principal is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Retrieves groups that the current security principal is a part of. */ - public function groups() + public function groups(): HasMany { return $this->hasMany(Group::class, 'member'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php index 784588771..165bd90f8 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php @@ -2,14 +2,14 @@ namespace LdapRecord\Models\ActiveDirectory; +use LdapRecord\Models\Relations\HasMany; + class Group extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'group', ]; @@ -17,23 +17,17 @@ class Group extends Entry /** * The groups relationship. * - * Retrieves groups that the current group is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Retrieves groups that the current group is a part of. */ - public function groups() + public function groups(): HasMany { return $this->hasMany(static::class, 'member'); } /** * The members relationship. - * - * Retrieves members that are apart of the group. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function members() + public function members(): HasMany { return $this->hasMany([ static::class, User::class, Contact::class, Computer::class, @@ -44,12 +38,8 @@ class Group extends Entry /** * The primary group members relationship. - * - * Retrieves members that are apart the primary group. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function primaryGroupMembers() + public function primaryGroupMembers(): HasMany { return $this->hasMany([ static::class, User::class, Contact::class, Computer::class, @@ -58,13 +48,11 @@ class Group extends Entry /** * Get the RID of the group. - * - * @return array */ - public function getRidAttribute() + public function getRidAttribute(): array { - $objectSidComponents = explode('-', (string) $this->getConvertedSid()); - - return [end($objectSidComponents)]; + return array_filter([ + last(explode('-', (string) $this->getConvertedSid())), + ]); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php index 80aae9f47..0801d1080 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php @@ -6,20 +6,16 @@ class OrganizationalUnit extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'organizationalunit', ]; /** * Get the creatable RDN attribute name. - * - * @return string */ - public function getCreatableRdnAttribute() + public function getCreatableRdnAttribute(): string { return 'ou'; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php index df7421610..71534981d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php @@ -6,8 +6,6 @@ class Printer extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = ['printqueue']; + public static array $objectClasses = ['printqueue']; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php index 40350c97a..971f79066 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php @@ -9,11 +9,8 @@ class HasOnePrimaryGroup extends HasOne { /** * Get the foreign model by the given value. - * - * @param string $value - * @return Model|null */ - protected function getForeignModelByValue($value) + protected function getForeignModelByValue(string $value): ?Model { return $this->query->findBySid( $this->getParentModelObjectSid() @@ -24,11 +21,8 @@ class HasOnePrimaryGroup extends HasOne * Get the foreign value from the given model. * * Retrieves the last RID from the models Object SID. - * - * @param Model $model - * @return string */ - protected function getForeignValueFromModel(Model $model) + protected function getForeignValueFromModel(Model $model): ?string { $objectSidComponents = explode('-', $model->getConvertedSid()); @@ -37,10 +31,8 @@ class HasOnePrimaryGroup extends HasOne /** * Get the parent relationship models converted object sid. - * - * @return string */ - protected function getParentModelObjectSid() + protected function getParentModelObjectSid(): string { return preg_replace( '/\d+$/', diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php index 76df79ca3..24a2387d3 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php @@ -10,12 +10,8 @@ class HasServerRoleAttribute implements Scope { /** * Includes condition of having a serverRole attribute. - * - * @param Builder $query - * @param Model $model - * @return void */ - public function apply(Builder $query, Model $model) + public function apply(Builder $query, Model $model): void { $query->whereHas('serverRole'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php index dc8a4d21b..b7942cf4d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php @@ -12,13 +12,9 @@ class InConfigurationContext implements Scope /** * Refines the base dn to be inside the configuration context. * - * @param Builder $query - * @param Model $model - * @return void - * * @throws \LdapRecord\Models\ModelNotFoundException */ - public function apply(Builder $query, Model $model) + public function apply(Builder $query, Model $model): void { $query->in($this->getConfigurationNamingContext($model)); } @@ -26,9 +22,6 @@ class InConfigurationContext implements Scope /** * Get the LDAP server configuration naming context distinguished name. * - * @param Model $model - * @return mixed - * * @throws \LdapRecord\Models\ModelNotFoundException */ protected function getConfigurationNamingContext(Model $model) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php index 9d00cf8fa..30545b802 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php @@ -10,12 +10,8 @@ class RejectComputerObjectClass implements Scope { /** * Prevent computer objects from being included in results. - * - * @param Builder $query - * @param Model $model - * @return void */ - public function apply(Builder $query, Model $model) + public function apply(Builder $query, Model $model): void { $query->where('objectclass', '!=', 'computer'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php index c2ea0325d..3faec3882 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php @@ -4,39 +4,36 @@ namespace LdapRecord\Models\ActiveDirectory; use Carbon\Carbon; use Illuminate\Contracts\Auth\Authenticatable; +use LdapRecord\Models\ActiveDirectory\Concerns\HasAccountControl; use LdapRecord\Models\ActiveDirectory\Concerns\HasPrimaryGroup; use LdapRecord\Models\ActiveDirectory\Scopes\RejectComputerObjectClass; -use LdapRecord\Models\Attributes\AccountControl; use LdapRecord\Models\Concerns\CanAuthenticate; use LdapRecord\Models\Concerns\HasPassword; +use LdapRecord\Models\Relations\HasMany; +use LdapRecord\Models\Relations\HasOne; use LdapRecord\Query\Model\Builder; class User extends Entry implements Authenticatable { + use CanAuthenticate; + use HasAccountControl; use HasPassword; use HasPrimaryGroup; - use CanAuthenticate; /** * The password's attribute name. - * - * @var string */ - protected $passwordAttribute = 'unicodepwd'; + protected string $passwordAttribute = 'unicodepwd'; /** * The password's hash method. - * - * @var string */ - protected $passwordHashMethod = 'encode'; + protected string $passwordHashMethod = 'encode'; /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'person', 'organizationalperson', @@ -45,10 +42,8 @@ class User extends Entry implements Authenticatable /** * The attributes that should be mutated to dates. - * - * @var array */ - protected $dates = [ + protected array $dates = [ 'lastlogon' => 'windows-int', 'lastlogoff' => 'windows-int', 'pwdlastset' => 'windows-int', @@ -59,9 +54,9 @@ class User extends Entry implements Authenticatable ]; /** - * @inheritdoc + * {@inheritdoc} */ - protected static function boot() + protected static function boot(): void { parent::boot(); @@ -69,49 +64,23 @@ class User extends Entry implements Authenticatable // class. This is needed due to computer objects containing all // of the ActiveDirectory 'user' object classes. Without // this scope, they would be included in results. - static::addGlobalScope(new RejectComputerObjectClass()); + static::addGlobalScope(new RejectComputerObjectClass); } /** - * Determine if the user's account is enabled. - * - * @return bool + * Get the unique identifier for the user. */ - public function isEnabled() + public function getAuthIdentifier(): ?string { - return ! $this->isDisabled(); - } - - /** - * Determine if the user's account is disabled. - * - * @return bool - */ - public function isDisabled() - { - return $this->accountControl()->has(AccountControl::ACCOUNTDISABLE); - } - - /** - * Get the user's account control. - * - * @return AccountControl - */ - public function accountControl() - { - return new AccountControl( - $this->getFirstAttribute('userAccountControl') - ); + return $this->getConvertedGuid(); } /** * The groups relationship. * - * Retrieves groups that the user is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Retrieves groups that the user is a part of. */ - public function groups() + public function groups(): HasMany { return $this->hasMany(Group::class, 'member')->with($this->primaryGroup()); } @@ -120,10 +89,8 @@ class User extends Entry implements Authenticatable * The manager relationship. * * Retrieves the manager of the user. - * - * @return \LdapRecord\Models\Relations\HasOne */ - public function manager() + public function manager(): HasOne { return $this->hasOne(static::class, 'manager'); } @@ -131,33 +98,25 @@ class User extends Entry implements Authenticatable /** * The primary group relationship of the current user. * - * Retrieves the primary group the user is apart of. - * - * @return \LdapRecord\Models\Relations\HasOne + * Retrieves the primary group the user is a part of. */ - public function primaryGroup() + public function primaryGroup(): HasOne { return $this->hasOnePrimaryGroup(Group::class, 'primarygroupid'); } /** * Scopes the query to exchange mailbox users. - * - * @param Builder $query - * @return Builder */ - public function scopeWhereHasMailbox(Builder $query) + public function scopeWhereHasMailbox(Builder $query): Builder { return $query->whereHas('msExchMailboxGuid'); } /** * Scopes the query to users having a lockout value set. - * - * @param Builder $query - * @return Builder */ - public function scopeWhereHasLockout(Builder $query) + public function scopeWhereHasLockout(Builder $query): Builder { return $query->where('lockoutTime', '>=', 1); } @@ -167,12 +126,8 @@ class User extends Entry implements Authenticatable * * @see https://ldapwiki.com/wiki/Active%20Directory%20Account%20Lockout * @see https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/account-lockout-duration - * - * @param string|int $localTimezone - * @param int|null $durationInMinutes - * @return bool */ - public function isLockedOut($localTimezone, $durationInMinutes = null) + public function isLockedOut(string|int $localTimezone, ?int $durationInMinutes = null): bool { $time = $this->getFirstAttribute('lockouttime'); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php index 45fae214d..9024b934e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php @@ -3,8 +3,9 @@ namespace LdapRecord\Models\Attributes; use ReflectionClass; +use Stringable; -class AccountControl +class AccountControl implements Stringable { public const SCRIPT = 1; @@ -51,151 +52,122 @@ class AccountControl public const PARTIAL_SECRETS_ACCOUNT = 67108864; /** - * The account control flag values. + * The account control flags. * * @var array */ - protected $values = []; + protected array $flags = []; /** * Constructor. - * - * @param ?int $flag */ - public function __construct($flag = null) + public function __construct(?int $flag = null) { if (! is_null($flag)) { - $this->apply($flag); + $this->applyFlags($flag); } } /** - * Get the value when casted to string. - * - * @return string + * Get the value when cast to string. */ - public function __toString() + public function __toString(): string { return (string) $this->getValue(); } /** - * Get the value when casted to int. - * - * @return int + * Get the value when cast to int. */ - public function __toInt() + public function __toInt(): int { return $this->getValue(); } /** - * Add the flag to the account control values. - * - * @param int $flag - * @return $this + * Set a flag on the account control. */ - public function add($flag) + public function setFlag(int $flag): static { // Use the value as a key so if the same value // is used, it will always be overwritten - $this->values[$flag] = $flag; + $this->flags[$flag] = $flag; return $this; } /** - * Remove the flag from the account control. - * - * @param int $flag - * @return $this + * Unset a flag from the account control. */ - public function remove($flag) + public function unsetFlag(int $flag): static { - unset($this->values[$flag]); + unset($this->flags[$flag]); return $this; } /** - * Extract and apply the flag. - * - * @param int $flag - * @return void + * Extract and apply several flags. */ - public function apply($flag) + public function applyFlags(int $flags): void { - $this->setValues($this->extractFlags($flag)); + $this->setFlags($this->extractFlags($flags)); } /** - * Determine if the account control contains the given UAC flag(s). - * - * @param int $flag - * @return bool + * Determine if the account control contains the given flag(s). */ - public function has($flag) + public function hasFlag(int $flag): bool { // Here we will extract the given flag into an array // of possible flags. This will allow us to see if // our AccountControl object contains any of them. $flagsUsed = array_intersect( $this->extractFlags($flag), - $this->values + $this->flags ); return in_array($flag, $flagsUsed); } /** - * Determine if the account control does not contain the given UAC flag(s). - * - * @param int $flag - * @return bool + * Determine if the account control does not contain the given flag(s). */ - public function doesntHave($flag) + public function doesntHaveFlag(int $flag): bool { - return ! $this->has($flag); + return ! $this->hasFlag($flag); } /** * Generate an LDAP filter based on the current value. - * - * @return string */ - public function filter() + public function filter(): string { - return sprintf('(UserAccountControl:1.2.840.113556.1.4.803:=%s)', $this->getValue()); + return sprintf('(UserAccountControl:1.2.840.113556.1.4.803:=%s)', $this); } /** * The logon script will be run. - * - * @return $this */ - public function runLoginScript() + public function setRunLoginScript(): static { - return $this->add(static::SCRIPT); + return $this->setFlag(static::SCRIPT); } /** * The user account is locked. - * - * @return $this */ - public function accountIsLocked() + public function setAccountIsLocked(): static { - return $this->add(static::LOCKOUT); + return $this->setFlag(static::LOCKOUT); } /** * The user account is disabled. - * - * @return $this */ - public function accountIsDisabled() + public function setAccountIsDisabled(): static { - return $this->add(static::ACCOUNTDISABLE); + return $this->setFlag(static::ACCOUNTDISABLE); } /** @@ -203,117 +175,95 @@ class AccountControl * * This account provides user access to this domain, but not to any domain that * trusts this domain. This is sometimes referred to as a local user account. - * - * @return $this */ - public function accountIsTemporary() + public function setAccountIsTemporary(): static { - return $this->add(static::TEMP_DUPLICATE_ACCOUNT); + return $this->setFlag(static::TEMP_DUPLICATE_ACCOUNT); } /** * This is a default account type that represents a typical user. - * - * @return $this */ - public function accountIsNormal() + public function setAccountIsNormal(): static { - return $this->add(static::NORMAL_ACCOUNT); + return $this->setFlag(static::NORMAL_ACCOUNT); } /** * This is a permit to trust an account for a system domain that trusts other domains. - * - * @return $this */ - public function accountIsForInterdomain() + public function setAccountIsForInterdomain(): static { - return $this->add(static::INTERDOMAIN_TRUST_ACCOUNT); + return $this->setFlag(static::INTERDOMAIN_TRUST_ACCOUNT); } /** * This is a computer account for a computer that is running Microsoft * Windows NT 4.0 Workstation, Microsoft Windows NT 4.0 Server, Microsoft * Windows 2000 Professional, or Windows 2000 Server and is a member of this domain. - * - * @return $this */ - public function accountIsForWorkstation() + public function setAccountIsForWorkstation(): static { - return $this->add(static::WORKSTATION_TRUST_ACCOUNT); + return $this->setFlag(static::WORKSTATION_TRUST_ACCOUNT); } /** * This is a computer account for a domain controller that is a member of this domain. - * - * @return $this */ - public function accountIsForServer() + public function setAccountIsForServer(): static { - return $this->add(static::SERVER_TRUST_ACCOUNT); + return $this->setFlag(static::SERVER_TRUST_ACCOUNT); } /** * This is an MNS logon account. - * - * @return $this */ - public function accountIsMnsLogon() + public function setAccountIsMnsLogon(): static { - return $this->add(static::MNS_LOGON_ACCOUNT); + return $this->setFlag(static::MNS_LOGON_ACCOUNT); } /** * (Windows 2000/Windows Server 2003) This account does * not require Kerberos pre-authentication for logging on. - * - * @return $this */ - public function accountDoesNotRequirePreAuth() + public function setAccountDoesNotRequirePreAuth(): static { - return $this->add(static::DONT_REQ_PREAUTH); + return $this->setFlag(static::DONT_REQ_PREAUTH); } /** * When this flag is set, it forces the user to log on by using a smart card. - * - * @return $this */ - public function accountRequiresSmartCard() + public function setAccountRequiresSmartCard(): static { - return $this->add(static::SMARTCARD_REQUIRED); + return $this->setFlag(static::SMARTCARD_REQUIRED); } /** * (Windows Server 2008/Windows Server 2008 R2) The account is a read-only domain controller (RODC). * * This is a security-sensitive setting. Removing this setting from an RODC compromises security on that server. - * - * @return $this */ - public function accountIsReadOnly() + public function setAccountIsReadOnly(): static { - return $this->add(static::PARTIAL_SECRETS_ACCOUNT); + return $this->setFlag(static::PARTIAL_SECRETS_ACCOUNT); } /** * The home folder is required. - * - * @return $this */ - public function homeFolderIsRequired() + public function setHomeFolderIsRequired(): static { - return $this->add(static::HOMEDIR_REQUIRED); + return $this->setFlag(static::HOMEDIR_REQUIRED); } /** * No password is required. - * - * @return $this */ - public function passwordIsNotRequired() + public function setPasswordIsNotRequired(): static { - return $this->add(static::PASSWD_NOTREQD); + return $this->setFlag(static::PASSWD_NOTREQD); } /** @@ -322,42 +272,34 @@ class AccountControl * For information about how to programmatically set this permission, visit the following link: * * @see http://msdn2.microsoft.com/en-us/library/aa746398.aspx - * - * @return $this */ - public function passwordCannotBeChanged() + public function setPasswordCannotBeChanged(): static { - return $this->add(static::PASSWD_CANT_CHANGE); + return $this->setFlag(static::PASSWD_CANT_CHANGE); } /** * Represents the password, which should never expire on the account. - * - * @return $this */ - public function passwordDoesNotExpire() + public function setPasswordDoesNotExpire(): static { - return $this->add(static::DONT_EXPIRE_PASSWORD); + return $this->setFlag(static::DONT_EXPIRE_PASSWORD); } /** * (Windows 2000/Windows Server 2003) The user's password has expired. - * - * @return $this */ - public function passwordIsExpired() + public function setPasswordIsExpired(): static { - return $this->add(static::PASSWORD_EXPIRED); + return $this->setFlag(static::PASSWORD_EXPIRED); } /** * The user can send an encrypted password. - * - * @return $this */ - public function allowEncryptedTextPassword() + public function setAllowEncryptedTextPassword(): static { - return $this->add(static::ENCRYPTED_TEXT_PWD_ALLOWED); + return $this->setFlag(static::ENCRYPTED_TEXT_PWD_ALLOWED); } /** @@ -368,12 +310,10 @@ class AccountControl * * To enable a service for Kerberos delegation, you must set this * flag on the userAccountControl property of the service account. - * - * @return $this */ - public function trustForDelegation() + public function setTrustForDelegation(): static { - return $this->add(static::TRUSTED_FOR_DELEGATION); + return $this->setFlag(static::TRUSTED_FOR_DELEGATION); } /** @@ -383,44 +323,36 @@ class AccountControl * should be tightly controlled. This setting lets a service that runs under the * account assume a client's identity and authenticate as that user to other remote * servers on the network. - * - * @return $this */ - public function trustToAuthForDelegation() + public function setTrustToAuthForDelegation(): static { - return $this->add(static::TRUSTED_TO_AUTH_FOR_DELEGATION); + return $this->setFlag(static::TRUSTED_TO_AUTH_FOR_DELEGATION); } /** * When this flag is set, the security context of the user is not delegated to a * service even if the service account is set as trusted for Kerberos delegation. - * - * @return $this */ - public function doNotTrustForDelegation() + public function setDoNotTrustForDelegation(): static { - return $this->add(static::NOT_DELEGATED); + return $this->setFlag(static::NOT_DELEGATED); } /** * (Windows 2000/Windows Server 2003) Restrict this principal to * use only Data Encryption Standard (DES) encryption types for keys. - * - * @return $this */ - public function useDesKeyOnly() + public function setUseDesKeyOnly(): static { - return $this->add(static::USE_DES_KEY_ONLY); + return $this->setFlag(static::USE_DES_KEY_ONLY); } /** * Get the account control value. - * - * @return int */ - public function getValue() + public function getValue(): int { - return array_sum($this->values); + return array_sum($this->flags); } /** @@ -428,64 +360,56 @@ class AccountControl * * @return array */ - public function getValues() + public function getFlags(): array { - return $this->values; + return $this->flags; } /** * Set the account control values. * * @param array $flags - * @return void */ - public function setValues(array $flags) + public function setFlags(array $flags): void { - $this->values = $flags; + $this->flags = $flags; } /** * Get all flags that are currently applied to the value. - * - * @return array */ - public function getAppliedFlags() + public function getAppliedFlags(): array { $flags = $this->getAllFlags(); - $exists = []; + $applied = []; foreach ($flags as $name => $flag) { - if ($this->has($flag)) { - $exists[$name] = $flag; + if ($this->hasFlag($flag)) { + $applied[$name] = $flag; } } - return $exists; + return $applied; } /** * Get all possible account control flags. - * - * @return array */ - public function getAllFlags() + public function getAllFlags(): array { return (new ReflectionClass(__CLASS__))->getConstants(); } /** * Extracts the given flag into an array of flags used. - * - * @param int $flag - * @return array */ - public function extractFlags($flag) + protected function extractFlags(int $flag): array { $flags = []; for ($i = 0; $i <= 26; $i++) { - if ((int) $flag & (1 << $i)) { + if ($flag & (1 << $i)) { $flags[1 << $i] = 1 << $i; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php index fc981299a..09391091b 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php @@ -4,89 +4,69 @@ namespace LdapRecord\Models\Attributes; use LdapRecord\EscapesValues; use LdapRecord\Support\Arr; +use Stringable; -class DistinguishedName +class DistinguishedName implements Stringable { use EscapesValues; /** - * The underlying raw value. - * - * @var string + * The underlying raw distinguished name value. */ - protected $value; + protected string $value; /** * Constructor. - * - * @param string|null $value */ - public function __construct($value = null) + public function __construct(?string $value = null) { $this->value = trim((string) $value); } /** * Get the distinguished name value. - * - * @return string */ - public function __toString() + public function __toString(): string { - return (string) $this->value; + return $this->value; } /** * Alias of the "build" method. - * - * @param string|null $value - * @return DistinguishedNameBuilder */ - public static function of($value = null) + public static function of(?string $value = null): DistinguishedNameBuilder { return static::build($value); } /** * Get a new DN builder object from the given DN. - * - * @param string|null $value - * @return DistinguishedNameBuilder */ - public static function build($value = null) + public static function build(?string $value = null): DistinguishedNameBuilder { return new DistinguishedNameBuilder($value); } /** * Make a new distinguished name instance. - * - * @param string|null $value - * @return static */ - public static function make($value = null) + public static function make(?string $value = null): static { return new static($value); } /** * Determine if the given value is a valid distinguished name. - * - * @param string $value - * @return bool */ - public static function isValid($value) + public static function isValid(?string $value = null): bool { return ! static::make($value)->isEmpty(); } /** * Explode a distinguished name into relative distinguished names. - * - * @param string $dn - * @return array */ - public static function explode($dn) + public static function explode(string $dn): array { $components = ldap_explode_dn($dn, (int) $withoutAttributes = false); @@ -103,58 +83,34 @@ class DistinguishedName return $components; } - /** - * Un-escapes a hexadecimal string into its original string representation. - * - * @param string $value - * @return string - */ - public static function unescape($value) - { - return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function ($matches) { - return chr(hexdec($matches[1])); - }, $value); - } - /** * Explode the RDN into an attribute and value. - * - * @param string $rdn - * @return array */ - public static function explodeRdn($rdn) + public static function explodeRdn(string $rdn): array { return explode('=', $rdn, $limit = 2); } /** * Implode the component attribute and value into an RDN. - * - * @param string $rdn - * @return string */ - public static function makeRdn(array $component) + public static function makeRdn(array $component): string { return implode('=', $component); } /** * Get the underlying value. - * - * @return string|null */ - public function get() + public function get(): ?string { return $this->value; } /** * Set the underlying value. - * - * @param string|null $value - * @return $this */ - public function set($value) + public function set(?string $value = null): static { $this->value = $value; @@ -163,15 +119,13 @@ class DistinguishedName /** * Get the distinguished name values without attributes. - * - * @return array */ - public function values() + public function values(): array { $values = []; foreach ($this->multi() as [, $value]) { - $values[] = static::unescape($value); + $values[] = EscapedValue::unescape($value); } return $values; @@ -179,10 +133,8 @@ class DistinguishedName /** * Get the distinguished name attributes without values. - * - * @return array */ - public function attributes() + public function attributes(): array { $attributes = []; @@ -195,10 +147,8 @@ class DistinguishedName /** * Get the distinguished name components with attributes. - * - * @return array */ - public function components() + public function components(): array { $components = []; @@ -207,7 +157,7 @@ class DistinguishedName // escaped. This cannot be opted out of. Here we will unescape // the attribute value, then re-escape it to its original // representation from the server using the "dn" flag. - $value = $this->escape(static::unescape($value))->dn(); + $value = $this->escape(EscapedValue::unescape($value))->forDn(); $components[] = static::makeRdn([$attribute, $value]); } @@ -217,10 +167,8 @@ class DistinguishedName /** * Convert the distinguished name into an associative array. - * - * @return array */ - public function assoc() + public function assoc(): array { $map = []; @@ -237,52 +185,40 @@ class DistinguishedName /** * Split the RDNs into a multi-dimensional array. - * - * @return array */ - public function multi() + public function multi(): array { - return array_map(function ($rdn) { - return static::explodeRdn($rdn); - }, $this->rdns()); + return array_map(fn ($rdn) => static::explodeRdn($rdn), $this->rdns()); } /** * Split the distinguished name into an array of unescaped RDN's. - * - * @return array */ - public function rdns() + public function rdns(): array { return static::explode($this->value); } /** * Get the first RDNs value. - * - * @return string|null */ - public function name() + public function name(): ?string { return Arr::first($this->values()); } /** * Get the first RDNs attribute. - * - * @return string|null */ - public function head() + public function head(): ?string { return Arr::first($this->attributes()); } /** * Get the relative distinguished name. - * - * @return string|null */ - public function relative() + public function relative(): ?string { return Arr::first($this->components()); } @@ -291,20 +227,16 @@ class DistinguishedName * Alias of relative(). * * Get the first RDN from the distinguished name. - * - * @return string|null */ - public function first() + public function first(): ?string { return $this->relative(); } /** * Get the parent distinguished name. - * - * @return string|null */ - public function parent() + public function parent(): ?string { $components = $this->components(); @@ -315,112 +247,91 @@ class DistinguishedName /** * Determine if the distinguished name is empty. - * - * @return bool */ - public function isEmpty() + public function isEmpty(): bool { return empty( - array_filter($this->values()) + array_filter( + array_map('trim', $this->values()) + ) ); } /** - * Determine if the current distinguished name is a parent of the given child. - * - * @param DistinguishedName $child - * @return bool + * Determine if the distinguished name is not empty. */ - public function isParentOf(self $child) + public function isNotEmpty(): bool + { + return ! $this->isEmpty(); + } + + /** + * Determine if the current distinguished name is a parent of the given child. + */ + public function isParentOf(self $child): bool { return $child->isChildOf($this); } /** * Determine if the current distinguished name is a child of the given parent. - * - * @param DistinguishedName $parent - * @return bool */ - public function isChildOf(self $parent) + public function isChildOf(self $parent): bool { - if ( - empty($components = $this->components()) || - empty($parentComponents = $parent->components()) - ) { + if (! $this->isComparable($this->parent(), $parent->get())) { return false; } - array_shift($components); - - return $this->compare($components, $parentComponents); + return $this->normalize($this->parent()) === $this->normalize($parent->get()); } /** * Determine if the current distinguished name is an ancestor of the descendant. - * - * @param DistinguishedName $descendant - * @return bool */ - public function isAncestorOf(self $descendant) + public function isAncestorOf(self $descendant): bool { return $descendant->isDescendantOf($this); } /** * Determine if the current distinguished name is a descendant of the ancestor. - * - * @param DistinguishedName $ancestor - * @return bool */ - public function isDescendantOf(self $ancestor) + public function isDescendantOf(self $ancestor): bool { - if ( - empty($components = $this->components()) || - empty($ancestorComponents = $ancestor->components()) - ) { + if (! $this->isComparable($this->parent(), $ancestor->get())) { return false; } - if (! $length = count($components) - count($ancestorComponents)) { + return str_ends_with( + $this->normalize($this->parent()), + $this->normalize($ancestor->get()) + ); + } + + /** + * Determine if the current distinguished name is a sibling of the given distinguished name. + */ + public function isSiblingOf(self $sibling): bool + { + if (! $this->isComparable($this->parent(), $sibling->parent())) { return false; } - array_splice($components, $offset = 0, $length); - - return $this->compare($components, $ancestorComponents); + return $this->normalize($this->parent()) === $this->normalize($sibling->parent()); } /** - * Compare whether the two distinguished name values are equal. - * - * @param array $values - * @param array $other - * @return bool + * Determine if the distinguished names are comparable. */ - protected function compare(array $values, array $other) + protected function isComparable(?string $first, ?string $second): bool { - return $this->recase($values) == $this->recase($other); - } - - /** - * Recase the array values. - * - * @param array $values - * @return array - */ - protected function recase(array $values) - { - return array_map([$this, 'normalize'], $values); + return static::make($first)->isNotEmpty() && static::make($second)->isNotEmpty(); } /** * Normalize the string value. - * - * @param string $value - * @return string */ - protected function normalize($value) + protected function normalize(string $value): string { return strtolower($value); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php index a0d84d828..7345cb92d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php @@ -4,67 +4,53 @@ namespace LdapRecord\Models\Attributes; use LdapRecord\EscapesValues; use LdapRecord\Support\Arr; +use Stringable; -class DistinguishedNameBuilder +class DistinguishedNameBuilder implements Stringable { use EscapesValues; /** * The components of the DN. - * - * @var array */ - protected $components = []; + protected array $components = []; /** * Whether to output the DN in reverse. - * - * @var bool */ - protected $reverse = false; + protected bool $reverse = false; /** * Constructor. - * - * @param string|null $value */ public function __construct($dn = null) { - $this->components = array_map(function ($rdn) { - return DistinguishedName::explodeRdn($rdn); - }, DistinguishedName::make($dn)->components()); + $this->components = array_map( + fn ($rdn) => DistinguishedName::explodeRdn($rdn), + DistinguishedName::make($dn)->components() + ); } /** * Forward missing method calls onto the Distinguished Name object. - * - * @param string $method - * @param array $args - * @return mixed */ - public function __call($method, $args) + public function __call(string $method, array $args): mixed { return $this->get()->{$method}(...$args); } /** * Get the distinguished name value. - * - * @return string */ - public function __toString() + public function __toString(): string { return (string) $this->get(); } /** * Prepend an RDN onto the DN. - * - * @param string|array $attribute - * @param string|null $value - * @return $this */ - public function prepend($attribute, $value = null) + public function prepend(array|string $attribute, ?string $value = null): static { array_unshift( $this->components, @@ -76,12 +62,8 @@ class DistinguishedNameBuilder /** * Append an RDN onto the DN. - * - * @param string|array $attribute - * @param string|null $value - * @return $this */ - public function append($attribute, $value = null) + public function append(array|string $attribute, ?string $value = null): static { array_push( $this->components, @@ -93,12 +75,8 @@ class DistinguishedNameBuilder /** * Componentize the attribute and value. - * - * @param string|array $attribute - * @param string|null $value - * @return array */ - protected function componentize($attribute, $value = null) + protected function componentize(array|string $attribute, ?string $value = null): array { // Here we will make the assumption that an array of // RDN's have been given if the value is null, and @@ -120,65 +98,50 @@ class DistinguishedNameBuilder /** * Make a componentized array by exploding the value if it's a string. - * - * @param string $value - * @return array */ - protected function makeComponentizedArray($value) + protected function makeComponentizedArray(array|string $value): array { return is_array($value) ? $value : DistinguishedName::explodeRdn($value); } /** * Make an appendable component array from the attribute and value. - * - * @param string|array $attribute - * @param string|null $value - * @return array */ - protected function makeAppendableComponent($attribute, $value = null) + protected function makeAppendableComponent(string|array $attribute, ?string $value = null): array { - return [trim($attribute), $this->escape(trim($value))->dn()]; + return [trim($attribute), $this->escape(trim($value))->forDn()]; } /** * Pop an RDN off of the end of the DN. - * - * @param int $amount - * @param array $removed - * @return $this */ - public function pop($amount = 1, &$removed = []) + public function pop(int $amount = 1, ?array &$removed = null): static { - $removed = array_map(function ($component) { - return DistinguishedName::makeRdn($component); - }, array_splice($this->components, -$amount, $amount)); + $removed = array_map( + fn ($component) => DistinguishedName::makeRdn($component), + array_splice($this->components, -$amount, $amount) + ); return $this; } /** * Shift an RDN off of the beginning of the DN. - * - * @param int $amount - * @param array $removed - * @return $this */ - public function shift($amount = 1, &$removed = []) + public function shift(int $amount = 1, ?array &$removed = null): static { - $removed = array_map(function ($component) { - return DistinguishedName::makeRdn($component); - }, array_splice($this->components, 0, $amount)); + $removed = array_map( + fn ($component) => DistinguishedName::makeRdn($component), + array_splice($this->components, 0, $amount) + ); return $this; } /** * Whether to output the DN in reverse. - * - * @return $this */ - public function reverse() + public function reverse(): static { $this->reverse = true; @@ -187,11 +150,8 @@ class DistinguishedNameBuilder /** * Get the components of the DN. - * - * @param null|string $type - * @return array */ - public function components($type = null) + public function components(?string $type = null): array { return is_null($type) ? $this->components @@ -200,42 +160,36 @@ class DistinguishedNameBuilder /** * Get the components of a particular type. - * - * @param string $type - * @return array */ - protected function componentsOfType($type) + protected function componentsOfType(string $type): array { - $components = array_filter($this->components, function ($component) use ($type) { - return ([$name] = $component) && strtolower($name) === strtolower($type); - }); + $components = array_filter($this->components, fn ($component) => ( + ([$name] = $component) && strtolower($name) === strtolower($type) + )); return array_values($components); } /** * Get the fully qualified DN. - * - * @return DistinguishedName */ - public function get() + public function get(): DistinguishedName { return new DistinguishedName($this->build()); } /** * Build the distinguished name from the components. - * - * @return string */ - protected function build() + protected function build(): string { $components = $this->reverse ? array_reverse($this->components) : $this->components; - return implode(',', array_map(function ($component) { - return DistinguishedName::makeRdn($component); - }, $components)); + return implode(',', array_map( + fn ($component) => DistinguishedName::makeRdn($component), + $components + )); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php index 3c9d4db0a..c28d95c20 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php @@ -2,80 +2,75 @@ namespace LdapRecord\Models\Attributes; -class EscapedValue +use Stringable; + +class EscapedValue implements Stringable { /** * The value to be escaped. - * - * @var string */ - protected $value; + protected mixed $value; /** * The characters to ignore when escaping. - * - * @var string */ - protected $ignore; + protected string $ignore; /** * The escape flags. - * - * @var int */ - protected $flags; + protected int $flags; /** * Constructor. - * - * @param string $value - * @param string $ignore - * @param int $flags */ - public function __construct($value, $ignore = '', $flags = 0) + public function __construct(mixed $value, string $ignore = '', int $flags = 0) { - $this->value = (string) $value; + $this->value = $value; $this->ignore = $ignore; $this->flags = $flags; } /** - * Get the escaped value. - * - * @return string + * Un-escapes a hexadecimal string into its original string representation. */ - public function __toString() + public static function unescape(string $value): string { - return (string) $this->get(); + return preg_replace_callback( + '/\\\([0-9A-Fa-f]{2})/', + fn ($matches) => chr(hexdec($matches[1])), + $value + ); } /** * Get the escaped value. - * - * @return mixed */ - public function get() + public function __toString(): string { - return ldap_escape($this->value, $this->ignore, $this->flags); + return $this->get(); + } + + /** + * Get the escaped value. + */ + public function get(): string + { + return ldap_escape((string) $this->value, $this->ignore, $this->flags); } /** * Get the raw (unescaped) value. - * - * @return mixed */ - public function raw() + public function getRaw(): mixed { return $this->value; } /** * Set the characters to exclude from being escaped. - * - * @param string $characters - * @return $this */ - public function ignore($characters) + public function ignore(string $characters): static { $this->ignore = $characters; @@ -84,10 +79,8 @@ class EscapedValue /** * Prepare the value to be escaped for use in a distinguished name. - * - * @return $this */ - public function dn() + public function forDn(): static { $this->flags = LDAP_ESCAPE_DN; @@ -96,10 +89,8 @@ class EscapedValue /** * Prepare the value to be escaped for use in a filter. - * - * @return $this */ - public function filter() + public function forFilter(): static { $this->flags = LDAP_ESCAPE_FILTER; @@ -108,10 +99,8 @@ class EscapedValue /** * Prepare the value to be escaped for use in a distinguished name and filter. - * - * @return $this */ - public function both() + public function forDnAndFilter(): static { $this->flags = LDAP_ESCAPE_FILTER + LDAP_ESCAPE_DN; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php index e04b5cd3f..dfde16429 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php @@ -3,33 +3,14 @@ namespace LdapRecord\Models\Attributes; use InvalidArgumentException; -use LdapRecord\Utilities; +use Stringable; -class Guid +class Guid implements Stringable { /** * The string GUID value. - * - * @var string */ - protected $value; - - /** - * The guid structure in order by section to parse using substr(). - * - * @author Chad Sikorra - * - * @see https://github.com/ldaptools/ldaptools - * - * @var array - */ - protected $guidSections = [ - [[-26, 2], [-28, 2], [-30, 2], [-32, 2]], - [[-22, 2], [-24, 2]], - [[-18, 2], [-20, 2]], - [[-16, 4]], - [[-12, 12]], - ]; + protected ?string $value = null; /** * The hexadecimal octet order based on string position. @@ -37,10 +18,8 @@ class Guid * @author Chad Sikorra * * @see https://github.com/ldaptools/ldaptools - * - * @var array */ - protected $octetSections = [ + protected array $octetSections = [ [6, 4, 2, 0], [10, 8], [14, 12], @@ -48,24 +27,19 @@ class Guid ]; /** - * Determines if the specified GUID is valid. - * - * @param string $guid - * @return bool + * Determine if the specified GUID is valid. */ - public static function isValid($guid) + public static function isValid(string $guid): bool { - return Utilities::isValidGuid($guid); + return (bool) preg_match('/^([0-9a-fA-F]){8}(-([0-9a-fA-F]){4}){3}-([0-9a-fA-F]){12}$/', $guid); } /** * Constructor. * - * @param mixed $value - * * @throws InvalidArgumentException */ - public function __construct($value) + public function __construct(string $value) { if (static::isValid($value)) { $this->value = $value; @@ -77,66 +51,83 @@ class Guid } /** - * Returns the string value of the GUID. - * - * @return string + * Get the string value of the GUID. */ - public function __toString() + public function __toString(): string { return $this->getValue(); } /** - * Returns the string value of the SID. - * - * @return string + * Get the string value of the GUID. */ - public function getValue() + public function getValue(): string { return $this->value; } /** * Get the binary representation of the GUID string. - * - * @return string */ - public function getBinary() + public function getBinary(): string { return hex2bin($this->getHex()); } /** - * Get the hexadecimal representation of the GUID string. - * - * @return string + * Get the encoded hexadecimal representation of the GUID string. */ - public function getHex() + public function getEncodedHex(): string { - $data = ''; + return '\\'.implode('\\', str_split($this->getHex(), 2)); + } + + /** + * Get the hexadecimal representation of the GUID string. + */ + public function getHex(): string + { + return implode($this->getOctetSections()); + } + + /** + * Get the octect sections of the GUID. + */ + protected function getOctetSections(): array + { + $sections = []; $guid = str_replace('-', '', $this->value); foreach ($this->octetSections as $section) { - $data .= $this->parseSection($guid, $section, $octet = true); + $sections[] = $this->parseSection($guid, $section, true); } - return $data; + return $sections; } /** - * Returns the string variant of a binary GUID. - * - * @param string $binary - * @return string|null + * Get the string variant of a binary GUID. */ - protected function binaryGuidToString($binary) + protected function binaryGuidToString(string $binary): ?string { - return Utilities::binaryGuidToString($binary); + if (trim($binary) === '') { + return null; + } + + $hex = unpack('H*hex', $binary)['hex']; + + $hex1 = substr($hex, -26, 2).substr($hex, -28, 2).substr($hex, -30, 2).substr($hex, -32, 2); + $hex2 = substr($hex, -22, 2).substr($hex, -24, 2); + $hex3 = substr($hex, -18, 2).substr($hex, -20, 2); + $hex4 = substr($hex, -16, 4); + $hex5 = substr($hex, -12, 12); + + return sprintf('%s-%s-%s-%s-%s', $hex1, $hex2, $hex3, $hex4, $hex5); } /** - * Return the specified section of the hexadecimal string. + * Get the specified section of the hexadecimal string. * * @author Chad Sikorra * @@ -147,7 +138,7 @@ class Guid * @param bool $octet Whether this is for octet string form. * @return string The concatenated sections in upper-case. */ - protected function parseSection($hex, array $sections, $octet = false) + protected function parseSection(string $hex, array $sections, bool $octet = false): string { $parsedString = ''; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php index 72d4c6f48..c6eb4985e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php @@ -6,11 +6,8 @@ class MbString { /** * Get the integer value of a specific character. - * - * @param $string - * @return int */ - public static function ord($string) + public static function ord(string $string): int { if (static::isLoaded()) { $result = unpack('N', mb_convert_encoding($string, 'UCS-4BE', 'UTF-8')); @@ -25,11 +22,8 @@ class MbString /** * Get the character for a specific integer value. - * - * @param $int - * @return string */ - public static function chr($int) + public static function chr(int $int): string { if (static::isLoaded()) { return mb_convert_encoding(pack('n', $int), 'UTF-8', 'UTF-16BE'); @@ -40,36 +34,28 @@ class MbString /** * Split a string into its individual characters and return it as an array. - * - * @param string $value - * @return string[] */ - public static function split($value) + public static function split(string $value): array { return preg_split('/(? ['$1$', 12], + static::CRYPT_SALT_TYPE_SHA256 => ['$5$', 16], + static::CRYPT_SALT_TYPE_SHA512 => ['$6$', 16], + default => throw new InvalidArgumentException("Invalid crypt type [$type]."), + }; } /** * Attempt to retrieve the hash method used for the password. - * - * @param string $password - * @return string|void */ - public static function getHashMethod($password) + public static function getHashMethod(string $password): ?string { if (! preg_match('/^\{(\w+)\}/', $password, $matches)) { - return; + return null; } return $matches[1]; @@ -272,14 +198,11 @@ class Password /** * Attempt to retrieve the hash method and algorithm used for the password. - * - * @param string $password - * @return array|void */ - public static function getHashMethodAndAlgo($password) + public static function getHashMethodAndAlgo(string $password): ?array { if (! preg_match('/^\{(\w+)\}\$([0-9a-z]{1})\$/', $password, $matches)) { - return; + return null; } return [$matches[1], $matches[2]]; @@ -288,11 +211,9 @@ class Password /** * Attempt to retrieve a salt from the encrypted password. * - * @return string - * * @throws LdapRecordException */ - public static function getSalt($encryptedPassword) + public static function getSalt(string $encryptedPassword): string { // crypt() methods. if (preg_match('/^\{(\w+)\}(\$.*\$).*$/', $encryptedPassword, $matches)) { @@ -310,12 +231,9 @@ class Password /** * Determine if the hash method requires a salt to be given. * - * @param string $method - * @return bool - * * @throws \ReflectionException */ - public static function hashMethodRequiresSalt($method): bool + public static function hashMethodRequiresSalt(string $method): bool { $parameters = (new ReflectionMethod(static::class, $method))->getParameters(); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php index 7760453ce..08c36267c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php @@ -3,36 +3,29 @@ namespace LdapRecord\Models\Attributes; use InvalidArgumentException; -use LdapRecord\Utilities; +use Stringable; -class Sid +class Sid implements Stringable { /** * The string SID value. - * - * @var string */ - protected $value; + protected string $value; /** - * Determines if the specified SID is valid. - * - * @param string $sid - * @return bool + * Determine if the specified SID is valid. */ - public static function isValid($sid) + public static function isValid(string $sid): bool { - return Utilities::isValidSid($sid); + return (bool) preg_match("/^S-\d(-\d{1,10}){1,16}$/i", $sid); } /** * Constructor. * - * @param mixed $value - * * @throws InvalidArgumentException */ - public function __construct($value) + public function __construct(string $value) { if (static::isValid($value)) { $this->value = $value; @@ -44,31 +37,25 @@ class Sid } /** - * Returns the string value of the SID. - * - * @return string + * Get the string value of the SID. */ - public function __toString() + public function __toString(): string { return $this->getValue(); } /** - * Returns the string value of the SID. - * - * @return string + * Get the string value of the SID. */ - public function getValue() + public function getValue(): string { return $this->value; } /** - * Returns the binary variant of the SID. - * - * @return string + * Get the binary variant of the SID. */ - public function getBinary() + public function getBinary(): string { $sid = explode('-', ltrim($this->value, 'S-')); @@ -87,13 +74,50 @@ class Sid } /** - * Returns the string variant of a binary SID. - * - * @param string $binary - * @return string|null + * Get the string variant of a binary SID. */ - protected function binarySidToString($binary) + protected function binarySidToString(string $binary): ?string { - return Utilities::binarySidToString($binary); + if (trim($binary) === '') { + return null; + } + + // Revision - 8bit unsigned int (C1) + // Count - 8bit unsigned int (C1) + // 2 null bytes + // ID - 32bit unsigned long, big-endian order + $sid = @unpack('C1rev/C1count/x2/N1id', $binary); + + if (! isset($sid['id']) || ! isset($sid['rev'])) { + return null; + } + + $revisionLevel = $sid['rev']; + + $identifierAuthority = $sid['id']; + + $subs = $sid['count'] ?? 0; + + $sidHex = $subs ? bin2hex($binary) : ''; + + $subAuthorities = []; + + // The sub-authorities depend on the count, so only get as + // many as the count, regardless of data beyond it. + for ($i = 0; $i < $subs; $i++) { + $data = implode(array_reverse( + str_split( + substr($sidHex, 16 + ($i * 8), 8), + 2 + ) + )); + + $subAuthorities[] = hexdec($data); + } + + // Tack on the 'S-' and glue it all together... + return 'S-'.$revisionLevel.'-'.$identifierAuthority.implode( + preg_filter('/^/', '-', $subAuthorities) + ); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php index 499579f82..dd2d0ebda 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php @@ -29,10 +29,8 @@ class TSProperty * cannot find any information on them in Microsoft documentation. However, their values appear to stay in sync with * their non 'W' counterparts. But not doing so when manipulating the data manually does not seem to affect anything. * This probably needs more investigation. - * - * @var array */ - protected $propTypes = [ + protected array $propTypes = [ 'string' => [ 'CtxWFHomeDir', 'CtxWFHomeDirW', @@ -63,31 +61,23 @@ class TSProperty /** * The property name. - * - * @var string */ - protected $name; + protected ?string $name = null; /** * The property value. - * - * @var string|int */ - protected $value; + protected string|int|null $value = null; /** * The property value type. - * - * @var int */ - protected $valueType = 1; + protected int $valueType = 1; /** * Pass binary TSProperty data to construct its object representation. - * - * @param string|null $value */ - public function __construct($value = null) + public function __construct(string|int|null $value = null) { if ($value) { $this->decode(bin2hex($value)); @@ -96,11 +86,8 @@ class TSProperty /** * Set the name for the TSProperty. - * - * @param string $name - * @return TSProperty */ - public function setName($name) + public function setName(string $name): static { $this->name = $name; @@ -109,21 +96,16 @@ class TSProperty /** * Get the name for the TSProperty. - * - * @return string */ - public function getName() + public function getName(): ?string { return $this->name; } /** * Set the value for the TSProperty. - * - * @param string|int $value - * @return TSProperty */ - public function setValue($value) + public function setValue(string|int $value): static { $this->value = $value; @@ -132,10 +114,8 @@ class TSProperty /** * Get the value for the TSProperty. - * - * @return string|int */ - public function getValue() + public function getValue(): string|int|null { return $this->value; } @@ -143,10 +123,8 @@ class TSProperty /** * Convert the TSProperty name/value back to its binary * representation for the userParameters blob. - * - * @return string */ - public function toBinary() + public function toBinary(): string { $name = bin2hex($this->name); @@ -166,10 +144,8 @@ class TSProperty /** * Given a TSProperty blob, decode the name/value/type/etc. - * - * @param string $tsProperty */ - protected function decode($tsProperty) + protected function decode(string $tsProperty): void { $nameLength = hexdec(substr($tsProperty, 0, 2)); @@ -183,12 +159,8 @@ class TSProperty /** * Based on the property name/value in question, get its encoded form. - * - * @param string $propName - * @param string|int $propValue - * @return string */ - protected function getEncodedValueForProp($propName, $propValue) + protected function getEncodedValueForProp(string $propName, string|int $propValue): string { if (in_array($propName, $this->propTypes['string'])) { // Simple strings are null terminated. Unsure if this is @@ -206,12 +178,8 @@ class TSProperty /** * Based on the property name in question, get its actual value from the binary blob value. - * - * @param string $propName - * @param string $propValue - * @return string|int */ - protected function getDecodedValueForProp($propName, $propValue) + protected function getDecodedValueForProp(string $propName, string $propValue): string|int { if (in_array($propName, $this->propTypes['string'])) { // Strip away null terminators. I think this should @@ -234,11 +202,9 @@ class TSProperty * Decode the property by inspecting the nibbles of each blob, checking * the control, and adding up the results into a final value. * - * @param string $hex - * @param bool $string Whether or not this is simple string data. - * @return string + * @param bool $string Whether this is simple string data. */ - protected function decodePropValue($hex, $string = false) + protected function decodePropValue(string $hex, bool $string = false): string { $decodePropValue = ''; @@ -266,12 +232,8 @@ class TSProperty /** * Get the encoded property value as a binary blob. - * - * @param string $value - * @param bool $string - * @return string */ - protected function encodePropValue($value, $string = false) + protected function encodePropValue(string $value, bool $string = false): string { // An int must be properly padded. (then split and reversed). // For a string, we just split the chars. This seems @@ -307,12 +269,8 @@ class TSProperty * PHP's pack() function has no 'b' or 'B' template. This is * a workaround that turns a literal bit-string into a * packed byte-string with 8 bits per byte. - * - * @param string $bits - * @param bool $len - * @return string */ - protected function packBitString($bits, $len) + protected function packBitString(string $bits, int $len): string { $bits = substr($bits, 0, $len); // Pad input with zeros to next multiple of 4 above $len @@ -329,12 +287,8 @@ class TSProperty /** * Based on the control, adjust the nibble accordingly. - * - * @param string $nibble - * @param string $control - * @return string */ - protected function nibbleControl($nibble, $control) + protected function nibbleControl(string $nibble, string $control): string { // This control stays constant for the low/high nibbles, // so it doesn't matter which we compare to @@ -355,10 +309,8 @@ class TSProperty * must be subtracted by 9 before the final value is constructed. * * @param string $nibbleType Either X or Y - * @param string $nibble - * @return string */ - protected function getNibbleWithControl($nibbleType, $nibble) + protected function getNibbleWithControl(string $nibbleType, string $nibble): string { $dec = bindec($nibble); @@ -375,11 +327,9 @@ class TSProperty /** * Need to make sure hex values are always an even length, so pad as needed. * - * @param int $int * @param int $padLength The hex string must be padded to this length (with zeros). - * @return string */ - protected function dec2hex($int, $padLength = 2) + protected function dec2hex(int $int, int $padLength = 2): string { return str_pad(dechex($int), $padLength, 0, STR_PAD_LEFT); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php index 8320dd8ed..a81018143 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php @@ -36,33 +36,31 @@ class TSPropertyArray ]; /** - * @var string The default data that occurs before the TSPropertyArray (CtxCfgPresent with a bunch of spaces...?) + * The default data that occurs before the TSPropertyArray (CtxCfgPresent with a bunch of spaces...?). */ - protected $defaultPreBinary = '43747843666750726573656e742020202020202020202020202020202020202020202020202020202020202020202020'; + protected string $defaultPreBinary = '43747843666750726573656e742020202020202020202020202020202020202020202020202020202020202020202020'; /** + * The TSProperty array. + * * @var TSProperty[] */ - protected $tsProperty = []; + protected array $tsProperty = []; /** - * @var string + * The TSProperty signature. */ - protected $signature = self::VALID_SIGNATURE; + protected string $signature = self::VALID_SIGNATURE; /** * Binary data that occurs before the TSPropertyArray data in userParameters. - * - * @var string */ - protected $preBinary = ''; + protected string $preBinary = ''; /** * Binary data that occurs after the TSPropertyArray data in userParameters. - * - * @var string */ - protected $postBinary = ''; + protected string $postBinary = ''; /** * Construct in one of the following ways:. @@ -70,10 +68,8 @@ class TSPropertyArray * - Pass an array of TSProperty key => value pairs (See DEFAULTS constant). * - Pass the userParameters binary value. The object representation of that will be decoded and constructed. * - Pass nothing and a default set of TSProperty key => value pairs will be used (See DEFAULTS constant). - * - * @param mixed $tsPropertyArray */ - public function __construct($tsPropertyArray = null) + public function __construct(mixed $tsPropertyArray = null) { $this->preBinary = hex2bin($this->defaultPreBinary); @@ -81,7 +77,7 @@ class TSPropertyArray $tsPropertyArray = $tsPropertyArray ?: self::DEFAULTS; foreach ($tsPropertyArray as $key => $value) { - $tsProperty = new TSProperty(); + $tsProperty = new TSProperty; $this->tsProperty[$key] = $tsProperty->setName($key)->setValue($value); } @@ -92,22 +88,16 @@ class TSPropertyArray /** * Check if a specific TSProperty exists by its property name. - * - * @param string $propName - * @return bool */ - public function has($propName) + public function has(string $propName): bool { return array_key_exists(strtolower($propName), array_change_key_case($this->tsProperty)); } /** * Get a TSProperty object by its property name (ie. CtxWFProfilePath). - * - * @param string $propName - * @return TSProperty */ - public function get($propName) + public function get(string $propName): TSProperty { $this->validateProp($propName); @@ -116,11 +106,8 @@ class TSPropertyArray /** * Add a TSProperty object. If it already exists, it will be overwritten. - * - * @param TSProperty $tsProperty - * @return $this */ - public function add(TSProperty $tsProperty) + public function add(TSProperty $tsProperty): static { $this->tsProperty[$tsProperty->getName()] = $tsProperty; @@ -128,12 +115,9 @@ class TSPropertyArray } /** - * Remove a TSProperty by its property name (ie. CtxMinEncryptionLevel). - * - * @param string $propName - * @return $this + * Remove a TSProperty by its property name (i.e. CtxMinEncryptionLevel). */ - public function remove($propName) + public function remove(string $propName): static { foreach (array_keys($this->tsProperty) as $property) { if (strtolower($propName) == strtolower($property)) { @@ -146,12 +130,8 @@ class TSPropertyArray /** * Set the value for a specific TSProperty by its name. - * - * @param string $propName - * @param mixed $propValue - * @return $this */ - public function set($propName, $propValue) + public function set(string $propName, string|int $propValue): static { $this->validateProp($propName); @@ -162,10 +142,8 @@ class TSPropertyArray /** * Get the full binary representation of the userParameters containing the TSPropertyArray data. - * - * @return string */ - public function toBinary() + public function toBinary(): string { $binary = $this->preBinary; @@ -182,10 +160,8 @@ class TSPropertyArray /** * Get a simple associative array containing of all TSProperty names and values. - * - * @return array */ - public function toArray() + public function toArray(): array { $userParameters = []; @@ -201,17 +177,15 @@ class TSPropertyArray * * @return TSProperty[] */ - public function getTSProperties() + public function getTSProperties(): array { return $this->tsProperty; } /** * Validates that the given property name exists. - * - * @param string $propName */ - protected function validateProp($propName) + protected function validateProp(string $propName): void { if (! $this->has($propName)) { throw new InvalidArgumentException(sprintf('TSProperty for "%s" does not exist.', $propName)); @@ -219,21 +193,17 @@ class TSPropertyArray } /** - * @param string $propName - * @return TSProperty + * Get the TS property object for the given property. */ - protected function getTsPropObj($propName) + protected function getTsPropObj(string $propName): TSProperty { return array_change_key_case($this->tsProperty)[strtolower($propName)]; } /** - * Get an associative array with all of the userParameters property names and values. - * - * @param string $userParameters - * @return void + * Get an associative array with all the userParameters property names and values. */ - protected function decodeUserParameters($userParameters) + protected function decodeUserParameters(string $userParameters): void { $userParameters = bin2hex($userParameters); @@ -263,11 +233,9 @@ class TSPropertyArray * individual TSProperty structures. Return the full length * of the TSPropertyArray data. * - * @param string $tsPropertyArray - * @param int $tsPropCount * @return int The length of the data in the TSPropertyArray */ - protected function addTSPropData($tsPropertyArray, $tsPropCount) + protected function addTSPropData(string $tsPropertyArray, int $tsPropCount): int { $length = 0; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php index 0f07bc5a0..4046eb715 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php @@ -7,38 +7,37 @@ use Carbon\CarbonInterface; use DateTime; use DateTimeZone; use LdapRecord\LdapRecordException; -use LdapRecord\Utilities; class Timestamp { + public const TYPE_LDAP = 'ldap'; + + public const TYPE_WINDOWS = 'windows'; + + public const TYPE_WINDOWS_INT = 'windows-int'; + public const WINDOWS_INT_MAX = 9223372036854775807; /** * The current timestamp type. - * - * @var string */ - protected $type; + protected string $type; /** * The available timestamp types. - * - * @var array */ - protected $types = [ - 'ldap', - 'windows', - 'windows-int', + protected array $types = [ + Timestamp::TYPE_LDAP, + Timestamp::TYPE_WINDOWS, + Timestamp::TYPE_WINDOWS_INT, ]; /** * Constructor. * - * @param string $type - * * @throws LdapRecordException */ - public function __construct($type) + public function __construct(string $type) { $this->setType($type); } @@ -46,11 +45,9 @@ class Timestamp /** * Set the type of timestamp to convert from / to. * - * @param string $type - * * @throws LdapRecordException */ - public function setType($type) + public function setType(string $type): void { if (! in_array($type, $this->types)) { throw new LdapRecordException("Unrecognized LDAP date type [$type]"); @@ -62,18 +59,15 @@ class Timestamp /** * Converts the value to an LDAP date string. * - * @param mixed $value - * @return float|string - * * @throws LdapRecordException */ - public function fromDateTime($value) + public function fromDateTime(mixed $value): int|string { $value = is_array($value) ? reset($value) : $value; - // If the value is being converted to a windows integer format but it + // If the value is being converted to a windows integer format, but it // is already in that format, we will simply return the value back. - if ($this->type == 'windows-int' && $this->valueIsWindowsIntegerType($value)) { + if ($this->type === Timestamp::TYPE_WINDOWS_INT && $this->valueIsWindowsIntegerType($value)) { return $value; } // If the value is numeric, we will assume it's a UNIX timestamp. @@ -89,30 +83,18 @@ class Timestamp $value = Carbon::instance($value); } - switch ($this->type) { - case 'ldap': - $value = $this->convertDateTimeToLdapTime($value); - break; - case 'windows': - $value = $this->convertDateTimeToWindows($value); - break; - case 'windows-int': - $value = $this->convertDateTimeToWindowsInteger($value); - break; - default: - throw new LdapRecordException("Unrecognized date type [{$this->type}]"); - } - - return $value; + return match ($this->type) { + Timestamp::TYPE_LDAP => $this->convertDateTimeToLdapTime($value), + Timestamp::TYPE_WINDOWS => $this->convertDateTimeToWindows($value), + Timestamp::TYPE_WINDOWS_INT => $this->convertDateTimeToWindowsInteger($value), + default => throw new LdapRecordException("Unrecognized date type [{$this->type}]"), + }; } /** * Determine if the value given is in Windows Integer (NTFS Filetime) format. - * - * @param int|string $value - * @return bool */ - protected function valueIsWindowsIntegerType($value) + protected function valueIsWindowsIntegerType(mixed $value): bool { return is_numeric($value) && in_array(strlen((string) $value), [18, 19]); } @@ -120,12 +102,9 @@ class Timestamp /** * Converts the LDAP timestamp value to a Carbon instance. * - * @param mixed $value - * @return Carbon|int|false - * * @throws LdapRecordException */ - public function toDateTime($value) + public function toDateTime(mixed $value): Carbon|int|false { $value = is_array($value) ? reset($value) : $value; @@ -133,87 +112,70 @@ class Timestamp return Carbon::instance($value); } - switch ($this->type) { - case 'ldap': - $value = $this->convertLdapTimeToDateTime($value); - break; - case 'windows': - $value = $this->convertWindowsTimeToDateTime($value); - break; - case 'windows-int': - $value = $this->convertWindowsIntegerTimeToDateTime($value); - break; - default: - throw new LdapRecordException("Unrecognized date type [{$this->type}]"); - } + $value = match ($this->type) { + Timestamp::TYPE_LDAP => $this->convertLdapTimeToDateTime($value), + Timestamp::TYPE_WINDOWS => $this->convertWindowsTimeToDateTime($value), + Timestamp::TYPE_WINDOWS_INT => $this->convertWindowsIntegerTimeToDateTime($value), + default => throw new LdapRecordException("Unrecognized date type [{$this->type}]"), + }; return $value instanceof DateTime ? Carbon::instance($value) : $value; } /** * Converts standard LDAP timestamps to a date time object. - * - * @param string $value - * @return DateTime|false */ - protected function convertLdapTimeToDateTime($value) + protected function convertLdapTimeToDateTime(string $value): DateTime|false { - return DateTime::createFromFormat( - str_contains((string) $value, 'Z') ? 'YmdHis\Z' : 'YmdHisT', - $value - ); + return DateTime::createFromFormat(match (true) { + str_ends_with($value, '.000Z') => 'YmdHis.000\Z', + str_ends_with($value, '.0Z') => 'YmdHis.0\Z', + str_ends_with($value, 'Z') => 'YmdHis\Z', + default => 'YmdHisT', + }, $value); } /** * Converts date objects to a standard LDAP timestamp. - * - * @param DateTime $date - * @return string */ - protected function convertDateTimeToLdapTime(DateTime $date) + protected function convertDateTimeToLdapTime(DateTime $date): string { return $date->format( - $date->getOffset() == 0 ? 'YmdHis\Z' : 'YmdHisO' + $date->getOffset() == 0 + ? 'YmdHis\Z' + : 'YmdHisO' ); } /** * Converts standard windows timestamps to a date time object. - * - * @param string $value - * @return DateTime|false */ - protected function convertWindowsTimeToDateTime($value) + protected function convertWindowsTimeToDateTime(string $value): DateTime|false { - return DateTime::createFromFormat( - str_contains((string) $value, '0Z') ? 'YmdHis.0\Z' : 'YmdHis.0T', - $value, - new DateTimeZone('UTC') - ); + return DateTime::createFromFormat(match (true) { + str_ends_with($value, '.0Z') => 'YmdHis.0\Z', + default => 'YmdHis.0T' + }, $value, new DateTimeZone('UTC')); } /** * Converts date objects to a windows timestamp. - * - * @param DateTime $date - * @return string */ - protected function convertDateTimeToWindows(DateTime $date) + protected function convertDateTimeToWindows(DateTime $date): string { return $date->format( - $date->getOffset() == 0 ? 'YmdHis.0\Z' : 'YmdHis.0O' + $date->getOffset() == 0 + ? 'YmdHis.0\Z' + : 'YmdHis.0O' ); } /** * Converts standard windows integer dates to a date time object. * - * @param int $value - * @return DateTime|int|false - * * @throws \Exception */ - protected function convertWindowsIntegerTimeToDateTime($value) + protected function convertWindowsIntegerTimeToDateTime(string|int|null $value = null): DateTime|int|false { if (is_null($value) || $value === '') { return false; @@ -227,19 +189,16 @@ class Timestamp return (int) $value; } - return (new DateTime())->setTimestamp( - Utilities::convertWindowsTimeToUnixTime($value) + return (new DateTime)->setTimestamp( + (int) ($value / 10000000) - 11644473600 ); } /** * Converts date objects to a windows integer timestamp. - * - * @param DateTime $date - * @return float */ - protected function convertDateTimeToWindowsInteger(DateTime $date) + protected function convertDateTimeToWindowsInteger(DateTime $date): int { - return Utilities::convertUnixTimeToWindowsTime($date->getTimestamp()); + return ($date->getTimestamp() + 11644473600) * 10000000; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php index 954c58fcf..3b153095d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php @@ -9,48 +9,38 @@ class BatchModification use DetectsResetIntegers; /** - * The array keys to be used in batch modifications. + * The array key identifiers. */ public const KEY_ATTRIB = 'attrib'; + public const KEY_MODTYPE = 'modtype'; + public const KEY_VALUES = 'values'; /** * The attribute of the modification. - * - * @var string|null */ - protected $attribute; + protected ?string $attribute = null; /** * The original value of the attribute before modification. - * - * @var array */ - protected $original = []; + protected array $original = []; /** * The values of the modification. - * - * @var array */ - protected $values = []; + protected array $values = []; /** * The modtype integer of the batch modification. - * - * @var int|null */ - protected $type; + protected ?int $type = null; /** * Constructor. - * - * @param string|null $attribute - * @param string|int|null $type - * @param array $values */ - public function __construct($attribute = null, $type = null, array $values = []) + public function __construct(?string $attribute = null, ?int $type = null, array $values = []) { $this->setAttribute($attribute) ->setType($type) @@ -58,12 +48,17 @@ class BatchModification } /** - * Set the original value of the attribute before modification. - * - * @param array|string $original - * @return $this + * Make a new batch modification instance. */ - public function setOriginal($original = []) + public static function make(?string $attribute = null, ?int $type = null, array $values = []): self + { + return new static($attribute, $type, $values); + } + + /** + * Set the original value of the attribute before modification. + */ + public function setOriginal(array|string $original = []): static { $this->original = $this->normalizeAttributeValues($original); @@ -71,22 +66,17 @@ class BatchModification } /** - * Returns the original value of the attribute before modification. - * - * @return array + * Get the original value of the attribute before modification. */ - public function getOriginal() + public function getOriginal(): array { return $this->original; } /** * Set the attribute of the modification. - * - * @param string $attribute - * @return $this */ - public function setAttribute($attribute) + public function setAttribute(?string $attribute = null): static { $this->attribute = $attribute; @@ -94,64 +84,51 @@ class BatchModification } /** - * Returns the attribute of the modification. - * - * @return string + * Get the attribute of the modification. */ - public function getAttribute() + public function getAttribute(): string { return $this->attribute; } /** * Set the values of the modification. - * - * @param array $values - * @return $this */ - public function setValues(array $values = []) + public function setValues(array $values = []): static { // Null and empty values must also not be added to a batch // modification. Passing null or empty values will result // in an exception when trying to save the modification. $this->values = array_filter($this->normalizeAttributeValues($values), function ($value) { - return is_numeric($value) && $this->valueIsResetInteger((int) $value) ?: ! empty($value); + return is_numeric($value) && $this->valueIsResetInteger((int) $value) || ! empty($value); }); return $this; } /** - * Normalize all of the attribute values. - * - * @param array|string $values - * @return array + * Normalize all the attribute values. */ - protected function normalizeAttributeValues($values = []) + protected function normalizeAttributeValues(array|string $values = []): array { - // We must convert all of the values to strings. Only strings can + // We must convert all the values to strings. Only strings can // be used in batch modifications, otherwise we will we will // receive an LDAP exception while attempting to save. return array_map('strval', (array) $values); } /** - * Returns the values of the modification. - * - * @return array + * Get the values of the modification. */ - public function getValues() + public function getValues(): array { return $this->values; } /** * Set the type of the modification. - * - * @param int|null $type - * @return $this */ - public function setType($type = null) + public function setType(?int $type = null): static { if (is_null($type)) { return $this; @@ -167,21 +144,17 @@ class BatchModification } /** - * Returns the type of the modification. - * - * @return int + * Get the type of the modification. */ - public function getType() + public function getType(): ?int { return $this->type; } /** - * Determines if the batch modification is valid in its current state. - * - * @return bool + * Determine if the batch modification is valid in its current state. */ - public function isValid() + public function isValid(): bool { return ! is_null($this->get()); } @@ -189,51 +162,43 @@ class BatchModification /** * Builds the type of modification automatically * based on the current and original values. - * - * @return $this */ - public function build() + public function build(): static { - switch (true) { - case empty($this->original) && empty($this->values): - return $this; - case ! empty($this->original) && empty($this->values): - return $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL); - case empty($this->original) && ! empty($this->values): - return $this->setType(LDAP_MODIFY_BATCH_ADD); - default: - return $this->determineBatchTypeFromOriginal(); - } + return match (true) { + empty($this->original) && empty($this->values) => $this, + + ! empty($this->original) && empty($this->values) => $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL), + + empty($this->original) && ! empty($this->values) => $this->setType(LDAP_MODIFY_BATCH_ADD), + + default => $this->determineBatchTypeFromOriginal(), + }; } /** * Determine the batch modification type from the original values. - * - * @return $this */ - protected function determineBatchTypeFromOriginal() + protected function determineBatchTypeFromOriginal(): static { $added = $this->getAddedValues(); $removed = $this->getRemovedValues(); - switch (true) { - case ! empty($added) && ! empty($removed): - return $this->setType(LDAP_MODIFY_BATCH_REPLACE); - case ! empty($added): - return $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD); - case ! empty($removed): - return $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE); - default: - return $this; - } + return match (true) { + ! empty($added) && ! empty($removed) => $this->setType(LDAP_MODIFY_BATCH_REPLACE), + + ! empty($added) => $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD), + + ! empty($removed) => $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE), + + default => $this, + }; } /** * Get the values that were added to the attribute. - * - * @return array */ - protected function getAddedValues() + protected function getAddedValues(): array { return array_values( array_diff($this->values, $this->original) @@ -242,10 +207,8 @@ class BatchModification /** * Get the values that were removed from the attribute. - * - * @return array */ - protected function getRemovedValues() + protected function getRemovedValues(): array { return array_values( array_diff($this->original, $this->values) @@ -253,43 +216,30 @@ class BatchModification } /** - * Returns the built batch modification array. - * - * @return array|null + * Get the batch modification array. */ - public function get() + public function get(): ?array { - switch ($this->type) { - case LDAP_MODIFY_BATCH_REMOVE_ALL: - // A values key cannot be provided when - // a remove all type is selected. - return [ - static::KEY_ATTRIB => $this->attribute, - static::KEY_MODTYPE => $this->type, - ]; - case LDAP_MODIFY_BATCH_REMOVE: - // Fallthrough. - case LDAP_MODIFY_BATCH_ADD: - // Fallthrough. - case LDAP_MODIFY_BATCH_REPLACE: - return [ - static::KEY_ATTRIB => $this->attribute, - static::KEY_MODTYPE => $this->type, - static::KEY_VALUES => $this->values, - ]; - default: - // If the modtype isn't recognized, we'll return null. - return; - } + return match ($this->type) { + LDAP_MODIFY_BATCH_REMOVE_ALL => [ + static::KEY_ATTRIB => $this->attribute, + static::KEY_MODTYPE => $this->type, + ], + + LDAP_MODIFY_BATCH_REMOVE, LDAP_MODIFY_BATCH_ADD, LDAP_MODIFY_BATCH_REPLACE => [ + static::KEY_ATTRIB => $this->attribute, + static::KEY_MODTYPE => $this->type, + static::KEY_VALUES => $this->values, + ], + + default => null, + }; } /** - * Determines if the given modtype is valid. - * - * @param int $type - * @return bool + * Determine if the given modtype is valid. */ - protected function isValidType($type) + protected function isValidType(int $type): bool { return in_array($type, [ LDAP_MODIFY_BATCH_REMOVE_ALL, diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php index 11b4ca522..a0d8126a0 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php @@ -11,10 +11,8 @@ class Collection extends QueryCollection { /** * Get a collection of the model's distinguished names. - * - * @return static */ - public function modelDns() + public function modelDns(): static { return $this->map(function (Model $model) { return $model->getDn(); @@ -22,12 +20,11 @@ class Collection extends QueryCollection } /** - * Determine if the collection contains all of the given models, or any models. + * Determine if the collection contains all the given models, or any models. * - * @param mixed $models - * @return bool + * @param QueryCollection|Model|array|string|null $models */ - public function exists($models = null) + public function exists(mixed $models = null): bool { $models = $this->getArrayableModels($models); @@ -57,19 +54,11 @@ class Collection extends QueryCollection /** * Determine if any of the given models are contained in the collection. - * - * @param mixed $key - * @param mixed $operator - * @param mixed $value - * @return bool */ - public function contains($key, $operator = null, $value = null) + public function contains($key, $operator = null, $value = null): bool { if (func_num_args() > 1 || $key instanceof Closure) { - // If we are supplied with more than one argument, or - // we were passed a closure, we will utilize the - // parents contains method, for compatibility. - return parent::contains($key, $operator, $value); + return parent::contains(...func_get_args()); } foreach ($this->getArrayableModels($key) as $model) { @@ -87,25 +76,20 @@ class Collection extends QueryCollection /** * Get the provided models as an array. - * - * @param mixed $models - * @return array */ - protected function getArrayableModels($models = null) + protected function getArrayableModels(mixed $models = null): array { - return $models instanceof QueryCollection - ? $models->toArray() - : Arr::wrap($models); + if ($models instanceof QueryCollection) { + return $models->all(); + } + + return Arr::wrap($models); } /** * Compare the related model with the given. - * - * @param Model|string $model - * @param Model $related - * @return bool */ - protected function compareModelWithRelated($model, $related) + protected function compareModelWithRelated(Model|string $model, Model $related): bool { if (is_string($model)) { return $this->isValidDn($model) @@ -118,11 +102,8 @@ class Collection extends QueryCollection /** * Determine if the given string is a valid distinguished name. - * - * @param string $dn - * @return bool */ - protected function isValidDn($dn) + protected function isValidDn(string $dn): bool { return ! empty((new DistinguishedName($dn))->components()); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php index 6e8d4fb5d..e52657a44 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php @@ -7,60 +7,58 @@ trait CanAuthenticate { /** * Get the name of the unique identifier for the user. - * - * @return string */ - public function getAuthIdentifierName() + public function getAuthIdentifierName(): string { return $this->guidKey; } /** * Get the unique identifier for the user. - * - * @return string */ - public function getAuthIdentifier() + public function getAuthIdentifier(): string { - return $this->getConvertedGuid(); + return $this->getConvertedGuid( + $this->getFirstAttribute($this->getAuthIdentifierName()) + ); } /** * Get the password for the user. - * - * @return string */ - public function getAuthPassword() + public function getAuthPassword(): string { return ''; } /** - * Get the token value for the "remember me" session. - * - * @return string + * Get the name of the password attribute for the user. */ - public function getRememberToken() + public function getAuthPasswordName(): string + { + return 'password'; + } + + /** + * Get the token value for the "remember me" session. + */ + public function getRememberToken(): string { return ''; } /** * Set the token value for the "remember me" session. - * - * @param string $value - * @return void */ - public function setRememberToken($value) + public function setRememberToken($value): void { + // Do nothing. } /** * Get the column name for the "remember me" token. - * - * @return string */ - public function getRememberTokenName() + public function getRememberTokenName(): string { return ''; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php index a3d9df7d9..67b4cf703 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php @@ -10,6 +10,7 @@ use LdapRecord\Models\Attributes\MbString; use LdapRecord\Models\Attributes\Timestamp; use LdapRecord\Models\DetectsResetIntegers; use LdapRecord\Support\Arr; +use RuntimeException; trait HasAttributes { @@ -17,69 +18,56 @@ trait HasAttributes /** * The models original attributes. - * - * @var array */ - protected $original = []; + protected array $original = []; + + /** + * The models changed attributes. + */ + protected array $changes = []; /** * The models attributes. - * - * @var array */ - protected $attributes = []; + protected array $attributes = []; /** * The attributes that should be mutated to dates. - * - * @var array */ - protected $dates = []; + protected array $dates = []; /** * The attributes that should be cast to their native types. - * - * @var array */ - protected $casts = []; + protected array $casts = []; /** * The accessors to append to the model's array form. - * - * @var array */ - protected $appends = []; + protected array $appends = []; /** * The format that dates must be output to for serialization. - * - * @var string */ - protected $dateFormat; + protected ?string $dateFormat = null; /** * The default attributes that should be mutated to dates. - * - * @var array */ - protected $defaultDates = [ + protected array $defaultDates = [ 'createtimestamp' => 'ldap', 'modifytimestamp' => 'ldap', ]; /** * The cache of the mutated attributes for each class. - * - * @var array */ - protected static $mutatorCache = []; + protected static array $mutatorCache = []; /** * Convert the model's original attributes to an array. - * - * @return array */ - public function originalToArray() + public function originalToArray(): array { return $this->encodeAttributes( $this->convertAttributesForJson($this->original) @@ -88,16 +76,14 @@ trait HasAttributes /** * Convert the model's attributes to an array. - * - * @return array */ - public function attributesToArray() + public function attributesToArray(): array { // Here we will replace our LDAP formatted dates with // properly formatted ones, so dates do not need to // be converted manually after being returned. $attributes = $this->addDateAttributesToArray( - $attributes = $this->getArrayableAttributes() + $this->getArrayableAttributes() ); $attributes = $this->addMutatedAttributesToArray( @@ -125,39 +111,30 @@ trait HasAttributes /** * Convert the model's serialized original attributes to their original form. - * - * @param array $attributes - * @return array */ - public function arrayToOriginal(array $attributes) + public function arrayToOriginal(array $attributes): array { - return $this->decodeAttributes( - $this->convertAttributesFromJson($attributes) - ); + $attributes = $this->decodeAttributes($attributes); + + return $this->convertAttributesFromJson($attributes); } /** * Convert the model's serialized attributes to their original form. - * - * @param array $attributes - * @return array */ - public function arrayToAttributes(array $attributes) + public function arrayToAttributes(array $attributes): array { $attributes = $this->restoreDateAttributesFromArray($attributes); - return $this->decodeAttributes( - $this->convertAttributesFromJson($attributes) - ); + $attributes = $this->decodeAttributes($attributes); + + return $this->convertAttributesFromJson($attributes); } /** * Add the date attributes to the attributes array. - * - * @param array $attributes - * @return array */ - protected function addDateAttributesToArray(array $attributes) + protected function addDateAttributesToArray(array $attributes): array { foreach ($this->getDates() as $attribute => $type) { if (! isset($attributes[$attribute])) { @@ -176,18 +153,15 @@ trait HasAttributes /** * Restore the date attributes to their true value from serialized attributes. - * - * @param array $attributes - * @return array */ - protected function restoreDateAttributesFromArray(array $attributes) + protected function restoreDateAttributesFromArray(array $attributes): array { foreach ($this->getDates() as $attribute => $type) { if (! isset($attributes[$attribute])) { continue; } - $date = $this->fromDateTime($type, $attributes[$attribute]); + $date = $this->fromDateTime($attributes[$attribute], $type); $attributes[$attribute] = Arr::wrap($date); } @@ -197,21 +171,16 @@ trait HasAttributes /** * Prepare a date for array / JSON serialization. - * - * @param DateTimeInterface $date - * @return string */ - protected function serializeDate(DateTimeInterface $date) + protected function serializeDate(DateTimeInterface $date): string { return $date->format($this->getDateFormat()); } /** * Recursively UTF-8 encode the given attributes. - * - * @return array */ - public function encodeAttributes($attributes) + protected function encodeAttributes($attributes): array { array_walk_recursive($attributes, function (&$value) { $value = $this->encodeValue($value); @@ -222,11 +191,8 @@ trait HasAttributes /** * Recursively UTF-8 decode the given attributes. - * - * @param array $attributes - * @return array */ - public function decodeAttributes($attributes) + public function decodeAttributes(array $attributes): array { array_walk_recursive($attributes, function (&$value) { $value = $this->decodeValue($value); @@ -237,11 +203,8 @@ trait HasAttributes /** * Encode the value for serialization. - * - * @param string $value - * @return string */ - protected function encodeValue($value) + protected function encodeValue(string $value): string { // If we are able to detect the encoding, we will // encode only the attributes that need to be, @@ -250,18 +213,15 @@ trait HasAttributes return $value; } - return utf8_encode($value); + return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1'); } /** * Decode the value from serialization. - * - * @param string $value - * @return string */ - protected function decodeValue($value) + protected function decodeValue(string $value): string { - if (MbString::isLoaded() && MbString::isUtf8($value)) { + if (MbString::isLoaded() && ! MbString::isUtf8($value)) { return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1'); } @@ -270,12 +230,8 @@ trait HasAttributes /** * Add the mutated attributes to the attributes array. - * - * @param array $attributes - * @param array $mutatedAttributes - * @return array */ - protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes) + protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes): array { foreach ($mutatedAttributes as $key) { // We want to spin through all the mutated attributes for this model and call @@ -299,10 +255,8 @@ trait HasAttributes /** * Set the model's original attributes with the model's current attributes. - * - * @return $this */ - public function syncOriginal() + public function syncOriginal(): static { $this->original = $this->attributes; @@ -310,12 +264,19 @@ trait HasAttributes } /** - * Fills the entry with the supplied attributes. - * - * @param array $attributes - * @return $this + * Sync the changed attributes. */ - public function fill(array $attributes = []) + public function syncChanges(): static + { + $this->changes = $this->getDirty(); + + return $this; + } + + /** + * Fills the entry with the supplied attributes. + */ + public function fill(array $attributes = []): static { foreach ($attributes as $key => $value) { $this->setAttribute($key, $value); @@ -325,29 +286,21 @@ trait HasAttributes } /** - * Returns the models attribute by its key. - * - * @param int|string $key - * @param mixed $default - * @return mixed + * Get the models attribute by its key. */ - public function getAttribute($key, $default = null) + public function getAttribute(?string $key = null, mixed $default = null): mixed { if (! $key) { - return; + return null; } return $this->getAttributeValue($key, $default); } /** - * Get an attributes value. - * - * @param string $key - * @param mixed $default - * @return mixed + * Get an attribute's value. */ - public function getAttributeValue($key, $default = null) + public function getAttributeValue(string $key, mixed $default = null): mixed { $key = $this->normalizeAttributeKey($key); $value = $this->getAttributeFromArray($key); @@ -368,42 +321,56 @@ trait HasAttributes } /** - * Determine if the given attribute is a date. - * - * @param string $key - * @return bool + * Get the model's raw attribute value. */ - public function isDateAttribute($key) + public function getRawAttribute(string $key, mixed $default = null): mixed + { + return Arr::get($this->attributes, $this->normalizeAttributeKey($key), $default); + } + + /** + * Determine if the given attribute is a date. + */ + public function isDateAttribute(string $key): bool { return array_key_exists($key, $this->getDates()); } /** * Get the attributes that should be mutated to dates. - * - * @return array */ - public function getDates() + public function getDates(): array { // Since array string keys can be unique depending // on casing differences, we need to normalize the // array key case so they are merged properly. return array_merge( - array_change_key_case($this->defaultDates, CASE_LOWER), - array_change_key_case($this->dates, CASE_LOWER) + array_change_key_case($this->defaultDates), + array_change_key_case($this->dates), + array_change_key_case($this->getDateCasts()), ); } + /** + * Get the attributes casts that should be mutated to dates. + */ + protected function getDateCasts(): array + { + return array_map(function (string $cast) { + return explode(':', $cast, 2)[1] ?? throw new RuntimeException( + "Invalid date cast [$cast]. A date cast must be in the format 'datetime:format'." + ); + }, array_filter($this->getCasts(), function ($cast) { + return $this->isDateTimeCast($cast); + })); + } + /** * Convert the given date value to an LDAP compatible value. * - * @param string $type - * @param mixed $value - * @return float|string - * * @throws LdapRecordException */ - public function fromDateTime($type, $value) + public function fromDateTime(mixed $value, string $type): float|int|string { return (new Timestamp($type))->fromDateTime($value); } @@ -411,28 +378,20 @@ trait HasAttributes /** * Convert the given LDAP date value to a Carbon instance. * - * @param mixed $value - * @param string $type - * @return Carbon|false - * * @throws LdapRecordException */ - public function asDateTime($value, $type) + public function asDateTime(mixed $value, string $type): Carbon|int|false { return (new Timestamp($type))->toDateTime($value); } /** * Determine whether an attribute should be cast to a native type. - * - * @param string $key - * @param array|string|null $types - * @return bool */ - public function hasCast($key, $types = null) + public function hasCast(string $key, array|string|null $types = null): bool { if (array_key_exists($key, $this->getCasts())) { - return $types ? in_array($this->getCastType($key), (array) $types, true) : true; + return ! $types || in_array($this->getCastType($key), (array) $types, true); } return false; @@ -440,32 +399,24 @@ trait HasAttributes /** * Get the attributes that should be cast to their native types. - * - * @return array */ - protected function getCasts() + protected function getCasts(): array { - return array_change_key_case($this->casts, CASE_LOWER); + return array_change_key_case($this->casts); } /** * Determine whether a value is JSON castable for inbound manipulation. - * - * @param string $key - * @return bool */ - protected function isJsonCastable($key) + protected function isJsonCastable(string $key): bool { return $this->hasCast($key, ['array', 'json', 'object', 'collection']); } /** * Get the type of cast for a model attribute. - * - * @param string $key - * @return string */ - protected function getCastType($key) + protected function getCastType(string $key): string { if ($this->isDecimalCast($this->getCasts()[$key])) { return 'decimal'; @@ -480,45 +431,32 @@ trait HasAttributes /** * Determine if the cast is a decimal. - * - * @param string $cast - * @return bool */ - protected function isDecimalCast($cast) + protected function isDecimalCast(string $cast): bool { return strncmp($cast, 'decimal:', 8) === 0; } /** * Determine if the cast is a datetime. - * - * @param string $cast - * @return bool */ - protected function isDateTimeCast($cast) + protected function isDateTimeCast(string $cast): bool { return strncmp($cast, 'datetime:', 8) === 0; } /** * Determine if the given attribute must be casted. - * - * @param string $key - * @return bool */ - protected function isCastedAttribute($key) + protected function isCastedAttribute(string $key): bool { - return array_key_exists($key, array_change_key_case($this->casts, CASE_LOWER)); + return array_key_exists($key, array_change_key_case($this->casts)); } /** * Cast an attribute to a native PHP type. - * - * @param string $key - * @param array|null $value - * @return mixed */ - protected function castAttribute($key, $value) + protected function castAttribute(string $key, ?array $value): mixed { $value = $this->castRequiresArrayValue($key) ? $value : Arr::first($value); @@ -542,7 +480,7 @@ trait HasAttributes case 'boolean': return $this->asBoolean($value); case 'object': - return $this->fromJson($value, $asObject = true); + return $this->fromJson($value, true); case 'array': case 'json': return $this->fromJson($value); @@ -557,22 +495,16 @@ trait HasAttributes /** * Determine if the cast type requires the first attribute value. - * - * @return bool */ - protected function castRequiresArrayValue($key) + protected function castRequiresArrayValue(string $key): bool { - return in_array($this->getCastType($key), ['collection']); + return $this->getCastType($key) === 'collection'; } /** * Cast the given attribute to JSON. - * - * @param string $key - * @param mixed $value - * @return string */ - protected function castAttributeAsJson($key, $value) + protected function castAttributeAsJson(string $key, mixed $value): string { $value = $this->asJson($value); @@ -580,107 +512,104 @@ trait HasAttributes $class = get_class($this); $message = json_last_error_msg(); - throw new Exception("Unable to encode attribute [{$key}] for model [{$class}] to JSON: {$message}."); + throw new Exception("Unable to encode attribute [$key] for model [$class] to JSON: $message."); } return $value; } /** - * Convert the model to its JSON representation. - * - * @return string + * Cast the given attribute to an LDAP primitive type. */ - public function toJson() + protected function castAttributeAsPrimitive(string $key, mixed $value): string + { + return match ($this->getCastType($key)) { + 'bool', 'boolean' => $this->fromBoolean($value), + default => (string) $value, + }; + } + + /** + * Convert the model to its JSON representation. + */ + public function toJson(): string { return json_encode($this); } /** * Encode the given value as JSON. - * - * @param mixed $value - * @return string */ - protected function asJson($value) + protected function asJson(mixed $value): string|false { return json_encode($value); } /** * Decode the given JSON back into an array or object. - * - * @param string $value - * @param bool $asObject - * @return mixed */ - public function fromJson($value, $asObject = false) + public function fromJson(string $value, bool $asObject = false): mixed { return json_decode($value, ! $asObject); } /** * Decode the given float. - * - * @param mixed $value - * @return mixed */ - public function fromFloat($value) + public function fromFloat(float $value): float { - switch ((string) $value) { - case 'Infinity': - return INF; - case '-Infinity': - return -INF; - case 'NaN': - return NAN; - default: - return (float) $value; - } + return match ((string) $value) { + 'NaN' => NAN, + 'Infinity' => INF, + '-Infinity' => -INF, + default => $value, + }; } /** - * Cast the value to a boolean. - * - * @param mixed $value - * @return bool + * Cast the value from an LDAP boolean string to a primitive boolean. */ - protected function asBoolean($value) + protected function asBoolean(mixed $value): bool { - $map = ['true' => true, 'false' => false]; + return match (strtolower($value)) { + 'true' => true, + 'false' => false, + default => (bool) $value, + }; + } - return $map[strtolower($value)] ?? (bool) $value; + /** + * Cast the value from a primitive boolean to an LDAP boolean string. + */ + protected function fromBoolean(mixed $value): string + { + if (is_string($value)) { + $value = $this->asBoolean($value); + } + + return $value ? 'TRUE' : 'FALSE'; } /** * Cast a decimal value as a string. - * - * @param float $value - * @param int $decimals - * @return string */ - protected function asDecimal($value, $decimals) + protected function asDecimal(float $value, int $decimals): string { return number_format($value, $decimals, '.', ''); } /** * Get an attribute array of all arrayable attributes. - * - * @return array */ - protected function getArrayableAttributes() + protected function getArrayableAttributes(): array { return $this->getArrayableItems($this->attributes); } /** * Get an attribute array of all arrayable values. - * - * @param array $values - * @return array */ - protected function getArrayableItems(array $values) + protected function getArrayableItems(array $values): array { if (count($visible = $this->getVisible()) > 0) { $values = array_intersect_key($values, array_flip($visible)); @@ -694,11 +623,9 @@ trait HasAttributes } /** - * Get all of the appendable values that are arrayable. - * - * @return array + * Get all the appendable values that are arrayable. */ - protected function getArrayableAppends() + protected function getArrayableAppends(): array { if (empty($this->appends)) { return []; @@ -711,21 +638,16 @@ trait HasAttributes /** * Get the format for date serialization. - * - * @return string */ - public function getDateFormat() + public function getDateFormat(): string { return $this->dateFormat ?: DateTimeInterface::ISO8601; } /** * Set the date format used by the model for serialization. - * - * @param string $format - * @return $this */ - public function setDateFormat($format) + public function setDateFormat(string $format): static { $this->dateFormat = $format; @@ -734,33 +656,24 @@ trait HasAttributes /** * Get an attribute from the $attributes array. - * - * @param string $key - * @return mixed */ - protected function getAttributeFromArray($key) + protected function getAttributeFromArray(string $key): mixed { return $this->getNormalizedAttributes()[$key] ?? null; } /** * Get the attributes with their keys normalized. - * - * @return array */ - protected function getNormalizedAttributes() + protected function getNormalizedAttributes(): array { - return array_change_key_case($this->attributes, CASE_LOWER); + return array_change_key_case($this->attributes); } /** - * Returns the first attribute by the specified key. - * - * @param string $key - * @param mixed $default - * @return mixed + * Get the first attribute by the specified key. */ - public function getFirstAttribute($key, $default = null) + public function getFirstAttribute(string $key, mixed $default = null): mixed { return Arr::first( Arr::wrap($this->getAttribute($key, $default)), @@ -768,38 +681,36 @@ trait HasAttributes } /** - * Returns all of the models attributes. - * - * @return array + * Returns all the model's attributes. */ - public function getAttributes() + public function getAttributes(): array { return $this->attributes; } /** * Set an attribute value by the specified key. - * - * @param string $key - * @param mixed $value - * @return $this */ - public function setAttribute($key, $value) + public function setAttribute(string $key, mixed $value): static { $key = $this->normalizeAttributeKey($key); if ($this->hasSetMutator($key)) { return $this->setMutatedAttributeValue($key, $value); - } elseif ( + } + + if ( $value && $this->isDateAttribute($key) && ! $this->valueIsResetInteger($value) ) { - $value = $this->fromDateTime($this->getDates()[$key], $value); + $value = (string) $this->fromDateTime($value, $this->getDates()[$key]); } if ($this->isJsonCastable($key) && ! is_null($value)) { $value = $this->castAttributeAsJson($key, $value); + } elseif ($this->hasCast($key) && ! is_null($value)) { + $value = $this->castAttributeAsPrimitive($key, $value); } $this->attributes[$key] = Arr::wrap($value); @@ -809,12 +720,8 @@ trait HasAttributes /** * Set an attribute on the model. No checking is done. - * - * @param string $key - * @param mixed $value - * @return $this */ - public function setRawAttribute($key, $value) + public function setRawAttribute(string $key, mixed $value): static { $key = $this->normalizeAttributeKey($key); @@ -825,75 +732,71 @@ trait HasAttributes /** * Set the models first attribute value. - * - * @param string $key - * @param mixed $value - * @return $this */ - public function setFirstAttribute($key, $value) + public function setFirstAttribute(string $key, mixed $value): static { return $this->setAttribute($key, Arr::wrap($value)); } /** * Add a unique value to the given attribute. - * - * @param string $key - * @param mixed $value - * @return $this */ - public function addAttributeValue($key, $value) + public function addAttributeValue(string $key, mixed $value): static { - return $this->setAttribute($key, array_unique( - array_merge( - Arr::wrap($this->getAttribute($key)), - Arr::wrap($value) - ) - )); + return $this->setRawAttribute($key, array_unique(array_merge( + $this->getRawAttribute($key, []), + Arr::wrap($value) + ))); + } + + /** + * Remove a unique value from the given attribute. + */ + public function removeAttributeValue(string $key, mixed $value): static + { + $values = $this->getRawAttribute($key, []); + + foreach (Arr::wrap($value) as $value) { + $index = array_search($value, $values); + + if ($index !== false) { + unset($values[$index]); + } + } + + return $this->setRawAttribute($key, array_values($values)); } /** * Determine if a get mutator exists for an attribute. - * - * @param string $key - * @return bool */ - public function hasGetMutator($key) + public function hasGetMutator(string $key): bool { return method_exists($this, 'get'.$this->getMutatorMethodName($key).'Attribute'); } /** * Determine if a set mutator exists for an attribute. - * - * @param string $key - * @return bool */ - public function hasSetMutator($key) + public function hasSetMutator(string $key): bool { return method_exists($this, 'set'.$this->getMutatorMethodName($key).'Attribute'); } /** * Set the value of an attribute using its mutator. - * - * @param string $key - * @param mixed $value - * @return mixed */ - protected function setMutatedAttributeValue($key, $value) + protected function setMutatedAttributeValue(string $key, mixed $value): static { - return $this->{'set'.$this->getMutatorMethodName($key).'Attribute'}($value); + $this->{'set'.$this->getMutatorMethodName($key).'Attribute'}($value); + + return $this; } /** * Get the value of an attribute using its mutator. - * - * @param string $key - * @param mixed $value - * @return mixed */ - protected function getMutatedAttributeValue($key, $value) + protected function getMutatedAttributeValue(string $key, mixed $value): mixed { return $this->{'get'.$this->getMutatorMethodName($key).'Attribute'}($value); } @@ -902,11 +805,8 @@ trait HasAttributes * Get the mutator attribute method name. * * Hyphenated attributes will use pascal cased methods. - * - * @param string $key - * @return mixed */ - protected function getMutatorMethodName($key) + protected function getMutatorMethodName(string $key): string { $key = ucwords(str_replace('-', ' ', $key)); @@ -915,12 +815,8 @@ trait HasAttributes /** * Get the value of an attribute using its mutator for array conversion. - * - * @param string $key - * @param mixed $value - * @return array */ - protected function mutateAttributeForArray($key, $value) + protected function mutateAttributeForArray(string $key, mixed $value): array { return Arr::wrap( $this->getMutatedAttributeValue($key, $value) @@ -928,27 +824,22 @@ trait HasAttributes } /** - * Set the attributes property. + * Set the raw model attributes. * * Used when constructing an existing LDAP record. - * - * @param array $attributes - * @return $this */ - public function setRawAttributes(array $attributes = []) + public function setRawAttributes(array $attributes = []): static { // We will filter out those annoying 'count' keys // returned with LDAP results and lowercase all // root array keys to prevent any casing issues. - $raw = array_change_key_case($this->filterRawAttributes($attributes), CASE_LOWER); + $raw = array_change_key_case($this->filterRawAttributes($attributes)); // Before setting the models attributes, we will filter // out the attributes that contain an integer key. LDAP // search results will contain integer keys that have // attribute names as values. We don't need these. - $this->attributes = array_filter($raw, function ($key) { - return ! is_int($key); - }, ARRAY_FILTER_USE_KEY); + $this->attributes = array_filter($raw, fn ($key) => ! is_int($key), ARRAY_FILTER_USE_KEY); // LDAP search results will contain the distinguished // name inside of the `dn` key. We will retrieve this, @@ -971,12 +862,8 @@ trait HasAttributes /** * Filters the count key recursively from raw LDAP attributes. - * - * @param array $attributes - * @param array $keys - * @return array */ - public function filterRawAttributes(array $attributes = [], array $keys = ['count', 'dn']) + public function filterRawAttributes(array $attributes = [], array $keys = ['count', 'dn']): array { foreach ($keys as $key) { unset($attributes[$key]); @@ -993,41 +880,40 @@ trait HasAttributes /** * Determine if the model has the given attribute. - * - * @param int|string $key - * @return bool */ - public function hasAttribute($key) + public function hasAttribute(int|string $key): bool { - return [] !== ($this->attributes[$this->normalizeAttributeKey($key)] ?? []); + return ($this->attributes[$this->normalizeAttributeKey($key)] ?? []) !== []; } /** - * Returns the number of attributes. - * - * @return int + * Get the number of attributes. */ - public function countAttributes() + public function countAttributes(): int { return count($this->getAttributes()); } /** - * Returns the models original attributes. - * - * @return array + * Get the model's original attributes. */ - public function getOriginal() + public function getOriginal(): array { return $this->original; } /** - * Get the attributes that have been changed since last sync. - * - * @return array + * Get the model's raw original attribute values. */ - public function getDirty() + public function getRawOriginal(string $key, mixed $default = null): mixed + { + return Arr::get($this->original, $key, $default); + } + + /** + * Get the attributes that have been changed since last sync. + */ + public function getDirty(): array { $dirty = []; @@ -1044,33 +930,69 @@ trait HasAttributes } /** - * Determine if the given attribute is dirty. - * - * @param string $key - * @return bool + * Get the attributes that have been changed since the model was last saved. */ - public function isDirty($key) + public function getChanges(): array + { + return $this->changes; + } + + /** + * Determine if the given attribute is dirty. + */ + public function isDirty(string $key): bool { return ! $this->originalIsEquivalent($key); } /** - * Get the accessors being appended to the models array form. - * - * @return array + * Determine if given attribute has remained the same. */ - public function getAppends() + public function isClean(string $key): bool + { + return ! $this->isDirty($key); + } + + /** + * Discard attribute changes and reset the attributes to their original state. + */ + public function discardChanges(): static + { + [$this->attributes, $this->changes] = [$this->original, []]; + + return $this; + } + + /** + * Determine if the model or any of the given attribute(s) were changed when the model was last saved. + */ + public function wasChanged(array|string|null $attributes = null): bool + { + if (func_num_args() === 0) { + return count($this->changes) > 0; + } + + foreach ((array) $attributes as $attribute) { + if (array_key_exists($attribute, $this->changes)) { + return true; + } + } + + return false; + } + + /** + * Get the accessors being appended to the models array form. + */ + public function getAppends(): array { return $this->appends; } /** * Set the accessors to append to model arrays. - * - * @param array $appends - * @return $this */ - public function setAppends(array $appends) + public function setAppends(array $appends): static { $this->appends = $appends; @@ -1079,22 +1001,16 @@ trait HasAttributes /** * Return whether the accessor attribute has been appended. - * - * @param string $attribute - * @return bool */ - public function hasAppended($attribute) + public function hasAppended(string $attribute): bool { return in_array($attribute, $this->appends); } /** * Returns a normalized attribute key. - * - * @param string $key - * @return string */ - public function normalizeAttributeKey($key) + public function normalizeAttributeKey(string $key): string { // Since LDAP supports hyphens in attribute names, // we'll convert attributes being retrieved by @@ -1106,11 +1022,8 @@ trait HasAttributes /** * Determine if the new and old values for a given key are equivalent. - * - * @param string $key - * @return bool */ - protected function originalIsEquivalent($key) + protected function originalIsEquivalent(string $key): bool { if (! array_key_exists($key, $this->original)) { return false; @@ -1123,17 +1036,15 @@ trait HasAttributes return true; } - return is_numeric($current) && + return is_numeric($current) && is_numeric($original) && strcmp((string) $current, (string) $original) === 0; } /** * Get the mutated attributes for a given instance. - * - * @return array */ - public function getMutatedAttributes() + public function getMutatedAttributes(): array { $class = static::class; @@ -1146,26 +1057,19 @@ trait HasAttributes /** * Extract and cache all the mutated attributes of a class. - * - * @param string $class - * @return void */ - public static function cacheMutatedAttributes($class) + public static function cacheMutatedAttributes(string $class): void { - static::$mutatorCache[$class] = collect(static::getMutatorMethods($class))->reject(function ($match) { - return $match === 'First'; - })->map(function ($match) { - return lcfirst($match); - })->all(); + static::$mutatorCache[$class] = collect(static::getMutatorMethods($class)) + ->reject(fn ($match) => $match === 'First') + ->map(fn ($match) => lcfirst($match)) + ->all(); } /** * Get all of the attribute mutator methods. - * - * @param mixed $class - * @return array */ - protected static function getMutatorMethods($class) + protected static function getMutatorMethods(string $class): array { preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php index d9a41b892..7537f62f6 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php @@ -13,18 +13,15 @@ trait HasEvents { /** * Execute the callback without raising any events. - * - * @param Closure $callback - * @return mixed */ - protected static function withoutEvents(Closure $callback) + protected static function withoutEvents(Closure $callback): mixed { $container = static::getConnectionContainer(); - $dispatcher = $container->getEventDispatcher(); + $dispatcher = $container->getDispatcher(); if ($dispatcher) { - $container->setEventDispatcher( + $container->setDispatcher( new NullDispatcher($dispatcher) ); } @@ -33,19 +30,15 @@ trait HasEvents return $callback(); } finally { if ($dispatcher) { - $container->setEventDispatcher($dispatcher); + $container->setDispatcher($dispatcher); } } } /** * Dispatch the given model events. - * - * @param string|array $events - * @param array $args - * @return void */ - protected function dispatch($events, array $args = []) + protected function dispatch(array|string $events, array $args = []): void { foreach (Arr::wrap($events) as $name) { $this->fireCustomModelEvent($name, $args); @@ -54,38 +47,27 @@ trait HasEvents /** * Fire a custom model event. - * - * @param string $name - * @param array $args - * @return mixed */ - protected function fireCustomModelEvent($name, array $args = []) + protected function fireCustomModelEvent(string $name, array $args = []): void { $event = implode('\\', [Events::class, ucfirst($name)]); - return $this->fireModelEvent(new $event($this, ...$args)); + $this->fireModelEvent(new $event($this, ...$args)); } /** * Fire a model event. - * - * @param Event $event - * @return mixed */ - protected function fireModelEvent(Event $event) + protected function fireModelEvent(Event $event): void { - return static::getConnectionContainer()->getEventDispatcher()->fire($event); + static::getConnectionContainer()->getDispatcher()->fire($event); } /** * Listen to a model event. - * - * @param string $event - * @param Closure $listener - * @return mixed */ - protected function listenForModelEvent($event, Closure $listener) + protected function listenForModelEvent(string $event, Closure $listener): void { - return static::getConnectionContainer()->getEventDispatcher()->listen($event, $listener); + static::getConnectionContainer()->getDispatcher()->listen($event, $listener); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php index 4d0f2968f..855ba37c3 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php @@ -12,43 +12,33 @@ trait HasGlobalScopes /** * Register a new global scope on the model. * - * @param Scope|Closure|string $scope - * @param Closure|null $implementation - * @return mixed - * * @throws InvalidArgumentException */ - public static function addGlobalScope($scope, Closure $implementation = null) + public static function addGlobalScope(Scope|Closure|string $scope, ?Closure $implementation = null): void { if (is_string($scope) && ! is_null($implementation)) { - return static::$globalScopes[static::class][$scope] = $implementation; + static::$globalScopes[static::class][$scope] = $implementation; } elseif ($scope instanceof Closure) { - return static::$globalScopes[static::class][spl_object_hash($scope)] = $scope; + static::$globalScopes[static::class][spl_object_hash($scope)] = $scope; } elseif ($scope instanceof Scope) { - return static::$globalScopes[static::class][get_class($scope)] = $scope; + static::$globalScopes[static::class][get_class($scope)] = $scope; + } else { + throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.'); } - - throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.'); } /** * Determine if a model has a global scope. - * - * @param Scope|string $scope - * @return bool */ - public static function hasGlobalScope($scope) + public static function hasGlobalScope(Scope|string $scope): bool { return ! is_null(static::getGlobalScope($scope)); } /** * Get a global scope registered with the model. - * - * @param Scope|string $scope - * @return Scope|Closure|null */ - public static function getGlobalScope($scope) + public static function getGlobalScope(Scope|string $scope): Scope|Closure|null { if (array_key_exists(static::class, static::$globalScopes)) { $scopeName = is_string($scope) ? $scope : get_class($scope); @@ -57,14 +47,14 @@ trait HasGlobalScopes ? static::$globalScopes[static::class][$scopeName] : null; } + + return null; } /** * Get the global scopes for this class instance. - * - * @return array */ - public function getGlobalScopes() + public function getGlobalScopes(): array { return array_key_exists(static::class, static::$globalScopes) ? static::$globalScopes[static::class] diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php index 194efa8cf..c84bd977d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php @@ -12,13 +12,11 @@ trait HasPassword /** * Set the password on the user. * - * @param string|array $password - * * @throws ConnectionException */ - public function setPasswordAttribute($password) + public function setPasswordAttribute(array|string $password): void { - $this->validateSecureConnection(); + $this->assertSecureConnection(); // Here we will attempt to determine the password hash method in use // by parsing the users hashed password (if it as available). If a @@ -49,31 +47,25 @@ trait HasPassword /** * Alias for setting the password on the user. * - * @param string|array $password - * * @throws ConnectionException */ - public function setUnicodepwdAttribute($password) + public function setUnicodepwdAttribute(array|string $password): void { $this->setPasswordAttribute($password); } /** * An accessor for retrieving the user's hashed password value. - * - * @return string|null */ - public function getPasswordAttribute() + public function getPasswordAttribute(): ?string { return $this->getAttribute($this->getPasswordAttributeName())[0] ?? null; } /** * Get the name of the attribute that contains the user's password. - * - * @return string */ - public function getPasswordAttributeName() + public function getPasswordAttributeName(): string { if (property_exists($this, 'passwordAttribute')) { return $this->passwordAttribute; @@ -88,10 +80,8 @@ trait HasPassword /** * Get the name of the method to use for hashing the user's password. - * - * @return string */ - public function getPasswordHashMethod() + public function getPasswordHashMethod(): string { if (property_exists($this, 'passwordHashMethod')) { return $this->passwordHashMethod; @@ -106,13 +96,8 @@ trait HasPassword /** * Set the changed password. - * - * @param string $oldPassword - * @param string $newPassword - * @param string $attribute - * @return void */ - protected function setChangedPassword($oldPassword, $newPassword, $attribute) + protected function setChangedPassword(string $oldPassword, string $newPassword, string $attribute): void { // Create batch modification for removing the old password. $this->addModification( @@ -135,13 +120,15 @@ trait HasPassword /** * Set the password on the model. - * - * @param string $password - * @param string $attribute - * @return void */ - protected function setPassword($password, $attribute) + protected function setPassword(string $password, string $attribute): void { + if (! $this->exists) { + $this->setRawAttribute($attribute, $password); + + return; + } + $this->addModification( $this->newBatchModification( $attribute, @@ -154,14 +141,9 @@ trait HasPassword /** * Encode / hash the given password. * - * @param string $method - * @param string $password - * @param string $salt - * @return string - * * @throws LdapRecordException */ - protected function getHashedPassword($method, $password, $salt = null) + protected function getHashedPassword(string $method, string $password, ?string $salt = null): string { if (! method_exists(Password::class, $method)) { throw new LdapRecordException("Password hashing method [{$method}] does not exist."); @@ -177,18 +159,22 @@ trait HasPassword /** * Validates that the current LDAP connection is secure. * - * @return void - * * @throws ConnectionException */ - protected function validateSecureConnection() + protected function assertSecureConnection(): void { $connection = $this->getConnection(); + $config = $connection->getConfiguration(); + + if ($config->get('allow_insecure_password_changes') === true) { + return; + } + if ($connection->isConnected()) { $secure = $connection->getLdapConnection()->canChangePasswords(); } else { - $secure = $connection->getConfiguration()->get('use_ssl') || $connection->getConfiguration()->get('use_tls'); + $secure = $config->get('use_ssl') || $config->get('use_tls'); } if (! $secure) { @@ -200,14 +186,11 @@ trait HasPassword /** * Attempt to retrieve the password's salt. - * - * @param string $method - * @return string|null */ - public function getPasswordSalt($method) + public function getPasswordSalt(string $method): ?string { if (! Password::hashMethodRequiresSalt($method)) { - return; + return null; } return Password::getSalt($this->password); @@ -234,15 +217,11 @@ trait HasPassword $value = null ); - switch ($algo) { - case Password::CRYPT_SALT_TYPE_MD5: - return 'md5'.$method; - case Password::CRYPT_SALT_TYPE_SHA256: - return 'sha256'.$method; - case Password::CRYPT_SALT_TYPE_SHA512: - return 'sha512'.$method; - default: - return $method; - } + return match ((int) $algo) { + Password::CRYPT_SALT_TYPE_MD5 => 'md5'.$method, + Password::CRYPT_SALT_TYPE_SHA256 => 'sha256'.$method, + Password::CRYPT_SALT_TYPE_SHA512 => 'sha512'.$method, + default => $method, + }; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php index 87c0a7cc8..e81c3a15e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php @@ -12,61 +12,47 @@ trait HasRelationships { /** * Returns a new has one relationship. - * - * @param mixed $related - * @param string $relationKey - * @param string $foreignKey - * @return HasOne */ - public function hasOne($related, $relationKey, $foreignKey = 'dn') + public function hasOne(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasOne { return new HasOne($this->newQuery(), $this, $related, $relationKey, $foreignKey); } /** * Returns a new has many relationship. - * - * @param mixed $related - * @param string $relationKey - * @param string $foreignKey - * @return HasMany */ - public function hasMany($related, $relationKey, $foreignKey = 'dn') + public function hasMany(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasMany { return new HasMany($this->newQuery(), $this, $related, $relationKey, $foreignKey, $this->guessRelationshipName()); } /** * Returns a new has many in relationship. - * - * @param mixed $related - * @param string $relationKey - * @param string $foreignKey - * @return HasManyIn */ - public function hasManyIn($related, $relationKey, $foreignKey = 'dn') + public function hasManyIn(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasManyIn { return new HasManyIn($this->newQuery(), $this, $related, $relationKey, $foreignKey, $this->guessRelationshipName()); } /** * Get a relationship by its name. - * - * @param string $relationName - * @return Relation|null */ - public function getRelation($relationName) + public function getRelation(?string $relationName = null): ?Relation { + if (is_null($relationName)) { + return null; + } + if (! method_exists($this, $relationName)) { - return; + return null; } if (! $relation = $this->{$relationName}()) { - return; + return null; } if (! $relation instanceof Relation) { - return; + return null; } return $relation; @@ -74,10 +60,8 @@ trait HasRelationships /** * Get the relationships name. - * - * @return string|null */ - protected function guessRelationshipName() + protected function guessRelationshipName(): ?string { return Arr::last(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3))['function']; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php index cb227fecc..7420620ce 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php @@ -2,38 +2,34 @@ namespace LdapRecord\Models\Concerns; +use LdapRecord\Query\Model\Builder; + /** @mixin \LdapRecord\Models\Model */ trait HasScopes { /** * Begin querying the direct descendants of the model. - * - * @return \LdapRecord\Query\Model\Builder */ - public function descendants() + public function descendants(): Builder { - return $this->in($this->getDn())->listing(); + return $this->in($this->getDn())->list(); } /** * Begin querying the direct ancestors of the model. - * - * @return \LdapRecord\Query\Model\Builder */ - public function ancestors() + public function ancestors(): Builder { $parent = $this->getParentDn($this->getDn()); - return $this->in($this->getParentDn($parent))->listing(); + return $this->in($this->getParentDn($parent))->list(); } /** * Begin querying the direct siblings of the model. - * - * @return \LdapRecord\Query\Model\Builder */ - public function siblings() + public function siblings(): Builder { - return $this->in($this->getParentDn($this->getDn()))->listing(); + return $this->in($this->getParentDn($this->getDn()))->list(); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php index ecd328dab..533e8fc58 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php @@ -13,37 +13,29 @@ trait HidesAttributes { /** * The attributes that should be hidden for serialization. - * - * @var array */ - protected $hidden = []; + protected array $hidden = []; /** * The attributes that should be visible in serialization. - * - * @var array */ - protected $visible = []; + protected array $visible = []; /** * Get the hidden attributes for the model. - * - * @return array */ - public function getHidden() + public function getHidden(): array { - return array_map(function ($key) { - return $this->normalizeAttributeKey($key); - }, $this->hidden); + return array_map( + $this->normalizeAttributeKey(...), + $this->hidden + ); } /** * Set the hidden attributes for the model. - * - * @param array $hidden - * @return $this */ - public function setHidden(array $hidden) + public function setHidden(array $hidden): static { $this->hidden = $hidden; @@ -52,11 +44,8 @@ trait HidesAttributes /** * Add hidden attributes for the model. - * - * @param array|string|null $attributes - * @return void */ - public function addHidden($attributes = null) + public function addHidden(array|string|null $attributes = null): void { $this->hidden = array_merge( $this->hidden, @@ -66,23 +55,19 @@ trait HidesAttributes /** * Get the visible attributes for the model. - * - * @return array */ - public function getVisible() + public function getVisible(): array { - return array_map(function ($key) { - return $this->normalizeAttributeKey($key); - }, $this->visible); + return array_map( + $this->normalizeAttributeKey(...), + $this->visible + ); } /** * Set the visible attributes for the model. - * - * @param array $visible - * @return $this */ - public function setVisible(array $visible) + public function setVisible(array $visible): static { $this->visible = $visible; @@ -91,11 +76,8 @@ trait HidesAttributes /** * Add visible attributes for the model. - * - * @param array|string|null $attributes - * @return void */ - public function addVisible($attributes = null) + public function addVisible(array|string|null $attributes = null): void { $this->visible = array_merge( $this->visible, @@ -105,11 +87,8 @@ trait HidesAttributes /** * Make the given, typically hidden, attributes visible. - * - * @param array|string $attributes - * @return $this */ - public function makeVisible($attributes) + public function makeVisible(array|string $attributes): static { $this->hidden = array_diff($this->hidden, (array) $attributes); @@ -122,11 +101,8 @@ trait HidesAttributes /** * Make the given, typically visible, attributes hidden. - * - * @param array|string $attributes - * @return $this */ - public function makeHidden($attributes) + public function makeHidden(array|string $attributes): static { $attributes = (array) $attributes; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php index cf550c749..bc4fa28cd 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php @@ -7,12 +7,8 @@ trait SerializesAndRestoresPropertyValues { /** * Get the property value prepared for serialization. - * - * @param string $property - * @param mixed $value - * @return mixed */ - protected function getSerializedPropertyValue($property, $value) + protected function getSerializedPropertyValue(string $property, mixed $value): mixed { if ($property === 'original') { return $this->originalToArray(); @@ -27,12 +23,8 @@ trait SerializesAndRestoresPropertyValues /** * Get the unserialized property value after deserialization. - * - * @param string $property - * @param mixed $value - * @return mixed */ - protected function getUnserializedPropertyValue($property, $value) + protected function getUnserializedPropertyValue(string $property, mixed $value): mixed { if ($property === 'original') { return $this->arrayToOriginal($value); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php index 91f4bcfe3..65428fa40 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php @@ -11,10 +11,8 @@ trait SerializesProperties /** * Prepare the attributes for serialization. - * - * @return array */ - public function __sleep() + public function __sleep(): array { $properties = (new ReflectionClass($this))->getProperties(); @@ -25,17 +23,15 @@ trait SerializesProperties )); } - return array_values(array_filter(array_map(function ($p) { - return $p->isStatic() ? null : $p->getName(); - }, $properties))); + return array_values(array_filter( + array_map(fn ($p) => $p->isStatic() ? null : $p->getName(), $properties) + )); } /** * Restore the attributes after serialization. - * - * @return void */ - public function __wakeup() + public function __wakeup(): void { foreach ((new ReflectionClass($this))->getProperties() as $property) { if ($property->isStatic()) { @@ -51,10 +47,8 @@ trait SerializesProperties /** * Prepare the model for serialization. - * - * @return array */ - public function __serialize() + public function __serialize(): array { $values = []; @@ -92,11 +86,8 @@ trait SerializesProperties /** * Restore the model after serialization. - * - * @param array $values - * @return void */ - public function __unserialize(array $values) + public function __unserialize(array $values): void { $properties = (new ReflectionClass($this))->getProperties(); @@ -130,11 +121,8 @@ trait SerializesProperties /** * Get the property value for the given property. - * - * @param ReflectionProperty $property - * @return mixed */ - protected function getPropertyValue(ReflectionProperty $property) + protected function getPropertyValue(ReflectionProperty $property): mixed { $property->setAccessible(true); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php index 7b8d1830e..1f2e826bf 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php @@ -10,12 +10,9 @@ trait DetectsResetIntegers * The integer values '0' and '-1' can be used on certain * LDAP attributes to instruct the server to reset the * value to an 'unset' or 'cleared' state. - * - * @param mixed $value - * @return bool */ - protected function valueIsResetInteger($value) + protected function valueIsResetInteger(mixed $value): bool { - return in_array($value, [0, -1], $strict = true); + return in_array($value, [0, -1], true); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php index a67200e94..947daca1a 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php @@ -9,8 +9,6 @@ class Entry extends Model implements DirectoryServer { /** * The attribute key that contains the models object GUID. - * - * @var string */ - protected $guidKey = 'gidNumber'; + protected string $guidKey = 'gidNumber'; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php index 49a6e0aae..c5b0c17d8 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php @@ -6,10 +6,8 @@ class Group extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'groupOfUniqueNames', 'posixGroup', diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php index 430588b0a..4a3bc143c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php @@ -6,10 +6,8 @@ class User extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'nsPerson', 'nsAccount', diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php index 8dbd1d29a..340bc2ea5 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php @@ -8,15 +8,11 @@ abstract class Event { /** * The model that the event is being triggered on. - * - * @var Model */ - protected $model; + protected Model $model; /** * Constructor. - * - * @param Model $model */ public function __construct(Model $model) { @@ -24,11 +20,9 @@ abstract class Event } /** - * Returns the model that generated the event. - * - * @return Model + * Get the model that generated the event. */ - public function getModel() + public function getModel(): Model { return $this->model; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php index 5e7be97d7..4890e2bfc 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php @@ -8,26 +8,18 @@ class Renaming extends Event { /** * The models RDN. - * - * @var string */ - protected $rdn; + protected string $rdn; /** * The models new parent DN. - * - * @var string */ - protected $newParentDn; + protected string $newParentDn; /** * Constructor. - * - * @param Model $model - * @param string $rdn - * @param string $newParentDn */ - public function __construct(Model $model, $rdn, $newParentDn) + public function __construct(Model $model, string $rdn, string $newParentDn) { parent::__construct($model); @@ -37,20 +29,16 @@ class Renaming extends Event /** * Get the models RDN. - * - * @return string */ - public function getRdn() + public function getRdn(): string { return $this->rdn; } /** * Get the models parent DN. - * - * @return string */ - public function getNewParentDn() + public function getNewParentDn(): string { return $this->newParentDn; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php index be6322b15..4f29ef033 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php @@ -13,41 +13,34 @@ class Entry extends BaseEntry implements FreeIPA { /** * The attribute key that contains the models object GUID. - * - * @var string */ - protected $guidKey = 'ipauniqueid'; + protected string $guidKey = 'ipauniqueid'; /** * The default attributes that should be mutated to dates. - * - * @var array */ - protected $defaultDates = [ + protected array $defaultDates = [ 'krblastpwdchange' => 'ldap', 'krbpasswordexpiration' => 'ldap', ]; /** - * @inheritdoc + * {@inheritdoc} */ - protected static function boot() + protected static function boot(): void { parent::boot(); // Here we'll add a global scope to all FreeIPA models to ensure the // Entry UUID is always selected on each query. This attribute is // virtual, so it must be manually selected to be included. - static::addGlobalScope(new AddEntryUuidToSelects()); + static::addGlobalScope(new AddEntryUuidToSelects); } /** * Create a new query builder. - * - * @param Connection $connection - * @return FreeIpaBuilder */ - public function newQueryBuilder(Connection $connection) + public function newQueryBuilder(Connection $connection): FreeIpaBuilder { return new FreeIpaBuilder($connection); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php index 10fd93404..941977595 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php @@ -2,14 +2,14 @@ namespace LdapRecord\Models\FreeIPA; +use LdapRecord\Models\Relations\HasMany; + class Group extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'groupofnames', 'nestedgroup', @@ -20,21 +20,17 @@ class Group extends Entry /** * The groups relationship. * - * Retrieves groups that the current group is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Retrieves groups that the current group is a part of. */ - public function groups() + public function groups(): HasMany { return $this->hasMany(self::class, 'member'); } /** * Retrieve the members of the group. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function members() + public function members(): HasMany { return $this->hasMany(User::class, 'memberof')->using($this, 'member'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php index 581b5beed..d35ed9141 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php @@ -10,12 +10,8 @@ class AddEntryUuidToSelects implements Scope { /** * Add the entry UUID to the selected attributes. - * - * @param Builder $query - * @param Model $model - * @return void */ - public function apply(Builder $query, Model $model) + public function apply(Builder $query, Model $model): void { empty($query->columns) ? $query->addSelect(['*', $model->getGuidKey()]) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php index 24c7f3b7d..47964f010 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php @@ -2,14 +2,14 @@ namespace LdapRecord\Models\FreeIPA; +use LdapRecord\Models\Relations\HasMany; + class User extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'person', 'inetorgperson', @@ -17,11 +17,9 @@ class User extends Entry ]; /** - * Retrieve groups that the current user is apart of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Retrieve groups that the current user is a part of. */ - public function groups() + public function groups(): HasMany { return $this->hasMany(Group::class, 'member'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php index 932c1a3b1..b17d0793a 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php @@ -11,110 +11,92 @@ use LdapRecord\Container; use LdapRecord\EscapesValues; use LdapRecord\Models\Attributes\DistinguishedName; use LdapRecord\Models\Attributes\Guid; +use LdapRecord\Query\Builder as BaseBuilder; use LdapRecord\Query\Model\Builder; use LdapRecord\Support\Arr; +use RuntimeException; +use Stringable; use UnexpectedValueException; /** @mixin Builder */ -abstract class Model implements ArrayAccess, Arrayable, JsonSerializable +abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, Stringable { - use EscapesValues; - use Concerns\HasEvents; - use Concerns\HasScopes; use Concerns\HasAttributes; + use Concerns\HasEvents; use Concerns\HasGlobalScopes; - use Concerns\HidesAttributes; use Concerns\HasRelationships; + use Concerns\HasScopes; + use Concerns\HidesAttributes; use Concerns\SerializesProperties; + use EscapesValues; /** * Indicates if the model exists in the directory. - * - * @var bool */ - public $exists = false; + public bool $exists = false; /** * Indicates whether the model was created during the current request lifecycle. - * - * @var bool */ - public $wasRecentlyCreated = false; + public bool $wasRecentlyCreated = false; /** * Indicates whether the model was renamed during the current request lifecycle. - * - * @var bool */ - public $wasRecentlyRenamed = false; + public bool $wasRecentlyRenamed = false; /** * The models distinguished name. - * - * @var string|null */ - protected $dn; + protected ?string $dn = null; /** * The base DN of where the model should be created in. - * - * @var string|null */ - protected $in; + protected ?string $in = null; /** * The object classes of the model. - * - * @var array */ - public static $objectClasses = []; + public static array $objectClasses = []; /** * The connection container instance. - * - * @var Container */ - protected static $container; + protected static ?Container $container = null; /** * The connection name for the model. - * - * @var string|null */ - protected $connection; + protected ?string $connection = null; /** - * The attribute key that contains the models object GUID. - * - * @var string + * The attribute key containing the models object GUID. */ - protected $guidKey = 'objectguid'; + protected string $guidKey = 'objectguid'; /** - * Contains the models modifications. - * - * @var array + * The array of the model's modifications. */ - protected $modifications = []; - - /** - * The array of global scopes on the model. - * - * @var array - */ - protected static $globalScopes = []; + protected array $modifications = []; /** * The array of booted models. - * - * @var array */ - protected static $booted = []; + protected static array $booted = []; + + /** + * The array of global scopes on the model. + */ + protected static array $globalScopes = []; + + /** + * The morph model cache containing object classes and their corresponding models. + */ + protected static array $morphCache = []; /** * Constructor. - * - * @param array $attributes */ public function __construct(array $attributes = []) { @@ -125,10 +107,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Check if the model needs to be booted and if so, do it. - * - * @return void */ - protected function bootIfNotBooted() + protected function bootIfNotBooted(): void { if (! isset(static::$booted[static::class])) { static::$booted[static::class] = true; @@ -139,20 +119,16 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * The "boot" method of the model. - * - * @return void */ - protected static function boot() + protected static function boot(): void { // } /** - * Clear the list of booted models so they will be re-booted. - * - * @return void + * Clear the list of booted models, so they will be re-booted. */ - public static function clearBootedModels() + public static function clearBootedModels(): void { static::$booted = []; @@ -161,12 +137,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Handle dynamic method calls into the model. - * - * @param string $method - * @param array $parameters - * @return mixed */ - public function __call($method, $parameters) + public function __call(string $method, array $parameters): mixed { if (method_exists($this, $method)) { return $this->$method(...$parameters); @@ -177,88 +149,66 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Handle dynamic static method calls into the method. - * - * @param string $method - * @param array $parameters - * @return mixed */ - public static function __callStatic($method, $parameters) + public static function __callStatic(string $method, array $parameters): mixed { - return (new static())->$method(...$parameters); + return (new static)->$method(...$parameters); } /** - * Returns the models distinguished name. - * - * @return string|null + * Get the models distinguished name. */ - public function getDn() + public function getDn(): ?string { return $this->dn; } /** - * Set the models distinguished name. - * - * @param string $dn - * @return $this + * Set the model's distinguished name. */ - public function setDn($dn) + public function setDn(?string $dn = null): static { - $this->dn = (string) $dn; + $this->dn = $dn; return $this; } /** - * A mutator for setting the models distinguished name. - * - * @param string $dn - * @return $this + * A mutator for setting the model's distinguished name. */ - public function setDnAttribute($dn) + public function setDnAttribute(string $dn): static { return $this->setRawAttribute('dn', $dn)->setDn($dn); } /** - * A mutator for setting the models distinguished name. - * - * @param string $dn - * @return $this + * A mutator for setting the model's distinguished name. */ - public function setDistinguishedNameAttribute($dn) + public function setDistinguishedNameAttribute(string $dn): static { return $this->setRawAttribute('distinguishedname', $dn)->setDn($dn); } /** * Get the connection for the model. - * - * @return Connection */ - public function getConnection() + public function getConnection(): Connection { return static::resolveConnection($this->getConnectionName()); } /** * Get the current connection name for the model. - * - * @return string */ - public function getConnectionName() + public function getConnectionName(): ?string { return $this->connection; } /** * Set the connection associated with the model. - * - * @param string $name - * @return $this */ - public function setConnection($name) + public function setConnection(?string $name = null): static { $this->connection = $name; @@ -267,24 +217,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Make a new model instance. - * - * @param array $attributes - * @return static */ - public static function make($attributes = []) + public static function make(array $attributes = []): static { return new static($attributes); } /** * Begin querying the model on a given connection. - * - * @param string|null $connection - * @return Builder */ - public static function on($connection = null) + public static function on(?string $connection = null): Builder { - $instance = new static(); + $instance = new static; $instance->setConnection($connection); @@ -293,11 +237,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get all the models from the directory. - * - * @param array|mixed $attributes - * @return Collection|static[] */ - public static function all($attributes = ['*']) + public static function all(array|string $attributes = ['*']): array|Collection { return static::query()->select($attributes)->paginate(); } @@ -305,17 +246,15 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get the RootDSE (AD schema) record from the directory. * - * @param string|null $connection - * @return Model - * * @throws \LdapRecord\Models\ModelNotFoundException */ - public static function getRootDse($connection = null) + public static function getRootDse(?string $connection = null): Model { + /** @var Model $model */ $model = static::getRootDseModel(); return $model::on($connection ?? (new $model)->getConnectionName()) - ->in(null) + ->in() ->read() ->whereHas('objectclass') ->firstOrFail(); @@ -326,40 +265,31 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable * * @return class-string */ - protected static function getRootDseModel() + protected static function getRootDseModel(): string { - $instance = (new static); + $instance = new static; - switch (true) { - case $instance instanceof Types\ActiveDirectory: - return ActiveDirectory\Entry::class; - case $instance instanceof Types\DirectoryServer: - return OpenLDAP\Entry::class; - case $instance instanceof Types\OpenLDAP: - return OpenLDAP\Entry::class; - case $instance instanceof Types\FreeIPA: - return FreeIPA\Entry::class; - default: - return Entry::class; - } + return match (true) { + $instance instanceof Types\ActiveDirectory => ActiveDirectory\Entry::class, + $instance instanceof Types\DirectoryServer => DirectoryServer\Entry::class, + $instance instanceof Types\OpenLDAP => OpenLDAP\Entry::class, + $instance instanceof Types\FreeIPA => FreeIPA\Entry::class, + default => Entry::class, + }; } /** * Begin querying the model. - * - * @return Builder */ - public static function query() + public static function query(): Builder { - return (new static())->newQuery(); + return (new static)->newQuery(); } /** * Get a new query for builder filtered by the current models object classes. - * - * @return Builder */ - public function newQuery() + public function newQuery(): Builder { return $this->registerModelScopes( $this->newQueryWithoutScopes() @@ -368,10 +298,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get a new query builder that doesn't have any global scopes. - * - * @return Builder */ - public function newQueryWithoutScopes() + public function newQueryWithoutScopes(): Builder { return static::resolveConnection( $this->getConnectionName() @@ -380,85 +308,64 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Create a new query builder. - * - * @param Connection $connection - * @return Builder */ - public function newQueryBuilder(Connection $connection) + public function newQueryBuilder(Connection $connection): Builder { return new Builder($connection); } /** * Create a new model instance. - * - * @param array $attributes - * @return static */ - public function newInstance(array $attributes = []) + public function newInstance(array $attributes = []): static { return (new static($attributes))->setConnection($this->getConnectionName()); } /** * Resolve a connection instance. - * - * @param string|null $connection - * @return Connection */ - public static function resolveConnection($connection = null) + public static function resolveConnection(?string $connection = null): Connection { - return static::getConnectionContainer()->get($connection); + return static::getConnectionContainer()->getConnection($connection); } /** * Get the connection container. - * - * @return Container */ - public static function getConnectionContainer() + public static function getConnectionContainer(): Container { return static::$container ?? static::getDefaultConnectionContainer(); } /** * Get the default singleton container instance. - * - * @return Container */ - public static function getDefaultConnectionContainer() + public static function getDefaultConnectionContainer(): Container { return Container::getInstance(); } /** * Set the connection container. - * - * @param Container $container - * @return void */ - public static function setConnectionContainer(Container $container) + public static function setConnectionContainer(Container $container): void { static::$container = $container; } /** * Unset the connection container. - * - * @return void */ - public static function unsetConnectionContainer() + public static function unsetConnectionContainer(): void { static::$container = null; } /** * Register the query scopes for this builder instance. - * - * @param Builder $builder - * @return Builder */ - public function registerModelScopes($builder) + public function registerModelScopes(Builder $builder): Builder { $this->applyObjectClassScopes($builder); @@ -469,11 +376,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Register the global model scopes. - * - * @param Builder $builder - * @return Builder */ - public function registerGlobalScopes($builder) + public function registerGlobalScopes(Builder $builder): Builder { foreach ($this->getGlobalScopes() as $identifier => $scope) { $builder->withGlobalScope($identifier, $scope); @@ -484,11 +388,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Apply the model object class scopes to the given builder instance. - * - * @param Builder $query - * @return void */ - public function applyObjectClassScopes(Builder $query) + public function applyObjectClassScopes(Builder $query): void { foreach (static::$objectClasses as $objectClass) { $query->where('objectclass', '=', $objectClass); @@ -496,164 +397,121 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable } /** - * Returns the models distinguished name when the model is converted to a string. - * - * @return null|string + * Get the models distinguished name when the model is converted to a string. */ - public function __toString() + public function __toString(): string { - return $this->getDn(); + return (string) $this->getDn(); } /** * Returns a new batch modification. - * - * @param string|null $attribute - * @param string|int|null $type - * @param array $values - * @return BatchModification */ - public function newBatchModification($attribute = null, $type = null, $values = []) + public function newBatchModification(?string $attribute = null, ?int $type = null, array $values = []): BatchModification { return new BatchModification($attribute, $type, $values); } /** * Returns a new collection with the specified items. - * - * @param mixed $items - * @return Collection */ - public function newCollection($items = []) + public function newCollection(mixed $items = []): Collection { return new Collection($items); } /** * Dynamically retrieve attributes on the object. - * - * @param string $key - * @return mixed */ - public function __get($key) + public function __get(string $key): mixed { return $this->getAttribute($key); } /** * Dynamically set attributes on the object. - * - * @param string $key - * @param mixed $value - * @return $this */ - public function __set($key, $value) + public function __set(string $key, mixed $value): void { - return $this->setAttribute($key, $value); + $this->setAttribute($key, $value); } /** * Determine if the given offset exists. - * - * @param string $offset - * @return bool */ #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists(mixed $offset): bool { return ! is_null($this->getAttribute($offset)); } /** * Get the value for a given offset. - * - * @param string $offset - * @return mixed */ #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet(mixed $offset): mixed { return $this->getAttribute($offset); } /** * Set the value at the given offset. - * - * @param string $offset - * @param mixed $value - * @return void */ #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet(mixed $offset, mixed $value): void { $this->setAttribute($offset, $value); } /** * Unset the value at the given offset. - * - * @param string $offset - * @return void */ #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset(mixed $offset): void { unset($this->attributes[$offset]); } /** * Determine if an attribute exists on the model. - * - * @param string $key - * @return bool */ - public function __isset($key) + public function __isset(string $key): bool { return $this->offsetExists($key); } /** * Unset an attribute on the model. - * - * @param string $key - * @return void */ - public function __unset($key) + public function __unset(string $key): void { $this->offsetUnset($key); } /** * Convert the model to its JSON encodeable array form. - * - * @return array */ - public function toArray() + public function toArray(): array { return $this->attributesToArray(); } /** * Convert the model's attributes into JSON encodeable values. - * - * @return array */ #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } /** * Convert the attributes for JSON serialization. - * - * @param array $attributes - * @return array */ - protected function convertAttributesForJson(array $attributes = []) + protected function convertAttributesForJson(array $attributes = []): array { // If the model has a GUID set, we need to convert it to its - // string format, due to it being in binary. Otherwise + // string format, due to it being in binary. Otherwise, // we will receive a JSON serialization exception. if (isset($attributes[$this->guidKey])) { $attributes[$this->guidKey] = [$this->getConvertedGuid( @@ -666,21 +524,25 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Convert the attributes from JSON serialization. - * - * @param array $attributes - * @return array */ - protected function convertAttributesFromJson(array $attributes = []) + protected function convertAttributesFromJson(array $attributes = []): array { + // Here we are converting the model's GUID and SID attributes + // back to their original values from serialization, so that + // their original value may be used and compared against. + if (isset($attributes[$this->guidKey])) { + $attributes[$this->guidKey] = [$this->getBinaryGuid( + Arr::first($attributes[$this->guidKey]) + )]; + } + return $attributes; } /** * Reload a fresh model instance from the directory. - * - * @return static|false */ - public function fresh() + public function fresh(): static|false { if (! $this->exists) { return false; @@ -691,50 +553,106 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Determine if two models have the same distinguished name and belong to the same connection. - * - * @param Model|null $model - * @return bool */ - public function is($model) + public function is(?Model $model = null): bool { return ! is_null($model) - && $this->dn == $model->getDn() - && $this->getConnectionName() == $model->getConnectionName(); + && ! empty($this->dn) + && ! empty($model->getDn()) + && $this->dn == $model->getDn() + && $this->getConnectionName() == $model->getConnectionName(); } /** * Determine if two models are not the same. - * - * @param Model|null $model - * @return bool */ - public function isNot($model) + public function isNot(?Model $model = null): bool { return ! $this->is($model); } /** * Hydrate a new collection of models from search results. - * - * @param array $records - * @return Collection */ - public function hydrate($records) + public function hydrate(array $records): Collection { return $this->newCollection($records)->transform(function ($attributes) { - return $attributes instanceof static - ? $attributes - : static::newInstance()->setRawAttributes($attributes); + if ($attributes instanceof static) { + return $attributes; + } + + return static::newInstance()->setRawAttributes($attributes); }); } /** - * Converts the current model into the given model. - * - * @param Model $into - * @return Model + * Morph the model into a one of matching models using their object classes. */ - public function convert(self $into) + public function morphInto(array $models, ?callable $resolver = null): Model + { + if (class_exists($model = $this->determineMorphModel($this, $models, $resolver))) { + return $this->convert(new $model); + } + + return $this; + } + + /** + * Morph the model into a one of matching models or throw an exception. + */ + public function morphIntoOrFail(array $models, ?callable $resolver = null): Model + { + $model = $this->morphInto($models, $resolver); + + if ($model instanceof $this) { + throw new RuntimeException( + 'The model could not be morphed into any of the given models.' + ); + } + + return $model; + } + + /** + * Determine the model to morph into from the given models. + * + * @return class-string|bool + */ + protected function determineMorphModel(Model $model, array $models, ?callable $resolver = null): string|bool + { + $morphModelMap = []; + + foreach ($models as $modelClass) { + $morphModelMap[$modelClass] = static::$morphCache[$modelClass] ??= $this->normalizeObjectClasses( + $modelClass::$objectClasses + ); + } + + $objectClasses = $this->normalizeObjectClasses( + $model->getObjectClasses() + ); + + $resolver ??= function (array $objectClasses, array $morphModelMap) { + return array_search($objectClasses, $morphModelMap); + }; + + return $resolver($objectClasses, $morphModelMap); + } + + /** + * Sort and normalize the object classes. + */ + protected function normalizeObjectClasses(array $classes): array + { + sort($classes); + + return array_map('strtolower', $classes); + } + + /** + * Converts the current model into the given model. + */ + public function convert(self $into): Model { $into->setDn($this->getDn()); $into->setConnection($this->getConnectionName()); @@ -748,10 +666,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Refreshes the current models attributes with the directory values. - * - * @return bool */ - public function refresh() + public function refresh(): bool { if ($model = $this->fresh()) { $this->setRawAttributes($model->getAttributes()); @@ -764,10 +680,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get the model's batch modifications to be processed. - * - * @return array */ - public function getModifications() + public function getModifications(): array { $builtModifications = []; @@ -780,11 +694,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Set the models batch modifications. - * - * @param array $modifications - * @return $this */ - public function setModifications(array $modifications = []) + public function setModifications(array $modifications = []): static { $this->modifications = []; @@ -798,12 +709,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Adds a batch modification to the model. * - * @param array|BatchModification $mod - * @return $this - * * @throws InvalidArgumentException */ - public function addModification($mod = []) + public function addModification(BatchModification|array $mod = []): static { if ($mod instanceof BatchModification) { $mod = $mod->get(); @@ -822,85 +730,68 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get the model's guid attribute key name. - * - * @return string */ - public function getGuidKey() + public function getGuidKey(): string { return $this->guidKey; } /** * Get the model's ANR attributes for querying when incompatible with ANR. - * - * @return array */ - public function getAnrAttributes() + public function getAnrAttributes(): array { return ['cn', 'sn', 'uid', 'name', 'mail', 'givenname', 'displayname']; } /** * Get the name of the model, or the given DN. - * - * @param string|null $dn - * @return string|null */ - public function getName($dn = null) + public function getName(?string $dn = null): ?string { return $this->newDn($dn ?? $this->dn)->name(); } /** * Get the head attribute of the model, or the given DN. - * - * @param string|null $dn - * @return string|null */ - public function getHead($dn = null) + public function getHead(?string $dn = null): ?string { return $this->newDn($dn ?? $this->dn)->head(); } /** * Get the RDN of the model, of the given DN. - * - * @param string|null - * @return string|null */ - public function getRdn($dn = null) + public function getRdn(?string $dn = null): ?string { return $this->newDn($dn ?? $this->dn)->relative(); } /** * Get the parent distinguished name of the model, or the given DN. - * - * @param string|null - * @return string|null */ - public function getParentDn($dn = null) + public function getParentDn(?string $dn = null): ?string { return $this->newDn($dn ?? $this->dn)->parent(); } /** - * Create a new Distinguished Name object. - * - * @param string|null $dn - * @return DistinguishedName + * Create a new distinguished name. */ - public function newDn($dn = null) + public function newDn(?string $dn = null): DistinguishedName { + if (! is_null($dn) && str_contains($dn, BaseBuilder::BASE_DN_PLACEHOLDER)) { + $dn = $this->newQuery()->substituteBaseDn($dn); + } + return new DistinguishedName($dn); } /** * Get the model's object GUID key. - * - * @return string */ - public function getObjectGuidKey() + public function getObjectGuidKey(): string { return $this->guidKey; } @@ -909,76 +800,60 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable * Get the model's binary object GUID. * * @see https://msdn.microsoft.com/en-us/library/ms679021(v=vs.85).aspx - * - * @return string|null */ - public function getObjectGuid() + public function getObjectGuid(): ?string { return $this->getFirstAttribute($this->guidKey); } /** * Get the model's object classes. - * - * @return array */ - public function getObjectClasses() + public function getObjectClasses(): array { return $this->getAttribute('objectclass', static::$objectClasses); } /** * Get the model's string GUID. - * - * @param string|null $guid - * @return string|null */ - public function getConvertedGuid($guid = null) + public function getConvertedGuid(?string $guid = null): ?string { try { - return (string) $this->newObjectGuid( - $guid ?? $this->getObjectGuid() + return $this->newObjectGuid( + (string) ($guid ?? $this->getObjectGuid()) ); - } catch (InvalidArgumentException $e) { - return; + } catch (InvalidArgumentException) { + return null; } } /** * Get the model's binary GUID. - * - * @param string|null $guid - * @return string|null */ - public function getBinaryGuid($guid = null) + public function getBinaryGuid(?string $guid = null): ?string { try { return $this->newObjectGuid( $guid ?? $this->getObjectGuid() )->getBinary(); - } catch (InvalidArgumentException $e) { - return; + } catch (InvalidArgumentException) { + return null; } } /** * Make a new object Guid instance. - * - * @param string $value - * @return Guid */ - protected function newObjectGuid($value) + protected function newObjectGuid(string $value): Guid { return new Guid($value); } /** * Determine if the current model is a direct descendant of the given. - * - * @param static|string $parent - * @return bool */ - public function isChildOf($parent) + public function isChildOf(Model|string|null $parent = null): bool { return $this->newDn($this->getDn())->isChildOf( $this->newDn((string) $parent) @@ -986,12 +861,19 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable } /** - * Determine if the current model is a direct ascendant of the given. - * - * @param static|string $child - * @return bool + * Determine if the current model is a sibling of the given. */ - public function isParentOf($child) + public function isSiblingOf(Model|string|null $model = null): bool + { + return $this->newDn($this->getDn())->isSiblingOf( + $this->newDn((string) $model) + ); + } + + /** + * Determine if the current model is a direct ascendant of the given. + */ + public function isParentOf(Model|string|null $child = null): bool { return $this->newDn($this->getDn())->isParentOf( $this->newDn((string) $child) @@ -1000,34 +882,24 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Determine if the current model is a descendant of the given. - * - * @param static|string $model - * @return bool */ - public function isDescendantOf($model) + public function isDescendantOf(Model|string|null $model = null): bool { return $this->dnIsInside($this->getDn(), $model); } /** * Determine if the current model is a ancestor of the given. - * - * @param static|string $model - * @return bool */ - public function isAncestorOf($model) + public function isAncestorOf(Model|string|null $model = null): bool { return $this->dnIsInside($model, $this->getDn()); } /** - * Determines if the DN is inside of the parent DN. - * - * @param static|string $dn - * @param static|string $parentDn - * @return bool + * Determine if the DN is inside the parent DN. */ - protected function dnIsInside($dn, $parentDn) + protected function dnIsInside(Model|string|null $dn = null, Model|string|null $parentDn = null): bool { return $this->newDn((string) $dn)->isDescendantOf( $this->newDn($parentDn) @@ -1036,11 +908,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Set the base DN of where the model should be created in. - * - * @param static|string $dn - * @return $this */ - public function inside($dn) + public function inside(Model|string $dn): static { $this->in = $dn instanceof self ? $dn->getDn() : $dn; @@ -1050,12 +919,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Save the model to the directory without raising any events. * - * @param array $attributes - * @return void - * * @throws \LdapRecord\LdapRecordException */ - public function saveQuietly(array $attributes = []) + public function saveQuietly(array $attributes = []): void { static::withoutEvents(function () use ($attributes) { $this->save($attributes); @@ -1065,12 +931,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Save the model to the directory. * - * @param array $attributes The attributes to update or create for the current entry. - * @return void - * * @throws \LdapRecord\LdapRecordException */ - public function save(array $attributes = []) + public function save(array $attributes = []): void { $this->fill($attributes); @@ -1088,11 +951,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Inserts the model into the directory. * - * @return void - * * @throws \LdapRecord\LdapRecordException */ - protected function performInsert() + protected function performInsert(): void { // Here we will populate the models object classes if it // does not already have any set. An LDAP object cannot @@ -1112,11 +973,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable $this->dispatch('creating'); + // Some PHP versions prevent non-numerically indexed arrays + // from being sent to the server. To resolve this, we will + // convert the attributes to numerically indexed arrays. + $attributes = array_map('array_values', array_filter($this->getAttributes())); + // Here we perform the insert of new object in the directory, // but filter out any empty attributes before sending them // to the server. LDAP servers will throw an exception if // attributes have been given empty or null values. - $query->insert($this->getDn(), array_filter($this->getAttributes())); + $this->dn = $query->insertAndGetDn($this->getDn(), $attributes); + + $this->attributes = $attributes; $this->dispatch('created'); @@ -1130,11 +998,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Updates the model in the directory. * - * @return void - * * @throws \LdapRecord\LdapRecordException */ - protected function performUpdate() + protected function performUpdate(): void { if (! count($modifications = $this->getModifications())) { return; @@ -1146,18 +1012,17 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable $this->dispatch('updated'); + $this->syncChanges(); + $this->syncOriginal(); } /** * Create the model in the directory. * - * @param array $attributes The attributes for the new entry. - * @return Model - * * @throws \LdapRecord\LdapRecordException */ - public static function create(array $attributes = []) + public static function create(array $attributes = []): static { $instance = new static($attributes); @@ -1167,22 +1032,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable } /** - * Create an attribute on the model. - * - * @param string $attribute The attribute to create - * @param mixed $value The value of the new attribute - * @return void + * Add an attribute on the model with the given value. * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function createAttribute($attribute, $value) + public function addAttribute(string $attribute, mixed $value): void { $this->assertExists(); $this->dispatch(['saving', 'updating']); - $this->newQuery()->insertAttributes($this->dn, [$attribute => (array) $value]); + $this->newQuery()->add($this->dn, [$attribute => (array) $value]); $this->addAttributeValue($attribute, $value); @@ -1192,13 +1053,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Update the model. * - * @param array $attributes The attributes to update for the current entry. - * @return void - * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function update(array $attributes = []) + public function update(array $attributes = []): void { $this->assertExists(); @@ -1208,20 +1066,16 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Update the model attribute with the specified value. * - * @param string $attribute The attribute to modify - * @param mixed $value The new value for the attribute - * @return void - * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function updateAttribute($attribute, $value) + public function replaceAttribute(string $attribute, mixed $value): void { $this->assertExists(); $this->dispatch(['saving', 'updating']); - $this->newQuery()->updateAttributes($this->dn, [$attribute => (array) $value]); + $this->newQuery()->replace($this->dn, [$attribute => (array) $value]); $this->addAttributeValue($attribute, $value); @@ -1231,17 +1085,13 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Destroy the models for the given distinguished names. * - * @param Collection|array|string $dns - * @param bool $recursive - * @return int - * * @throws \LdapRecord\LdapRecordException */ - public static function destroy($dns, $recursive = false) + public static function destroy(mixed $dns, bool $recursive = false): int { $count = 0; - $instance = new static(); + $instance = new static; if ($dns instanceof Collection) { $dns = $dns->modelDns()->toArray(); @@ -1270,13 +1120,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable * Throws a ModelNotFoundException if the current model does * not exist or does not contain a distinguished name. * - * @param bool $recursive Whether to recursively delete leaf nodes (models that are children). - * @return void - * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function delete($recursive = false) + public function delete(bool $recursive = false): void { $this->assertExists(); @@ -1299,38 +1146,44 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Deletes leaf nodes that are attached to the model. * - * @return void - * * @throws \LdapRecord\LdapRecordException */ - protected function deleteLeafNodes() + protected function deleteLeafNodes(): void { $this->newQueryWithoutScopes() ->in($this->dn) - ->listing() + ->list() ->each(function (Model $model) { - $model->delete($recursive = true); + $model->delete(recursive: true); }); } /** - * Delete an attribute on the model. - * - * @param string|array $attributes The attribute(s) to delete - * - * Delete specific values in attributes: - * - * ["memberuid" => "jdoe"] - * - * Delete an entire attribute: - * - * ["memberuid" => []] - * @return void + * Remove an attribute on the model. * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function deleteAttribute($attributes) + public function removeAttribute(string $attribute, mixed $value = null): void + { + $this->removeAttributes([$attribute => $value]); + } + + /** + * Remove an attribute on the model. + * + * Remove specific values in attributes: + * + * ["memberuid" => "jdoe"] + * + * Remove an entire attribute: + * + * ["memberuid" => []] + * + * @throws ModelDoesNotExistException + * @throws \LdapRecord\LdapRecordException + */ + public function removeAttributes(array|string $attributes): void { $this->assertExists(); @@ -1338,7 +1191,7 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable $this->dispatch(['saving', 'updating']); - $this->newQuery()->deleteAttributes($this->dn, $attributes); + $this->newQuery()->remove($this->dn, $attributes); foreach ($attributes as $attribute => $value) { // If the attribute value is empty, we can assume the @@ -1364,11 +1217,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Make a deletable attribute array. - * - * @param string|array $attributes - * @return array */ - protected function makeDeletableAttributes($attributes) + protected function makeDeletableAttributes(string|array $attributes): array { $delete = []; @@ -1386,15 +1236,11 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable * * For example: $user->move($ou); * - * @param static|string $newParentDn The new parent of the current model. - * @param bool $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved. - * @return void - * * @throws UnexpectedValueException * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function move($newParentDn, $deleteOldRdn = true) + public function move(Model|string $newParentDn, bool $deleteOldRdn = true): void { $this->assertExists(); @@ -1408,15 +1254,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Rename the model to a new RDN and new parent. * - * @param string $rdn The models new relative distinguished name. Example: "cn=JohnDoe" - * @param static|string|null $newParentDn The models new parent distinguished name (if moving). Leave this null if you are only renaming. Example: "ou=MovedUsers,dc=acme,dc=org" - * @param bool|true $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved. - * @return void - * * @throws ModelDoesNotExistException * @throws \LdapRecord\LdapRecordException */ - public function rename($rdn, $newParentDn = null, $deleteOldRdn = true) + public function rename(string $rdn, Model|string|null $newParentDn = null, bool $deleteOldRdn = true): void { $this->assertExists(); @@ -1428,6 +1269,13 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable $newParentDn = $this->getParentDn($this->dn); } + // If the RDN we have been given is empty when parsed, we must + // have been given a string, with no attribute. In this case, + // we will create a new RDN using the current DN's head. + if ($this->newDn($rdn)->isEmpty()) { + $rdn = $this->getUpdateableRdn($rdn); + } + // If the RDN and the new parent DN are the same as the current, // we will simply return here to prevent a rename operation // being sent, which would fail anyway in such case. @@ -1438,21 +1286,12 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable return; } - // If the RDN we have been given is empty when parsed, we must - // have been given a string, with no attribute. In this case, - // we will create a new RDN using the current DN's head. - if ($this->newDn($rdn)->isEmpty()) { - $rdn = $this->getUpdateableRdn($rdn); - } - $this->dispatch('renaming', [$rdn, $newParentDn]); - $this->newQuery()->rename($this->dn, $rdn, $newParentDn, $deleteOldRdn); - // If the model was successfully renamed, we will set // its new DN so any further updates to the model // can be performed without any issues. - $this->dn = implode(',', [$rdn, $newParentDn]); + $this->dn = $this->newQuery()->renameAndGetDn($this->dn, $rdn, $newParentDn, $deleteOldRdn); $map = $this->newDn($this->dn)->assoc(); @@ -1471,24 +1310,17 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable } /** - * Get an updateable RDN for the model. - * - * @param string $name - * @return string + * Get an updatable RDN for the model. */ - public function getUpdateableRdn($name) + public function getUpdateableRdn(string $name): string { return $this->getCreatableRdn($name, $this->newDn($this->dn)->head()); } /** * Get a distinguished name that is creatable for the model. - * - * @param string|null $name - * @param string|null $attribute - * @return string */ - public function getCreatableDn($name = null, $attribute = null) + public function getCreatableDn(?string $name = null, ?string $attribute = null): string { return implode(',', [ $this->getCreatableRdn($name, $attribute), @@ -1498,39 +1330,30 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Get a creatable (escaped) RDN for the model. - * - * @param string|null $name - * @param string|null $attribute - * @return string */ - public function getCreatableRdn($name = null, $attribute = null) + public function getCreatableRdn(?string $name = null, ?string $attribute = null): string { $attribute = $attribute ?? $this->getCreatableRdnAttribute(); $name = $this->escape( $name ?? $this->getFirstAttribute($attribute) - )->dn(); + )->forDn(); return "$attribute=$name"; } /** * Get the creatable RDN attribute name. - * - * @return string */ - protected function getCreatableRdnAttribute() + protected function getCreatableRdnAttribute(): string { return 'cn'; } /** - * Determines if the given modification is valid. - * - * @param mixed $mod - * @return bool + * Determine if the given modification is valid. */ - protected function isValidModification($mod) + protected function isValidModification(mixed $mod): bool { return Arr::accessible($mod) && Arr::exists($mod, BatchModification::KEY_MODTYPE) @@ -1542,7 +1365,7 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable * * @return BatchModification[] */ - protected function buildModificationsFromDirty() + protected function buildModificationsFromDirty(): array { $modifications = []; @@ -1569,25 +1392,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable /** * Throw an exception if the model does not exist. * - * @deprecated - * - * @return void - * * @throws ModelDoesNotExistException */ - protected function requireExistence() - { - return $this->assertExists(); - } - - /** - * Throw an exception if the model does not exist. - * - * @return void - * - * @throws ModelDoesNotExistException - */ - protected function assertExists() + protected function assertExists(): void { if (! $this->exists || is_null($this->dn)) { throw ModelDoesNotExistException::forModel($this); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php index 508414911..98efa9865 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php @@ -7,30 +7,22 @@ use LdapRecord\LdapRecordException; class ModelDoesNotExistException extends LdapRecordException { /** - * The class name of the model that does not exist. - * - * @var Model + * The instance of the model that does not exist. */ - protected $model; + protected Model $model; /** * Create a new exception for the given model. - * - * @param Model $model - * @return ModelDoesNotExistException */ - public static function forModel(Model $model) + public static function forModel(Model $model): static { - return (new static())->setModel($model); + return (new static)->setModel($model); } /** - * Set the model that does not exist. - * - * @param Model $model - * @return ModelDoesNotExistException + * Set the model instance that does not exist. */ - public function setModel(Model $model) + public function setModel(Model $model): static { $this->model = $model; @@ -40,4 +32,12 @@ class ModelDoesNotExistException extends LdapRecordException return $this; } + + /** + * Get the instance of the model that does not exist. + */ + public function getModel(): Model + { + return $this->model; + } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php index c11ca72d4..e20016a45 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php @@ -13,31 +13,26 @@ class Entry extends BaseEntry implements OpenLDAP { /** * The attribute key that contains the models object GUID. - * - * @var string */ - protected $guidKey = 'entryuuid'; + protected string $guidKey = 'entryuuid'; /** - * @inheritdoc + * {@inheritdoc} */ - protected static function boot() + protected static function boot(): void { parent::boot(); // Here we'll add a global scope to all OpenLDAP models to ensure the // Entry UUID is always selected on each query. This attribute is // virtual, so it must be manually selected to be included. - static::addGlobalScope(new AddEntryUuidToSelects()); + static::addGlobalScope(new AddEntryUuidToSelects); } /** * Create a new query builder. - * - * @param Connection $connection - * @return OpenLdapBuilder */ - public function newQueryBuilder(Connection $connection) + public function newQueryBuilder(Connection $connection): OpenLdapBuilder { return new OpenLdapBuilder($connection); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php index a9a682a06..e7d81ef28 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php @@ -2,27 +2,23 @@ namespace LdapRecord\Models\OpenLDAP; +use LdapRecord\Models\Relations\HasManyIn; + class Group extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'groupofuniquenames', ]; /** * The members relationship. - * - * Retrieves members that are apart of the group. - * - * @return \LdapRecord\Models\Relations\HasMany */ - public function members() + public function members(): HasManyIn { - return $this->hasMany([static::class, User::class], 'memberUid'); + return $this->hasManyIn([static::class, User::class], 'uniquemember')->using($this, 'uniquemember'); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php index 7ae0a37a4..e304237e7 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php @@ -6,20 +6,16 @@ class OrganizationalUnit extends Entry { /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'organizationalunit', ]; /** * Get the creatable RDN attribute name. - * - * @return string */ - public function getCreatableRdnAttribute() + public function getCreatableRdnAttribute(): string { return 'ou'; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php index 780a633f3..78efa95f4 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php @@ -10,12 +10,8 @@ class AddEntryUuidToSelects implements Scope { /** * Add the entry UUID to the selected attributes. - * - * @param Builder $query - * @param Model $model - * @return void */ - public function apply(Builder $query, Model $model) + public function apply(Builder $query, Model $model): void { empty($query->columns) ? $query->addSelect(['*', $model->getGuidKey()]) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php index c8626de6d..beaba9e4c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php @@ -5,32 +5,27 @@ namespace LdapRecord\Models\OpenLDAP; use Illuminate\Contracts\Auth\Authenticatable; use LdapRecord\Models\Concerns\CanAuthenticate; use LdapRecord\Models\Concerns\HasPassword; +use LdapRecord\Models\Relations\HasMany; class User extends Entry implements Authenticatable { - use HasPassword; use CanAuthenticate; + use HasPassword; /** * The password's attribute name. - * - * @var string */ - protected $passwordAttribute = 'userpassword'; + protected string $passwordAttribute = 'userpassword'; /** * The password's hash method. - * - * @var string */ - protected $passwordHashMethod = 'ssha'; + protected string $passwordHashMethod = 'ssha'; /** * The object classes of the LDAP model. - * - * @var array */ - public static $objectClasses = [ + public static array $objectClasses = [ 'top', 'person', 'organizationalperson', @@ -38,14 +33,18 @@ class User extends Entry implements Authenticatable ]; /** - * The groups relationship. - * - * Retrieve groups that the user is a part of. - * - * @return \LdapRecord\Models\Relations\HasMany + * Get the unique identifier for the user. */ - public function groups() + public function getAuthIdentifier(): string { - return $this->hasMany(Group::class, 'memberuid', 'uid'); + return $this->getFirstAttribute($this->guidKey); + } + + /** + * The groups relationship. + */ + public function groups(): HasMany + { + return $this->hasMany(Group::class, 'uniquemember'); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php index 583f81c30..16e65b14c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php @@ -3,73 +3,21 @@ namespace LdapRecord\Models\Relations; use Closure; -use LdapRecord\DetectsErrors; -use LdapRecord\LdapRecordException; use LdapRecord\Models\Collection; use LdapRecord\Models\Model; -use LdapRecord\Models\ModelNotFoundException; +use LdapRecord\Query\Model\Builder; class HasMany extends OneToMany { - use DetectsErrors; - - /** - * The model to use for attaching / detaching. - * - * @var Model - */ - protected $using; - - /** - * The attribute key to use for attaching / detaching. - * - * @var string - */ - protected $usingKey; - /** * The pagination page size. - * - * @var int */ - protected $pageSize = 1000; - - /** - * The exceptions to bypass for each relation operation. - * - * @var array - */ - protected $bypass = [ - 'attach' => [ - 'Already exists', 'Type or value exists', - ], - 'detach' => [ - 'No such attribute', 'Server is unwilling to perform', - ], - ]; - - /** - * Set the model and attribute to use for attaching / detaching. - * - * @param Model $using - * @param string $usingKey - * @return $this - */ - public function using(Model $using, $usingKey) - { - $this->using = $using; - $this->usingKey = $usingKey; - - return $this; - } + protected int $pageSize = 1000; /** * Set the pagination page size of the relation query. - * - * @param int $pageSize - * @return $this */ - public function setPageSize($pageSize) + public function setPageSize(int $pageSize): static { $this->pageSize = $pageSize; @@ -78,22 +26,16 @@ class HasMany extends OneToMany /** * Paginate the relation using the given page size. - * - * @param int $pageSize - * @return Collection */ - public function paginate($pageSize = 1000) + public function paginate(int $pageSize = 1000): Collection { return $this->paginateOnceUsing($pageSize); } /** * Paginate the relation using the page size once. - * - * @param int $pageSize - * @return Collection */ - protected function paginateOnceUsing($pageSize) + protected function paginateOnceUsing(int $pageSize): Collection { $size = $this->pageSize; @@ -106,44 +48,32 @@ class HasMany extends OneToMany /** * Execute a callback over each result while chunking. - * - * @param Closure $callback - * @param int $pageSize - * @return bool */ - public function each(Closure $callback, $pageSize = 1000) + public function each(Closure $callback, int $pageSize = 1000): bool { - $this->chunk($pageSize, function ($results) use ($callback) { + return $this->chunk($pageSize, function ($results) use ($callback) { foreach ($results as $key => $value) { if ($callback($value, $key) === false) { return false; } } + + return true; }); } /** * Chunk the relation results using the given callback. - * - * @param int $pageSize - * @param Closure $callback - * @param array $loaded - * @return bool */ - public function chunk($pageSize, Closure $callback) + public function chunk(int $pageSize, Closure $callback): bool { return $this->chunkRelation($pageSize, $callback); } /** * Execute the callback over chunks of relation results. - * - * @param int $pageSize - * @param Closure $callback - * @param array $loaded - * @return bool */ - protected function chunkRelation($pageSize, Closure $callback, $loaded = []) + protected function chunkRelation(int $pageSize, Closure $callback, array $loaded = []): bool { return $this->getRelationQuery()->chunk($pageSize, function (Collection $results) use ($pageSize, $callback, $loaded) { $models = $this->transformResults($results)->when($this->recursive, function (Collection $models) use ($loaded) { @@ -165,15 +95,15 @@ class HasMany extends OneToMany } }); }); + + return true; }); } /** * Get the relationships results. - * - * @return Collection */ - public function getRelationResults() + public function getRelationResults(): Collection { return $this->transformResults( $this->getRelationQuery()->paginate($this->pageSize) @@ -182,10 +112,8 @@ class HasMany extends OneToMany /** * Get the prepared relationship query. - * - * @return \LdapRecord\Query\Model\Builder */ - public function getRelationQuery() + public function getRelationQuery(): Builder { $columns = $this->query->getSelects(); @@ -209,212 +137,4 @@ class HasMany extends OneToMany $this->getEscapedForeignValueFromModel($this->parent) ); } - - /** - * Attach a model to the relation. - * - * @param Model|string $model - * @return Model|string|false - */ - public function attach($model) - { - return $this->attemptFailableOperation( - $this->buildAttachCallback($model), - $this->bypass['attach'], - $model - ); - } - - /** - * Build the attach callback. - * - * @param Model|string $model - * @return \Closure - */ - protected function buildAttachCallback($model) - { - return function () use ($model) { - $foreign = $this->getAttachableForeignValue($model); - - if ($this->using) { - return $this->using->createAttribute($this->usingKey, $foreign); - } - - if (! $model instanceof Model) { - $model = $this->getForeignModelByValueOrFail($model); - } - - return $model->createAttribute($this->relationKey, $foreign); - }; - } - - /** - * Attach a collection of models to the parent instance. - * - * @param iterable $models - * @return iterable - */ - public function attachMany($models) - { - foreach ($models as $model) { - $this->attach($model); - } - - return $models; - } - - /** - * Detach the model from the relation. - * - * @param Model|string $model - * @return Model|string|false - */ - public function detach($model) - { - return $this->attemptFailableOperation( - $this->buildDetachCallback($model), - $this->bypass['detach'], - $model - ); - } - - /** - * Detach the model or delete the parent if the relation is empty. - * - * @param Model|string $model - * @return void - */ - public function detachOrDeleteParent($model) - { - $count = $this->onceWithoutMerging(function () { - return $this->count(); - }); - - if ($count <= 1) { - return $this->getParent()->delete(); - } - - return $this->detach($model); - } - - /** - * Build the detach callback. - * - * @param Model|string $model - * @return \Closure - */ - protected function buildDetachCallback($model) - { - return function () use ($model) { - $foreign = $this->getAttachableForeignValue($model); - - if ($this->using) { - return $this->using->deleteAttribute([$this->usingKey => $foreign]); - } - - if (! $model instanceof Model) { - $model = $this->getForeignModelByValueOrFail($model); - } - - return $model->deleteAttribute([$this->relationKey => $foreign]); - }; - } - - /** - * Get the attachable foreign value from the model. - * - * @param Model|string $model - * @return string - */ - protected function getAttachableForeignValue($model) - { - if ($model instanceof Model) { - return $this->using - ? $this->getForeignValueFromModel($model) - : $this->getParentForeignValue(); - } - - return $this->using ? $model : $this->getParentForeignValue(); - } - - /** - * Get the foreign model by the given value, or fail. - * - * @param string $model - * @return Model - * - * @throws ModelNotFoundException - */ - protected function getForeignModelByValueOrFail($model) - { - if (! is_null($model = $this->getForeignModelByValue($model))) { - return $model; - } - - throw ModelNotFoundException::forQuery( - $this->query->getUnescapedQuery(), - $this->query->getDn() - ); - } - - /** - * Attempt a failable operation and return the value if successful. - * - * If a bypassable exception is encountered, the value will be returned. - * - * @param callable $operation - * @param string|array $bypass - * @param mixed $value - * @return mixed - * - * @throws LdapRecordException - */ - protected function attemptFailableOperation($operation, $bypass, $value) - { - try { - $operation(); - - return $value; - } catch (LdapRecordException $e) { - if ($this->errorContainsMessage($e->getMessage(), $bypass)) { - return $value; - } - - throw $e; - } - } - - /** - * Detach all relation models. - * - * @return Collection - */ - public function detachAll() - { - return $this->onceWithoutMerging(function () { - return $this->get()->each(function (Model $model) { - $this->detach($model); - }); - }); - } - - /** - * Detach all relation models or delete the model if its relation is empty. - * - * @return Collection - */ - public function detachAllOrDelete() - { - return $this->onceWithoutMerging(function () { - return $this->get()->each(function (Model $model) { - $relation = $model->getRelation($this->relationName); - - if ($relation && $relation->count() >= 1) { - $model->delete(); - } else { - $this->detach($model); - } - }); - }); - } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php index 303a1440d..8b5d561f0 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php @@ -2,21 +2,19 @@ namespace LdapRecord\Models\Relations; -use LdapRecord\Query\Collection; +use LdapRecord\Models\Collection; class HasManyIn extends OneToMany { /** * Get the relationships results. - * - * @return Collection */ - public function getRelationResults() + public function getRelationResults(): Collection { $results = $this->parent->newCollection(); foreach ((array) $this->parent->getAttribute($this->relationKey) as $value) { - if ($foreign = $this->getForeignModelByValue($value)) { + if ($value && $foreign = $this->getForeignModelByValue($value)) { $results->push($foreign); } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php index 243cd2ed9..0199f2178 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php @@ -2,20 +2,19 @@ namespace LdapRecord\Models\Relations; +use LdapRecord\Models\Collection; use LdapRecord\Models\Model; class HasOne extends Relation { /** * Get the results of the relationship. - * - * @return \LdapRecord\Query\Collection */ - public function getResults() + public function getResults(): Collection { - $model = $this->getForeignModelByValue( - $this->getFirstAttributeValue($this->parent, $this->relationKey) - ); + $relationValue = $this->getFirstAttributeValue($this->parent, $this->relationKey); + + $model = $relationValue ? $this->getForeignModelByValue($relationValue) : null; return $this->transformResults( $this->parent->newCollection($model ? [$model] : null) @@ -24,31 +23,20 @@ class HasOne extends Relation /** * Attach a model instance to the parent model. - * - * @param Model|string $model - * @return Model|string - * - * @throws \LdapRecord\LdapRecordException */ - public function attach($model) + public function attach(Model|string $model): void { $foreign = $model instanceof Model ? $this->getForeignValueFromModel($model) : $model; $this->parent->setAttribute($this->relationKey, $foreign)->save(); - - return $model; } /** * Detach the related model from the parent. - * - * @return void - * - * @throws \LdapRecord\LdapRecordException */ - public function detach() + public function detach(): void { $this->parent->setAttribute($this->relationKey, null)->save(); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php index aa873b60b..8eb88cbcf 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php @@ -2,44 +2,59 @@ namespace LdapRecord\Models\Relations; +use Closure; +use LdapRecord\DetectsErrors; +use LdapRecord\LdapRecordException; +use LdapRecord\Models\Collection; use LdapRecord\Models\Model; -use LdapRecord\Query\Collection; +use LdapRecord\Models\ModelNotFoundException; use LdapRecord\Query\Model\Builder; abstract class OneToMany extends Relation { + use DetectsErrors; + + /** + * The model to use for attaching / detaching. + */ + protected ?Model $using = null; + /** * The relation to merge results with. - * - * @var OneToMany|null */ - protected $with; + protected ?Relation $with = null; + + /** + * The attribute key to use for attaching / detaching. + */ + protected ?string $usingKey = null; /** * The name of the relationship. - * - * @var string */ - protected $relationName; + protected ?string $relationName = null; /** * Whether to include recursive results. - * - * @var bool */ - protected $recursive = false; + protected bool $recursive = false; + + /** + * The exceptions to bypass for each relation operation. + */ + protected array $bypass = [ + 'attach' => [ + 'Already exists', 'Type or value exists', + ], + 'detach' => [ + 'No such attribute', 'Server is unwilling to perform', + ], + ]; /** * Constructor. - * - * @param Builder $query - * @param Model $parent - * @param string $related - * @param string $relationKey - * @param string $foreignKey - * @param string $relationName */ - public function __construct(Builder $query, Model $parent, $related, $relationKey, $foreignKey, $relationName) + public function __construct(Builder $query, Model $parent, array|string $related, string $relationKey, string $foreignKey, string $relationName) { $this->relationName = $relationName; @@ -47,12 +62,20 @@ abstract class OneToMany extends Relation } /** - * Set the relation to load with its parent. - * - * @param Relation $relation - * @return $this + * Set the model and attribute to use for attaching / detaching. */ - public function with(Relation $relation) + public function using(Model $using, string $usingKey): static + { + $this->using = $using; + $this->usingKey = $usingKey; + + return $this; + } + + /** + * Set the relation to load with its parent. + */ + public function with(Relation $relation): static { $this->with = $relation; @@ -61,30 +84,23 @@ abstract class OneToMany extends Relation /** * Whether to include recursive results. - * - * @param bool $enable - * @return $this */ - public function recursive($enable = true) + public function recursive(bool $recursive = true): static { - $this->recursive = $enable; + $this->recursive = $recursive; return $this; } /** * Get the immediate relationships results. - * - * @return Collection */ - abstract public function getRelationResults(); + abstract public function getRelationResults(): Collection; /** * Get the results of the relationship. - * - * @return Collection */ - public function getResults() + public function getResults(): Collection { $results = $this->recursive ? $this->getRecursiveResults() @@ -97,11 +113,8 @@ abstract class OneToMany extends Relation /** * Execute the callback excluding the merged query result. - * - * @param callable $callback - * @return mixed */ - protected function onceWithoutMerging($callback) + protected function onceWithoutMerging(Closure $callback): mixed { $merging = $this->with; @@ -116,20 +129,262 @@ abstract class OneToMany extends Relation /** * Get the relation name. - * - * @return string */ - public function getRelationName() + public function getRelationName(): string { return $this->relationName; } /** - * Get the results of the merging 'with' relation. - * - * @return Collection + * Attach the model in the relation. */ - protected function getMergingRelationResults() + public function attach(mixed $model): void + { + if (is_iterable($model)) { + array_map($this->attach(...), [...$model]); + + return; + } + + $this->attemptFailableOperation( + $this->buildAttachCallback($model), + $this->bypass['attach'], + $model + ); + } + + /** + * Build the attach callback. + */ + protected function buildAttachCallback(Model|string $model): Closure + { + return function () use ($model) { + $foreign = $this->getAttachableForeignValue($model); + + if ($this->using) { + $this->using->addAttribute($this->usingKey, $foreign); + + return; + } + + if (! $model instanceof Model) { + $model = $this->getForeignModelByValueOrFail($model); + } + + $model->addAttribute($this->relationKey, $foreign); + }; + } + + /** + * Get the foreign model by the given value, or fail. + * + * @throws ModelNotFoundException + */ + protected function getForeignModelByValueOrFail(string $model): Model + { + if (! is_null($model = $this->getForeignModelByValue($model))) { + return $model; + } + + throw ModelNotFoundException::forQuery( + $this->query->getUnescapedQuery(), + $this->query->getDn() + ); + } + + /** + * Detach the model from the relation. + */ + public function detach(mixed $model): void + { + if (is_iterable($model)) { + array_map($this->detach(...), [...$model]); + + return; + } + + $this->attemptFailableOperation( + $this->buildDetachCallback($model), + $this->bypass['detach'], + $model + ); + } + + /** + * Detach the model or delete the parent if the relation is empty. + */ + public function detachOrDeleteParent(Model|string $model): void + { + /** @var Collection $related */ + $related = $this->onceWithoutMerging(function () { + return $this->get('dn'); + }); + + if (! $related->exists($model)) { + return; + } + + if ($related->count() <= 1) { + $this->getParent()->delete(); + + return; + } + + $this->detach($model); + } + + /** + * Build the detach callback. + */ + protected function buildDetachCallback(Model|string $model): Closure + { + return function () use ($model) { + $foreign = $this->getAttachableForeignValue($model); + + if ($this->using) { + $this->using->removeAttribute($this->usingKey, $foreign); + + return; + } + + if (! $model instanceof Model) { + $model = $this->getForeignModelByValueOrFail($model); + } + + $model->removeAttribute($this->relationKey, $foreign); + }; + } + + /** + * Associate the model in the relation. + */ + public function associate(mixed $model): void + { + if (is_iterable($model)) { + array_map($this->associate(...), [...$model]); + + return; + } + + $foreign = $this->getAttachableForeignValue($model); + + if ($this->using) { + $this->using->addAttributeValue($this->usingKey, $foreign); + + return; + } + + if (! $model instanceof Model) { + $model = $this->getForeignModelByValueOrFail($model); + } + + $model->addAttributeValue($this->relationKey, $foreign); + } + + /** + * Dissociate the model in the relation. + */ + public function dissociate(mixed $model): void + { + if (is_iterable($model)) { + array_map($this->dissociate(...), [...$model]); + + return; + } + + $foreign = $this->getAttachableForeignValue($model); + + if ($this->using) { + $this->using->removeAttributeValue($this->usingKey, $foreign); + + return; + } + + if (! $model instanceof Model) { + $model = $this->getForeignModelByValueOrFail($model); + } + + $model->removeAttributeValue($this->relationKey, $foreign); + } + + /** + * Alias of "dissociate" method. + */ + public function disassociate(Model|string $model): void + { + $this->dissociate($model); + } + + /** + * Get the attachable foreign value from the model. + */ + protected function getAttachableForeignValue(Model|string $model): string + { + if ($model instanceof Model) { + return $this->using + ? $this->getForeignValueFromModel($model) + : $this->getParentForeignValue(); + } + + return $this->using ? $model : $this->getParentForeignValue(); + } + + /** + * Attempt a failable operation and return the value if successful. + * + * If a bypassable exception is encountered, the value will be returned. + * + * @throws LdapRecordException + */ + protected function attemptFailableOperation(Closure $operation, string|array $bypass, mixed $value): mixed + { + try { + $operation(); + + return $value; + } catch (LdapRecordException $e) { + if ($this->errorContainsMessage($e->getMessage(), $bypass)) { + return $value; + } + + throw $e; + } + } + + /** + * Detach all relation models. + */ + public function detachAll(): Collection + { + return $this->onceWithoutMerging( + fn () => $this->get()->each(function (Model $model) { + $this->detach($model); + }) + ); + } + + /** + * Detach all relation models or delete the model if its relation is empty. + */ + public function detachAllOrDelete(): Collection + { + return $this->onceWithoutMerging( + fn () => $this->get()->each(function (Model $model) { + $relation = $model->getRelation($this->relationName); + + if ($relation && $relation->count() >= 1) { + $model->delete(); + } else { + $this->detach($model); + } + }) + ); + } + + /** + * Get the results of the merging 'with' relation. + */ + protected function getMergingRelationResults(): Collection { return $this->with ? $this->with->recursive($this->recursive)->get() @@ -137,24 +392,23 @@ abstract class OneToMany extends Relation } /** - * Get the results for the models relation recursively. + * Get the results for the model's relation recursively. * * @param string[] $loaded The distinguished names of models already loaded - * @return Collection */ - protected function getRecursiveResults(array $loaded = []) + protected function getRecursiveResults(array $loaded = []): Collection { - $results = $this->getRelationResults()->reject(function (Model $model) use ($loaded) { + $results = $this->getRelationResults()->reject(fn (Model $model) => // Here we will exclude the models that we have already // loaded the recursive results for so we don't run // into issues with circular relations in LDAP. - return in_array($model->getDn(), $loaded); - }); + in_array($model->getDn(), $loaded) + ); foreach ($results as $model) { $loaded[] = $model->getDn(); - // Finally, we will fetch the related models relations, + // Finally, we will fetch the related model's relations, // passing along our loaded models, to ensure we do // not attempt fetching already loaded relations. $results = $results->merge( @@ -167,12 +421,8 @@ abstract class OneToMany extends Relation /** * Get the recursive relation results for given model. - * - * @param Model $model - * @param array $loaded - * @return Collection */ - protected function getRecursiveRelationResults(Model $model, array $loaded) + protected function getRecursiveRelationResults(Model $model, array $loaded): Collection { return ($relation = $model->getRelation($this->relationName)) ? $relation->getRecursiveResults($loaded) diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php index 31b0969c9..b2d26100e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php @@ -3,13 +3,13 @@ namespace LdapRecord\Models\Relations; use Closure; +use LdapRecord\Models\Collection; use LdapRecord\Models\Entry; use LdapRecord\Models\Model; -use LdapRecord\Query\Collection; use LdapRecord\Query\Model\Builder; /** - * @method bool exists($models = null) Determine if the relation contains all of the given models, or any models + * @method bool exists($models = null) Determine if the relation contains all the given models, or any models * @method bool contains($models) Determine if any of the given models are contained in the relation * @method bool count() Retrieve the "count" result of the query. */ @@ -17,70 +17,48 @@ abstract class Relation { /** * The underlying LDAP query. - * - * @var Builder */ - protected $query; + protected Builder $query; /** * The parent model instance. - * - * @var Model */ - protected $parent; + protected Model $parent; /** * The related model class names. - * - * @var array */ - protected $related; + protected array $related; /** * The relation key. - * - * @var string */ - protected $relationKey; + protected string $relationKey; /** * The foreign key. - * - * @var string */ - protected $foreignKey; + protected string $foreignKey; /** * The default relation model. - * - * @var string */ - protected $default = Entry::class; + protected string $default = Entry::class; /** * The callback to use for resolving relation models. - * - * @var Closure */ - protected static $modelResolver; + protected static ?Closure $modelResolver = null; /** * The methods that should be passed along to a relation collection. - * - * @var string[] */ - protected $passthru = ['count', 'exists', 'contains']; + protected array $passthru = ['count', 'exists', 'contains']; /** * Constructor. - * - * @param Builder $query - * @param Model $parent - * @param string|array $related - * @param string $relationKey - * @param string $foreignKey */ - public function __construct(Builder $query, Model $parent, $related, $relationKey, $foreignKey) + public function __construct(Builder $query, Model $parent, array|string $related, string $relationKey, string $foreignKey) { $this->query = $query; $this->parent = $parent; @@ -88,21 +66,13 @@ abstract class Relation $this->relationKey = $relationKey; $this->foreignKey = $foreignKey; - static::$modelResolver = static::$modelResolver ?? function (array $modelObjectClasses, array $relationMap) { - return array_search($modelObjectClasses, $relationMap); - }; - $this->initRelation(); } /** * Handle dynamic method calls to the relationship. - * - * @param string $method - * @param array $parameters - * @return mixed */ - public function __call($method, $parameters) + public function __call(string $method, array $parameters): mixed { if (in_array($method, $this->passthru)) { return $this->get('objectclass')->$method(...$parameters); @@ -119,21 +89,16 @@ abstract class Relation /** * Set the callback to use for resolving models from relation results. - * - * @param Closure $callback - * @return void */ - public static function resolveModelsUsing(Closure $callback) + public static function resolveModelsUsing(?Closure $callback = null): void { static::$modelResolver = $callback; } /** * Only return objects matching the related model's object classes. - * - * @return $this */ - public function onlyRelated() + public function onlyRelated(): static { $relations = []; @@ -158,18 +123,13 @@ abstract class Relation /** * Get the results of the relationship. - * - * @return Collection */ - abstract public function getResults(); + abstract public function getResults(): Collection; /** * Execute the relationship query. - * - * @param array|string $columns - * @return Collection */ - public function get($columns = ['*']) + public function get(array|string $columns = ['*']): Collection { return $this->getResultsWithColumns($columns); } @@ -178,11 +138,8 @@ abstract class Relation * Get the results of the relationship while selecting the given columns. * * If the query columns are empty, the given columns are applied. - * - * @param array $columns - * @return Collection */ - protected function getResultsWithColumns($columns) + protected function getResultsWithColumns(array|string $columns): Collection { if (is_null($this->query->columns)) { $this->query->select($columns); @@ -193,21 +150,16 @@ abstract class Relation /** * Get the first result of the relationship. - * - * @param array|string $columns - * @return Model|null */ - public function first($columns = ['*']) + public function first(array|string $columns = ['*']): ?Model { return $this->get($columns)->first(); } /** * Prepare the relation query. - * - * @return static */ - public function initRelation() + public function initRelation(): static { $this->query ->clearFilters() @@ -219,11 +171,8 @@ abstract class Relation /** * Set the underlying query for the relation. - * - * @param Builder $query - * @return $this */ - public function setQuery(Builder $query) + public function setQuery(Builder $query): static { $this->query = $query; @@ -234,72 +183,58 @@ abstract class Relation /** * Get the underlying query for the relation. - * - * @return Builder */ - public function getQuery() + public function getQuery(): Builder { return $this->query; } /** * Get the parent model of the relation. - * - * @return Model */ - public function getParent() + public function getParent(): Model { return $this->parent; } /** * Get the relation attribute key. - * - * @return string */ - public function getRelationKey() + public function getRelationKey(): string { return $this->relationKey; } /** * Get the related model classes for the relation. - * - * @return array */ - public function getRelated() + public function getRelated(): array { return $this->related; } /** * Get the relation foreign attribute key. - * - * @return string */ - public function getForeignKey() + public function getForeignKey(): string { return $this->foreignKey; } /** * Get the class name of the default model. - * - * @return string */ - public function getDefaultModel() + public function getDefaultModel(): string { return $this->default; } /** * Get a new instance of the default model on the relation. - * - * @return Model */ - public function getNewDefaultModel() + public function getNewDefaultModel(): Model { - $model = new $this->default(); + $model = new $this->default; $model->setConnection($this->parent->getConnectionName()); @@ -308,132 +243,65 @@ abstract class Relation /** * Get the foreign model by the given value. - * - * @param string $value - * @return Model|null */ - protected function getForeignModelByValue($value) + protected function getForeignModelByValue(string $value): ?Model { return $this->foreignKeyIsDistinguishedName() - ? $this->query->find($value) - : $this->query->findBy($this->foreignKey, $value); + ? $this->query->clearFilters()->find($value) + : $this->query->clearFilters()->findBy($this->foreignKey, $value); } /** - * Returns the escaped foreign key value for use in an LDAP filter from the model. - * - * @param Model $model - * @return string + * Get the escaped foreign key value for use in an LDAP filter from the model. */ - protected function getEscapedForeignValueFromModel(Model $model) + protected function getEscapedForeignValueFromModel(Model $model): string { return $this->query->escape( $this->getForeignValueFromModel($model) - )->both(); + )->forDnAndFilter(); } /** * Get the relation parents foreign value. - * - * @return string */ - protected function getParentForeignValue() + protected function getParentForeignValue(): ?string { return $this->getForeignValueFromModel($this->parent); } /** * Get the foreign key value from the model. - * - * @param Model $model - * @return string */ - protected function getForeignValueFromModel(Model $model) + protected function getForeignValueFromModel(Model $model): ?string { return $this->foreignKeyIsDistinguishedName() - ? $model->getDn() - : $this->getFirstAttributeValue($model, $this->foreignKey); + ? $model->getDn() + : $this->getFirstAttributeValue($model, $this->foreignKey); } /** * Get the first attribute value from the model. - * - * @param Model $model - * @param string $attribute - * @return string|null */ - protected function getFirstAttributeValue(Model $model, $attribute) + protected function getFirstAttributeValue(Model $model, string $attribute): mixed { return $model->getFirstAttribute($attribute); } /** * Transforms the results by converting the models into their related. - * - * @param Collection $results - * @return Collection */ - protected function transformResults(Collection $results) + protected function transformResults(Collection $results): Collection { - $relationMap = []; - - foreach ($this->related as $relation) { - $relationMap[$relation] = $this->normalizeObjectClasses( - $relation::$objectClasses - ); - } - - return $results->transform(function (Model $entry) use ($relationMap) { - $model = $this->determineModelFromRelated($entry, $relationMap); - - return class_exists($model) ? $entry->convert(new $model()) : $entry; - }); + return $results->transform( + fn (Model $entry) => $entry->morphInto($this->related, static::$modelResolver) + ); } /** - * Determines if the foreign key is a distinguished name. - * - * @return bool + * Determine if the foreign key is a distinguished name. */ - protected function foreignKeyIsDistinguishedName() + protected function foreignKeyIsDistinguishedName(): bool { return in_array($this->foreignKey, ['dn', 'distinguishedname']); } - - /** - * Determines the model from the given relation map. - * - * @param Model $model - * @param array $relationMap - * @return class-string|bool - */ - protected function determineModelFromRelated(Model $model, array $relationMap) - { - // We must normalize all the related models object class - // names to the same case so we are able to properly - // determine the owning model from search results. - $modelObjectClasses = $this->normalizeObjectClasses( - $model->getObjectClasses() - ); - - return call_user_func( - static::$modelResolver, - $modelObjectClasses, - $relationMap, - $model, - ); - } - - /** - * Sort and normalize the object classes. - * - * @param array $classes - * @return array - */ - protected function normalizeObjectClasses($classes) - { - sort($classes); - - return array_map('strtolower', $classes); - } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php index f61cf686b..09c0c0c2c 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php @@ -8,10 +8,6 @@ interface Scope { /** * Apply the scope to the given query. - * - * @param Builder $query - * @param Model $model - * @return void */ - public function apply(Builder $query, Model $model); + public function apply(Builder $query, Model $model): void; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php index 3edcf88c9..2fc54e4a4 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php @@ -5,34 +5,24 @@ namespace LdapRecord\Models\Types; interface ActiveDirectory extends TypeInterface { /** - * Returns the models object SID key. - * - * @return string + * Get the models object SID key. */ - public function getObjectSidKey(); + public function getObjectSidKey(): string; /** - * Returns the model's hex object SID. + * Get the model's hex object SID. * * @see https://msdn.microsoft.com/en-us/library/ms679024(v=vs.85).aspx - * - * @return string */ - public function getObjectSid(); + public function getObjectSid(): ?string; /** - * Returns the model's SID. - * - * @param string|null $sid - * @return string|null + * Get the model's SID. */ - public function getConvertedSid($sid = null); + public function getConvertedSid(?string $sid = null): ?string; /** - * Returns the model's binary SID. - * - * @param string|null $sid - * @return string|null + * Get the model's binary SID. */ - public function getBinarySid($sid = null); + public function getBinarySid(?string $sid = null): ?string; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php index 2fb9c9a72..d4a9137c0 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php @@ -10,15 +10,13 @@ class ArrayCacheStore implements CacheInterface /** * An array of stored values. - * - * @var array */ - protected $storage = []; + protected array $storage = []; /** - * @inheritdoc + * {@inheritdoc} */ - public function get($key, $default = null) + public function get($key, $default = null): mixed { if (! isset($this->storage[$key])) { return $default; @@ -38,9 +36,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function set($key, $value, $ttl = null) + public function set($key, $value, $ttl = null): bool { $this->storage[$key] = [ 'value' => $value, @@ -52,30 +50,24 @@ class ArrayCacheStore implements CacheInterface /** * Get the expiration time of the key. - * - * @param int $seconds - * @return int */ - protected function calculateExpiration($seconds) + protected function calculateExpiration($seconds = null): int { return $this->toTimestamp($seconds); } /** * Get the UNIX timestamp for the given number of seconds. - * - * @param int $seconds - * @return int */ - protected function toTimestamp($seconds) + protected function toTimestamp($seconds = null): int { return $seconds > 0 ? $this->availableAt($seconds) : 0; } /** - * @inheritdoc + * {@inheritdoc} */ - public function delete($key) + public function delete($key): bool { unset($this->storage[$key]); @@ -83,9 +75,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function clear() + public function clear(): bool { $this->storage = []; @@ -93,9 +85,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function getMultiple($keys, $default = null) + public function getMultiple($keys, $default = null): iterable { $values = []; @@ -107,9 +99,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function setMultiple($values, $ttl = null) + public function setMultiple($values, $ttl = null): bool { foreach ($values as $key => $value) { $this->set($key, $value, $ttl); @@ -119,9 +111,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function deleteMultiple($keys) + public function deleteMultiple($keys): bool { foreach ($keys as $key) { $this->delete($key); @@ -131,9 +123,9 @@ class ArrayCacheStore implements CacheInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function has($key) + public function has($key): bool { return isset($this->storage[$key]); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php index c93c17809..642cf32af 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php @@ -5,6 +5,7 @@ namespace LdapRecord\Query; use BadMethodCallException; use Closure; use DateTimeInterface; +use Generator; use InvalidArgumentException; use LDAP\Result; use LdapRecord\Connection; @@ -12,31 +13,42 @@ use LdapRecord\Container; use LdapRecord\EscapesValues; use LdapRecord\LdapInterface; use LdapRecord\LdapRecordException; +use LdapRecord\Models\Attributes\EscapedValue; use LdapRecord\Models\Model; use LdapRecord\Query\Events\QueryExecuted; use LdapRecord\Query\Model\Builder as ModelBuilder; use LdapRecord\Query\Pagination\LazyPaginator; use LdapRecord\Query\Pagination\Paginator; use LdapRecord\Support\Arr; -use LdapRecord\Utilities; class Builder { use EscapesValues; + public const TYPE_SEARCH = 'search'; + + public const TYPE_READ = 'read'; + + public const TYPE_CHUNK = 'chunk'; + + public const TYPE_LIST = 'list'; + + public const TYPE_PAGINATE = 'paginate'; + + /** + * The base distinguished name placeholder. + */ + public const BASE_DN_PLACEHOLDER = '{base}'; + /** * The selected columns to retrieve on the query. - * - * @var array */ - public $columns; + public ?array $columns = null; /** * The query filters. - * - * @var array */ - public $filters = [ + public array $filters = [ 'and' => [], 'or' => [], 'raw' => [], @@ -44,120 +56,92 @@ class Builder /** * The LDAP server controls to be sent. - * - * @var array */ - public $controls = []; + public array $controls = []; /** * The LDAP server controls that were processed. - * - * @var array */ - public $controlsResponse = []; + public array $controlsResponse = []; /** * The size limit of the query. - * - * @var int */ - public $limit = 0; + public int $limit = 0; /** - * Determines whether the current query is paginated. - * - * @var bool + * Determine whether the current query is paginated. */ - public $paginated = false; + public bool $paginated = false; /** * The distinguished name to perform searches upon. - * - * @var string|null */ - protected $dn; + protected ?string $dn = null; /** * The base distinguished name to perform searches inside. - * - * @var string|null */ - protected $baseDn; + protected ?string $baseDn = null; /** * The default query type. - * - * @var string */ - protected $type = 'search'; + protected string $type = self::TYPE_SEARCH; /** - * Determines whether the query is nested. - * - * @var bool + * Determine whether the query is nested. */ - protected $nested = false; + protected bool $nested = false; /** - * Determines whether the query should be cached. - * - * @var bool + * Determine whether the query should be cached. */ - protected $caching = false; + protected bool $caching = false; + + /** + * The custom cache key to use when caching results. + */ + protected ?string $cacheKey = null; /** * How long the query should be cached until. - * - * @var DateTimeInterface|null */ - protected $cacheUntil = null; + protected ?DateTimeInterface $cacheUntil = null; /** - * Determines whether the query cache must be flushed. - * - * @var bool + * Determine whether the query cache must be flushed. */ - protected $flushCache = false; + protected bool $flushCache = false; /** * The current connection instance. - * - * @var Connection */ - protected $connection; + protected Connection $connection; /** * The current grammar instance. - * - * @var Grammar */ - protected $grammar; + protected Grammar $grammar; /** * The current cache instance. - * - * @var Cache|null */ - protected $cache; + protected ?Cache $cache = null; /** * Constructor. - * - * @param Connection $connection */ public function __construct(Connection $connection) { $this->connection = $connection; - $this->grammar = new Grammar(); + $this->grammar = new Grammar; } /** * Set the current connection. - * - * @param Connection $connection - * @return $this */ - public function setConnection(Connection $connection) + public function setConnection(Connection $connection): static { $this->connection = $connection; @@ -166,11 +150,8 @@ class Builder /** * Set the current filter grammar. - * - * @param Grammar $grammar - * @return $this */ - public function setGrammar(Grammar $grammar) + public function setGrammar(Grammar $grammar): static { $this->grammar = $grammar; @@ -179,11 +160,8 @@ class Builder /** * Set the cache to store query results. - * - * @param Cache|null $cache - * @return $this */ - public function setCache(Cache $cache = null) + public function setCache(?Cache $cache = null): static { $this->cache = $cache; @@ -192,26 +170,18 @@ class Builder /** * Returns a new Query Builder instance. - * - * @param string $baseDn - * @return $this */ - public function newInstance($baseDn = null) + public function newInstance(?string $baseDn = null): Builder { - // We'll set the base DN of the new Builder so - // developers don't need to do this manually. - $dn = is_null($baseDn) ? $this->getDn() : $baseDn; - - return (new static($this->connection))->setDn($dn); + return (new static($this->connection))->setDn( + is_null($baseDn) ? $this->getDn() : $baseDn + ); } /** * Returns a new nested Query Builder instance. - * - * @param Closure|null $closure - * @return $this */ - public function newNestedInstance(Closure $closure = null) + public function newNestedInstance(?Closure $closure = null): Builder { $query = $this->newInstance()->nested(); @@ -224,27 +194,20 @@ class Builder /** * Executes the LDAP query. - * - * @param string|array $columns - * @return Collection|array */ - public function get($columns = ['*']) + public function get(array|string $columns = ['*']): Collection|array { - return $this->onceWithColumns(Arr::wrap($columns), function () { - return $this->query($this->getQuery()); - }); + return $this->onceWithColumns( + Arr::wrap($columns), fn () => $this->query($this->getQuery()) + ); } /** * Execute the given callback while selecting the given columns. * * After running the callback, the columns are reset to the original value. - * - * @param array $columns - * @param Closure $callback - * @return mixed */ - protected function onceWithColumns($columns, Closure $callback) + protected function onceWithColumns(array $columns, Closure $callback): mixed { $original = $this->columns; @@ -260,11 +223,9 @@ class Builder } /** - * Compiles and returns the current query string. - * - * @return string + * Compile the query into an LDAP filter string. */ - public function getQuery() + public function getQuery(): string { // We need to ensure we have at least one filter, as // no query results will be returned otherwise. @@ -276,134 +237,101 @@ class Builder } /** - * Returns the unescaped query. - * - * @return string + * Get the unescaped query. */ - public function getUnescapedQuery() + public function getUnescapedQuery(): string { - return Utilities::unescape($this->getQuery()); + return EscapedValue::unescape($this->getQuery()); } /** - * Returns the current Grammar instance. - * - * @return Grammar + * Get the current Grammar instance. */ - public function getGrammar() + public function getGrammar(): Grammar { return $this->grammar; } /** - * Returns the current Cache instance. - * - * @return Cache|null + * Get the current Cache instance. */ - public function getCache() + public function getCache(): ?Cache { return $this->cache; } /** - * Returns the current Connection instance. - * - * @return Connection + * Get the current Connection instance. */ - public function getConnection() + public function getConnection(): Connection { return $this->connection; } /** - * Returns the query type. - * - * @return string + * Get the query type. */ - public function getType() + public function getType(): string { return $this->type; } /** * Set the base distinguished name of the query. - * - * @param Model|string $dn - * @return $this */ - public function setBaseDn($dn) + public function setBaseDn(Model|string|null $dn = null): static { - $this->baseDn = $this->substituteBaseInDn($dn); + $this->baseDn = $this->substituteBaseDn($dn); return $this; } /** * Get the base distinguished name of the query. - * - * @return string|null */ - public function getBaseDn() + public function getBaseDn(): ?string { return $this->baseDn; } /** * Get the distinguished name of the query. - * - * @return string */ - public function getDn() + public function getDn(): ?string { return $this->dn; } /** * Set the distinguished name for the query. - * - * @param string|Model|null $dn - * @return $this */ - public function setDn($dn = null) + public function setDn(Model|string|null $dn = null): static { - $this->dn = $this->substituteBaseInDn($dn); + $this->dn = $this->substituteBaseDn($dn); return $this; } /** * Substitute the base DN string template for the current base. - * - * @param Model|string $dn - * @return string */ - protected function substituteBaseInDn($dn) + public function substituteBaseDn(Model|string|null $dn = null): string { - return str_replace( - '{base}', - $this->baseDn ?: '', - (string) ($dn instanceof Model ? $dn->getDn() : $dn) - ); + return str_replace(static::BASE_DN_PLACEHOLDER, $this->baseDn ?? '', (string) $dn); } /** * Alias for setting the distinguished name for the query. - * - * @param string|Model|null $dn - * @return $this */ - public function in($dn = null) + public function in(Model|string|null $dn = null): static { return $this->setDn($dn); } /** * Set the size limit of the current query. - * - * @param int $limit - * @return $this */ - public function limit($limit = 0) + public function limit(int $limit = 0): static { $this->limit = $limit; @@ -412,11 +340,8 @@ class Builder /** * Returns a new query for the given model. - * - * @param Model $model - * @return ModelBuilder */ - public function model(Model $model) + public function model(Model $model): ModelBuilder { return $model->newQueryBuilder($this->connection) ->setCache($this->connection->getCache()) @@ -426,20 +351,15 @@ class Builder /** * Performs the specified query on the current LDAP connection. - * - * @param string $query - * @return Collection|array */ - public function query($query) + public function query(string $query): Collection|array { $start = microtime(true); // Here we will create the execution callback. This allows us // to only execute an LDAP request if caching is disabled // or if no cache of the given query exists yet. - $callback = function () use ($query) { - return $this->parse($this->run($query)); - }; + $callback = fn () => $this->parse($this->run($query)); $results = $this->getCachedResponse($query, $callback); @@ -450,12 +370,8 @@ class Builder /** * Paginates the current LDAP query. - * - * @param int $pageSize - * @param bool $isCritical - * @return Collection|array */ - public function paginate($pageSize = 1000, $isCritical = false) + public function paginate(int $pageSize = 1000, bool $isCritical = false): Collection|array { $this->paginated = true; @@ -466,42 +382,37 @@ class Builder // Here we will create the pagination callback. This allows us // to only execute an LDAP request if caching is disabled // or if no cache of the given query exists yet. - $callback = function () use ($query, $pageSize, $isCritical) { - return $this->runPaginate($query, $pageSize, $isCritical); - }; + $callback = fn () => $this->runPaginate($query, $pageSize, $isCritical); $pages = $this->getCachedResponse($query, $callback); - $this->logQuery($this, 'paginate', $this->getElapsedTime($start)); + $this->logQuery($this, self::TYPE_PAGINATE, $this->getElapsedTime($start)); return $this->process($pages); } /** * Runs the paginate operation with the given filter. - * - * @param string $filter - * @param int $perPage - * @param bool $isCritical - * @return array */ - protected function runPaginate($filter, $perPage, $isCritical) + protected function runPaginate(string $filter, int $perPage, bool $isCritical): array { - return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) { - return (new Paginator($this, $filter, $perPage, $isCritical))->execute($ldap); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $this->newPaginator($filter, $perPage, $isCritical)->execute($ldap) + ); + } + + /** + * Make a new paginator instance. + */ + protected function newPaginator(string $filter, int $perPage, bool $isCritical): Paginator + { + return new Paginator($this, $filter, $perPage, $isCritical); } /** * Execute a callback over each item while chunking. - * - * @param Closure $callback - * @param int $pageSize - * @param bool $isCritical - * @param bool $isolate - * @return bool */ - public function each(Closure $callback, $pageSize = 1000, $isCritical = false, $isolate = false) + public function each(Closure $callback, int $pageSize = 1000, bool $isCritical = false, bool $isolate = false): bool { return $this->chunk($pageSize, function ($results) use ($callback) { foreach ($results as $key => $value) { @@ -514,15 +425,11 @@ class Builder /** * Chunk the results of a paginated LDAP query. - * - * @param int $pageSize - * @param Closure $callback - * @param bool $isCritical - * @param bool $isolate - * @return bool */ - public function chunk($pageSize, Closure $callback, $isCritical = false, $isolate = false) + public function chunk(int $pageSize, Closure $callback, bool $isCritical = false, bool $isolate = false): bool { + $this->limit(0); + $start = microtime(true); $chunk = function (Builder $query) use ($pageSize, $callback, $isCritical) { @@ -537,40 +444,40 @@ class Builder } }; - $isolate ? $this->connection->isolate(function (Connection $replicate) use ($chunk) { - $chunk($this->clone()->setConnection($replicate)); - }) : $chunk($this); + // Connection isolation creates a new, temporary connection for the pagination + // request to occur on. This allows connections that do not support executing + // other queries during a pagination request, to do so without interruption. + $isolate ? $this->connection->isolate( + fn (Connection $replicate) => $chunk($this->clone()->setConnection($replicate)) + ) : $chunk($this); - $this->logQuery($this, 'chunk', $this->getElapsedTime($start)); + $this->logQuery($this, self::TYPE_CHUNK, $this->getElapsedTime($start)); return true; } /** * Runs the chunk operation with the given filter. - * - * @param string $filter - * @param int $perPage - * @param bool $isCritical - * @return \Generator */ - protected function runChunk($filter, $perPage, $isCritical) + protected function runChunk(string $filter, int $perPage, bool $isCritical): Generator { - return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) { - return (new LazyPaginator($this, $filter, $perPage, $isCritical))->execute($ldap); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $this->newLazyPaginator($filter, $perPage, $isCritical)->execute($ldap) + ); + } + + /** + * Make a new lazy paginator instance. + */ + protected function newLazyPaginator(string $filter, int $perPage, bool $isCritical): LazyPaginator + { + return new LazyPaginator($this, $filter, $perPage, $isCritical); } /** * Create a slice of the LDAP query into a page. - * - * @param int $page - * @param int $perPage - * @param string $orderBy - * @param string $orderByDir - * @return Slice */ - public function slice($page = 1, $perPage = 100, $orderBy = 'cn', $orderByDir = 'asc') + public function slice(int $page = 1, int $perPage = 100, string $orderBy = 'cn', string $orderByDir = 'asc'): Slice { $results = $this->forPage($page, $perPage, $orderBy, $orderByDir); @@ -589,14 +496,8 @@ class Builder /** * Get the results of a query for a given page. - * - * @param int $page - * @param int $perPage - * @param string $orderBy - * @param string $orderByDir - * @return Collection|array */ - public function forPage($page = 1, $perPage = 100, $orderBy = 'cn', $orderByDir = 'asc') + public function forPage(int $page = 1, int $perPage = 100, string $orderBy = 'cn', string $orderByDir = 'asc'): Collection|array { if (! $this->hasOrderBy()) { $this->orderBy($orderBy, $orderByDir); @@ -614,11 +515,8 @@ class Builder /** * Processes and converts the given LDAP results into models. - * - * @param array $results - * @return array */ - protected function process(array $results) + protected function process(array $results): mixed { unset($results['count']); @@ -631,11 +529,8 @@ class Builder /** * Flattens LDAP paged results into a single array. - * - * @param array $pages - * @return array */ - protected function flattenPages(array $pages) + protected function flattenPages(array $pages): array { $records = []; @@ -650,15 +545,11 @@ class Builder /** * Get the cached response or execute and cache the callback value. - * - * @param string $query - * @param Closure $callback - * @return mixed */ - protected function getCachedResponse($query, Closure $callback) + protected function getCachedResponse(string $query, Closure $callback): mixed { if ($this->cache && $this->caching) { - $key = $this->getCacheKey($query); + $key = $this->cacheKey ?? $this->getCacheKey($query); if ($this->flushCache) { $this->cache->delete($key); @@ -667,16 +558,20 @@ class Builder return $this->cache->remember($key, $this->cacheUntil, $callback); } - return $callback(); + try { + return $callback(); + } finally { + $this->caching = false; + $this->cacheKey = null; + $this->cacheUntil = null; + $this->flushCache = false; + } } /** * Runs the query operation with the given filter. - * - * @param string $filter - * @return resource */ - public function run($filter) + public function run(string $filter): mixed { return $this->connection->run(function (LdapInterface $ldap) use ($filter) { // We will avoid setting the controls during any pagination @@ -690,7 +585,7 @@ class Builder } return $ldap->{$this->type}( - $this->dn ?? $this->baseDn, + (string) ($this->dn ?? $this->baseDn), $filter, $this->getSelects(), $onlyAttributes = false, @@ -701,11 +596,8 @@ class Builder /** * Parses the given LDAP resource by retrieving its entries. - * - * @param resource $resource - * @return array */ - public function parse($resource) + public function parse(mixed $resource): array { if (! $resource) { return []; @@ -714,17 +606,10 @@ class Builder return $this->connection->run(function (LdapInterface $ldap) use ($resource) { $this->controlsResponse = $this->controls; - $errorCode = 0; - $dn = $errorMessage = $refs = null; - // Process the server controls response. $ldap->parseResult( - $resource, - $errorCode, - $dn, - $errorMessage, - $refs, - $this->controlsResponse + result: $resource, + controls: $this->controlsResponse ); $entries = $ldap->getEntries($resource); @@ -739,16 +624,13 @@ class Builder } /** - * Returns the cache key. - * - * @param string $query - * @return string + * Get the cache key. */ - protected function getCacheKey($query) + protected function getCacheKey(string $query): string { - $host = $this->connection->run(function (LdapInterface $ldap) { - return $ldap->getHost(); - }); + $host = $this->connection->run( + fn (LdapInterface $ldap) => $ldap->getHost() + ); $key = $host .$this->type @@ -762,12 +644,9 @@ class Builder } /** - * Returns the first entry in a search result. - * - * @param array|string $columns - * @return Model|null + * Get the first entry in a search result. */ - public function first($columns = ['*']) + public function first(array|string $columns = ['*']): Model|array|null { return Arr::first( $this->limit(1)->get($columns) @@ -775,16 +654,13 @@ class Builder } /** - * Returns the first entry in a search result. + * Get the first entry in a search result. * * If no entry is found, an exception is thrown. * - * @param array|string $columns - * @return Model|array - * * @throws ObjectNotFoundException */ - public function firstOrFail($columns = ['*']) + public function firstOrFail(array|string $columns = ['*']): Model|array { if (! $record = $this->first($columns)) { $this->throwNotFoundException($this->getUnescapedQuery(), $this->dn); @@ -794,12 +670,9 @@ class Builder } /** - * Return the first entry in a result, or execute the callback. - * - * @param Closure $callback - * @return Model|mixed + * Get the first entry in a result, or execute the callback. */ - public function firstOr(Closure $callback) + public function firstOr(Closure $callback): mixed { return $this->first() ?: $callback(); } @@ -807,13 +680,10 @@ class Builder /** * Execute the query and get the first result if it's the sole matching record. * - * @param array|string $columns - * @return Model|array - * * @throws ObjectsNotFoundException * @throws MultipleObjectsFoundException */ - public function sole($columns = ['*']) + public function sole(array|string $columns = ['*']): Model|array { $result = $this->limit(2)->get($columns); @@ -830,31 +700,24 @@ class Builder /** * Determine if any results exist for the current query. - * - * @return bool */ - public function exists() + public function exists(): bool { return ! is_null($this->first()); } /** * Determine if no results exist for the current query. - * - * @return bool */ - public function doesntExist() + public function doesntExist(): bool { return ! $this->exists(); } /** * Execute the given callback if no rows exist for the current query. - * - * @param Closure $callback - * @return bool|mixed */ - public function existsOr(Closure $callback) + public function existsOr(Closure $callback): mixed { return $this->exists() ? true : $callback(); } @@ -862,12 +725,9 @@ class Builder /** * Throws a not found exception. * - * @param string $query - * @param string $dn - * * @throws ObjectNotFoundException */ - protected function throwNotFoundException($query, $dn) + protected function throwNotFoundException(string $query, ?string $dn = null): void { throw ObjectNotFoundException::forQuery($query, $dn); } @@ -875,17 +735,14 @@ class Builder /** * Finds a record by the specified attribute and value. * - * @param string $attribute - * @param string $value - * @param array|string $columns * @return Model|static|null */ - public function findBy($attribute, $value, $columns = ['*']) + public function findBy(string $attribute, string $value, array|string $columns = ['*']): Model|array|null { try { return $this->findByOrFail($attribute, $value, $columns); } catch (ObjectNotFoundException $e) { - return; + return null; } } @@ -894,26 +751,17 @@ class Builder * * If no record is found an exception is thrown. * - * @param string $attribute - * @param string $value - * @param array|string $columns - * @return Model - * * @throws ObjectNotFoundException */ - public function findByOrFail($attribute, $value, $columns = ['*']) + public function findByOrFail(string $attribute, string $value, array|string $columns = ['*']): Model|array { return $this->whereEquals($attribute, $value)->firstOrFail($columns); } /** * Find many records by distinguished name. - * - * @param string|array $dns - * @param array $columns - * @return array|Collection */ - public function findMany($dns, $columns = ['*']) + public function findMany(array|string $dns, array|string $columns = ['*']): Collection|array { if (empty($dns)) { return $this->process([]); @@ -932,13 +780,8 @@ class Builder /** * Finds many records by the specified attribute. - * - * @param string $attribute - * @param array $values - * @param array $columns - * @return Collection */ - public function findManyBy($attribute, array $values = [], $columns = ['*']) + public function findManyBy(string $attribute, array $values = [], array|string $columns = ['*']): Collection|array { $query = $this->select($columns); @@ -951,12 +794,8 @@ class Builder /** * Finds a record by its distinguished name. - * - * @param string|array $dn - * @param array|string $columns - * @return Model|static|array|Collection|null */ - public function find($dn, $columns = ['*']) + public function find(array|string $dn, array|string $columns = ['*']): Collection|Model|array|null { if (is_array($dn)) { return $this->findMany($dn, $columns); @@ -965,7 +804,7 @@ class Builder try { return $this->findOrFail($dn, $columns); } catch (ObjectNotFoundException $e) { - return; + return null; } } @@ -974,13 +813,9 @@ class Builder * * Fails upon no records returned. * - * @param string $dn - * @param array|string $columns - * @return Model|static - * * @throws ObjectNotFoundException */ - public function findOrFail($dn, $columns = ['*']) + public function findOrFail(string $dn, array|string $columns = ['*']): Model|array { return $this->setDn($dn) ->read() @@ -990,11 +825,8 @@ class Builder /** * Adds the inserted fields to query on the current LDAP connection. - * - * @param array|string $columns - * @return $this */ - public function select($columns = ['*']) + public function select(array|string $columns = ['*']): static { $columns = is_array($columns) ? $columns : func_get_args(); @@ -1007,11 +839,8 @@ class Builder /** * Add a new select column to the query. - * - * @param array|mixed $column - * @return $this */ - public function addSelect($column) + public function addSelect(array|string $column): static { $column = is_array($column) ? $column : func_get_args(); @@ -1022,46 +851,38 @@ class Builder /** * Add an order by control to the query. - * - * @param string $attribute - * @param string $direction - * @return $this */ - public function orderBy($attribute, $direction = 'asc') + public function orderBy(string $attribute, string $direction = 'asc', array $options = []): static { return $this->addControl(LDAP_CONTROL_SORTREQUEST, true, [ - ['attr' => $attribute, 'reverse' => $direction === 'desc'], + [ + ...$options, + 'attr' => $attribute, + 'reverse' => $direction === 'desc', + ], ]); } /** * Add an order by descending control to the query. - * - * @param string $attribute - * @return $this */ - public function orderByDesc($attribute) + public function orderByDesc(string $attribute, array $options = []): static { - return $this->orderBy($attribute, 'desc'); + return $this->orderBy($attribute, 'desc', $options); } /** * Determine if the query has a sotr request control header. - * - * @return bool */ - public function hasOrderBy() + public function hasOrderBy(): bool { return $this->hasControl(LDAP_CONTROL_SORTREQUEST); } /** * Adds a raw filter to the current query. - * - * @param array|string $filters - * @return $this */ - public function rawFilter($filters = []) + public function rawFilter(array|string $filters = []): static { $filters = is_array($filters) ? $filters : func_get_args(); @@ -1074,11 +895,8 @@ class Builder /** * Adds a nested 'and' filter to the current query. - * - * @param Closure $closure - * @return $this */ - public function andFilter(Closure $closure) + public function andFilter(Closure $closure): static { $query = $this->newNestedInstance($closure); @@ -1089,11 +907,8 @@ class Builder /** * Adds a nested 'or' filter to the current query. - * - * @param Closure $closure - * @return $this */ - public function orFilter(Closure $closure) + public function orFilter(Closure $closure): static { $query = $this->newNestedInstance($closure); @@ -1104,11 +919,8 @@ class Builder /** * Adds a nested 'not' filter to the current query. - * - * @param Closure $closure - * @return $this */ - public function notFilter(Closure $closure) + public function notFilter(Closure $closure): static { $query = $this->newNestedInstance($closure); @@ -1120,30 +932,23 @@ class Builder /** * Adds a where clause to the current query. * - * @param string|array $field - * @param string $operator - * @param string $value - * @param string $boolean - * @param bool $raw - * @return $this - * * @throws InvalidArgumentException */ - public function where($field, $operator = null, $value = null, $boolean = 'and', $raw = false) + public function where(array|string $field, mixed $operator = null, mixed $value = null, string $boolean = 'and', bool $raw = false): static { if (is_array($field)) { // If the field is an array, we will assume we have been // provided with an array of key-value pairs and can - // add them each as their own seperate where clause. + // add them each as their own separate where clause. return $this->addArrayOfWheres($field, $boolean, $raw); } // If we have been provided with two arguments not a "has" or // "not has" operator, we'll assume the developer is creating // an "equals" clause and set the proper operator in place. - if (func_num_args() === 2 && ! in_array($operator, ['*', '!*'])) { - [$value, $operator] = [$operator, '=']; - } + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 && ! $this->operatorRequiresValue($operator) + ); if (! in_array($operator, $this->grammar->getOperators())) { throw new InvalidArgumentException("Invalid LDAP filter operator [$operator]"); @@ -1152,7 +957,7 @@ class Builder // We'll escape the value if raw isn't requested. $value = $this->prepareWhereValue($field, $value, $raw); - $field = $this->escape($field)->both()->get(); + $field = $this->escape($field)->forDnAndFilter()->get(); $this->addFilter($boolean, compact('field', 'operator', 'value')); @@ -1160,125 +965,114 @@ class Builder } /** - * Prepare the value for being queried. - * - * @param string $field - * @param string $value - * @param bool $raw - * @return string + * Prepare the value and operator for a where clause. */ - protected function prepareWhereValue($field, $value, $raw = false) + public function prepareValueAndOperator(mixed $value, mixed $operator, bool $useDefault = false): array { - return $raw ? $value : $this->escape($value); + if ($useDefault) { + return [$operator, '=']; + } + + return [$value, $operator]; + } + + /** + * Determine if the operator requires a value to be present. + */ + protected function operatorRequiresValue(mixed $operator): bool + { + return in_array($operator, ['*', '!*']); + } + + /** + * Prepare the value for being queried. + */ + protected function prepareWhereValue(string $field, mixed $value = null, bool $raw = false): string + { + return $raw ? $value : $this->escape($value)->get(); } /** * Adds a raw where clause to the current query. * * Values given to this method are not escaped. - * - * @param string|array $field - * @param string $operator - * @param string $value - * @return $this */ - public function whereRaw($field, $operator = null, $value = null) + public function whereRaw(array|string $field, ?string $operator = null, mixed $value = null): static { return $this->where($field, $operator, $value, 'and', true); } /** * Adds a 'where equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereEquals($field, $value) + public function whereEquals(string $field, string $value): static { return $this->where($field, '=', $value); } /** * Adds a 'where not equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereNotEquals($field, $value) + public function whereNotEquals(string $field, string $value): static { return $this->where($field, '!', $value); } /** * Adds a 'where approximately equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereApproximatelyEquals($field, $value) + public function whereApproximatelyEquals(string $field, string $value): static { return $this->where($field, '~=', $value); } /** * Adds a 'where has' clause to the current query. - * - * @param string $field - * @return $this */ - public function whereHas($field) + public function whereHas(string $field): static { return $this->where($field, '*'); } /** * Adds a 'where not has' clause to the current query. - * - * @param string $field - * @return $this */ - public function whereNotHas($field) + public function whereNotHas(string $field): static { return $this->where($field, '!*'); } /** * Adds a 'where contains' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereContains($field, $value) + public function whereContains(string $field, string $value): static { return $this->where($field, 'contains', $value); } /** * Adds a 'where contains' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereNotContains($field, $value) + public function whereNotContains(string $field, string $value): static { return $this->where($field, 'not_contains', $value); } /** * Query for entries that match any of the values provided for the given field. - * - * @param string $field - * @param array $values - * @return $this */ - public function whereIn($field, array $values) + public function whereIn(string $field, array $values): static { - return $this->orFilter(function (self $query) use ($field, $values) { + if (empty($values)) { + // If the array of values is empty, we will + // add an empty OR filter to the query to + // ensure that no results are returned. + $this->rawFilter('(|)'); + + return $this; + } + + return $this->orFilter(function (Builder $query) use ($field, $values) { foreach ($values as $value) { $query->whereEquals($field, $value); } @@ -1287,12 +1081,8 @@ class Builder /** * Adds a 'between' clause to the current query. - * - * @param string $field - * @param array $values - * @return $this */ - public function whereBetween($field, array $values) + public function whereBetween(string $field, array $values): static { return $this->where([ [$field, '>=', $values[0]], @@ -1302,81 +1092,56 @@ class Builder /** * Adds a 'where starts with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereStartsWith($field, $value) + public function whereStartsWith(string $field, string $value): static { return $this->where($field, 'starts_with', $value); } /** * Adds a 'where *not* starts with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereNotStartsWith($field, $value) + public function whereNotStartsWith(string $field, string $value): static { return $this->where($field, 'not_starts_with', $value); } /** * Adds a 'where ends with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereEndsWith($field, $value) + public function whereEndsWith(string $field, string $value): static { return $this->where($field, 'ends_with', $value); } /** * Adds a 'where *not* ends with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function whereNotEndsWith($field, $value) + public function whereNotEndsWith(string $field, string $value): static { return $this->where($field, 'not_ends_with', $value); } /** * Only include deleted models in the results. - * - * @return $this */ - public function whereDeleted() + public function whereDeleted(): static { return $this->withDeleted()->whereEquals('isDeleted', 'TRUE'); } /** * Set the LDAP control option to include deleted LDAP models. - * - * @return $this */ - public function withDeleted() + public function withDeleted(): static { return $this->addControl(LdapInterface::OID_SERVER_SHOW_DELETED, $isCritical = true); } /** * Add a server control to the query. - * - * @param string $oid - * @param bool $isCritical - * @param mixed $value - * @return $this */ - public function addControl($oid, $isCritical = false, $value = null) + public function addControl(string $oid, bool $isCritical = false, mixed $value = null): static { $this->controls[$oid] = compact('oid', 'isCritical', 'value'); @@ -1385,25 +1150,21 @@ class Builder /** * Determine if the server control exists on the query. - * - * @param string $oid - * @return bool */ - public function hasControl($oid) + public function hasControl(string $oid): bool { return array_key_exists($oid, $this->controls); } /** * Adds an 'or where' clause to the current query. - * - * @param array|string $field - * @param string|null $operator - * @param string|null $value - * @return $this */ - public function orWhere($field, $operator = null, $value = null) + public function orWhere(array|string $field, ?string $operator = null, ?string $value = null): static { + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 && ! $this->operatorRequiresValue($operator) + ); + return $this->where($field, $operator, $value, 'or'); } @@ -1411,143 +1172,96 @@ class Builder * Adds a raw or where clause to the current query. * * Values given to this method are not escaped. - * - * @param string $field - * @param string $operator - * @param string $value - * @return $this */ - public function orWhereRaw($field, $operator = null, $value = null) + public function orWhereRaw(array|string $field, ?string $operator = null, ?string $value = null): static { return $this->where($field, $operator, $value, 'or', true); } /** * Adds an 'or where has' clause to the current query. - * - * @param string $field - * @return $this */ - public function orWhereHas($field) + public function orWhereHas(string $field): static { return $this->orWhere($field, '*'); } /** * Adds a 'where not has' clause to the current query. - * - * @param string $field - * @return $this */ - public function orWhereNotHas($field) + public function orWhereNotHas(string $field): static { return $this->orWhere($field, '!*'); } /** * Adds an 'or where equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereEquals($field, $value) + public function orWhereEquals(string $field, string $value): static { return $this->orWhere($field, '=', $value); } /** * Adds an 'or where not equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereNotEquals($field, $value) + public function orWhereNotEquals(string $field, string $value): static { return $this->orWhere($field, '!', $value); } /** * Adds a 'or where approximately equals' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereApproximatelyEquals($field, $value) + public function orWhereApproximatelyEquals(string $field, string $value): static { return $this->orWhere($field, '~=', $value); } /** * Adds an 'or where contains' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereContains($field, $value) + public function orWhereContains(string $field, string $value): static { return $this->orWhere($field, 'contains', $value); } /** * Adds an 'or where *not* contains' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereNotContains($field, $value) + public function orWhereNotContains(string $field, string $value): static { return $this->orWhere($field, 'not_contains', $value); } /** * Adds an 'or where starts with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereStartsWith($field, $value) + public function orWhereStartsWith(string $field, string $value): static { return $this->orWhere($field, 'starts_with', $value); } /** * Adds an 'or where *not* starts with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereNotStartsWith($field, $value) + public function orWhereNotStartsWith(string $field, string $value): static { return $this->orWhere($field, 'not_starts_with', $value); } /** * Adds an 'or where ends with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereEndsWith($field, $value) + public function orWhereEndsWith(string $field, string $value): static { return $this->orWhere($field, 'ends_with', $value); } /** * Adds an 'or where *not* ends with' clause to the current query. - * - * @param string $field - * @param string $value - * @return $this */ - public function orWhereNotEndsWith($field, $value) + public function orWhereNotEndsWith(string $field, string $value): static { return $this->orWhere($field, 'not_ends_with', $value); } @@ -1555,13 +1269,9 @@ class Builder /** * Adds a filter binding onto the current query. * - * @param string $type The type of filter to add. - * @param array $bindings The bindings of the filter. - * @return $this - * * @throws InvalidArgumentException */ - public function addFilter($type, array $bindings) + public function addFilter(string $type, array $bindings): static { if (! array_key_exists($type, $this->filters)) { throw new InvalidArgumentException("Filter type: [$type] is invalid."); @@ -1583,11 +1293,8 @@ class Builder /** * Extract any missing required binding keys. - * - * @param array $bindings - * @return array */ - protected function missingBindingKeys($bindings) + protected function missingBindingKeys(array $bindings): array { $required = array_flip(['field', 'operator', 'value']); @@ -1598,20 +1305,16 @@ class Builder /** * Get all the filters on the query. - * - * @return array */ - public function getFilters() + public function getFilters(): array { return $this->filters; } /** * Clear the query filters. - * - * @return $this */ - public function clearFilters() + public function clearFilters(): static { foreach (array_keys($this->filters) as $type) { $this->filters[$type] = []; @@ -1622,20 +1325,16 @@ class Builder /** * Determine if the query has attributes selected. - * - * @return bool */ - public function hasSelects() + public function hasSelects(): bool { - return count($this->columns) > 0; + return count($this->columns ?? []) > 0; } /** * Get the attributes to select on the search. - * - * @return array */ - public function getSelects() + public function getSelects(): array { $selects = $this->columns ?? ['*']; @@ -1659,49 +1358,48 @@ class Builder * Set the query to search on the base distinguished name. * * This will result in one record being returned. - * - * @return $this */ - public function read() + public function read(): static { - $this->type = 'read'; + $this->type = self::TYPE_READ; return $this; } /** * Set the query to search one level on the base distinguished name. - * - * @return $this */ - public function listing() + public function list(): static { - $this->type = 'listing'; + $this->type = self::TYPE_LIST; return $this; } /** - * Set the query to search the entire directory on the base distinguished name. - * - * @return $this + * Alias for the "search" method. */ - public function recursive() + public function recursive(): static { - $this->type = 'search'; + return $this->search(); + } + + /** + * Set the query to search the entire directory on the base distinguished name. + */ + public function search(): static + { + $this->type = self::TYPE_SEARCH; return $this; } /** * Whether to mark the current query as nested. - * - * @param bool $nested - * @return $this */ - public function nested($nested = true) + public function nested(bool $nested = true): static { - $this->nested = (bool) $nested; + $this->nested = $nested; return $this; } @@ -1710,14 +1408,11 @@ class Builder * Enables caching on the current query until the given date. * * If flushing is enabled, the query cache will be flushed and then re-cached. - * - * @param DateTimeInterface $until When to expire the query cache. - * @param bool $flush Whether to force-flush the query cache. - * @return $this */ - public function cache(DateTimeInterface $until = null, $flush = false) + public function cache(?DateTimeInterface $until = null, bool $flush = false, ?string $key = null): static { $this->caching = true; + $this->cacheKey = $key; $this->cacheUntil = $until; $this->flushCache = $flush; @@ -1726,20 +1421,16 @@ class Builder /** * Determine if the query is nested. - * - * @return bool */ - public function isNested() + public function isNested(): bool { return $this->nested === true; } /** * Determine whether the query is paginated. - * - * @return bool */ - public function isPaginated() + public function isPaginated(): bool { return $this->paginated; } @@ -1747,14 +1438,22 @@ class Builder /** * Insert an entry into the directory. * - * @param string $dn - * @param array $attributes - * @return bool + * @throws LdapRecordException + */ + public function insert(string $dn, array $attributes): bool + { + return (bool) $this->insertAndGetDn($dn, $attributes); + } + + /** + * Insert an entry into the directory and get the inserted distinguished name. * * @throws LdapRecordException */ - public function insert($dn, array $attributes) + public function insertAndGetDn(string $dn, array $attributes): string|false { + $dn = $this->substituteBaseDn($dn); + if (empty($dn)) { throw new LdapRecordException('A new LDAP object must have a distinguished name (dn).'); } @@ -1765,102 +1464,85 @@ class Builder ); } - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) { - return $ldap->add($dn, $attributes); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->add($dn, $attributes) + ) ? $dn : false; } /** - * Create attributes on the entry in the directory. - * - * @param string $dn - * @param array $attributes - * @return bool + * Add attributes to an entry in the directory. */ - public function insertAttributes($dn, array $attributes) + public function add(string $dn, array $attributes): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) { - return $ldap->modAdd($dn, $attributes); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->modAdd($dn, $attributes) + ); } /** * Update the entry with the given modifications. - * - * @param string $dn - * @param array $modifications - * @return bool */ - public function update($dn, array $modifications) + public function update(string $dn, array $modifications): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $modifications) { - return $ldap->modifyBatch($dn, $modifications); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->modifyBatch($dn, $modifications) + ); } /** - * Update an entries attribute in the directory. - * - * @param string $dn - * @param array $attributes - * @return bool + * Replace an entry's attributes in the directory. */ - public function updateAttributes($dn, array $attributes) + public function replace(string $dn, array $attributes): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) { - return $ldap->modReplace($dn, $attributes); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->modReplace($dn, $attributes) + ); } /** * Delete an entry from the directory. - * - * @param string $dn - * @return bool */ - public function delete($dn) + public function delete(string $dn): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn) { - return $ldap->delete($dn); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->delete($dn) + ); } /** - * Delete attributes on the entry in the directory. - * - * @param string $dn - * @param array $attributes - * @return bool + * Remove attributes on the entry in the directory. */ - public function deleteAttributes($dn, array $attributes) + public function remove(string $dn, array $attributes): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) { - return $ldap->modDelete($dn, $attributes); - }); + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->modDelete($dn, $attributes) + ); } /** * Rename an entry in the directory. - * - * @param string $dn - * @param string $rdn - * @param string $newParentDn - * @param bool $deleteOldRdn - * @return bool */ - public function rename($dn, $rdn, $newParentDn, $deleteOldRdn = true) + public function rename(string $dn, string $rdn, string $newParentDn, bool $deleteOldRdn = true): bool { - return $this->connection->run(function (LdapInterface $ldap) use ($dn, $rdn, $newParentDn, $deleteOldRdn) { - return $ldap->rename($dn, $rdn, $newParentDn, $deleteOldRdn); - }); + return (bool) $this->renameAndGetDn($dn, $rdn, $newParentDn, $deleteOldRdn); + } + + /** + * Rename an entry in the directory and get the new distinguished name. + */ + public function renameAndGetDn(string $dn, string $rdn, string $newParentDn, bool $deleteOldRdn = true): string|false + { + $newParentDn = $this->substituteBaseDn($newParentDn); + + return $this->connection->run( + fn (LdapInterface $ldap) => $ldap->rename($dn, $rdn, $newParentDn, $deleteOldRdn) + ) ? implode(',', [$rdn, $newParentDn]) : false; } /** * Clone the query. - * - * @return static */ - public function clone() + public function clone(): static { return clone $this; } @@ -1868,18 +1550,14 @@ class Builder /** * Handle dynamic method calls on the query builder. * - * @param string $method - * @param array $parameters - * @return mixed - * * @throws BadMethodCallException */ - public function __call($method, $parameters) + public function __call(string $method, array $parameters): static { // If the beginning of the method being called contains // 'where', we will assume a dynamic 'where' clause is // being performed and pass the parameters to it. - if (substr($method, 0, 5) === 'where') { + if (str_starts_with($method, 'where')) { return $this->dynamicWhere($method, $parameters); } @@ -1893,11 +1571,9 @@ class Builder /** * Handles dynamic "where" clauses to the query. * - * @param string $method - * @param array $parameters * @return $this */ - public function dynamicWhere($method, $parameters) + public function dynamicWhere(string $method, array $parameters): static { $finder = substr($method, 5); @@ -1933,13 +1609,8 @@ class Builder /** * Adds an array of wheres to the current query. - * - * @param array $wheres - * @param string $boolean - * @param bool $raw - * @return $this */ - protected function addArrayOfWheres($wheres, $boolean, $raw) + protected function addArrayOfWheres(array $wheres, string $boolean, bool $raw): static { foreach ($wheres as $key => $value) { if (is_numeric($key) && is_array($value)) { @@ -1964,14 +1635,8 @@ class Builder /** * Add a single dynamic where clause statement to the query. - * - * @param string $segment - * @param string $connector - * @param array $parameters - * @param int $index - * @return void */ - protected function addDynamic($segment, $connector, $parameters, $index) + protected function addDynamic(string $segment, string $connector, array $parameters, int $index): void { // If no parameters were given to the dynamic where clause, // we can assume a "has" attribute filter is being added. @@ -1984,55 +1649,34 @@ class Builder /** * Logs the given executed query information by firing its query event. - * - * @param Builder $query - * @param string $type - * @param null|float $time - * @return void */ - protected function logQuery($query, $type, $time = null) + protected function logQuery(Builder $query, string $type, ?float $time = null): void { $args = [$query, $time]; - switch ($type) { - case 'listing': - $event = new Events\Listing(...$args); - break; - case 'read': - $event = new Events\Read(...$args); - break; - case 'chunk': - $event = new Events\Chunk(...$args); - break; - case 'paginate': - $event = new Events\Paginate(...$args); - break; - default: - $event = new Events\Search(...$args); - break; - } - - $this->fireQueryEvent($event); + $this->fireQueryEvent( + match ($type) { + self::TYPE_READ => new Events\Read(...$args), + self::TYPE_CHUNK => new Events\Chunk(...$args), + self::TYPE_LIST => new Events\Listing(...$args), + self::TYPE_PAGINATE => new Events\Paginate(...$args), + default => new Events\Search(...$args), + } + ); } /** * Fires the given query event. - * - * @param QueryExecuted $event - * @return void */ - protected function fireQueryEvent(QueryExecuted $event) + protected function fireQueryEvent(QueryExecuted $event): void { - Container::getInstance()->getEventDispatcher()->fire($event); + Container::getInstance()->getDispatcher()->fire($event); } /** * Get the elapsed time since a given starting point. - * - * @param int $start - * @return float */ - protected function getElapsedTime($start) + protected function getElapsedTime(float $start): float { return round((microtime(true) - $start) * 1000, 2); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php index d6057bfb3..184455ced 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php @@ -13,15 +13,11 @@ class Cache /** * The cache driver. - * - * @var CacheInterface */ - protected $store; + protected CacheInterface $store; /** * Constructor. - * - * @param CacheInterface $store */ public function __construct(CacheInterface $store) { @@ -30,47 +26,26 @@ class Cache /** * Get an item from the cache. - * - * @param string $key - * @return mixed */ - public function get($key) + public function get(string $key): mixed { return $this->store->get($key); } /** * Store an item in the cache. - * - * @param string $key - * @param mixed $value - * @param DateTimeInterface|DateInterval|int|null $ttl - * @return bool */ - public function put($key, $value, $ttl = null) + public function put(string $key, mixed $value, DateTimeInterface|DateInterval|int|null $ttl = null): bool { - $seconds = $this->secondsUntil($ttl); - - if ($seconds <= 0) { - return $this->delete($key); - } - - return $this->store->set($key, $value, $seconds); + return $this->store->set($key, $value, $this->secondsUntil($ttl)); } /** * Get an item from the cache, or execute the given Closure and store the result. - * - * @param string $key - * @param DateTimeInterface|DateInterval|int|null $ttl - * @param Closure $callback - * @return mixed */ - public function remember($key, $ttl, Closure $callback) + public function remember(string $key, DateTimeInterface|DateInterval|int|null $ttl, Closure $callback): mixed { - $value = $this->get($key); - - if (! is_null($value)) { + if (! is_null($value = $this->get($key))) { return $value; } @@ -81,21 +56,16 @@ class Cache /** * Delete an item from the cache. - * - * @param string $key - * @return bool */ - public function delete($key) + public function delete(string $key): bool { return $this->store->delete($key); } /** * Get the underlying cache store. - * - * @return CacheInterface */ - public function store() + public function store(): CacheInterface { return $this->store; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php index 036affa22..9cda10cdb 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php @@ -2,25 +2,23 @@ namespace LdapRecord\Query; +use Illuminate\Support\Collection as BaseCollection; use LdapRecord\Models\Model; -use Tightenco\Collect\Support\Collection as BaseCollection; class Collection extends BaseCollection { /** - * @inheritdoc + * {@inheritdoc} */ - protected function valueRetriever($value) + protected function valueRetriever(mixed $value): callable { if ($this->useAsCallable($value)) { /** @var callable $value */ return $value; } - return function ($item) use ($value) { - return $item instanceof Model + return fn ($item) => $item instanceof Model ? $item->getFirstAttribute($value) : data_get($item, $value); - }; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php index 8ed8f835d..95cadd6ae 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php @@ -8,46 +8,35 @@ class QueryExecuted { /** * The LDAP filter that was used for the query. - * - * @var Builder */ - protected $query; + protected Builder $query; /** * The number of milliseconds it took to execute the query. - * - * @var ?float */ - protected $time; + protected ?float $time; /** * Constructor. - * - * @param Builder $query - * @param null|float $time */ - public function __construct(Builder $query, $time = null) + public function __construct(Builder $query, ?float $time = null) { $this->query = $query; $this->time = $time; } /** - * Returns the LDAP filter that was used for the query. - * - * @return Builder + * Get the LDAP filter that was used for the query. */ - public function getQuery() + public function getQuery(): Builder { return $this->query; } /** - * Returns the number of milliseconds it took to execute the query. - * - * @return float|null + * Get the number of milliseconds it took to execute the query. */ - public function getTime() + public function getTime(): ?float { return $this->time; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php index 6203360c5..4dfed722b 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php @@ -8,38 +8,28 @@ class ConditionNode extends Node { /** * The condition's attribute. - * - * @var string */ - protected $attribute; + protected string $attribute; /** * The condition's operator. - * - * @var string */ - protected $operator; + protected string $operator; /** * The condition's value. - * - * @var string */ - protected $value; + protected string $value; /** * The available condition operators. - * - * @var array */ - protected $operators = ['>=', '<=', '~=', '=']; + protected array $operators = ['>=', '<=', '~=', '=']; /** * Constructor. - * - * @param string $filter */ - public function __construct($filter) + public function __construct(string $filter) { $this->raw = $filter; @@ -48,51 +38,38 @@ class ConditionNode extends Node /** * Get the condition's attribute. - * - * @return string */ - public function getAttribute() + public function getAttribute(): string { return $this->attribute; } /** * Get the condition's operator. - * - * @return string */ - public function getOperator() + public function getOperator(): string { return $this->operator; } /** * Get the condition's value. - * - * @return string */ - public function getValue() + public function getValue(): string { return $this->value; } /** * Extract the condition components from the filter. - * - * @param string $filter - * @return array */ - protected function extractComponents($filter) + protected function extractComponents(string $filter): array { $components = Str::whenContains( $filter, $this->operators, - function ($operator, $filter) { - return explode($this->operator = $operator, $filter, 2); - }, - function ($filter) { - throw new ParserException("Invalid query condition. No operator found in [$filter]"); - }, + fn ($operator, $filter) => explode($this->operator = $operator, $filter, 2), + fn ($filter) => throw new ParserException("Invalid query condition. No operator found in [$filter]"), ); return $components; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php index 1a3596f3e..1af71369e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php @@ -6,24 +6,20 @@ class GroupNode extends Node { /** * The group's operator. - * - * @var string */ - protected $operator; + protected string $operator; /** * The group's sub-nodes. * * @var Node[] */ - protected $nodes = []; + protected array $nodes = []; /** * Constructor. - * - * @param string $filter */ - public function __construct($filter) + public function __construct(string $filter) { $this->raw = $filter; @@ -34,10 +30,8 @@ class GroupNode extends Node /** * Get the group's operator. - * - * @return string */ - public function getOperator() + public function getOperator(): string { return $this->operator; } @@ -47,7 +41,7 @@ class GroupNode extends Node * * @return Node[] */ - public function getNodes() + public function getNodes(): array { return $this->nodes; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php index faf88d41f..3e9c039f1 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php @@ -6,24 +6,18 @@ abstract class Node { /** * The raw value of the node. - * - * @var string */ - protected $raw; + protected string $raw; /** * Create a new filter node. - * - * @param string $filter */ - abstract public function __construct($filter); + abstract public function __construct(string $filter); /** * Get the raw value of the node. - * - * @return string */ - public function getRaw() + public function getRaw(): string { return $this->raw; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php index 7717ac522..1fea1810d 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php @@ -10,12 +10,11 @@ class Parser /** * Parse an LDAP filter into nodes. * - * @param string $string * @return (ConditionNode|GroupNode)[] * * @throws ParserException */ - public static function parse($string) + public static function parse(string $string): array { [$open, $close] = static::countParenthesis($string); @@ -34,11 +33,8 @@ class Parser /** * Perform a match for all filters in the string. - * - * @param string $string - * @return array */ - protected static function match($string) + protected static function match(string $string): array { preg_match_all("/\((((?>[^()]+)|(?R))*)\)/", trim($string), $matches); @@ -49,22 +45,18 @@ class Parser * Assemble the parsed nodes into a single filter. * * @param Node|Node[] $nodes - * @return string */ - public static function assemble($nodes = []) + public static function assemble(Node|array $nodes = []): string { - return array_reduce(Arr::wrap($nodes), function ($carry, Node $node) { - return $carry .= static::compileNode($node); - }); + return array_reduce(Arr::wrap($nodes), fn ($carry, Node $node) => ( + $carry .= static::compileNode($node) + )); } /** * Assemble the node into its string based format. - * - * @param GroupNode|ConditionNode $node - * @return string */ - protected static function compileNode(Node $node) + protected static function compileNode(Node $node): string { switch (true) { case $node instanceof GroupNode: @@ -84,7 +76,7 @@ class Parser * * @throws ParserException */ - protected static function buildNodes(array $filters = []) + protected static function buildNodes(array $filters = []): array { return array_map(function ($filter) { if (static::isWrapped($filter)) { @@ -103,33 +95,24 @@ class Parser /** * Count the open and close parenthesis of the sting. - * - * @param string $string - * @return array */ - protected static function countParenthesis($string) + protected static function countParenthesis(string $string): array { return [Str::substrCount($string, '('), Str::substrCount($string, ')')]; } /** * Wrap the value in parentheses. - * - * @param string $value - * @return string */ - protected static function wrap($value) + protected static function wrap(string $value): string { return "($value)"; } /** * Recursively unwrwap the value from its parentheses. - * - * @param string $value - * @return string */ - protected static function unwrap($value) + protected static function unwrap(string $value): string { $nodes = static::parse($value); @@ -140,22 +123,16 @@ class Parser /** * Determine if the filter is wrapped. - * - * @param string $filter - * @return bool */ - protected static function isWrapped($filter) + protected static function isWrapped(string $filter): bool { return Str::startsWith($filter, '(') && Str::endsWith($filter, ')'); } /** * Determine if the filter is a group. - * - * @param string $filter - * @return bool */ - protected static function isGroup($filter) + protected static function isGroup(string $filter): bool { return Str::startsWith($filter, ['&', '|', '!']); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php index 68a4ca171..3c3d68e4f 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php @@ -4,6 +4,4 @@ namespace LdapRecord\Query\Filter; use LdapRecord\LdapRecordException; -class ParserException extends LdapRecordException -{ -} +class ParserException extends LdapRecordException {} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php index 84c4b8d0c..0506c983e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php @@ -8,10 +8,8 @@ class Grammar { /** * The query operators and their method names. - * - * @var array */ - public $operators = [ + public array $operators = [ '*' => 'has', '!*' => 'notHas', '=' => 'equals', @@ -30,17 +28,13 @@ class Grammar /** * The query wrapper. - * - * @var string|null */ - protected $wrapper; + protected ?string $wrapper = null; /** * Get all the available operators. - * - * @return array */ - public function getOperators() + public function getOperators(): array { return array_keys($this->operators); } @@ -49,24 +43,16 @@ class Grammar * Wraps a query string in brackets. * * Produces: (query) - * - * @param string $query - * @param string $prefix - * @param string $suffix - * @return string */ - public function wrap($query, $prefix = '(', $suffix = ')') + public function wrap(string $query, ?string $prefix = '(', ?string $suffix = ')'): string { return $prefix.$query.$suffix; } /** * Compiles the Builder instance into an LDAP query string. - * - * @param Builder $query - * @return string */ - public function compile(Builder $query) + public function compile(Builder $query): string { if ($this->queryMustBeWrapped($query)) { $this->wrapper = 'and'; @@ -76,50 +62,37 @@ class Grammar .$this->compileWheres($query) .$this->compileOrWheres($query); - switch ($this->wrapper) { - case 'and': - return $this->compileAnd($filter); - case 'or': - return $this->compileOr($filter); - default: - return $filter; - } + return match ($this->wrapper) { + 'and' => $this->compileAnd($filter), + 'or' => $this->compileOr($filter), + default => $filter, + }; } /** * Determine if the query must be wrapped in an encapsulating statement. - * - * @param Builder $query - * @return bool */ - protected function queryMustBeWrapped(Builder $query) + protected function queryMustBeWrapped(Builder $query): bool { return ! $query->isNested() && $this->hasMultipleFilters($query); } /** - * Assembles all of the "raw" filters on the query. - * - * @param Builder $builder - * @return string + * Assembles all the "raw" filters on the query. */ - protected function compileRaws(Builder $builder) + protected function compileRaws(Builder $builder): string { return $this->concatenate($builder->filters['raw']); } /** * Assembles all where clauses in the current wheres property. - * - * @param Builder $builder - * @param string $type - * @return string */ - protected function compileWheres(Builder $builder, $type = 'and') + protected function compileWheres(Builder $builder, string $type = 'and'): string { $filter = ''; - foreach ($builder->filters[$type] as $where) { + foreach ($builder->filters[$type] ?? [] as $where) { $filter .= $this->compileWhere($where); } @@ -128,11 +101,8 @@ class Grammar /** * Assembles all or where clauses in the current orWheres property. - * - * @param Builder $query - * @return string */ - protected function compileOrWheres(Builder $query) + protected function compileOrWheres(Builder $query): string { $filter = $this->compileWheres($query, 'or'); @@ -154,24 +124,18 @@ class Grammar /** * Determine if the query can be wrapped in a single or statement. - * - * @param Builder $query - * @return bool */ - protected function queryCanBeWrappedInSingleOrStatement(Builder $query) + protected function queryCanBeWrappedInSingleOrStatement(Builder $query): bool { - return $this->has($query, 'or', '>=', 1) && - $this->has($query, 'and', '<=', 1) && - $this->has($query, 'raw', '=', 0); + return $this->has($query, 'or', '>=', 1) + && $this->has($query, 'and', '<=', 1) + && $this->has($query, 'raw', '=', 0); } /** * Concatenates filters into a single string. - * - * @param array $bindings - * @return string */ - public function concatenate(array $bindings = []) + public function concatenate(array $bindings = []): string { // Filter out empty query segments. return implode( @@ -181,69 +145,48 @@ class Grammar /** * Determine if the binding value is not empty. - * - * @param string $value - * @return bool */ - protected function bindingValueIsNotEmpty($value) + protected function bindingValueIsNotEmpty(string $value): bool { return ! empty($value); } /** * Determine if the query is using multiple filters. - * - * @param Builder $query - * @return bool */ - protected function hasMultipleFilters(Builder $query) + protected function hasMultipleFilters(Builder $query): bool { return $this->has($query, ['and', 'or', 'raw'], '>', 1); } /** * Determine if the query contains the given filter statement type. - * - * @param Builder $query - * @param string|array $type - * @param string $operator - * @param int $count - * @return bool */ - protected function has(Builder $query, $type, $operator = '>=', $count = 1) + protected function has(Builder $query, array|string $type, string $operator = '>=', int $count = 1): bool { $types = (array) $type; $filters = 0; foreach ($types as $type) { - $filters += count($query->filters[$type]); + $filters += count($query->filters[$type] ?? []); } - switch ($operator) { - case '>': - return $filters > $count; - case '>=': - return $filters >= $count; - case '<': - return $filters < $count; - case '<=': - return $filters <= $count; - default: - return $filters == $count; - } + return match ($operator) { + '>' => $filters > $count, + '>=' => $filters >= $count, + '<' => $filters < $count, + '<=' => $filters <= $count, + default => $filters == $count, + }; } /** * Returns a query string for equals. * * Produces: (field=value) - * - * @param string $field - * @param string $value - * @return string */ - public function compileEquals($field, $value) + public function compileEquals(string $field, string $value): string { return $this->wrap($field.'='.$value); } @@ -252,12 +195,8 @@ class Grammar * Returns a query string for does not equal. * * Produces: (!(field=value)) - * - * @param string $field - * @param string $value - * @return string */ - public function compileDoesNotEqual($field, $value) + public function compileDoesNotEqual(string $field, string $value): string { return $this->compileNot( $this->compileEquals($field, $value) @@ -268,12 +207,8 @@ class Grammar * Alias for does not equal operator (!=) operator. * * Produces: (!(field=value)) - * - * @param string $field - * @param string $value - * @return string */ - public function compileDoesNotEqualAlias($field, $value) + public function compileDoesNotEqualAlias(string $field, string $value): string { return $this->compileDoesNotEqual($field, $value); } @@ -282,12 +217,8 @@ class Grammar * Returns a query string for greater than or equals. * * Produces: (field>=value) - * - * @param string $field - * @param string $value - * @return string */ - public function compileGreaterThanOrEquals($field, $value) + public function compileGreaterThanOrEquals(string $field, string $value): string { return $this->wrap("$field>=$value"); } @@ -296,12 +227,8 @@ class Grammar * Returns a query string for less than or equals. * * Produces: (field<=value) - * - * @param string $field - * @param string $value - * @return string */ - public function compileLessThanOrEquals($field, $value) + public function compileLessThanOrEquals(string $field, string $value): string { return $this->wrap("$field<=$value"); } @@ -310,12 +237,8 @@ class Grammar * Returns a query string for approximately equals. * * Produces: (field~=value) - * - * @param string $field - * @param string $value - * @return string */ - public function compileApproximatelyEquals($field, $value) + public function compileApproximatelyEquals(string $field, string $value): string { return $this->wrap("$field~=$value"); } @@ -324,12 +247,8 @@ class Grammar * Returns a query string for starts with. * * Produces: (field=value*) - * - * @param string $field - * @param string $value - * @return string */ - public function compileStartsWith($field, $value) + public function compileStartsWith(string $field, string $value): string { return $this->wrap("$field=$value*"); } @@ -338,12 +257,8 @@ class Grammar * Returns a query string for does not start with. * * Produces: (!(field=*value)) - * - * @param string $field - * @param string $value - * @return string */ - public function compileNotStartsWith($field, $value) + public function compileNotStartsWith(string $field, string $value): string { return $this->compileNot( $this->compileStartsWith($field, $value) @@ -354,12 +269,8 @@ class Grammar * Returns a query string for ends with. * * Produces: (field=*value) - * - * @param string $field - * @param string $value - * @return string */ - public function compileEndsWith($field, $value) + public function compileEndsWith(string $field, string $value): string { return $this->wrap("$field=*$value"); } @@ -368,12 +279,8 @@ class Grammar * Returns a query string for does not end with. * * Produces: (!(field=value*)) - * - * @param string $field - * @param string $value - * @return string */ - public function compileNotEndsWith($field, $value) + public function compileNotEndsWith(string $field, string $value): string { return $this->compileNot($this->compileEndsWith($field, $value)); } @@ -382,12 +289,8 @@ class Grammar * Returns a query string for contains. * * Produces: (field=*value*) - * - * @param string $field - * @param string $value - * @return string */ - public function compileContains($field, $value) + public function compileContains(string $field, string $value): string { return $this->wrap("$field=*$value*"); } @@ -396,12 +299,8 @@ class Grammar * Returns a query string for does not contain. * * Produces: (!(field=*value*)) - * - * @param string $field - * @param string $value - * @return string */ - public function compileNotContains($field, $value) + public function compileNotContains(string $field, string $value): string { return $this->compileNot( $this->compileContains($field, $value) @@ -412,11 +311,8 @@ class Grammar * Returns a query string for a where has. * * Produces: (field=*) - * - * @param string $field - * @return string */ - public function compileHas($field) + public function compileHas(string $field): string { return $this->wrap("$field=*"); } @@ -425,11 +321,8 @@ class Grammar * Returns a query string for a where does not have. * * Produces: (!(field=*)) - * - * @param string $field - * @return string */ - public function compileNotHas($field) + public function compileNotHas(string $field): string { return $this->compileNot( $this->compileHas($field) @@ -440,11 +333,8 @@ class Grammar * Wraps the inserted query inside an AND operator. * * Produces: (&query) - * - * @param string $query - * @return string */ - public function compileAnd($query) + public function compileAnd(string $query): string { return $query ? $this->wrap($query, '(&') : ''; } @@ -453,22 +343,16 @@ class Grammar * Wraps the inserted query inside an OR operator. * * Produces: (|query) - * - * @param string $query - * @return string */ - public function compileOr($query) + public function compileOr(string $query): string { return $query ? $this->wrap($query, '(|') : ''; } /** * Wraps the inserted query inside an NOT operator. - * - * @param string $query - * @return string */ - public function compileNot($query) + public function compileNot(string $query): string { return $query ? $this->wrap($query, '(!') : ''; } @@ -476,12 +360,9 @@ class Grammar /** * Assembles a single where query. * - * @param array $where - * @return string - * * @throws UnexpectedValueException */ - protected function compileWhere(array $where) + protected function compileWhere(array $where): string { $method = $this->makeCompileMethod($where['operator']); @@ -491,12 +372,9 @@ class Grammar /** * Make the compile method name for the operator. * - * @param string $operator - * @return string - * * @throws UnexpectedValueException */ - protected function makeCompileMethod($operator) + protected function makeCompileMethod(string $operator): string { if (! $this->operatorExists($operator)) { throw new UnexpectedValueException("Invalid LDAP filter operator ['$operator']"); @@ -507,11 +385,8 @@ class Grammar /** * Determine if the operator exists. - * - * @param string $operator - * @return bool */ - protected function operatorExists($operator) + protected function operatorExists(string $operator): bool { return array_key_exists($operator, $this->operators); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php index e8024c033..111c2c201 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php @@ -15,11 +15,8 @@ trait InteractsWithTime { /** * Get the number of seconds until the given DateTime. - * - * @param DateTimeInterface|DateInterval|int $delay - * @return int */ - protected function secondsUntil($delay) + protected function secondsUntil(DateTimeInterface|DateInterval|int|null $delay = null): int { $delay = $this->parseDateInterval($delay); @@ -30,11 +27,8 @@ trait InteractsWithTime /** * Get the "available at" UNIX timestamp. - * - * @param DateTimeInterface|DateInterval|int $delay - * @return int */ - protected function availableAt($delay = 0) + protected function availableAt(DateTimeInterface|DateInterval|int $delay = 0): int { $delay = $this->parseDateInterval($delay); @@ -45,11 +39,8 @@ trait InteractsWithTime /** * If the given value is an interval, convert it to a DateTime instance. - * - * @param DateTimeInterface|DateInterval|int $delay - * @return DateTimeInterface|int */ - protected function parseDateInterval($delay) + protected function parseDateInterval(DateTimeInterface|DateInterval|int|null $delay = null): DateTimeInterface|int|null { if ($delay instanceof DateInterval) { $delay = Carbon::now()->add($delay); @@ -60,10 +51,8 @@ trait InteractsWithTime /** * Get the current system time as a UNIX timestamp. - * - * @return int */ - protected function currentTime() + protected function currentTime(): int { return Carbon::now()->getTimestamp(); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php index 3b0e96f79..7fb8ab682 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php @@ -5,23 +5,20 @@ namespace LdapRecord\Query\Model; use Closure; use LdapRecord\LdapInterface; use LdapRecord\Models\Attributes\AccountControl; +use LdapRecord\Models\Model; use LdapRecord\Models\ModelNotFoundException; class ActiveDirectoryBuilder extends Builder { /** * Finds a record by its Object SID. - * - * @param string $sid - * @param array|string $columns - * @return \LdapRecord\Models\ActiveDirectory\Entry|static|null */ - public function findBySid($sid, $columns = []) + public function findBySid(string $sid, array|string $columns = ['*']): ?Model { try { return $this->findBySidOrFail($sid, $columns); - } catch (ModelNotFoundException $e) { - return; + } catch (ModelNotFoundException) { + return null; } } @@ -30,190 +27,157 @@ class ActiveDirectoryBuilder extends Builder * * Fails upon no records returned. * - * @param string $sid - * @param array|string $columns - * @return \LdapRecord\Models\ActiveDirectory\Entry|static - * * @throws ModelNotFoundException */ - public function findBySidOrFail($sid, $columns = []) + public function findBySidOrFail(string $sid, array $columns = ['*']): Model { return $this->findByOrFail('objectsid', $sid, $columns); } /** * Adds a enabled filter to the current query. - * - * @return $this */ - public function whereEnabled() + public function whereEnabled(): static { - return $this->notFilter(function ($query) { - return $query->whereDisabled(); - }); + return $this->notFilter( + fn (self $query) => $query->whereDisabled() + ); } /** * Adds a disabled filter to the current query. - * - * @return $this */ - public function whereDisabled() + public function whereDisabled(): static { return $this->rawFilter( - (new AccountControl())->accountIsDisabled()->filter() + (new AccountControl)->setAccountIsDisabled()->filter() ); } /** * Adds a 'where member' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function whereMember($dn, $nested = false) + public function whereMember(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->whereEquals($attribute, $dn); - }, 'member', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)), + 'member', + $nested + ); } /** * Adds an 'or where member' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function orWhereMember($dn, $nested = false) + public function orWhereMember(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->orWhereEquals($attribute, $dn); - }, 'member', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)), + 'member', + $nested + ); } /** * Adds a 'where member of' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function whereMemberOf($dn, $nested = false) + public function whereMemberOf(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->whereEquals($attribute, $dn); - }, 'memberof', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)), + 'memberof', + $nested + ); } /** * Adds a 'where not member of' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function whereNotMemberof($dn, $nested = false) + public function whereNotMemberof(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->whereNotEquals($attribute, $dn); - }, 'memberof', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->whereNotEquals($attribute, $this->substituteBaseDn($dn)), + 'memberof', + $nested + ); } /** * Adds an 'or where member of' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function orWhereMemberOf($dn, $nested = false) + public function orWhereMemberOf(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->orWhereEquals($attribute, $dn); - }, 'memberof', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)), + 'memberof', + $nested + ); } /** * Adds a 'or where not member of' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function orWhereNotMemberof($dn, $nested = false) + public function orWhereNotMemberof(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->orWhereNotEquals($attribute, $dn); - }, 'memberof', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->orWhereNotEquals($attribute, $this->substituteBaseDn($dn)), + 'memberof', + $nested + ); } /** * Adds a 'where manager' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function whereManager($dn, $nested = false) + public function whereManager(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->whereEquals($attribute, $dn); - }, 'manager', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)), + 'manager', + $nested + ); } /** * Adds a 'where not manager' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function whereNotManager($dn, $nested = false) + public function whereNotManager(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->whereNotEquals($attribute, $dn); - }, 'manager', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->whereNotEquals($attribute, $this->substituteBaseDn($dn)), + 'manager', + $nested + ); } /** * Adds an 'or where manager' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function orWhereManager($dn, $nested = false) + public function orWhereManager(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->orWhereEquals($attribute, $dn); - }, 'manager', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)), + 'manager', + $nested + ); } /** * Adds an 'or where not manager' filter to the current query. - * - * @param string $dn - * @param bool $nested - * @return $this */ - public function orWhereNotManager($dn, $nested = false) + public function orWhereNotManager(string $dn, bool $nested = false): static { - return $this->nestedMatchQuery(function ($attribute) use ($dn) { - return $this->orWhereNotEquals($attribute, $dn); - }, 'manager', $nested); + return $this->nestedMatchQuery( + fn (string $attribute) => $this->orWhereNotEquals($attribute, $this->substituteBaseDn($dn)), + 'manager', + $nested + ); } /** * Execute the callback with a nested match attribute. - * - * @param Closure $callback - * @param string $attribute - * @param bool $nested - * @return $this */ - protected function nestedMatchQuery(Closure $callback, $attribute, $nested = false) + protected function nestedMatchQuery(Closure $callback, string $attribute, bool $nested = false): static { return $callback( $nested ? $this->makeNestedMatchAttribute($attribute) : $attribute @@ -222,11 +186,8 @@ class ActiveDirectoryBuilder extends Builder /** * Make a "nested match" filter attribute for querying descendants. - * - * @param string $attribute - * @return string */ - protected function makeNestedMatchAttribute($attribute) + protected function makeNestedMatchAttribute(string $attribute): string { return sprintf('%s:%s:', $attribute, LdapInterface::OID_MATCHING_RULE_IN_CHAIN); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php index a6886ea96..741646e7e 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php @@ -4,51 +4,41 @@ namespace LdapRecord\Query\Model; use Closure; use DateTime; +use LdapRecord\Models\Attributes\Guid; +use LdapRecord\Models\Collection; use LdapRecord\Models\Model; use LdapRecord\Models\ModelNotFoundException; use LdapRecord\Models\Scope; use LdapRecord\Models\Types\ActiveDirectory; use LdapRecord\Query\Builder as BaseBuilder; -use LdapRecord\Utilities; +use UnexpectedValueException; class Builder extends BaseBuilder { /** * The model being queried. - * - * @var Model */ - protected $model; + protected Model $model; /** * The global scopes to be applied. - * - * @var array */ - protected $scopes = []; + protected array $scopes = []; /** * The removed global scopes. - * - * @var array */ - protected $removedScopes = []; + protected array $removedScopes = []; /** * The applied global scopes. - * - * @var array */ - protected $appliedScopes = []; + protected array $appliedScopes = []; /** * Dynamically handle calls into the query instance. - * - * @param string $method - * @param array $parameters - * @return mixed */ - public function __call($method, $parameters) + public function __call(string $method, array $parameters): static { if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) { return $this->callScope([$this->model, $scope], $parameters); @@ -59,12 +49,8 @@ class Builder extends BaseBuilder /** * Apply the given scope on the current builder instance. - * - * @param callable $scope - * @param array $parameters - * @return mixed */ - protected function callScope(callable $scope, $parameters = []) + protected function callScope(callable $scope, array $parameters = []): static { array_unshift($parameters, $this); @@ -73,10 +59,8 @@ class Builder extends BaseBuilder /** * Get the attributes to select on the search. - * - * @return array */ - public function getSelects() + public function getSelects(): array { // Here we will ensure the models GUID attribute is always // selected. In some LDAP directories, the attribute is @@ -88,11 +72,8 @@ class Builder extends BaseBuilder /** * Set the model instance for the model being queried. - * - * @param Model $model - * @return $this */ - public function setModel(Model $model) + public function setModel(Model $model): static { $this->model = $model; @@ -100,48 +81,97 @@ class Builder extends BaseBuilder } /** - * Returns the model being queried for. - * - * @return Model + * Get the model being queried for. */ - public function getModel() + public function getModel(): Model { return $this->model; } /** * Get a new model query builder instance. - * - * @param string|null $baseDn - * @return static */ - public function newInstance($baseDn = null) + public function newInstance(?string $baseDn = null): BaseBuilder { return parent::newInstance($baseDn)->model($this->model); } /** - * Finds a model by its distinguished name. - * - * @param array|string $dn - * @param array|string|string[] $columns - * @return Model|\LdapRecord\Query\Collection|static|null + * {@inheritDoc} */ - public function find($dn, $columns = ['*']) + public function first(array|string $columns = ['*']): ?Model { - return $this->afterScopes(function () use ($dn, $columns) { - return parent::find($dn, $columns); - }); + return parent::first($columns); + } + + /** + * {@inheritDoc} + */ + public function firstOrFail(array|string $columns = ['*']): Model + { + return parent::firstOrFail($columns); + } + + /** + * {@inheritDoc} + */ + public function sole(array|string $columns = ['*']): Model + { + return parent::sole($columns); + } + + /** + * {@inheritDoc} + */ + public function find(array|string $dn, array|string $columns = ['*']): Model|Collection|null + { + return $this->afterScopes(fn () => parent::find($dn, $columns)); + } + + /** + * {@inheritDoc} + */ + public function findOrFail(string $dn, array|string $columns = ['*']): Model + { + return parent::findOrFail($dn, $columns); + } + + /** + * {@inheritDoc} + */ + public function findByOrFail(string $attribute, string $value, array|string $columns = ['*']): Model + { + return parent::findByOrFail($attribute, $value, $columns); + } + + /** + * {@inheritDoc} + */ + public function findBy(string $attribute, string $value, array|string $columns = ['*']): ?Model + { + return parent::findBy($attribute, $value, $columns); + } + + /** + * {@inheritDoc} + */ + public function findMany(array|string $dns, array|string $columns = ['*']): Collection + { + return parent::findMany($dns, $columns); + } + + /** + * {@inheritDoc} + */ + public function findManyBy(string $attribute, array $values = [], array|string $columns = ['*']): Collection + { + return parent::findManyBy($attribute, $values, $columns); } /** * Finds a record using ambiguous name resolution. - * - * @param string|array $value - * @param array|string $columns - * @return Model|\LdapRecord\Query\Collection|static|null */ - public function findByAnr($value, $columns = ['*']) + public function findByAnr(array|string $value, array|string $columns = ['*']): Model|Collection|null { if (is_array($value)) { return $this->findManyByAnr($value, $columns); @@ -159,10 +189,8 @@ class Builder extends BaseBuilder /** * Determine if the current model is compatible with ANR filters. - * - * @return bool */ - protected function modelIsCompatibleWithAnr() + protected function modelIsCompatibleWithAnr(): bool { return $this->model instanceof ActiveDirectory; } @@ -172,13 +200,9 @@ class Builder extends BaseBuilder * * If a record is not found, an exception is thrown. * - * @param string $value - * @param array|string $columns - * @return Model - * * @throws ModelNotFoundException */ - public function findByAnrOrFail($value, $columns = ['*']) + public function findByAnrOrFail(string $value, array|string $columns = ['*']): Model { if (! $entry = $this->findByAnr($value, $columns)) { $this->throwNotFoundException($this->getUnescapedQuery(), $this->dn); @@ -190,24 +214,17 @@ class Builder extends BaseBuilder /** * Throws a not found exception. * - * @param string $query - * @param string $dn - * * @throws ModelNotFoundException */ - protected function throwNotFoundException($query, $dn) + protected function throwNotFoundException(string $query, ?string $dn = null): void { throw ModelNotFoundException::forQuery($query, $dn); } /** * Finds multiple records using ambiguous name resolution. - * - * @param array $values - * @param array $columns - * @return \LdapRecord\Query\Collection */ - public function findManyByAnr(array $values = [], $columns = ['*']) + public function findManyByAnr(array $values = [], array|string $columns = ['*']): Collection { $this->select($columns); @@ -224,13 +241,10 @@ class Builder extends BaseBuilder /** * Creates an ANR equivalent query for LDAP distributions that do not support ANR. - * - * @param string $value - * @return $this */ - protected function prepareAnrEquivalentQuery($value) + protected function prepareAnrEquivalentQuery(string $value): static { - return $this->orFilter(function (self $query) use ($value) { + return $this->orFilter(function (BaseBuilder $query) use ($value) { foreach ($this->model->getAnrAttributes() as $attribute) { $query->whereEquals($attribute, $value); } @@ -239,35 +253,25 @@ class Builder extends BaseBuilder /** * Finds a record by its string GUID. - * - * @param string $guid - * @param array|string $columns - * @return Model|static|null */ - public function findByGuid($guid, $columns = ['*']) + public function findByGuid(string $guid, array|string $columns = ['*']): ?Model { try { return $this->findByGuidOrFail($guid, $columns); } catch (ModelNotFoundException $e) { - return; + return null; } } /** - * Finds a record by its string GUID. - * - * Fails upon no records returned. - * - * @param string $guid - * @param array|string $columns - * @return Model|static + * Finds a record by its string GUID or throw an exception. * * @throws ModelNotFoundException */ - public function findByGuidOrFail($guid, $columns = ['*']) + public function findByGuidOrFail(string $guid, array|string $columns = ['*']): Model { if ($this->model instanceof ActiveDirectory) { - $guid = Utilities::stringGuidToHex($guid); + $guid = (new Guid($guid))->getEncodedHex(); } return $this->whereRaw([ @@ -276,22 +280,17 @@ class Builder extends BaseBuilder } /** - * @inheritdoc + * {@inheritdoc} */ - public function getQuery() + public function getQuery(): string { - return $this->afterScopes(function () { - return parent::getQuery(); - }); + return $this->afterScopes(fn () => parent::getQuery()); } /** * Apply the query scopes and execute the callback. - * - * @param Closure $callback - * @return mixed */ - protected function afterScopes(Closure $callback) + protected function afterScopes(Closure $callback): mixed { $this->applyScopes(); @@ -300,10 +299,8 @@ class Builder extends BaseBuilder /** * Apply the global query scopes. - * - * @return $this */ - public function applyScopes() + public function applyScopes(): static { if (! $this->scopes) { return $this; @@ -326,12 +323,8 @@ class Builder extends BaseBuilder /** * Register a new global scope. - * - * @param string $identifier - * @param Scope|\Closure $scope - * @return $this */ - public function withGlobalScope($identifier, $scope) + public function withGlobalScope(string $identifier, Scope|Closure $scope): static { $this->scopes[$identifier] = $scope; @@ -340,11 +333,8 @@ class Builder extends BaseBuilder /** * Remove a registered global scope. - * - * @param Scope|string $scope - * @return $this */ - public function withoutGlobalScope($scope) + public function withoutGlobalScope(Scope|string $scope): static { if (! is_string($scope)) { $scope = get_class($scope); @@ -359,11 +349,8 @@ class Builder extends BaseBuilder /** * Remove all or passed registered global scopes. - * - * @param array|null $scopes - * @return $this */ - public function withoutGlobalScopes(array $scopes = null) + public function withoutGlobalScopes(?array $scopes = null): static { if (! is_array($scopes)) { $scopes = array_keys($this->scopes); @@ -378,51 +365,44 @@ class Builder extends BaseBuilder /** * Get an array of global scopes that were removed from the query. - * - * @return array */ - public function removedScopes() + public function removedScopes(): array { return $this->removedScopes; } /** * Get an array of the global scopes that were applied to the query. - * - * @return array */ - public function appliedScopes() + public function appliedScopes(): array { return $this->appliedScopes; } /** * Processes and converts the given LDAP results into models. - * - * @param array $results - * @return \LdapRecord\Query\Collection */ - protected function process(array $results) + protected function process(array $results): Collection { return $this->model->hydrate(parent::process($results)); } /** - * @inheritdoc + * {@inheritdoc} */ - protected function prepareWhereValue($field, $value, $raw = false) + protected function prepareWhereValue(string $field, mixed $value = null, $raw = false): string { if ($value instanceof DateTime) { $field = $this->model->normalizeAttributeKey($field); if (! $this->model->isDateAttribute($field)) { - throw new \UnexpectedValueException( + throw new UnexpectedValueException( "Cannot convert field [$field] to an LDAP timestamp. You must add this field as a model date." - .' Refer to https://ldaprecord.com/docs/core/v2/model-mutators/#date-mutators' + .' Refer to https://ldaprecord.com/docs/core/v3/model-mutators/#date-mutators' ); } - $value = $this->model->fromDateTime($this->model->getDates()[$field], $value); + $value = $this->model->fromDateTime($value, $this->model->getDates()[$field]); } return parent::prepareWhereValue($field, $value, $raw); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php index 5e3d43fef..cac5ac30b 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php @@ -6,20 +6,16 @@ class FreeIpaBuilder extends Builder { /** * Adds a enabled filter to the current query. - * - * @return $this */ - public function whereEnabled() + public function whereEnabled(): static { return $this->rawFilter('(!(pwdAccountLockedTime=*))'); } /** * Adds a disabled filter to the current query. - * - * @return $this */ - public function whereDisabled() + public function whereDisabled(): static { return $this->rawFilter('(pwdAccountLockedTime=*)'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php index dd41344b7..e0a8d5ebc 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php @@ -6,20 +6,16 @@ class OpenLdapBuilder extends Builder { /** * Adds a enabled filter to the current query. - * - * @return $this */ - public function whereEnabled() + public function whereEnabled(): static { return $this->rawFilter('(!(pwdAccountLockedTime=*))'); } /** * Adds a disabled filter to the current query. - * - * @return $this */ - public function whereDisabled() + public function whereDisabled(): static { return $this->rawFilter('(pwdAccountLockedTime=*)'); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php index 0ece752cf..79ed1e3ef 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php @@ -4,6 +4,4 @@ namespace LdapRecord\Query; use LdapRecord\LdapRecordException; -class MultipleObjectsFoundException extends LdapRecordException -{ -} +class MultipleObjectsFoundException extends LdapRecordException {} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php index 99c2e85e3..8fb22a218 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php @@ -8,38 +8,26 @@ class ObjectNotFoundException extends LdapRecordException { /** * The query filter that was used. - * - * @var string */ - protected $query; + protected string $query; /** * The base DN of the query that was used. - * - * @var string */ - protected $baseDn; + protected ?string $baseDn; /** * Create a new exception for the executed filter. - * - * @param string $query - * @param ?string $baseDn - * @return static */ - public static function forQuery($query, $baseDn = null) + public static function forQuery(string $query, ?string $baseDn = null): static { - return (new static())->setQuery($query, $baseDn); + return (new static)->setQuery($query, $baseDn); } /** * Set the query that was used. - * - * @param string $query - * @param string|null $baseDn - * @return $this */ - public function setQuery($query, $baseDn = null) + public function setQuery(string $query, ?string $baseDn = null): static { $this->query = $query; $this->baseDn = $baseDn; diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php index a9846005c..85edb7f00 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php @@ -4,6 +4,4 @@ namespace LdapRecord\Query; use LdapRecord\LdapRecordException; -class ObjectsNotFoundException extends LdapRecordException -{ -} +class ObjectsNotFoundException extends LdapRecordException {} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php index 11e2dc547..c55677314 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php @@ -9,38 +9,28 @@ abstract class AbstractPaginator { /** * The query builder instance. - * - * @var Builder */ - protected $query; + protected Builder $query; /** * The filter to execute. - * - * @var string */ - protected $filter; + protected string $filter; /** * The amount of objects to fetch per page. - * - * @var int */ - protected $perPage; + protected int $perPage; /** * Whether the operation is critical. - * - * @var bool */ - protected $isCritical; + protected bool $isCritical; /** * Constructor. - * - * @param Builder $query */ - public function __construct(Builder $query, $filter, $perPage, $isCritical) + public function __construct(Builder $query, string $filter, int $perPage, bool $isCritical = false) { $this->query = $query; $this->filter = $filter; @@ -50,11 +40,8 @@ abstract class AbstractPaginator /** * Execute the pagination request. - * - * @param LdapInterface $ldap - * @return array */ - public function execute(LdapInterface $ldap) + public function execute(LdapInterface $ldap): mixed { $pages = []; @@ -78,53 +65,37 @@ abstract class AbstractPaginator } /** - * Whether the paginater should continue iterating. - * - * @return bool + * Whether the paginator should continue iterating. */ - protected function shouldContinue() + protected function shouldContinue(): bool { - $cookie = (string) $this->fetchCookie(); + $cookie = $this->fetchCookie(); return $cookie !== ''; } /** * Fetch the pagination cookie. - * - * @return string */ - abstract protected function fetchCookie(); + abstract protected function fetchCookie(): ?string; /** * Prepare the server controls before executing the pagination request. - * - * @return void */ - abstract protected function prepareServerControls(); + abstract protected function prepareServerControls(): void; /** * Apply the server controls. - * - * @param LdapInterface $ldap - * @return void */ - abstract protected function applyServerControls(LdapInterface $ldap); + abstract protected function applyServerControls(LdapInterface $ldap): void; /** * Reset the server controls. - * - * @param LdapInterface $ldap - * @return void */ - abstract protected function resetServerControls(LdapInterface $ldap); + abstract protected function resetServerControls(LdapInterface $ldap): void; /** * Update the server controls. - * - * @param LdapInterface $ldap - * @param resource $resource - * @return void */ - abstract protected function updateServerControls(LdapInterface $ldap, $resource); + abstract protected function updateServerControls(LdapInterface $ldap, mixed $resource): void; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php deleted file mode 100644 index b4a7f8db9..000000000 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php +++ /dev/null @@ -1,58 +0,0 @@ -cookie; - } - - /** - * @inheritdoc - */ - protected function prepareServerControls() - { - $this->cookie = ''; - } - - /** - * @inheritdoc - */ - protected function applyServerControls(LdapInterface $ldap) - { - $ldap->controlPagedResult($this->perPage, $this->isCritical, $this->cookie); - } - - /** - * @inheritdoc - */ - protected function updateServerControls(LdapInterface $ldap, $resource) - { - $ldap->controlPagedResultResponse($resource, $this->cookie); - } - - /** - * @inheritdoc - */ - protected function resetServerControls(LdapInterface $ldap) - { - $ldap->controlPagedResult(); - } -} diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php index 8b12d526c..d770259ed 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php @@ -2,17 +2,15 @@ namespace LdapRecord\Query\Pagination; +use Generator; use LdapRecord\LdapInterface; class LazyPaginator extends Paginator { /** * Execute the pagination request. - * - * @param LdapInterface $ldap - * @return \Generator */ - public function execute(LdapInterface $ldap) + public function execute(LdapInterface $ldap): Generator { $this->prepareServerControls(); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php index c0a31afd9..50671a77a 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php @@ -7,17 +7,17 @@ use LdapRecord\LdapInterface; class Paginator extends AbstractPaginator { /** - * @inheritdoc + * {@inheritdoc} */ - protected function fetchCookie() + protected function fetchCookie(): ?string { return $this->query->controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? null; } /** - * @inheritdoc + * {@inheritdoc} */ - protected function prepareServerControls() + protected function prepareServerControls(): void { $this->query->addControl(LDAP_CONTROL_PAGEDRESULTS, $this->isCritical, [ 'size' => $this->perPage, 'cookie' => '', @@ -25,31 +25,27 @@ class Paginator extends AbstractPaginator } /** - * @inheritdoc + * {@inheritdoc} */ - protected function applyServerControls(LdapInterface $ldap) + protected function applyServerControls(LdapInterface $ldap): void { $ldap->setOption(LDAP_OPT_SERVER_CONTROLS, $this->query->controls); } /** - * @inheritdoc + * {@inheritdoc} */ - protected function updateServerControls(LdapInterface $ldap, $resource) + protected function updateServerControls(LdapInterface $ldap, mixed $resource): void { - $errorCode = 0; - $dn = $errorMessage = $refs = null; $controls = $this->query->controls; - $ldap->parseResult( - $resource, - $errorCode, - $dn, - $errorMessage, - $refs, - $controls + $response = $ldap->parseResult( + result: $resource, + controls: $controls ); + $controls = array_merge($controls, $response->controls ?? []); + $cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? ''; $this->query->controls[LDAP_CONTROL_PAGEDRESULTS]['value'] = [ @@ -59,9 +55,9 @@ class Paginator extends AbstractPaginator } /** - * @inheritdoc + * {@inheritdoc} */ - protected function resetServerControls(LdapInterface $ldap) + protected function resetServerControls(LdapInterface $ldap): void { unset($this->query->controls[LDAP_CONTROL_PAGEDRESULTS]); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php index 12faa5bd1..2921724ca 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php @@ -10,49 +10,34 @@ use JsonSerializable; class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable { /** - * All of the items being paginated. - * - * @var \LdapRecord\Query\Collection|array + * All the items in the slice. */ - protected $items; + protected Collection|array $items; /** * The number of items to be shown per page. - * - * @var int */ - protected $perPage; + protected int $perPage; /** * The total number of items before slicing. - * - * @var int */ - protected $total; + protected int $total; /** * The last available page. - * - * @var int */ - protected $lastPage; + protected int $lastPage; /** * The current page being "viewed". - * - * @var int */ - protected $currentPage; + protected int $currentPage; /** * Constructor. - * - * @param \LdapRecord\Query\Collection|array $items - * @param int $total - * @param int $perPage - * @param int|null $currentPage */ - public function __construct($items, $total, $perPage, $currentPage = null) + public function __construct(Collection|array $items, int $total, int $perPage, ?int $currentPage = null) { $this->items = $items; $this->total = $total; @@ -63,202 +48,159 @@ class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable /** * Get the slice of items being paginated. - * - * @return \LdapRecord\Query\Collection|array */ - public function items() + public function items(): Collection|array { return $this->items; } /** * Get the total number of items being paginated. - * - * @return int */ - public function total() + public function total(): int { return $this->total; } /** * Get the number of items shown per page. - * - * @return int */ - public function perPage() + public function perPage(): int { return $this->perPage; } /** * Determine if there are more items in the data source. - * - * @return bool */ - public function hasMorePages() + public function hasMorePages(): bool { return $this->currentPage() < $this->lastPage(); } /** * Determine if there are enough items to split into multiple pages. - * - * @return bool */ - public function hasPages() + public function hasPages(): bool { return $this->currentPage() != 1 || $this->hasMorePages(); } /** * Determine if the paginator is on the first page. - * - * @return bool */ - public function onFirstPage() + public function onFirstPage(): bool { return $this->currentPage() <= 1; } /** * Determine if the paginator is on the last page. - * - * @return bool */ - public function onLastPage() + public function onLastPage(): bool { return ! $this->hasMorePages(); } /** * Get the current page. - * - * @return int */ - public function currentPage() + public function currentPage(): int { return $this->currentPage; } /** * Get the last page. - * - * @return int */ - public function lastPage() + public function lastPage(): int { return $this->lastPage; } /** * Get an iterator for the items. - * - * @return \ArrayIterator */ #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ArrayIterator { return new ArrayIterator($this->items); } /** * Determine if the list of items is empty. - * - * @return bool */ - public function isEmpty() + public function isEmpty(): bool { return empty($this->items); } /** * Determine if the list of items is not empty. - * - * @return bool */ - public function isNotEmpty() + public function isNotEmpty(): bool { return ! $this->isEmpty(); } /** * Get the number of items for the current page. - * - * @return int */ #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->items); } /** * Determine if the given item exists. - * - * @param mixed $key - * @return bool */ #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists(mixed $offset): bool { - return array_key_exists($key, $this->items); + return array_key_exists($offset, $this->items); } /** * Get the item at the given offset. - * - * @param mixed $key - * @return mixed */ #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet(mixed $offset): mixed { - return $this->items[$key] ?? null; + return $this->items[$offset] ?? null; } /** * Set the item at the given offset. - * - * @param mixed $key - * @param mixed $value - * @return void */ #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet(mixed $offset, mixed $value): void { - $this->items[$key] = $value; + $this->items[$offset] = $value; } /** * Unset the item at the given key. - * - * @param mixed $key - * @return void */ #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset(mixed $offset): void { - unset($this->items[$key]); + unset($this->items[$offset]); } /** * Convert the object into something JSON serializable. - * - * @return array */ #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } /** * Get the arrayable items. - * - * @return array */ - public function getArrayableItems() + public function getArrayableItems(): array { return $this->items instanceof Collection ? $this->items->all() @@ -267,10 +209,8 @@ class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable /** * Get the instance as an array. - * - * @return array */ - public function toArray() + public function toArray(): array { return [ 'current_page' => $this->currentPage(), diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php index 7475859ae..6c3217a50 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php @@ -8,23 +8,16 @@ class Arr { /** * Determine whether the given value is array accessible. - * - * @param mixed $value - * @return bool */ - public static function accessible($value) + public static function accessible(mixed $value): bool { return is_array($value) || $value instanceof ArrayAccess; } /** * Determine if the given key exists in the provided array. - * - * @param \ArrayAccess|array $array - * @param string|int $key - * @return bool */ - public static function exists($array, $key) + public static function exists(ArrayAccess|array $array, string|int $key): bool { if ($array instanceof ArrayAccess) { return $array->offsetExists($key); @@ -35,11 +28,8 @@ class Arr /** * If the given value is not an array and not null, wrap it in one. - * - * @param mixed $value - * @return array */ - public static function wrap($value) + public static function wrap(mixed $value): array { if (is_null($value)) { return []; @@ -49,14 +39,9 @@ class Arr } /** - * Return the first element in an array passing a given truth test. - * - * @param iterable $array - * @param callable|null $callback - * @param mixed $default - * @return mixed + * Get the first element in an array passing a given truth test. */ - public static function first($array, callable $callback = null, $default = null) + public static function first(iterable $array, ?callable $callback = null, mixed $default = null): mixed { if (is_null($callback)) { if (empty($array)) { @@ -78,14 +63,11 @@ class Arr } /** - * Return the last element in an array passing a given truth test. + * Get the last element in an array passing a given truth test. * * @param array $array - * @param callable|null $callback - * @param mixed $default - * @return mixed */ - public static function last($array, callable $callback = null, $default = null) + public static function last(iterable $array, ?callable $callback = null, mixed $default = null): mixed { if (is_null($callback)) { return empty($array) ? Helpers::value($default) : end($array); @@ -96,13 +78,8 @@ class Arr /** * Get an item from an array using "dot" notation. - * - * @param ArrayAccess|array $array - * @param string|int|null $key - * @param mixed $default - * @return mixed */ - public static function get($array, $key, $default = null) + public static function get(ArrayAccess|array $array, string|int|null $key, mixed $default = null): mixed { if (! static::accessible($array)) { return Helpers::value($default); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php index ab217d6ff..5b4bd46fb 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php @@ -7,13 +7,9 @@ use Closure; class Helpers { /** - * Return the default value of the given value. - * - * @param mixed $value - * @param mixed $args - * @return mixed + * Get the default value of the given value. */ - public static function value($value, ...$args) + public static function value(mixed $value, mixed ...$args): mixed { return $value instanceof Closure ? $value(...$args) : $value; } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php index 820834e21..ced2a5fd1 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php @@ -5,19 +5,49 @@ namespace LdapRecord\Support; class Str { /** - * Return the remainder of a string after the last occurrence of a given value. - * - * @param string $subject - * @param string $search - * @return string + * Determine if a given string matches a given pattern. */ - public static function afterLast($subject, $search) + public static function is(string|iterable $pattern, string $value): bool + { + if (! is_iterable($pattern)) { + $pattern = [$pattern]; + } + + foreach ($pattern as $pattern) { + $pattern = (string) $pattern; + + // If the given value is an exact match we can of course return true right + // from the beginning. Otherwise, we will translate asterisks and do an + // actual pattern match against the two strings to see if they match. + if ($pattern === $value) { + return true; + } + + $pattern = preg_quote($pattern, '#'); + + // Asterisks are translated into zero-or-more regular expression wildcards + // to make it convenient to check if the strings starts with the given + // pattern such as "library/*", making any string check convenient. + $pattern = str_replace('\*', '.*', $pattern); + + if (preg_match('#^'.$pattern.'\z#u', $value) === 1) { + return true; + } + } + + return false; + } + + /** + * Get the remainder of a string after the last occurrence of a given value. + */ + public static function afterLast(string $subject, string $search): string { if ($search === '') { return $subject; } - $position = strrpos($subject, (string) $search); + $position = strrpos($subject, $search); if ($position === false) { return $subject; @@ -28,12 +58,8 @@ class Str /** * Determine if a given string starts with a given substring. - * - * @param string $haystack - * @param string|string[] $needles - * @return bool */ - public static function startsWith($haystack, $needles) + public static function startsWith(string $haystack, array|string $needles): bool { foreach ((array) $needles as $needle) { if ((string) $needle !== '' && str_starts_with($haystack, $needle)) { @@ -46,12 +72,8 @@ class Str /** * Determine if a given string ends with a given substring. - * - * @param string $haystack - * @param string|string[] $needles - * @return bool */ - public static function endsWith($haystack, $needles) + public static function endsWith(string $haystack, array|string $needles): bool { foreach ((array) $needles as $needle) { if ( @@ -67,14 +89,8 @@ class Str /** * Execute a callback when a needle is found in the haystack. - * - * @param string $haystack - * @param string|string[] $needles - * @param \Closure|mixed $callback - * @param \Closure|mixed $default - * @return mixed */ - public static function whenContains($haystack, $needles, $callback, $default = null) + public static function whenContains(string $haystack, array|string $needles, mixed $callback, mixed $default = null): mixed { foreach ((array) $needles as $needle) { if (static::contains($haystack, $needle)) { @@ -87,13 +103,8 @@ class Str /** * Determine if a given string contains a given substring. - * - * @param string $haystack - * @param string|string[] $needles - * @param bool $ignoreCase - * @return bool */ - public static function contains($haystack, $needles, $ignoreCase = false) + public static function contains(string $haystack, array|string $needles, bool $ignoreCase = false): bool { if ($ignoreCase) { $haystack = mb_strtolower($haystack); @@ -110,15 +121,9 @@ class Str } /** - * Returns the number of substring occurrences. - * - * @param string $haystack - * @param string $needle - * @param int $offset - * @param int|null $length - * @return int + * Get the number of substring occurrences. */ - public static function substrCount($haystack, $needle, $offset = 0, $length = null) + public static function substrCount(string $haystack, string $needle, int $offset = 0, ?int $length = null): int { if (! is_null($length)) { return substr_count($haystack, $needle, $offset, $length); diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php index 4a691506d..36574c0d5 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php @@ -8,11 +8,6 @@ class AuthGuardFake extends Guard { /** * Always allow binding as configured user. - * - * @return bool */ - public function bindAsConfiguredUser() - { - return true; - } + public function bindAsConfiguredUser(): void {} } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php index 09530f5c7..2c76a06d5 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php @@ -4,6 +4,7 @@ namespace LdapRecord\Testing; use LdapRecord\Auth\Guard; use LdapRecord\Connection; +use LdapRecord\LdapInterface; use LdapRecord\Models\Model; class ConnectionFake extends Connection @@ -13,25 +14,19 @@ class ConnectionFake extends Connection * * @var LdapFake */ - protected $ldap; + protected LdapInterface $ldap; /** * Whether the fake is connected. - * - * @var bool */ - protected $connected = false; + protected bool $connected = false; /** * Make a new fake LDAP connection instance. - * - * @param array $config - * @param string $ldap - * @return static */ - public static function make(array $config = [], $ldap = LdapFake::class) + public static function make(array $config = [], string $ldap = LdapFake::class): static { - $connection = new static($config, new $ldap()); + $connection = new static($config, new $ldap); $connection->configure(); @@ -40,13 +35,10 @@ class ConnectionFake extends Connection /** * Set the user to authenticate as. - * - * @param Model|string $user - * @return $this */ - public function actingAs($user) + public function actingAs(Model|string $user): static { - $this->ldap->shouldAuthenticateWith( + $this->ldap->shouldAllowBindWith( $user instanceof Model ? $user->getDn() : $user ); @@ -55,10 +47,8 @@ class ConnectionFake extends Connection /** * Set the connection to bypass bind attempts as the configured user. - * - * @return $this */ - public function shouldBeConnected() + public function shouldBeConnected(): static { $this->connected = true; @@ -71,10 +61,8 @@ class ConnectionFake extends Connection /** * Set the connection to attempt binding as the configured user. - * - * @return $this */ - public function shouldNotBeConnected() + public function shouldNotBeConnected(): static { $this->connected = false; @@ -86,10 +74,20 @@ class ConnectionFake extends Connection } /** - * @inheritdoc + * {@inheritdoc} */ - public function isConnected() + public function isConnected(): bool { return $this->connected ?: parent::isConnected(); } + + /** + * Perform tear down tasks on the fake. + * + * @throws LdapExpectationException + */ + public function tearDown(): void + { + $this->ldap->assertMinimumExpectationCounts(); + } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php index 72be02af3..90cbf7ae6 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php @@ -7,44 +7,50 @@ use LdapRecord\Container; class DirectoryFake { /** - * Setup the fake connection. + * The LDAP connections that were replaced with fakes. * - * @param string|null $name - * @return ConnectionFake + * @var \LdapRecord\Connection[] + */ + protected static array $replaced = []; + + /** + * Replace a connection a fake. * * @throws \LdapRecord\ContainerException */ - public static function setup($name = null) + public static function setup(?string $name = null): ConnectionFake { - $connection = Container::getConnection($name); + $name = $name ?? Container::getDefaultConnectionName(); + + $connection = static::$replaced[$name] = Container::getConnection($name); $fake = static::makeConnectionFake( $connection->getConfiguration()->all() ); - // Replace the connection with a fake. Container::addConnection($fake, $name); return $fake; } /** - * Reset the container. - * - * @return void + * Replace all faked connections with their original. */ - public static function tearDown() + public static function tearDown(): void { - Container::reset(); + foreach (static::$replaced as $name => $connection) { + Container::getConnection($name)->tearDown(); + } + + Container::flush(); + + static::$replaced = []; } /** * Make a connection fake. - * - * @param array $config - * @return ConnectionFake */ - public static function makeConnectionFake(array $config = []) + public static function makeConnectionFake(array $config = []): ConnectionFake { return ConnectionFake::make($config)->shouldBeConnected(); } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php index 693459149..2e010d7d7 100644 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php @@ -3,7 +3,9 @@ namespace LdapRecord\Testing; use Closure; +use Exception; use LdapRecord\LdapRecordException; +use LdapRecord\LdapResultResponse; use PHPUnit\Framework\Constraint\Callback; use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\IsEqual; @@ -13,91 +15,76 @@ class LdapExpectation { /** * The value to return from the expectation. - * - * @var mixed */ - protected $value; + protected mixed $value = null; /** * The exception to throw from the expectation. - * - * @var null|LdapRecordException|\Exception */ - protected $exception; + protected ?Exception $exception = null; /** - * The amount of times the expectation should be called. - * - * @var int + * The tracked number of times the expectation should be called. */ - protected $count = 1; + protected int $count = 1; + + /** + * The original number of times the expectation should be called. + */ + protected int $originalCount = 1; + + /** + * The actual number of times the expectation was called. + */ + protected int $called = 0; /** * The method that the expectation belongs to. - * - * @var string */ - protected $method; + protected ?string $method = null; /** * The methods argument's. - * - * @var array */ - protected $args = []; + protected array $args = []; /** * Whether the same expectation should be returned indefinitely. - * - * @var bool */ - protected $indefinitely = true; + protected bool $indefinitely = true; /** - * Whether the expectation should return errors. - * - * @var bool + * Whether the expectation should return an error. */ - protected $errors = false; + protected bool $errors = false; /** - * The error number to return. - * - * @var int + * The error code to return. */ - protected $errorCode = 1; + protected int $errorCode = 1; /** - * The last error string to return. - * - * @var string + * The error message to return. */ - protected $errorMessage = ''; + protected string $errorMessage = 'Unknown error'; /** * The diagnostic message string to return. - * - * @var string */ - protected $errorDiagnosticMessage = ''; + protected ?string $errorDiagnosticMessage = null; /** * Constructor. - * - * @param string $method */ - public function __construct($method) + public function __construct(string $method) { $this->method = $method; } /** * Set the arguments that the operation should receive. - * - * @param mixed $args - * @return $this */ - public function with($args) + public function with(mixed $args): static { $this->args = array_map(function ($arg) { if ($arg instanceof Closure) { @@ -116,11 +103,8 @@ class LdapExpectation /** * Set the expected value to return. - * - * @param mixed $value - * @return $this */ - public function andReturn($value) + public function andReturn(mixed $value): static { $this->value = $value; @@ -128,31 +112,62 @@ class LdapExpectation } /** - * The error message to return from the expectation. - * - * @param int $code - * @param string $error - * @param string $diagnosticMessage - * @return $this + * Set the expected value to return true. */ - public function andReturnError($code = 1, $error = '', $diagnosticMessage = '') + public function andReturnTrue(): static + { + return $this->andReturn(true); + } + + /** + * Set the expected value to return false. + */ + public function andReturnFalse(): static + { + return $this->andReturn(false); + } + + /** + * The error message to return from the expectation. + */ + public function andReturnError(int $errorCode = 1, string $errorMessage = 'Unknown error', ?string $diagnosticMessage = null): static { $this->errors = true; - $this->errorCode = $code; - $this->errorMessage = $error; + $this->errorCode = $errorCode; + $this->errorMessage = $errorMessage; $this->errorDiagnosticMessage = $diagnosticMessage; return $this; } /** - * Set the expected exception to throw. - * - * @param string|\Exception|LdapRecordException $exception - * @return $this + * Return an error LDAP result response. */ - public function andThrow($exception) + public function andReturnErrorResponse(int $code = 1, ?string $errorMessage = null): static + { + return $this->andReturnResponse($code, $errorMessage); + } + + /** + * Return an LDAP result response. + */ + public function andReturnResponse( + int $errorCode = 0, + ?string $matchedDn = null, + ?string $errorMessage = null, + array $referrals = [], + array $controls = [] + ): static { + return $this->andReturn( + new LdapResultResponse($errorCode, $matchedDn, $errorMessage, $referrals, $controls) + ); + } + + /** + * Set the expected exception to throw. + */ + public function andThrow(string|Exception $exception): static { if (is_string($exception)) { $exception = new LdapRecordException($exception); @@ -165,45 +180,36 @@ class LdapExpectation /** * Set the expectation to be only called once. - * - * @return $this */ - public function once() + public function once(): static { - return $this->times(1); + return $this->times(); } /** * Set the expectation to be only called twice. - * - * @return $this */ - public function twice() + public function twice(): static { return $this->times(2); } /** * Set the expectation to be called the given number of times. - * - * @param int $count - * @return $this */ - public function times($count = 1) + public function times(int $count = 1): static { $this->indefinitely = false; - $this->count = $count; + $this->originalCount = $this->count = $count; return $this; } /** * Get the method the expectation belongs to. - * - * @return string */ - public function getMethod() + public function getMethod(): string { if (is_null($this->method)) { throw new UnexpectedValueException('An expectation must have a method.'); @@ -214,89 +220,105 @@ class LdapExpectation /** * Get the expected call count. - * - * @return int */ - public function getExpectedCount() + public function getExpectedCount(): int { return $this->count; } + /** + * Get the original expected call count. + */ + public function getOriginalExpectedCount(): int + { + return $this->originalCount; + } + + /** + * Get the count that the expectation was called. + */ + public function getCalledCount(): int + { + return $this->called; + } + /** * Get the expected arguments. * * @return Constraint[] */ - public function getExpectedArgs() + public function getExpectedArgs(): array { return $this->args; } /** * Get the expected exception. - * - * @return null|\Exception|LdapRecordException */ - public function getExpectedException() + public function getExpectedException(): ?Exception { return $this->exception; } /** * Get the expected value. - * - * @return mixed */ - public function getExpectedValue() + public function getExpectedValue(): mixed { return $this->value; } /** - * Determine whether the expectation is returning an error. - * - * @return bool + * Determine whether the expectation can be called indefinitely. */ - public function isReturningError() + public function isIndefinite(): bool + { + return $this->indefinitely; + } + + /** + * Determine whether the expectation is returning an error. + */ + public function isReturningError(): bool { return $this->errors; } /** - * @return int + * Get the expected error code. */ - public function getExpectedErrorCode() + public function getExpectedErrorCode(): int { return $this->errorCode; } /** - * @return string + * Get the expected error message. */ - public function getExpectedErrorMessage() + public function getExpectedErrorMessage(): ?string { return $this->errorMessage; } /** - * @return string + * Get the expected diagnostic message. */ - public function getExpectedErrorDiagnosticMessage() + public function getExpectedErrorDiagnosticMessage(): ?string { return $this->errorDiagnosticMessage; } /** - * Decrement the call count of the expectation. - * - * @return $this + * Decrement the expected count of the expectation. */ - public function decrementCallCount() + public function decrementExpectedCount(): static { if (! $this->indefinitely) { $this->count -= 1; } + $this->called++; + return $this; } } diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php new file mode 100644 index 000000000..74a3ebe33 --- /dev/null +++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php @@ -0,0 +1,7 @@ + */ - protected $expectations = []; + protected array $expectations = []; /** * The default fake error number. - * - * @var int */ - protected $errNo = 1; + protected int $errNo = 1; /** * The default fake last error string. - * - * @var string */ - protected $lastError = ''; + protected string $lastError = 'Unknown error'; /** * The default fake diagnostic message string. - * - * @var string */ - protected $diagnosticMessage = ''; + protected ?string $diagnosticMessage = null; /** * Create a new expected operation. - * - * @param string $method - * @return LdapExpectation */ - public static function operation($method) + public static function operation(string $method): LdapExpectation { return new LdapExpectation($method); } /** - * Set the user that will pass binding. - * - * @param string $dn - * @return $this + * Set the fake LDAP host. */ - public function shouldAuthenticateWith($dn) + public function setHost(string $host): void { - return $this->expect( - static::operation('bind')->with($dn, PHPUnit::anything())->andReturn(true) - ); + $this->host = $host; } /** * Add an LDAP method expectation. - * - * @param LdapExpectation|array $expectations - * @return $this */ - public function expect($expectations = []) + public function expect(LdapExpectation|array $expectations = []): static { $expectations = Arr::wrap($expectations); @@ -101,11 +85,8 @@ class LdapFake implements LdapInterface /** * Determine if the method has any expectations. - * - * @param string $method - * @return bool */ - public function hasExpectations($method) + public function hasExpectations(string $method): bool { return count($this->getExpectations($method)) > 0; } @@ -113,33 +94,55 @@ class LdapFake implements LdapInterface /** * Get expectations by method. * - * @param string $method - * @return LdapExpectation[]|mixed + * @return LdapExpectation[] */ - public function getExpectations($method) + public function getExpectations(string $method): array { return $this->expectations[$method] ?? []; } /** * Remove an expectation by method and key. - * - * @param string $method - * @param int $key - * @return void */ - public function removeExpectation($method, $key) + public function removeExpectation(string $method, int $key): void { unset($this->expectations[$method][$key]); } /** - * Set the error number of a failed bind attempt. - * - * @param int $number - * @return $this + * Set the fake to allow any bind attempt. */ - public function shouldReturnErrorNumber($number = 1) + public function shouldAllowAnyBind(): static + { + return $this->expect( + static::operation('bind')->andReturnResponse() + ); + } + + /** + * Set the fake to allow any bind attempt with the given DN. + */ + public function shouldAllowBindWith(string $dn): static + { + return $this->expect( + static::operation('bind')->with($dn, PHPUnit::anything())->andReturnResponse() + ); + } + + /** + * Set the user that will pass binding. + * + * @deprecated Use shouldAllowBindWith instead. + */ + public function shouldAuthenticateWith(string $dn): static + { + return $this->shouldAllowBindWith($dn); + } + + /** + * Set the error number of a failed bind attempt. + */ + public function shouldReturnErrorNumber(int $number = 1): static { $this->errNo = $number; @@ -148,11 +151,8 @@ class LdapFake implements LdapInterface /** * Set the last error of a failed bind attempt. - * - * @param string $message - * @return $this */ - public function shouldReturnError($message = '') + public function shouldReturnError(string $message): static { $this->lastError = $message; @@ -161,11 +161,8 @@ class LdapFake implements LdapInterface /** * Set the diagnostic message of a failed bind attempt. - * - * @param string $message - * @return $this */ - public function shouldReturnDiagnosticMessage($message = '') + public function shouldReturnDiagnosticMessage(?string $message): static { $this->diagnosticMessage = $message; @@ -174,38 +171,32 @@ class LdapFake implements LdapInterface /** * Return a fake error number. - * - * @return int */ - public function errNo() + public function errNo(): int { return $this->errNo; } /** * Return a fake error. - * - * @return string */ - public function getLastError() + public function getLastError(): string { return $this->lastError; } /** - * @inheritdoc + * Return a fake diagnostic message. */ - public function getDiagnosticMessage() + public function getDiagnosticMessage(): ?string { return $this->diagnosticMessage; } /** * Return a fake detailed error. - * - * @return DetailedError */ - public function getDetailedError() + public function getDetailedError(): DetailedError { return new DetailedError( $this->errNo(), @@ -215,258 +206,309 @@ class LdapFake implements LdapInterface } /** - * @inheritdoc + * {@inheritdoc} */ - public function getEntries($searchResults) + public function getEntries(mixed $result): array { - return $searchResults; + return $result; } /** - * @inheritdoc + * {@inheritDoc} */ - public function isUsingSSL() + public function getValuesLen(mixed $entry, string $attribute): array|false { - return $this->hasExpectations('isUsingSSL') - ? $this->resolveExpectation('isUsingSSL') + return $this->resolveExpectation(__FUNCTION__, func_get_args()); + } + + /** + * {@inheritDoc} + */ + public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int + { + return $this->resolveExpectation(__FUNCTION__, func_get_args()); + } + + /** + * {@inheritDoc} + */ + public function setRebindCallback(callable $callback): bool + { + return $this->resolveExpectation(__FUNCTION__, func_get_args()); + } + + /** + * {@inheritDoc} + */ + public function getFirstEntry(mixed $result): mixed + { + return $this->executeFailableOperation(function () use ($result) { + return ldap_first_entry($this->connection, $result); + }); + } + + /** + * {@inheritDoc} + */ + public function getNextEntry(mixed $entry): mixed + { + return $this->executeFailableOperation(function () use ($entry) { + return ldap_next_entry($this->connection, $entry); + }); + } + + /** + * {@inheritDoc} + */ + public function getAttributes(mixed $entry): array|false + { + return $this->executeFailableOperation(function () use ($entry) { + return ldap_get_attributes($this->connection, $entry); + }); + } + + /** + * {@inheritDoc} + */ + public function countEntries(mixed $result): int + { + return $this->executeFailableOperation(function () use ($result) { + return ldap_count_entries($this->connection, $result); + }); + } + + /** + * {@inheritdoc} + */ + public function isUsingSSL(): bool + { + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__) : $this->useSSL; } /** - * @inheritdoc + * {@inheritdoc} */ - public function isUsingTLS() + public function isUsingTLS(): bool { - return $this->hasExpectations('isUsingTLS') - ? $this->resolveExpectation('isUsingTLS') + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__) : $this->useTLS; } /** - * @inheritdoc + * {@inheritdoc} */ - public function isBound() + public function isBound(): bool { - return $this->hasExpectations('isBound') - ? $this->resolveExpectation('isBound') + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__) : $this->bound; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getHost() + public function setOption(int $option, mixed $value): bool { - return $this->hasExpectations('getHost') - ? $this->resolveExpectation('getHost') - : $this->host; - } - - /** - * @inheritdoc - */ - public function setOption($option, $value) - { - return $this->hasExpectations('setOption') - ? $this->resolveExpectation('setOption', func_get_args()) + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__, func_get_args()) : true; } /** - * @inheritdoc + * {@inheritdoc} */ - public function getOption($option, &$value = null) + public function getOption(int $option, mixed &$value = null): mixed { - return $this->resolveExpectation('getOption', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function startTLS() + public function startTLS(): bool { - return $this->resolveExpectation('startTLS', func_get_args()); + return $this->secure = $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function connect($hosts = [], $port = 389) + public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool { $this->bound = false; - + $this->protocol = $protocol; $this->host = $this->makeConnectionUris($hosts, $port); - return $this->connection = $this->hasExpectations('connect') - ? $this->resolveExpectation('connect', func_get_args()) + return $this->connection = $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__, func_get_args()) : true; } /** - * @inheritdoc + * {@inheritdoc} */ - public function close() + public function close(): bool { - $this->connection = null; $this->bound = false; - $this->host = null; + $this->secure = false; - return $this->hasExpectations('close') - ? $this->resolveExpectation('close') + $this->host = null; + $this->protocol = null; + $this->connection = null; + + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__) : true; } /** - * @inheritdoc + * {@inheritdoc} */ - public function bind($username, $password) + public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse { - return $this->bound = $this->resolveExpectation('bind', func_get_args()); + $result = $this->resolveExpectation(__FUNCTION__, func_get_args()); + + $this->handleBindResponse($result); + + return $result; } /** - * @inheritdoc + * {@inheritDoc} */ - public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function saslBind(?string $dn = null, ?string $password = null, ?array $options = null): bool { - return $this->resolveExpectation('search', func_get_args()); + return $this->bound = $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { - return $this->resolveExpectation('listing', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []) + public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { - return $this->resolveExpectation('read', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = []) + public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed { - return $this->resolveExpectation('parseResult', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function add($dn, array $entry) + public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false { - return $this->resolveExpectation('add', func_get_args()); + return $this->hasExpectations(__FUNCTION__) + ? $this->resolveExpectation(__FUNCTION__, func_get_args()) + : new LdapResultResponse; } /** - * @inheritdoc + * {@inheritdoc} */ - public function delete($dn) + public function add(string $dn, array $entry): bool { - return $this->resolveExpectation('delete', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false) + public function delete(string $dn): bool { - return $this->resolveExpectation('rename', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function modify($dn, array $entry) + public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool { - return $this->resolveExpectation('modify', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function modifyBatch($dn, array $values) + public function modify(string $dn, array $entry): bool { - return $this->resolveExpectation('modifyBatch', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function modAdd($dn, array $entry) + public function modifyBatch(string $dn, array $values): bool { - return $this->resolveExpectation('modAdd', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function modReplace($dn, array $entry) + public function modAdd(string $dn, array $entry): bool { - return $this->resolveExpectation('modReplace', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function modDelete($dn, array $entry) + public function modReplace(string $dn, array $entry): bool { - return $this->resolveExpectation('modDelete', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '') + public function modDelete(string $dn, array $entry): bool { - return $this->resolveExpectation('controlPagedResult', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function controlPagedResultResponse($result, &$cookie) + public function freeResult(mixed $result): bool { - return $this->resolveExpectation('controlPagedResultResponse', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** - * @inheritdoc + * {@inheritdoc} */ - public function freeResult($result) + public function err2Str(int $number): string { - return $this->resolveExpectation('freeResult', func_get_args()); - } - - /** - * @inheritdoc - */ - public function err2Str($number) - { - return $this->resolveExpectation('err2Str', func_get_args()); + return $this->resolveExpectation(__FUNCTION__, func_get_args()); } /** * Resolve the methods expectations. * - * @param string $method - * @param array $args - * @return mixed - * - * @throws Exception + * @throws LdapExpectationException */ - protected function resolveExpectation($method, array $args = []) + protected function resolveExpectation(string $method, array $args = []): mixed { foreach ($this->getExpectations($method) as $key => $expectation) { $this->assertMethodArgumentsMatch($method, $expectation->getExpectedArgs(), $args); - $expectation->decrementCallCount(); + $expectation->decrementExpectedCount(); if ($expectation->getExpectedCount() === 0) { $this->removeExpectation($method, $key); @@ -483,31 +525,43 @@ class LdapFake implements LdapInterface return $expectation->getExpectedValue(); } - throw new Exception("LDAP method [$method] was unexpected."); + throw new LdapExpectationException("LDAP method [$method] was unexpected."); } /** * Apply the expectation error to the fake. - * - * @param LdapExpectation $expectation - * @return void */ - protected function applyExpectationError(LdapExpectation $expectation) + protected function applyExpectationError(LdapExpectation $expectation): void { $this->shouldReturnError($expectation->getExpectedErrorMessage()); $this->shouldReturnErrorNumber($expectation->getExpectedErrorCode()); $this->shouldReturnDiagnosticMessage($expectation->getExpectedErrorDiagnosticMessage()); } + /** + * Assert that the expectations have been called their minimum amount of times. + * + * @throws LdapExpectationException + */ + public function assertMinimumExpectationCounts(): void + { + foreach ($this->expectations as $method => $expectations) { + foreach ($expectations as $expectation) { + if (! $expectation->isIndefinite() && $expectation->getExpectedCount()) { + $remaining = ($original = $expectation->getOriginalExpectedCount()) - $expectation->getExpectedCount(); + + throw new LdapExpectationException("Method [$method] should be called $original times but was called $remaining times."); + } + } + } + } + /** * Assert that the expected arguments match the operations arguments. * - * @param string $method * @param Constraint[] $expectedArgs - * @param array $methodArgs - * @return void */ - protected function assertMethodArgumentsMatch($method, array $expectedArgs = [], array $methodArgs = []) + protected function assertMethodArgumentsMatch(string $method, array $expectedArgs = [], array $methodArgs = []): void { foreach ($expectedArgs as $key => $constraint) { $argNumber = $key + 1; @@ -515,7 +569,7 @@ class LdapFake implements LdapInterface PHPUnit::assertArrayHasKey( $key, $methodArgs, - "LDAP method [$method] argument #{$argNumber} does not exist." + "LDAP method [$method] argument #$argNumber does not exist." ); $constraint->evaluate( diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php deleted file mode 100644 index c4f5190d8..000000000 --- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php +++ /dev/null @@ -1,187 +0,0 @@ - $value) { - $dn[$rdn] = static::unescape($value); - } - - return $dn; - } - - /** - * Un-escapes a hexadecimal string into its original string representation. - * - * @param string $value - * @return string - */ - public static function unescape($value) - { - return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function ($matches) { - return chr(hexdec($matches[1])); - }, $value); - } - - /** - * Convert a binary SID to a string SID. - * - * @author Chad Sikorra - * - * @see https://github.com/ChadSikorra - * @see https://stackoverflow.com/questions/39533560/php-ldap-get-user-sid - * - * @param string $value The Binary SID - * @return string|null - */ - public static function binarySidToString($value) - { - // Revision - 8bit unsigned int (C1) - // Count - 8bit unsigned int (C1) - // 2 null bytes - // ID - 32bit unsigned long, big-endian order - $sid = @unpack('C1rev/C1count/x2/N1id', $value); - - if (! isset($sid['id']) || ! isset($sid['rev'])) { - return; - } - - $revisionLevel = $sid['rev']; - - $identifierAuthority = $sid['id']; - - $subs = isset($sid['count']) ? $sid['count'] : 0; - - $sidHex = $subs ? bin2hex($value) : ''; - - $subAuthorities = []; - - // The sub-authorities depend on the count, so only get as - // many as the count, regardless of data beyond it. - for ($i = 0; $i < $subs; $i++) { - $data = implode(array_reverse( - str_split( - substr($sidHex, 16 + ($i * 8), 8), - 2 - ) - )); - - $subAuthorities[] = hexdec($data); - } - - // Tack on the 'S-' and glue it all together... - return 'S-'.$revisionLevel.'-'.$identifierAuthority.implode( - preg_filter('/^/', '-', $subAuthorities) - ); - } - - /** - * Convert a binary GUID to a string GUID. - * - * @param string $binGuid - * @return string|null - */ - public static function binaryGuidToString($binGuid) - { - if (is_null($binGuid) || trim($binGuid) == '') { - return; - } - - $hex = unpack('H*hex', $binGuid)['hex']; - - $hex1 = substr($hex, -26, 2).substr($hex, -28, 2).substr($hex, -30, 2).substr($hex, -32, 2); - $hex2 = substr($hex, -22, 2).substr($hex, -24, 2); - $hex3 = substr($hex, -18, 2).substr($hex, -20, 2); - $hex4 = substr($hex, -16, 4); - $hex5 = substr($hex, -12, 12); - - return sprintf('%s-%s-%s-%s-%s', $hex1, $hex2, $hex3, $hex4, $hex5); - } - - /** - * Converts a string GUID to it's hex variant. - * - * @param string $string - * @return string - */ - public static function stringGuidToHex($string) - { - $hex = '\\'.substr($string, 6, 2).'\\'.substr($string, 4, 2).'\\'.substr($string, 2, 2).'\\'.substr($string, 0, 2); - $hex = $hex.'\\'.substr($string, 11, 2).'\\'.substr($string, 9, 2); - $hex = $hex.'\\'.substr($string, 16, 2).'\\'.substr($string, 14, 2); - $hex = $hex.'\\'.substr($string, 19, 2).'\\'.substr($string, 21, 2); - $hex = $hex.'\\'.substr($string, 24, 2).'\\'.substr($string, 26, 2).'\\'.substr($string, 28, 2).'\\'.substr($string, 30, 2).'\\'.substr($string, 32, 2).'\\'.substr($string, 34, 2); - - return $hex; - } - - /** - * Round a Windows timestamp down to seconds and remove - * the seconds between 1601-01-01 and 1970-01-01. - * - * @param int $windowsTime - * @return int - */ - public static function convertWindowsTimeToUnixTime($windowsTime) - { - return (int) (round($windowsTime / 10000000) - 11644473600); - } - - /** - * Convert a Unix timestamp to Windows timestamp. - * - * @param int $unixTime - * @return int - */ - public static function convertUnixTimeToWindowsTime($unixTime) - { - return ($unixTime + 11644473600) * 10000000; - } - - /** - * Validates that the inserted string is an object SID. - * - * @param string $sid - * @return bool - */ - public static function isValidSid($sid) - { - return (bool) preg_match("/^S-\d(-\d{1,10}){1,16}$/i", (string) $sid); - } - - /** - * Validates that the inserted string is an object GUID. - * - * @param string $guid - * @return bool - */ - public static function isValidGuid($guid) - { - return (bool) preg_match('/^([0-9a-fA-F]){8}(-([0-9a-fA-F]){4}){3}-([0-9a-fA-F]){12}$/', (string) $guid); - } -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php b/data/web/inc/lib/vendor/illuminate/collections/Arr.php similarity index 88% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php rename to data/web/inc/lib/vendor/illuminate/collections/Arr.php index f3a4b042e..d83cf5f73 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php +++ b/data/web/inc/lib/vendor/illuminate/collections/Arr.php @@ -1,10 +1,10 @@ $value) { @@ -214,7 +216,7 @@ class Arr * @param mixed $default * @return mixed */ - public static function last($array, callable $callback = null, $default = null) + public static function last($array, ?callable $callback = null, $default = null) { if (is_null($callback)) { return empty($array) ? value($default) : end($array); @@ -223,6 +225,22 @@ class Arr return static::first(array_reverse($array, true), $callback, $default); } + /** + * Take the first or last {$limit} items from an array. + * + * @param array $array + * @param int $limit + * @return array + */ + public static function take($array, $limit) + { + if ($limit < 0) { + return array_slice($array, $limit, abs($limit)); + } + + return array_slice($array, 0, $limit); + } + /** * Flatten a multi-dimensional array into a single level. * @@ -410,9 +428,7 @@ class Arr */ public static function isAssoc(array $array) { - $keys = array_keys($array); - - return array_keys($keys) !== $keys; + return ! array_is_list($array); } /** @@ -425,7 +441,7 @@ class Arr */ public static function isList($array) { - return ! self::isAssoc($array); + return array_is_list($array); } /** @@ -476,9 +492,7 @@ class Arr */ public static function prependKeysWith($array, $prependWith) { - return Collection::make($array)->mapWithKeys(function ($item, $key) use ($prependWith) { - return [$prependWith.$key => $item]; - })->all(); + return static::mapWithKeys($array, fn ($item, $key) => [$prependWith.$key => $item]); } /** @@ -493,6 +507,32 @@ class Arr return array_intersect_key($array, array_flip((array) $keys)); } + /** + * Select an array of values from an array. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function select($array, $keys) + { + $keys = static::wrap($keys); + + return static::map($array, function ($item) use ($keys) { + $result = []; + + foreach ($keys as $key) { + if (Arr::accessible($item) && Arr::exists($item, $key)) { + $result[$key] = $item[$key]; + } elseif (is_object($item) && isset($item->{$key})) { + $result[$key] = $item->{$key}; + } + } + + return $result; + }); + } + /** * Pluck an array of values from an array. * @@ -565,6 +605,35 @@ class Arr return array_combine($keys, $items); } + /** + * Run an associative map over each of the items. + * + * The callback should return an associative array with a single key/value pair. + * + * @template TKey + * @template TValue + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param array $array + * @param callable(TValue, TKey): array $callback + * @return array + */ + public static function mapWithKeys(array $array, callable $callback) + { + $result = []; + + foreach ($array as $key => $value) { + $assoc = $callback($value, $key); + + foreach ($assoc as $mapKey => $mapValue) { + $result[$mapKey] = $mapValue; + } + } + + return $result; + } + /** * Push an item onto the beginning of an array. * @@ -759,7 +828,7 @@ class Arr } } - if (static::isAssoc($array)) { + if (! array_is_list($array)) { $descending ? krsort($array, $options) : ksort($array, $options); @@ -772,6 +841,18 @@ class Arr return $array; } + /** + * Recursively sort an array by keys and values in descending order. + * + * @param array $array + * @param int $options + * @return array + */ + public static function sortRecursiveDesc($array, $options = SORT_REGULAR) + { + return static::sortRecursive($array, $options, true); + } + /** * Conditionally compile classes from an array into a CSS class list. * diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php b/data/web/inc/lib/vendor/illuminate/collections/Collection.php similarity index 86% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php rename to data/web/inc/lib/vendor/illuminate/collections/Collection.php index e705ee0d0..2f0c768f1 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php +++ b/data/web/inc/lib/vendor/illuminate/collections/Collection.php @@ -1,26 +1,28 @@ - * @implements \Tightenco\Collect\Support\Enumerable + * @implements \Illuminate\Support\Enumerable */ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable { /** - * @use \Tightenco\Collect\Support\Traits\EnumeratesValues + * @use \Illuminate\Support\Traits\EnumeratesValues */ use EnumeratesValues, Macroable; @@ -34,7 +36,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Create a new collection. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items * @return void */ public function __construct($items = []) @@ -67,7 +69,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get a lazy collection for the items in this collection. * - * @return \Tightenco\Collect\Support\LazyCollection + * @return \Illuminate\Support\LazyCollection */ public function lazy() { @@ -220,7 +222,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * @template TCrossJoinKey * @template TCrossJoinValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists * @return static> */ public function crossJoin(...$lists) @@ -233,7 +235,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection that are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -244,7 +246,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection that are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -256,7 +258,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys and values are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -267,7 +269,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys and values are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -279,7 +281,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -290,7 +292,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items in the collection whose keys are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -356,11 +358,15 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get all items except for those with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function except($keys) { + if (is_null($keys)) { + return new static($this->items); + } + if ($keys instanceof Enumerable) { $keys = $keys->all(); } elseif (! is_array($keys)) { @@ -373,10 +379,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Run a filter over each of the items. * - * @param (callable(TValue, TKey): bool)|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ - public function filter(callable $callback = null) + public function filter(?callable $callback = null) { if ($callback) { return new static(Arr::where($this->items, $callback)); @@ -394,7 +400,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * @param TFirstDefault|(\Closure(): TFirstDefault) $default * @return TValue|TFirstDefault */ - public function first(callable $callback = null, $default = null) + public function first(?callable $callback = null, $default = null) { return Arr::first($this->items, $callback, $default); } @@ -423,12 +429,13 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Remove an item from the collection by key. * - * @param TKey|array $keys + * \Illuminate\Contracts\Support\Arrayable|iterable|TKey $keys + * * @return $this */ public function forget($keys) { - foreach ((array) $keys as $key) { + foreach ($this->getArrayableItems($keys) as $key) { $this->offsetUnset($key); } @@ -456,9 +463,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get an item from the collection by key or add it to collection if it does not exist. * + * @template TGetOrPutValue + * * @param mixed $key - * @param mixed $value - * @return mixed + * @param TGetOrPutValue|(\Closure(): TGetOrPutValue) $value + * @return TValue|TGetOrPutValue */ public function getOrPut($key, $value) { @@ -500,6 +509,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl foreach ($groupKeys as $groupKey) { $groupKey = match (true) { is_bool($groupKey) => (int) $groupKey, + $groupKey instanceof \BackedEnum => $groupKey->value, $groupKey instanceof \Stringable => (string) $groupKey, default => $groupKey, }; @@ -603,7 +613,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl $first = $this->first(); - if (is_array($first) || (is_object($first) && ! $first instanceof \Illuminate\Support\Stringable)) { + if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) { return implode($glue ?? '', $this->pluck($value)->all()); } @@ -613,7 +623,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -624,7 +634,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -636,7 +646,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items with additional index check. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectAssoc($items) @@ -647,7 +657,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items with additional index check, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -659,7 +669,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Intersect the collection with the given items by key. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -738,7 +748,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * @param TLastDefault|(\Closure(): TLastDefault) $default * @return TValue|TLastDefault */ - public function last(callable $callback = null, $default = null) + public function last(?callable $callback = null, $default = null) { return Arr::last($this->items, $callback, $default); } @@ -813,23 +823,13 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl */ public function mapWithKeys(callable $callback) { - $result = []; - - foreach ($this->items as $key => $value) { - $assoc = $callback($value, $key); - - foreach ($assoc as $mapKey => $mapValue) { - $result[$mapKey] = $mapValue; - } - } - - return new static($result); + return new static(Arr::mapWithKeys($this->items, $callback)); } /** * Merge the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -842,7 +842,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @template TMergeRecursiveValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function mergeRecursive($items) @@ -855,7 +855,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @template TCombineValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function combine($values) @@ -866,7 +866,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Union the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -901,7 +901,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get the items with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array|string|null $keys + * @param \Illuminate\Support\Enumerable|array|string|null $keys * @return static */ public function only($keys) @@ -919,6 +919,27 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl return new static(Arr::only($this->items, $keys)); } + /** + * Select specific values from the items within the collection. + * + * @param \Illuminate\Support\Enumerable|array|string|null $keys + * @return static + */ + public function select($keys) + { + if (is_null($keys)) { + return new static($this->items); + } + + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } + + $keys = is_array($keys) ? $keys : func_get_args(); + + return new static(Arr::select($this->items, $keys)); + } + /** * Get and remove the last N items from the collection. * @@ -978,8 +999,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Push all of the given items onto the collection. * - * @param iterable $source - * @return static + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static */ public function concat($source) { @@ -1024,27 +1048,28 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Get one or a specified number of items randomly from the collection. * * @param (callable(self): int)|int|null $number + * @param bool $preserveKeys * @return static|TValue * * @throws \InvalidArgumentException */ - public function random($number = null) + public function random($number = null, $preserveKeys = false) { if (is_null($number)) { return Arr::random($this->items); } if (is_callable($number)) { - return new static(Arr::random($this->items, $number($this))); + return new static(Arr::random($this->items, $number($this), $preserveKeys)); } - return new static(Arr::random($this->items, $number)); + return new static(Arr::random($this->items, $number, $preserveKeys)); } /** * Replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -1055,7 +1080,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Recursively replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -1078,7 +1103,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return TKey|bool + * @return TKey|false */ public function search($value, $strict = false) { @@ -1100,17 +1125,27 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @param int $count * @return static|TValue|null + * + * @throws \InvalidArgumentException */ public function shift($count = 1) { - if ($count === 1) { - return array_shift($this->items); + if ($count < 0) { + throw new InvalidArgumentException('Number of shifted items may not be less than zero.'); } if ($this->isEmpty()) { + return null; + } + + if ($count === 0) { return new static; } + if ($count === 1) { + return array_shift($this->items); + } + $results = []; $collectionCount = $this->count(); @@ -1144,9 +1179,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl { $chunks = floor(($this->count() - $size) / $step) + 1; - return static::times($chunks, function ($number) use ($size, $step) { - return $this->slice(($number - 1) * $step, $size); - }); + return static::times($chunks, fn ($number) => $this->slice(($number - 1) * $step, $size)); } /** @@ -1250,8 +1283,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException - * @throws \Tightenco\Collect\Support\MultipleItemsFoundException + * @throws \Illuminate\Support\ItemNotFoundException + * @throws \Illuminate\Support\MultipleItemsFoundException */ public function sole($key = null, $operator = null, $value = null) { @@ -1282,7 +1315,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException + * @throws \Illuminate\Support\ItemNotFoundException */ public function firstOrFail($key = null, $operator = null, $value = null) { @@ -1378,7 +1411,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl public function sortBy($callback, $options = SORT_REGULAR, $descending = false) { if (is_array($callback) && ! is_callable($callback)) { - return $this->sortByMany($callback); + return $this->sortByMany($callback, $options); } $results = []; @@ -1409,13 +1442,14 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * Sort the collection using multiple comparisons. * * @param array $comparisons + * @param int $options * @return static */ - protected function sortByMany(array $comparisons = []) + protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR) { $items = $this->items; - uasort($items, function ($a, $b) use ($comparisons) { + uasort($items, function ($a, $b) use ($comparisons, $options) { foreach ($comparisons as $comparison) { $comparison = Arr::wrap($comparison); @@ -1433,7 +1467,21 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl $values = array_reverse($values); } - $result = $values[0] <=> $values[1]; + if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) { + if (($options & SORT_NATURAL) === SORT_NATURAL) { + $result = strnatcasecmp($values[0], $values[1]); + } else { + $result = strcasecmp($values[0], $values[1]); + } + } else { + $result = match ($options) { + SORT_NUMERIC => intval($values[0]) <=> intval($values[1]), + SORT_STRING => strcmp($values[0], $values[1]), + SORT_NATURAL => strnatcmp($values[0], $values[1]), + SORT_LOCALE_STRING => strcoll($values[0], $values[1]), + default => $values[0] <=> $values[1], + }; + } } if ($result === 0) { @@ -1456,6 +1504,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl */ public function sortByDesc($callback, $options = SORT_REGULAR) { + if (is_array($callback) && ! is_callable($callback)) { + foreach ($callback as $index => $key) { + $comparison = Arr::wrap($key); + + $comparison[1] = 'desc'; + + $callback[$index] = $comparison; + } + } + return $this->sortBy($callback, $options, true); } @@ -1568,6 +1626,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl return $this; } + /** + * Flatten a multi-dimensional associative array with dots. + * + * @return static + */ + public function dot() + { + return new static(Arr::dot($this->all())); + } + /** * Convert a flatten "dot" notation array into an expanded array. * @@ -1622,7 +1690,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl * * @template TZipValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items * @return static> */ public function zip($items) @@ -1695,7 +1763,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl /** * Get a base Support collection instance from this collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Illuminate\Support\Collection */ public function toBase() { diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php b/data/web/inc/lib/vendor/illuminate/collections/Enumerable.php similarity index 88% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php rename to data/web/inc/lib/vendor/illuminate/collections/Enumerable.php index 1f0db03ae..806a6923f 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php +++ b/data/web/inc/lib/vendor/illuminate/collections/Enumerable.php @@ -1,20 +1,21 @@ + * @template-covariant TValue + * + * @extends \Illuminate\Contracts\Support\Arrayable * @extends \IteratorAggregate */ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable @@ -25,7 +26,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @template TMakeKey of array-key * @template TMakeValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items * @return static */ public static function make($items = []); @@ -37,7 +38,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param callable|null $callback * @return static */ - public static function times($number, callable $callback = null); + public static function times($number, ?callable $callback = null); /** * Create a collection with the given range. @@ -167,7 +168,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @template TCrossJoinKey * @template TCrossJoinValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists * @return static> */ public function crossJoin(...$lists); @@ -190,7 +191,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items that are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items); @@ -198,7 +199,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items that are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -207,7 +208,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys and values are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items); @@ -215,7 +216,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -224,7 +225,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items); @@ -232,7 +233,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items whose keys are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -284,7 +285,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get all items except for those with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys); @@ -295,7 +296,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable(TValue): bool)|null $callback * @return static */ - public function filter(callable $callback = null); + public function filter(?callable $callback = null); /** * Apply the callback if the given "value" is (or resolves to) truthy. @@ -307,7 +308,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TWhenReturnType)|null $default * @return $this|TWhenReturnType */ - public function when($value, callable $callback = null, callable $default = null); + public function when($value, ?callable $callback = null, ?callable $default = null); /** * Apply the callback if the collection is empty. @@ -318,7 +319,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TWhenEmptyReturnType)|null $default * @return $this|TWhenEmptyReturnType */ - public function whenEmpty(callable $callback, callable $default = null); + public function whenEmpty(callable $callback, ?callable $default = null); /** * Apply the callback if the collection is not empty. @@ -329,7 +330,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TWhenNotEmptyReturnType)|null $default * @return $this|TWhenNotEmptyReturnType */ - public function whenNotEmpty(callable $callback, callable $default = null); + public function whenNotEmpty(callable $callback, ?callable $default = null); /** * Apply the callback if the given "value" is (or resolves to) truthy. @@ -341,7 +342,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TUnlessReturnType)|null $default * @return $this|TUnlessReturnType */ - public function unless($value, callable $callback, callable $default = null); + public function unless($value, callable $callback, ?callable $default = null); /** * Apply the callback unless the collection is empty. @@ -352,7 +353,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TUnlessEmptyReturnType)|null $default * @return $this|TUnlessEmptyReturnType */ - public function unlessEmpty(callable $callback, callable $default = null); + public function unlessEmpty(callable $callback, ?callable $default = null); /** * Apply the callback unless the collection is not empty. @@ -363,7 +364,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param (callable($this): TUnlessNotEmptyReturnType)|null $default * @return $this|TUnlessNotEmptyReturnType */ - public function unlessNotEmpty(callable $callback, callable $default = null); + public function unlessNotEmpty(callable $callback, ?callable $default = null); /** * Filter items by the given key value pair. @@ -404,7 +405,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -414,7 +415,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values); @@ -423,7 +424,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values); @@ -432,7 +433,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values); @@ -441,7 +442,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -451,7 +452,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values); @@ -475,7 +476,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param TFirstDefault|(\Closure(): TFirstDefault) $default * @return TValue|TFirstDefault */ - public function first(callable $callback = null, $default = null); + public function first(?callable $callback = null, $default = null); /** * Get the first item by the given key value pair. @@ -549,7 +550,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ @@ -558,7 +559,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Intersect the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items); @@ -566,7 +567,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Intersect the collection with the given items by key. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items); @@ -617,7 +618,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param TLastDefault|(\Closure(): TLastDefault) $default * @return TValue|TLastDefault */ - public function last(callable $callback = null, $default = null); + public function last(?callable $callback = null, $default = null); /** * Run a map over each of the items. @@ -682,7 +683,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @template TFlatMapKey of array-key * @template TFlatMapValue * - * @param callable(TValue, TKey): (\Tightenco\Collect\Support\Collection|array) $callback + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback * @return static */ public function flatMap(callable $callback); @@ -700,7 +701,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Merge the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items); @@ -710,7 +711,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * @template TMergeRecursiveValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function mergeRecursive($items); @@ -720,7 +721,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * @template TCombineValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function combine($values); @@ -728,7 +729,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Union the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items); @@ -761,7 +762,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Get the items with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array|string $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys); @@ -788,8 +789,11 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Push all of the given items onto the collection. * - * @param iterable $source - * @return static + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static */ public function concat($source); @@ -829,7 +833,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items); @@ -837,7 +841,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Recursively replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items); @@ -924,8 +928,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException - * @throws \Tightenco\Collect\Support\MultipleItemsFoundException + * @throws \Illuminate\Support\ItemNotFoundException + * @throws \Illuminate\Support\MultipleItemsFoundException */ public function sole($key = null, $operator = null, $value = null); @@ -937,7 +941,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException + * @throws \Illuminate\Support\ItemNotFoundException */ public function firstOrFail($key = null, $operator = null, $value = null); @@ -1078,8 +1082,10 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Pass the collection into a new class. * - * @param class-string $class - * @return mixed + * @template TPipeIntoValue + * + * @param class-string $class + * @return TPipeIntoValue */ public function pipeInto($class); @@ -1180,7 +1186,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, * * @template TZipValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items * @return static> */ public function zip($items); @@ -1188,7 +1194,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, /** * Collect the values into a collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect(); diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php b/data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php similarity index 86% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php rename to data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php index 01ac43f96..106356c3a 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php +++ b/data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php @@ -1,16 +1,16 @@ + * @template-covariant TValue + * + * @implements \Illuminate\Support\Enumerable */ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable { /** - * @use \Tightenco\Collect\Support\Traits\EnumeratesValues + * @use \Illuminate\Support\Traits\EnumeratesValues */ use EnumeratesValues, Macroable; @@ -37,7 +38,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Create a new lazy collection instance. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source * @return void */ public function __construct($source = null) @@ -61,7 +62,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @template TMakeKey of array-key * @template TMakeValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items * @return static */ public static function make($items = []) @@ -281,7 +282,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @template TCrossJoinKey * @template TCrossJoinValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$arrays + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$arrays * @return static> */ public function crossJoin(...$arrays) @@ -321,7 +322,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items that are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -332,7 +333,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items that are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -344,7 +345,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys and values are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -355,7 +356,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -367,7 +368,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys are not present in the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -378,7 +379,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items whose keys are not present in the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TKey, TKey): int $callback * @return static */ @@ -413,7 +414,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get all items except for those with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -427,7 +428,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @param (callable(TValue, TKey): bool)|null $callback * @return static */ - public function filter(callable $callback = null) + public function filter(?callable $callback = null) { if (is_null($callback)) { $callback = fn ($value) => (bool) $value; @@ -451,7 +452,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @param TFirstDefault|(\Closure(): TFirstDefault) $default * @return TValue|TFirstDefault */ - public function first(callable $callback = null, $default = null) + public function first(?callable $callback = null, $default = null) { $iterator = $this->getIterator(); @@ -622,7 +623,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -633,7 +634,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -645,7 +646,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items with additional index check. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectAssoc($items) @@ -656,7 +657,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items with additional index check, using the callback. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @param callable(TValue, TValue): int $callback * @return static */ @@ -668,7 +669,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Intersect the collection with the given items by key. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -731,7 +732,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @param TLastDefault|(\Closure(): TLastDefault) $default * @return TValue|TLastDefault */ - public function last(callable $callback = null, $default = null) + public function last(?callable $callback = null, $default = null) { $needle = $placeholder = new stdClass; @@ -830,7 +831,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Merge the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -843,7 +844,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * @template TMergeRecursiveValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function mergeRecursive($items) @@ -887,7 +888,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Union the collection with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -920,7 +921,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Get the items with the specified keys. * - * @param \Tightenco\Collect\Support\Enumerable|array|string $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys) @@ -952,11 +953,49 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable }); } + /** + * Select specific values from the items within the collection. + * + * @param \Illuminate\Support\Enumerable|array|string $keys + * @return static + */ + public function select($keys) + { + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } elseif (! is_null($keys)) { + $keys = is_array($keys) ? $keys : func_get_args(); + } + + return new static(function () use ($keys) { + if (is_null($keys)) { + yield from $this; + } else { + foreach ($this as $item) { + $result = []; + + foreach ($keys as $key) { + if (Arr::accessible($item) && Arr::exists($item, $key)) { + $result[$key] = $item[$key]; + } elseif (is_object($item) && isset($item->{$key})) { + $result[$key] = $item->{$key}; + } + } + + yield $result; + } + } + }); + } + /** * Push all of the given items onto the collection. * - * @param iterable $source - * @return static + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static */ public function concat($source) { @@ -984,7 +1023,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -1011,7 +1050,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable /** * Recursively replace the collection items with the given items. * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -1034,7 +1073,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return TKey|bool + * @return TKey|false */ public function search($value, $strict = false) { @@ -1202,8 +1241,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException - * @throws \Tightenco\Collect\Support\MultipleItemsFoundException + * @throws \Illuminate\Support\ItemNotFoundException + * @throws \Illuminate\Support\MultipleItemsFoundException */ public function sole($key = null, $operator = null, $value = null) { @@ -1227,7 +1266,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * @param mixed $value * @return TValue * - * @throws \Tightenco\Collect\Support\ItemNotFoundException + * @throws \Illuminate\Support\ItemNotFoundException */ public function firstOrFail($key = null, $operator = null, $value = null) { @@ -1420,7 +1459,21 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable public function take($limit) { if ($limit < 0) { - return $this->passthru('take', func_get_args()); + return new static(function () use ($limit) { + $limit = abs($limit); + $ringBuffer = []; + $position = 0; + + foreach ($this as $key => $value) { + $ringBuffer[$position] = [$key, $value]; + $position = ($position + 1) % $limit; + } + + for ($i = 0, $end = min($limit, count($ringBuffer)); $i < $end; $i++) { + $pointer = ($position + $i) % $limit; + yield $ringBuffer[$pointer][0] => $ringBuffer[$pointer][1]; + } + }); } return new static(function () use ($limit) { @@ -1518,6 +1571,16 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable }); } + /** + * Flatten a multi-dimensional associative array with dots. + * + * @return static + */ + public function dot() + { + return $this->passthru('dot', []); + } + /** * Convert a flatten "dot" notation array into an expanded array. * @@ -1574,7 +1637,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable * * @template TZipValue * - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items * @return static> */ public function zip($items) @@ -1715,6 +1778,8 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable */ protected function now() { - return time(); + return class_exists(Carbon::class) + ? Carbon::now()->timestamp + : time(); } } diff --git a/data/web/inc/lib/vendor/illuminate/collections/MultipleItemsFoundException.php b/data/web/inc/lib/vendor/illuminate/collections/MultipleItemsFoundException.php new file mode 100644 index 000000000..d90d835b4 --- /dev/null +++ b/data/web/inc/lib/vendor/illuminate/collections/MultipleItemsFoundException.php @@ -0,0 +1,40 @@ +count = $count; + + parent::__construct("$count items were found.", $code, $previous); + } + + /** + * Get the number of items found. + * + * @return int + */ + public function getCount() + { + return $this->count; + } +} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php b/data/web/inc/lib/vendor/illuminate/collections/Traits/EnumeratesValues.php similarity index 85% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php rename to data/web/inc/lib/vendor/illuminate/collections/Traits/EnumeratesValues.php index 25cde2216..9718f5bc5 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/EnumeratesValues.php +++ b/data/web/inc/lib/vendor/illuminate/collections/Traits/EnumeratesValues.php @@ -1,25 +1,28 @@ |iterable|null $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items * @return static */ public static function make($items = []) @@ -159,7 +164,7 @@ trait EnumeratesValues * @param (callable(int): TTimesValue)|null $callback * @return static */ - public static function times($number, callable $callback = null) + public static function times($number, ?callable $callback = null) { if ($number < 1) { return new static; @@ -296,9 +301,11 @@ trait EnumeratesValues /** * Get a single key's value from the first matching item in the collection. * + * @template TValueDefault + * * @param string $key - * @param mixed $default - * @return mixed + * @param TValueDefault|(\Closure(): TValueDefault) $default + * @return TValue|TValueDefault */ public function value($key, $default = null) { @@ -309,6 +316,35 @@ trait EnumeratesValues return value($default); } + /** + * Ensure that every item in the collection is of the expected type. + * + * @template TEnsureOfType + * + * @param class-string|array> $type + * @return static + * + * @throws \UnexpectedValueException + */ + public function ensure($type) + { + $allowedTypes = is_array($type) ? $type : [$type]; + + return $this->each(function ($item) use ($allowedTypes) { + $itemType = get_debug_type($item); + + foreach ($allowedTypes as $allowedType) { + if ($itemType === $allowedType || $item instanceof $allowedType) { + return true; + } + } + + throw new UnexpectedValueException( + sprintf("Collection should only include [%s] items, but '%s' found.", implode(', ', $allowedTypes), $itemType) + ); + }); + } + /** * Determine if the collection is not empty. * @@ -324,7 +360,7 @@ trait EnumeratesValues * * @template TMapSpreadValue * - * @param callable(mixed): TMapSpreadValue $callback + * @param callable(mixed...): TMapSpreadValue $callback * @return static */ public function mapSpread(callable $callback) @@ -360,7 +396,7 @@ trait EnumeratesValues * @template TFlatMapKey of array-key * @template TFlatMapValue * - * @param callable(TValue, TKey): (\Tightenco\Collect\Support\Collection|array) $callback + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback * @return static */ public function flatMap(callable $callback) @@ -455,6 +491,25 @@ trait EnumeratesValues return new static([new static($passed), new static($failed)]); } + /** + * Calculate the percentage of items that pass a given truth test. + * + * @param (callable(TValue, TKey): bool) $callback + * @param int $precision + * @return float|null + */ + public function percentage(callable $callback, int $precision = 2) + { + if ($this->isEmpty()) { + return null; + } + + return round( + $this->filter($callback)->count() / $this->count() * 100, + $precision + ); + } + /** * Get the sum of the given values. * @@ -479,7 +534,7 @@ trait EnumeratesValues * @param (callable($this): TWhenEmptyReturnType)|null $default * @return $this|TWhenEmptyReturnType */ - public function whenEmpty(callable $callback, callable $default = null) + public function whenEmpty(callable $callback, ?callable $default = null) { return $this->when($this->isEmpty(), $callback, $default); } @@ -493,7 +548,7 @@ trait EnumeratesValues * @param (callable($this): TWhenNotEmptyReturnType)|null $default * @return $this|TWhenNotEmptyReturnType */ - public function whenNotEmpty(callable $callback, callable $default = null) + public function whenNotEmpty(callable $callback, ?callable $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } @@ -507,7 +562,7 @@ trait EnumeratesValues * @param (callable($this): TUnlessEmptyReturnType)|null $default * @return $this|TUnlessEmptyReturnType */ - public function unlessEmpty(callable $callback, callable $default = null) + public function unlessEmpty(callable $callback, ?callable $default = null) { return $this->whenNotEmpty($callback, $default); } @@ -521,7 +576,7 @@ trait EnumeratesValues * @param (callable($this): TUnlessNotEmptyReturnType)|null $default * @return $this|TUnlessNotEmptyReturnType */ - public function unlessNotEmpty(callable $callback, callable $default = null) + public function unlessNotEmpty(callable $callback, ?callable $default = null) { return $this->whenEmpty($callback, $default); } @@ -577,7 +632,7 @@ trait EnumeratesValues * Filter items by the given key value pair. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -592,7 +647,7 @@ trait EnumeratesValues * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values) @@ -604,7 +659,7 @@ trait EnumeratesValues * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values) @@ -616,7 +671,7 @@ trait EnumeratesValues * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values) @@ -630,7 +685,7 @@ trait EnumeratesValues * Filter items by the given key value pair. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -645,7 +700,7 @@ trait EnumeratesValues * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values) @@ -694,8 +749,10 @@ trait EnumeratesValues /** * Pass the collection into a new class. * - * @param class-string $class - * @return mixed + * @template TPipeIntoValue + * + * @param class-string $class + * @return TPipeIntoValue */ public function pipeInto($class) { @@ -764,6 +821,21 @@ trait EnumeratesValues return $result; } + /** + * Reduce an associative collection to a single value. + * + * @template TReduceWithKeysInitial + * @template TReduceWithKeysReturnType + * + * @param callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType $callback + * @param TReduceWithKeysInitial $initial + * @return TReduceWithKeysReturnType + */ + public function reduceWithKeys(callable $callback, $initial = null) + { + return $this->reduce($callback, $initial); + } + /** * Create a collection of all elements that do not pass a given truth test. * @@ -830,7 +902,7 @@ trait EnumeratesValues /** * Collect the values into a collection. * - * @return \Tightenco\Collect\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect() { @@ -952,21 +1024,18 @@ trait EnumeratesValues { if (is_array($items)) { return $items; - } elseif ($items instanceof Enumerable) { - return $items->all(); - } elseif ($items instanceof Arrayable) { - return $items->toArray(); - } elseif ($items instanceof Traversable) { - return iterator_to_array($items); - } elseif ($items instanceof Jsonable) { - return json_decode($items->toJson(), true); - } elseif ($items instanceof JsonSerializable) { - return (array) $items->jsonSerialize(); - } elseif ($items instanceof UnitEnum) { - return [$items]; } - return (array) $items; + return match (true) { + $items instanceof WeakMap => throw new InvalidArgumentException('Collections can not be created using instances of WeakMap.'), + $items instanceof Enumerable => $items->all(), + $items instanceof Arrayable => $items->toArray(), + $items instanceof Traversable => iterator_to_array($items), + $items instanceof Jsonable => json_decode($items->toJson(), true), + $items instanceof JsonSerializable => (array) $items->jsonSerialize(), + $items instanceof UnitEnum => [$items], + default => (array) $items, + }; } /** diff --git a/data/web/inc/lib/vendor/illuminate/collections/composer.json b/data/web/inc/lib/vendor/illuminate/collections/composer.json new file mode 100644 index 000000000..5e11a788e --- /dev/null +++ b/data/web/inc/lib/vendor/illuminate/collections/composer.json @@ -0,0 +1,42 @@ +{ + "name": "illuminate/collections", + "description": "The Illuminate Collections package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.1", + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^6.2)." + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/data/web/inc/lib/vendor/illuminate/collections/functions.php b/data/web/inc/lib/vendor/illuminate/collections/functions.php new file mode 100644 index 000000000..6ccd9b3ed --- /dev/null +++ b/data/web/inc/lib/vendor/illuminate/collections/functions.php @@ -0,0 +1,27 @@ + $value->value, + $value instanceof \UnitEnum => $value->name, + + default => $value ?? value($default), + }; + } +} diff --git a/data/web/inc/lib/vendor/illuminate/collections/helpers.php b/data/web/inc/lib/vendor/illuminate/collections/helpers.php new file mode 100644 index 000000000..235edceb1 --- /dev/null +++ b/data/web/inc/lib/vendor/illuminate/collections/helpers.php @@ -0,0 +1,226 @@ +|iterable|null $value + * @return \Illuminate\Support\Collection + */ + function collect($value = []) + { + return new Collection($value); + } +} + +if (! function_exists('data_fill')) { + /** + * Fill in data where it's missing. + * + * @param mixed $target + * @param string|array $key + * @param mixed $value + * @return mixed + */ + function data_fill(&$target, $key, $value) + { + return data_set($target, $key, $value, false); + } +} + +if (! function_exists('data_get')) { + /** + * Get an item from an array or object using "dot" notation. + * + * @param mixed $target + * @param string|array|int|null $key + * @param mixed $default + * @return mixed + */ + function data_get($target, $key, $default = null) + { + if (is_null($key)) { + return $target; + } + + $key = is_array($key) ? $key : explode('.', $key); + + foreach ($key as $i => $segment) { + unset($key[$i]); + + if (is_null($segment)) { + return $target; + } + + if ($segment === '*') { + if ($target instanceof Collection) { + $target = $target->all(); + } elseif (! is_iterable($target)) { + return value($default); + } + + $result = []; + + foreach ($target as $item) { + $result[] = data_get($item, $key); + } + + return in_array('*', $key) ? Arr::collapse($result) : $result; + } + + if (Arr::accessible($target) && Arr::exists($target, $segment)) { + $target = $target[$segment]; + } elseif (is_object($target) && isset($target->{$segment})) { + $target = $target->{$segment}; + } else { + return value($default); + } + } + + return $target; + } +} + +if (! function_exists('data_set')) { + /** + * Set an item on an array or object using dot notation. + * + * @param mixed $target + * @param string|array $key + * @param mixed $value + * @param bool $overwrite + * @return mixed + */ + function data_set(&$target, $key, $value, $overwrite = true) + { + $segments = is_array($key) ? $key : explode('.', $key); + + if (($segment = array_shift($segments)) === '*') { + if (! Arr::accessible($target)) { + $target = []; + } + + if ($segments) { + foreach ($target as &$inner) { + data_set($inner, $segments, $value, $overwrite); + } + } elseif ($overwrite) { + foreach ($target as &$inner) { + $inner = $value; + } + } + } elseif (Arr::accessible($target)) { + if ($segments) { + if (! Arr::exists($target, $segment)) { + $target[$segment] = []; + } + + data_set($target[$segment], $segments, $value, $overwrite); + } elseif ($overwrite || ! Arr::exists($target, $segment)) { + $target[$segment] = $value; + } + } elseif (is_object($target)) { + if ($segments) { + if (! isset($target->{$segment})) { + $target->{$segment} = []; + } + + data_set($target->{$segment}, $segments, $value, $overwrite); + } elseif ($overwrite || ! isset($target->{$segment})) { + $target->{$segment} = $value; + } + } else { + $target = []; + + if ($segments) { + data_set($target[$segment], $segments, $value, $overwrite); + } elseif ($overwrite) { + $target[$segment] = $value; + } + } + + return $target; + } +} + +if (! function_exists('data_forget')) { + /** + * Remove / unset an item from an array or object using "dot" notation. + * + * @param mixed $target + * @param string|array|int|null $key + * @return mixed + */ + function data_forget(&$target, $key) + { + $segments = is_array($key) ? $key : explode('.', $key); + + if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) { + if ($segments) { + foreach ($target as &$inner) { + data_forget($inner, $segments); + } + } + } elseif (Arr::accessible($target)) { + if ($segments && Arr::exists($target, $segment)) { + data_forget($target[$segment], $segments); + } else { + Arr::forget($target, $segment); + } + } elseif (is_object($target)) { + if ($segments && isset($target->{$segment})) { + data_forget($target->{$segment}, $segments); + } elseif (isset($target->{$segment})) { + unset($target->{$segment}); + } + } + + return $target; + } +} + +if (! function_exists('head')) { + /** + * Get the first element of an array. Useful for method chaining. + * + * @param array $array + * @return mixed + */ + function head($array) + { + return reset($array); + } +} + +if (! function_exists('last')) { + /** + * Get the last element from an array. + * + * @param array $array + * @return mixed + */ + function last($array) + { + return end($array); + } +} + +if (! function_exists('value')) { + /** + * Return the default value of the given value. + * + * @param mixed $value + * @param mixed ...$args + * @return mixed + */ + function value($value, ...$args) + { + return $value instanceof Closure ? $value(...$args) : $value; + } +} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php b/data/web/inc/lib/vendor/illuminate/conditionable/HigherOrderWhenProxy.php similarity index 98% rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php rename to data/web/inc/lib/vendor/illuminate/conditionable/HigherOrderWhenProxy.php index eaf24812b..579114cf1 100644 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Conditionable/HigherOrderWhenProxy.php +++ b/data/web/inc/lib/vendor/illuminate/conditionable/HigherOrderWhenProxy.php @@ -1,6 +1,6 @@ name)) { - $method->setAccessible(true); static::macro($method->name, $method->invoke($mixin)); } } diff --git a/data/web/inc/lib/vendor/illuminate/macroable/composer.json b/data/web/inc/lib/vendor/illuminate/macroable/composer.json new file mode 100644 index 000000000..231d2333a --- /dev/null +++ b/data/web/inc/lib/vendor/illuminate/macroable/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/macroable", + "description": "The Illuminate Macroable package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.1" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md b/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md deleted file mode 100644 index 7481cff1a..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/CHANGELOG.md +++ /dev/null @@ -1,91 +0,0 @@ -CHANGELOG -========= - -6.4 ---- - - * Dump uninitialized properties - -6.3 ---- - - * Add caster for `WeakMap` - * Add support of named arguments to `dd()` and `dump()` to display the argument name - * Add support for `Relay\Relay` - * Add display of invisible characters - -6.2 ---- - - * Add support for `FFI\CData` and `FFI\CType` - * Deprecate calling `VarDumper::setHandler()` without arguments - -5.4 ---- - - * Add ability to style integer and double values independently - * Add casters for Symfony's UUIDs and ULIDs - * Add support for `Fiber` - -5.2.0 ------ - - * added support for PHPUnit `--colors` option - * added `VAR_DUMPER_FORMAT=server` env var value support - * prevent replacing the handler when the `VAR_DUMPER_FORMAT` env var is set - -5.1.0 ------ - - * added `RdKafka` support - -4.4.0 ------ - - * added `VarDumperTestTrait::setUpVarDumper()` and `VarDumperTestTrait::tearDownVarDumper()` - to configure casters & flags to use in tests - * added `ImagineCaster` and infrastructure to dump images - * added the stamps of a message after it is dispatched in `TraceableMessageBus` and `MessengerDataCollector` collected data - * added `UuidCaster` - * made all casters final - * added support for the `NO_COLOR` env var (https://no-color.org/) - -4.3.0 ------ - - * added `DsCaster` to support dumping the contents of data structures from the Ds extension - -4.2.0 ------ - - * support selecting the format to use by setting the environment variable `VAR_DUMPER_FORMAT` to `html` or `cli` - -4.1.0 ------ - - * added a `ServerDumper` to send serialized Data clones to a server - * added a `ServerDumpCommand` and `DumpServer` to run a server collecting - and displaying dumps on a single place with multiple formats support - * added `CliDescriptor` and `HtmlDescriptor` descriptors for `server:dump` CLI and HTML formats support - -4.0.0 ------ - - * support for passing `\ReflectionClass` instances to the `Caster::castObject()` - method has been dropped, pass class names as strings instead - * the `Data::getRawData()` method has been removed - * the `VarDumperTestTrait::assertDumpEquals()` method expects a 3rd `$filter = 0` - argument and moves `$message = ''` argument at 4th position. - * the `VarDumperTestTrait::assertDumpMatchesFormat()` method expects a 3rd `$filter = 0` - argument and moves `$message = ''` argument at 4th position. - -3.4.0 ------ - - * added `AbstractCloner::setMinDepth()` function to ensure minimum tree depth - * deprecated `MongoCaster` - -2.7.0 ------ - - * deprecated `Cloner\Data::getLimitedClone()`. Use `withMaxDepth`, `withMaxItemsPerDepth` or `withRefHandles` instead. diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php deleted file mode 100644 index 22026f46a..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/AmqpCaster.php +++ /dev/null @@ -1,227 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Amqp related classes to array representation. - * - * @author Grégoire Pineau - * - * @final - */ -class AmqpCaster -{ - private const FLAGS = [ - \AMQP_DURABLE => 'AMQP_DURABLE', - \AMQP_PASSIVE => 'AMQP_PASSIVE', - \AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE', - \AMQP_AUTODELETE => 'AMQP_AUTODELETE', - \AMQP_INTERNAL => 'AMQP_INTERNAL', - \AMQP_NOLOCAL => 'AMQP_NOLOCAL', - \AMQP_AUTOACK => 'AMQP_AUTOACK', - \AMQP_IFEMPTY => 'AMQP_IFEMPTY', - \AMQP_IFUNUSED => 'AMQP_IFUNUSED', - \AMQP_MANDATORY => 'AMQP_MANDATORY', - \AMQP_IMMEDIATE => 'AMQP_IMMEDIATE', - \AMQP_MULTIPLE => 'AMQP_MULTIPLE', - \AMQP_NOWAIT => 'AMQP_NOWAIT', - \AMQP_REQUEUE => 'AMQP_REQUEUE', - ]; - - private const EXCHANGE_TYPES = [ - \AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT', - \AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT', - \AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC', - \AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS', - ]; - - /** - * @return array - */ - public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'is_connected' => $c->isConnected(), - ]; - - // Recent version of the extension already expose private properties - if (isset($a["\x00AMQPConnection\x00login"])) { - return $a; - } - - // BC layer in the amqp lib - if (method_exists($c, 'getReadTimeout')) { - $timeout = $c->getReadTimeout(); - } else { - $timeout = $c->getTimeout(); - } - - $a += [ - $prefix.'is_connected' => $c->isConnected(), - $prefix.'login' => $c->getLogin(), - $prefix.'password' => $c->getPassword(), - $prefix.'host' => $c->getHost(), - $prefix.'vhost' => $c->getVhost(), - $prefix.'port' => $c->getPort(), - $prefix.'read_timeout' => $timeout, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'is_connected' => $c->isConnected(), - $prefix.'channel_id' => $c->getChannelId(), - ]; - - // Recent version of the extension already expose private properties - if (isset($a["\x00AMQPChannel\x00connection"])) { - return $a; - } - - $a += [ - $prefix.'connection' => $c->getConnection(), - $prefix.'prefetch_size' => $c->getPrefetchSize(), - $prefix.'prefetch_count' => $c->getPrefetchCount(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'flags' => self::extractFlags($c->getFlags()), - ]; - - // Recent version of the extension already expose private properties - if (isset($a["\x00AMQPQueue\x00name"])) { - return $a; - } - - $a += [ - $prefix.'connection' => $c->getConnection(), - $prefix.'channel' => $c->getChannel(), - $prefix.'name' => $c->getName(), - $prefix.'arguments' => $c->getArguments(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'flags' => self::extractFlags($c->getFlags()), - ]; - - $type = isset(self::EXCHANGE_TYPES[$c->getType()]) ? new ConstStub(self::EXCHANGE_TYPES[$c->getType()], $c->getType()) : $c->getType(); - - // Recent version of the extension already expose private properties - if (isset($a["\x00AMQPExchange\x00name"])) { - $a["\x00AMQPExchange\x00type"] = $type; - - return $a; - } - - $a += [ - $prefix.'connection' => $c->getConnection(), - $prefix.'channel' => $c->getChannel(), - $prefix.'name' => $c->getName(), - $prefix.'type' => $type, - $prefix.'arguments' => $c->getArguments(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $deliveryMode = new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode()); - - // Recent version of the extension already expose private properties - if (isset($a["\x00AMQPEnvelope\x00body"])) { - $a["\0AMQPEnvelope\0delivery_mode"] = $deliveryMode; - - return $a; - } - - if (!($filter & Caster::EXCLUDE_VERBOSE)) { - $a += [$prefix.'body' => $c->getBody()]; - } - - $a += [ - $prefix.'delivery_tag' => $c->getDeliveryTag(), - $prefix.'is_redelivery' => $c->isRedelivery(), - $prefix.'exchange_name' => $c->getExchangeName(), - $prefix.'routing_key' => $c->getRoutingKey(), - $prefix.'content_type' => $c->getContentType(), - $prefix.'content_encoding' => $c->getContentEncoding(), - $prefix.'headers' => $c->getHeaders(), - $prefix.'delivery_mode' => $deliveryMode, - $prefix.'priority' => $c->getPriority(), - $prefix.'correlation_id' => $c->getCorrelationId(), - $prefix.'reply_to' => $c->getReplyTo(), - $prefix.'expiration' => $c->getExpiration(), - $prefix.'message_id' => $c->getMessageId(), - $prefix.'timestamp' => $c->getTimeStamp(), - $prefix.'type' => $c->getType(), - $prefix.'user_id' => $c->getUserId(), - $prefix.'app_id' => $c->getAppId(), - ]; - - return $a; - } - - private static function extractFlags(int $flags): ConstStub - { - $flagsArray = []; - - foreach (self::FLAGS as $value => $name) { - if ($flags & $value) { - $flagsArray[] = $name; - } - } - - if (!$flagsArray) { - $flagsArray = ['AMQP_NOPARAM']; - } - - return new ConstStub(implode('|', $flagsArray), $flags); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php deleted file mode 100644 index 9dc24c1b1..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ArgsStub.php +++ /dev/null @@ -1,80 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents a list of function arguments. - * - * @author Nicolas Grekas - */ -class ArgsStub extends EnumStub -{ - private static array $parameters = []; - - public function __construct(array $args, string $function, ?string $class) - { - [$variadic, $params] = self::getParameters($function, $class); - - $values = []; - foreach ($args as $k => $v) { - $values[$k] = !\is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v; - } - if (null === $params) { - parent::__construct($values, false); - - return; - } - if (\count($values) < \count($params)) { - $params = \array_slice($params, 0, \count($values)); - } elseif (\count($values) > \count($params)) { - $values[] = new EnumStub(array_splice($values, \count($params)), false); - $params[] = $variadic; - } - if (['...'] === $params) { - $this->dumpKeys = false; - $this->value = $values[0]->value; - } else { - $this->value = array_combine($params, $values); - } - } - - private static function getParameters(string $function, ?string $class): array - { - if (isset(self::$parameters[$k = $class.'::'.$function])) { - return self::$parameters[$k]; - } - - try { - $r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function); - } catch (\ReflectionException) { - return [null, null]; - } - - $variadic = '...'; - $params = []; - foreach ($r->getParameters() as $v) { - $k = '$'.$v->name; - if ($v->isPassedByReference()) { - $k = '&'.$k; - } - if ($v->isVariadic()) { - $variadic .= $k; - } else { - $params[] = $k; - } - } - - return self::$parameters[$k] = [$variadic, $params]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php deleted file mode 100644 index d9577e7ae..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/Caster.php +++ /dev/null @@ -1,198 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Helper for filtering out properties in casters. - * - * @author Nicolas Grekas - * - * @final - */ -class Caster -{ - public const EXCLUDE_VERBOSE = 1; - public const EXCLUDE_VIRTUAL = 2; - public const EXCLUDE_DYNAMIC = 4; - public const EXCLUDE_PUBLIC = 8; - public const EXCLUDE_PROTECTED = 16; - public const EXCLUDE_PRIVATE = 32; - public const EXCLUDE_NULL = 64; - public const EXCLUDE_EMPTY = 128; - public const EXCLUDE_NOT_IMPORTANT = 256; - public const EXCLUDE_STRICT = 512; - public const EXCLUDE_UNINITIALIZED = 1024; - - public const PREFIX_VIRTUAL = "\0~\0"; - public const PREFIX_DYNAMIC = "\0+\0"; - public const PREFIX_PROTECTED = "\0*\0"; - // usage: sprintf(Caster::PATTERN_PRIVATE, $class, $property) - public const PATTERN_PRIVATE = "\0%s\0%s"; - - private static array $classProperties = []; - - /** - * Casts objects to arrays and adds the dynamic property prefix. - * - * @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not - */ - public static function castObject(object $obj, string $class, bool $hasDebugInfo = false, ?string $debugClass = null): array - { - if ($hasDebugInfo) { - try { - $debugInfo = $obj->__debugInfo(); - } catch (\Throwable) { - // ignore failing __debugInfo() - $hasDebugInfo = false; - } - } - - $a = $obj instanceof \Closure ? [] : (array) $obj; - - if ($obj instanceof \__PHP_Incomplete_Class) { - return $a; - } - - $classProperties = self::$classProperties[$class] ??= self::getClassProperties(new \ReflectionClass($class)); - $a = array_replace($classProperties, $a); - - if ($a) { - $debugClass ??= get_debug_type($obj); - - $i = 0; - $prefixedKeys = []; - foreach ($a as $k => $v) { - if ("\0" !== ($k[0] ?? '')) { - if (!isset($classProperties[$k])) { - $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k; - } - } elseif ($debugClass !== $class && 1 === strpos($k, $class)) { - $prefixedKeys[$i] = "\0".$debugClass.strrchr($k, "\0"); - } - ++$i; - } - if ($prefixedKeys) { - $keys = array_keys($a); - foreach ($prefixedKeys as $i => $k) { - $keys[$i] = $k; - } - $a = array_combine($keys, $a); - } - } - - if ($hasDebugInfo && \is_array($debugInfo)) { - foreach ($debugInfo as $k => $v) { - if (!isset($k[0]) || "\0" !== $k[0]) { - if (\array_key_exists(self::PREFIX_DYNAMIC.$k, $a)) { - continue; - } - $k = self::PREFIX_VIRTUAL.$k; - } - - unset($a[$k]); - $a[$k] = $v; - } - } - - return $a; - } - - /** - * Filters out the specified properties. - * - * By default, a single match in the $filter bit field filters properties out, following an "or" logic. - * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed. - * - * @param array $a The array containing the properties to filter - * @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out - * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set - * @param int|null &$count Set to the number of removed properties - */ - public static function filter(array $a, int $filter, array $listedProperties = [], ?int &$count = 0): array - { - $count = 0; - - foreach ($a as $k => $v) { - $type = self::EXCLUDE_STRICT & $filter; - - if (null === $v) { - $type |= self::EXCLUDE_NULL & $filter; - $type |= self::EXCLUDE_EMPTY & $filter; - } elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || [] === $v) { - $type |= self::EXCLUDE_EMPTY & $filter; - } elseif ($v instanceof UninitializedStub) { - $type |= self::EXCLUDE_UNINITIALIZED & $filter; - } - if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) { - $type |= self::EXCLUDE_NOT_IMPORTANT; - } - if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) { - $type |= self::EXCLUDE_VERBOSE; - } - - if (!isset($k[1]) || "\0" !== $k[0]) { - $type |= self::EXCLUDE_PUBLIC & $filter; - } elseif ('~' === $k[1]) { - $type |= self::EXCLUDE_VIRTUAL & $filter; - } elseif ('+' === $k[1]) { - $type |= self::EXCLUDE_DYNAMIC & $filter; - } elseif ('*' === $k[1]) { - $type |= self::EXCLUDE_PROTECTED & $filter; - } else { - $type |= self::EXCLUDE_PRIVATE & $filter; - } - - if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) { - unset($a[$k]); - ++$count; - } - } - - return $a; - } - - public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, bool $isNested): array - { - if (isset($a['__PHP_Incomplete_Class_Name'])) { - $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')'; - unset($a['__PHP_Incomplete_Class_Name']); - } - - return $a; - } - - private static function getClassProperties(\ReflectionClass $class): array - { - $classProperties = []; - $className = $class->name; - - if ($parent = $class->getParentClass()) { - $classProperties += self::$classProperties[$parent->name] ??= self::getClassProperties($parent); - } - - foreach ($class->getProperties() as $p) { - if ($p->isStatic()) { - continue; - } - - $classProperties[match (true) { - $p->isPublic() => $p->name, - $p->isProtected() => self::PREFIX_PROTECTED.$p->name, - default => "\0".$className."\0".$p->name, - }] = new UninitializedStub($p); - } - - return $classProperties; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php deleted file mode 100644 index 914728663..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ClassStub.php +++ /dev/null @@ -1,107 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents a PHP class identifier. - * - * @author Nicolas Grekas - */ -class ClassStub extends ConstStub -{ - /** - * @param string $identifier A PHP identifier, e.g. a class, method, interface, etc. name - * @param callable $callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier - */ - public function __construct(string $identifier, callable|array|string|null $callable = null) - { - $this->value = $identifier; - - try { - if (null !== $callable) { - if ($callable instanceof \Closure) { - $r = new \ReflectionFunction($callable); - } elseif (\is_object($callable)) { - $r = [$callable, '__invoke']; - } elseif (\is_array($callable)) { - $r = $callable; - } elseif (false !== $i = strpos($callable, '::')) { - $r = [substr($callable, 0, $i), substr($callable, 2 + $i)]; - } else { - $r = new \ReflectionFunction($callable); - } - } elseif (0 < $i = strpos($identifier, '::') ?: strpos($identifier, '->')) { - $r = [substr($identifier, 0, $i), substr($identifier, 2 + $i)]; - } else { - $r = new \ReflectionClass($identifier); - } - - if (\is_array($r)) { - try { - $r = new \ReflectionMethod($r[0], $r[1]); - } catch (\ReflectionException) { - $r = new \ReflectionClass($r[0]); - } - } - - if (str_contains($identifier, "@anonymous\0")) { - $this->value = $identifier = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $identifier); - } - - if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) { - $s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE); - $s = ReflectionCaster::getSignature($s); - - if (str_ends_with($identifier, '()')) { - $this->value = substr_replace($identifier, $s, -2); - } else { - $this->value .= $s; - } - } - } catch (\ReflectionException) { - return; - } finally { - if (0 < $i = strrpos($this->value, '\\')) { - $this->attr['ellipsis'] = \strlen($this->value) - $i; - $this->attr['ellipsis-type'] = 'class'; - $this->attr['ellipsis-tail'] = 1; - } - } - - if ($f = $r->getFileName()) { - $this->attr['file'] = $f; - $this->attr['line'] = $r->getStartLine(); - } - } - - /** - * @return mixed - */ - public static function wrapCallable(mixed $callable) - { - if (\is_object($callable) || !\is_callable($callable)) { - return $callable; - } - - if (!\is_array($callable)) { - $callable = new static($callable, $callable); - } elseif (\is_string($callable[0])) { - $callable[0] = new static($callable[0], $callable); - } else { - $callable[1] = new static($callable[1], $callable); - } - - return $callable; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php deleted file mode 100644 index 587c6c398..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ConstStub.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents a PHP constant and its value. - * - * @author Nicolas Grekas - */ -class ConstStub extends Stub -{ - public function __construct(string $name, string|int|float|null $value = null) - { - $this->class = $name; - $this->value = 1 < \func_num_args() ? $value : $name; - } - - public function __toString(): string - { - return (string) $this->value; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php deleted file mode 100644 index 0e4fb363d..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutArrayStub.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -/** - * Represents a cut array. - * - * @author Nicolas Grekas - */ -class CutArrayStub extends CutStub -{ - public $preservedSubset; - - public function __construct(array $value, array $preservedKeys) - { - parent::__construct($value); - - $this->preservedSubset = array_intersect_key($value, array_flip($preservedKeys)); - $this->cut -= \count($this->preservedSubset); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php deleted file mode 100644 index 772399ef6..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/CutStub.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents the main properties of a PHP variable, pre-casted by a caster. - * - * @author Nicolas Grekas - */ -class CutStub extends Stub -{ - public function __construct(mixed $value) - { - $this->value = $value; - - switch (\gettype($value)) { - case 'object': - $this->type = self::TYPE_OBJECT; - $this->class = $value::class; - - if ($value instanceof \Closure) { - ReflectionCaster::castClosure($value, [], $this, true, Caster::EXCLUDE_VERBOSE); - } - - $this->cut = -1; - break; - - case 'array': - $this->type = self::TYPE_ARRAY; - $this->class = self::ARRAY_ASSOC; - $this->cut = $this->value = \count($value); - break; - - case 'resource': - case 'unknown type': - case 'resource (closed)': - $this->type = self::TYPE_RESOURCE; - $this->handle = (int) $value; - if ('Unknown' === $this->class = @get_resource_type($value)) { - $this->class = 'Closed'; - } - $this->cut = -1; - break; - - case 'string': - $this->type = self::TYPE_STRING; - $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; - $this->cut = self::STRING_BINARY === $this->class ? \strlen($value) : mb_strlen($value, 'UTF-8'); - $this->value = ''; - break; - } - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php deleted file mode 100644 index d2d3fc129..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DOMCaster.php +++ /dev/null @@ -1,312 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts DOM related classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class DOMCaster -{ - private const ERROR_CODES = [ - \DOM_PHP_ERR => 'DOM_PHP_ERR', - \DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR', - \DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR', - \DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR', - \DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR', - \DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR', - \DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR', - \DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR', - \DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR', - \DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR', - \DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR', - \DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR', - \DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR', - \DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR', - \DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR', - \DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR', - \DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR', - ]; - - private const NODE_TYPES = [ - \XML_ELEMENT_NODE => 'XML_ELEMENT_NODE', - \XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE', - \XML_TEXT_NODE => 'XML_TEXT_NODE', - \XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE', - \XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE', - \XML_ENTITY_NODE => 'XML_ENTITY_NODE', - \XML_PI_NODE => 'XML_PI_NODE', - \XML_COMMENT_NODE => 'XML_COMMENT_NODE', - \XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE', - \XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE', - \XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE', - \XML_NOTATION_NODE => 'XML_NOTATION_NODE', - \XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE', - \XML_DTD_NODE => 'XML_DTD_NODE', - \XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE', - \XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE', - \XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE', - \XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE', - ]; - - /** - * @return array - */ - public static function castException(\DOMException $e, array $a, Stub $stub, bool $isNested) - { - $k = Caster::PREFIX_PROTECTED.'code'; - if (isset($a[$k], self::ERROR_CODES[$a[$k]])) { - $a[$k] = new ConstStub(self::ERROR_CODES[$a[$k]], $a[$k]); - } - - return $a; - } - - /** - * @return array - */ - public static function castLength($dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'length' => $dom->length, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castImplementation(\DOMImplementation $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - Caster::PREFIX_VIRTUAL.'Core' => '1.0', - Caster::PREFIX_VIRTUAL.'XML' => '2.0', - ]; - - return $a; - } - - /** - * @return array - */ - public static function castNode(\DOMNode $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'nodeName' => $dom->nodeName, - 'nodeValue' => new CutStub($dom->nodeValue), - 'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType), - 'parentNode' => new CutStub($dom->parentNode), - 'childNodes' => $dom->childNodes, - 'firstChild' => new CutStub($dom->firstChild), - 'lastChild' => new CutStub($dom->lastChild), - 'previousSibling' => new CutStub($dom->previousSibling), - 'nextSibling' => new CutStub($dom->nextSibling), - 'attributes' => $dom->attributes, - 'ownerDocument' => new CutStub($dom->ownerDocument), - 'namespaceURI' => $dom->namespaceURI, - 'prefix' => $dom->prefix, - 'localName' => $dom->localName, - 'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI, - 'textContent' => new CutStub($dom->textContent), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'nodeName' => $dom->nodeName, - 'nodeValue' => new CutStub($dom->nodeValue), - 'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType), - 'prefix' => $dom->prefix, - 'localName' => $dom->localName, - 'namespaceURI' => $dom->namespaceURI, - 'ownerDocument' => new CutStub($dom->ownerDocument), - 'parentNode' => new CutStub($dom->parentNode), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $a += [ - 'doctype' => $dom->doctype, - 'implementation' => $dom->implementation, - 'documentElement' => new CutStub($dom->documentElement), - 'actualEncoding' => $dom->actualEncoding, - 'encoding' => $dom->encoding, - 'xmlEncoding' => $dom->xmlEncoding, - 'standalone' => $dom->standalone, - 'xmlStandalone' => $dom->xmlStandalone, - 'version' => $dom->version, - 'xmlVersion' => $dom->xmlVersion, - 'strictErrorChecking' => $dom->strictErrorChecking, - 'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI, - 'config' => $dom->config, - 'formatOutput' => $dom->formatOutput, - 'validateOnParse' => $dom->validateOnParse, - 'resolveExternals' => $dom->resolveExternals, - 'preserveWhiteSpace' => $dom->preserveWhiteSpace, - 'recover' => $dom->recover, - 'substituteEntities' => $dom->substituteEntities, - ]; - - if (!($filter & Caster::EXCLUDE_VERBOSE)) { - $formatOutput = $dom->formatOutput; - $dom->formatOutput = true; - $a += [Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()]; - $dom->formatOutput = $formatOutput; - } - - return $a; - } - - /** - * @return array - */ - public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'data' => $dom->data, - 'length' => $dom->length, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'name' => $dom->name, - 'specified' => $dom->specified, - 'value' => $dom->value, - 'ownerElement' => $dom->ownerElement, - 'schemaTypeInfo' => $dom->schemaTypeInfo, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castElement(\DOMElement $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'tagName' => $dom->tagName, - 'schemaTypeInfo' => $dom->schemaTypeInfo, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castText(\DOMText $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'wholeText' => $dom->wholeText, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'name' => $dom->name, - 'entities' => $dom->entities, - 'notations' => $dom->notations, - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - 'internalSubset' => $dom->internalSubset, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - 'notationName' => $dom->notationName, - 'actualEncoding' => $dom->actualEncoding, - 'encoding' => $dom->encoding, - 'version' => $dom->version, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'target' => $dom->target, - 'data' => $dom->data, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, bool $isNested) - { - $a += [ - 'document' => $dom->document, - ]; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php deleted file mode 100644 index a0cbddb76..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DateCaster.php +++ /dev/null @@ -1,139 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts DateTimeInterface related classes to array representation. - * - * @author Dany Maillard - * - * @final - */ -class DateCaster -{ - private const PERIOD_LIMIT = 3; - - /** - * @return array - */ - public static function castDateTime(\DateTimeInterface $d, array $a, Stub $stub, bool $isNested, int $filter) - { - $prefix = Caster::PREFIX_VIRTUAL; - $location = $d->getTimezone() ? $d->getTimezone()->getLocation() : null; - $fromNow = (new \DateTimeImmutable())->diff($d); - - $title = $d->format('l, F j, Y') - ."\n".self::formatInterval($fromNow).' from now' - .($location ? ($d->format('I') ? "\nDST On" : "\nDST Off") : '') - ; - - unset( - $a[Caster::PREFIX_DYNAMIC.'date'], - $a[Caster::PREFIX_DYNAMIC.'timezone'], - $a[Caster::PREFIX_DYNAMIC.'timezone_type'] - ); - $a[$prefix.'date'] = new ConstStub(self::formatDateTime($d, $location ? ' e (P)' : ' P'), $title); - - $stub->class .= $d->format(' @U'); - - return $a; - } - - /** - * @return array - */ - public static function castInterval(\DateInterval $interval, array $a, Stub $stub, bool $isNested, int $filter) - { - $now = new \DateTimeImmutable('@0', new \DateTimeZone('UTC')); - $numberOfSeconds = $now->add($interval)->getTimestamp() - $now->getTimestamp(); - $title = number_format($numberOfSeconds, 0, '.', ' ').'s'; - - $i = [Caster::PREFIX_VIRTUAL.'interval' => new ConstStub(self::formatInterval($interval), $title)]; - - return $filter & Caster::EXCLUDE_VERBOSE ? $i : $i + $a; - } - - private static function formatInterval(\DateInterval $i): string - { - $format = '%R '; - - if (0 === $i->y && 0 === $i->m && ($i->h >= 24 || $i->i >= 60 || $i->s >= 60)) { - $d = new \DateTimeImmutable('@0', new \DateTimeZone('UTC')); - $i = $d->diff($d->add($i)); // recalculate carry over points - $format .= 0 < $i->days ? '%ad ' : ''; - } else { - $format .= ($i->y ? '%yy ' : '').($i->m ? '%mm ' : '').($i->d ? '%dd ' : ''); - } - - $format .= $i->h || $i->i || $i->s || $i->f ? '%H:%I:'.self::formatSeconds($i->s, substr($i->f, 2)) : ''; - $format = '%R ' === $format ? '0s' : $format; - - return $i->format(rtrim($format)); - } - - /** - * @return array - */ - public static function castTimeZone(\DateTimeZone $timeZone, array $a, Stub $stub, bool $isNested, int $filter) - { - $location = $timeZone->getLocation(); - $formatted = (new \DateTimeImmutable('now', $timeZone))->format($location ? 'e (P)' : 'P'); - $title = $location && \extension_loaded('intl') ? \Locale::getDisplayRegion('-'.$location['country_code']) : ''; - - $z = [Caster::PREFIX_VIRTUAL.'timezone' => new ConstStub($formatted, $title)]; - - return $filter & Caster::EXCLUDE_VERBOSE ? $z : $z + $a; - } - - /** - * @return array - */ - public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, bool $isNested, int $filter) - { - $dates = []; - foreach (clone $p as $i => $d) { - if (self::PERIOD_LIMIT === $i) { - $now = new \DateTimeImmutable('now', new \DateTimeZone('UTC')); - $dates[] = sprintf('%s more', ($end = $p->getEndDate()) - ? ceil(($end->format('U.u') - $d->format('U.u')) / ((int) $now->add($p->getDateInterval())->format('U.u') - (int) $now->format('U.u'))) - : $p->recurrences - $i - ); - break; - } - $dates[] = sprintf('%s) %s', $i + 1, self::formatDateTime($d)); - } - - $period = sprintf( - 'every %s, from %s%s %s', - self::formatInterval($p->getDateInterval()), - $p->include_start_date ? '[' : ']', - self::formatDateTime($p->getStartDate()), - ($end = $p->getEndDate()) ? 'to '.self::formatDateTime($end).(\PHP_VERSION_ID >= 80200 && $p->include_end_date ? ']' : '[') : 'recurring '.$p->recurrences.' time/s' - ); - - $p = [Caster::PREFIX_VIRTUAL.'period' => new ConstStub($period, implode("\n", $dates))]; - - return $filter & Caster::EXCLUDE_VERBOSE ? $p : $p + $a; - } - - private static function formatDateTime(\DateTimeInterface $d, string $extra = ''): string - { - return $d->format('Y-m-d H:i:'.self::formatSeconds($d->format('s'), $d->format('u')).$extra); - } - - private static function formatSeconds(string $s, string $us): string - { - return sprintf('%02d.%s', $s, 0 === ($len = \strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us)); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php deleted file mode 100644 index 3120c3d91..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DoctrineCaster.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Doctrine\Common\Proxy\Proxy as CommonProxy; -use Doctrine\ORM\PersistentCollection; -use Doctrine\ORM\Proxy\Proxy as OrmProxy; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Doctrine related classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class DoctrineCaster -{ - /** - * @return array - */ - public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, bool $isNested) - { - foreach (['__cloner__', '__initializer__'] as $k) { - if (\array_key_exists($k, $a)) { - unset($a[$k]); - ++$stub->cut; - } - } - - return $a; - } - - /** - * @return array - */ - public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, bool $isNested) - { - foreach (['_entityPersister', '_identifier'] as $k) { - if (\array_key_exists($k = "\0Doctrine\\ORM\\Proxy\\Proxy\0".$k, $a)) { - unset($a[$k]); - ++$stub->cut; - } - } - - return $a; - } - - /** - * @return array - */ - public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, bool $isNested) - { - foreach (['snapshot', 'association', 'typeClass'] as $k) { - if (\array_key_exists($k = "\0Doctrine\\ORM\\PersistentCollection\0".$k, $a)) { - $a[$k] = new CutStub($a[$k]); - } - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php deleted file mode 100644 index b34b67004..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsCaster.php +++ /dev/null @@ -1,70 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Ds\Collection; -use Ds\Map; -use Ds\Pair; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Ds extension classes to array representation. - * - * @author Jáchym Toušek - * - * @final - */ -class DsCaster -{ - public static function castCollection(Collection $c, array $a, Stub $stub, bool $isNested): array - { - $a[Caster::PREFIX_VIRTUAL.'count'] = $c->count(); - $a[Caster::PREFIX_VIRTUAL.'capacity'] = $c->capacity(); - - if (!$c instanceof Map) { - $a += $c->toArray(); - } - - return $a; - } - - public static function castMap(Map $c, array $a, Stub $stub, bool $isNested): array - { - foreach ($c as $k => $v) { - $a[] = new DsPairStub($k, $v); - } - - return $a; - } - - public static function castPair(Pair $c, array $a, Stub $stub, bool $isNested): array - { - foreach ($c->toArray() as $k => $v) { - $a[Caster::PREFIX_VIRTUAL.$k] = $v; - } - - return $a; - } - - public static function castPairStub(DsPairStub $c, array $a, Stub $stub, bool $isNested): array - { - if ($isNested) { - $stub->class = Pair::class; - $stub->value = null; - $stub->handle = 0; - - $a = $c->value; - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php deleted file mode 100644 index afa2727b1..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/DsPairStub.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Nicolas Grekas - */ -class DsPairStub extends Stub -{ - public function __construct(mixed $key, mixed $value) - { - $this->value = [ - Caster::PREFIX_VIRTUAL.'key' => $key, - Caster::PREFIX_VIRTUAL.'value' => $value, - ]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php deleted file mode 100644 index 7a4e98a21..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/EnumStub.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents an enumeration of values. - * - * @author Nicolas Grekas - */ -class EnumStub extends Stub -{ - public $dumpKeys = true; - - public function __construct(array $values, bool $dumpKeys = true) - { - $this->value = $values; - $this->dumpKeys = $dumpKeys; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php deleted file mode 100644 index 02efb1b02..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ExceptionCaster.php +++ /dev/null @@ -1,419 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\ErrorHandler\Exception\FlattenException; -use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext; -use Symfony\Component\VarDumper\Cloner\Stub; -use Symfony\Component\VarDumper\Exception\ThrowingCasterException; - -/** - * Casts common Exception classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class ExceptionCaster -{ - public static int $srcContext = 1; - public static bool $traceArgs = true; - public static array $errorTypes = [ - \E_DEPRECATED => 'E_DEPRECATED', - \E_USER_DEPRECATED => 'E_USER_DEPRECATED', - \E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', - \E_ERROR => 'E_ERROR', - \E_WARNING => 'E_WARNING', - \E_PARSE => 'E_PARSE', - \E_NOTICE => 'E_NOTICE', - \E_CORE_ERROR => 'E_CORE_ERROR', - \E_CORE_WARNING => 'E_CORE_WARNING', - \E_COMPILE_ERROR => 'E_COMPILE_ERROR', - \E_COMPILE_WARNING => 'E_COMPILE_WARNING', - \E_USER_ERROR => 'E_USER_ERROR', - \E_USER_WARNING => 'E_USER_WARNING', - \E_USER_NOTICE => 'E_USER_NOTICE', - \E_STRICT => 'E_STRICT', - ]; - - private static array $framesCache = []; - - /** - * @return array - */ - public static function castError(\Error $e, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter); - } - - /** - * @return array - */ - public static function castException(\Exception $e, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter); - } - - /** - * @return array - */ - public static function castErrorException(\ErrorException $e, array $a, Stub $stub, bool $isNested) - { - if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) { - $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); - } - - return $a; - } - - /** - * @return array - */ - public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, bool $isNested) - { - $trace = Caster::PREFIX_VIRTUAL.'trace'; - $prefix = Caster::PREFIX_PROTECTED; - $xPrefix = "\0Exception\0"; - - if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) { - $b = (array) $a[$xPrefix.'previous']; - $class = get_debug_type($a[$xPrefix.'previous']); - self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']); - $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value)); - } - - unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']); - - return $a; - } - - /** - * @return array - */ - public static function castSilencedErrorContext(SilencedErrorContext $e, array $a, Stub $stub, bool $isNested) - { - $sPrefix = "\0".SilencedErrorContext::class."\0"; - - if (!isset($a[$s = $sPrefix.'severity'])) { - return $a; - } - - if (isset(self::$errorTypes[$a[$s]])) { - $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); - } - - $trace = [[ - 'file' => $a[$sPrefix.'file'], - 'line' => $a[$sPrefix.'line'], - ]]; - - if (isset($a[$sPrefix.'trace'])) { - $trace = array_merge($trace, $a[$sPrefix.'trace']); - } - - unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']); - $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs); - - return $a; - } - - /** - * @return array - */ - public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, bool $isNested) - { - if (!$isNested) { - return $a; - } - $stub->class = ''; - $stub->handle = 0; - $frames = $trace->value; - $prefix = Caster::PREFIX_VIRTUAL; - - $a = []; - $j = \count($frames); - if (0 > $i = $trace->sliceOffset) { - $i = max(0, $j + $i); - } - if (!isset($trace->value[$i])) { - return []; - } - $lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : ''; - $frames[] = ['function' => '']; - $collapse = false; - - for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) { - $f = $frames[$i]; - $call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'] : '???'; - - $frame = new FrameStub( - [ - 'object' => $f['object'] ?? null, - 'class' => $f['class'] ?? null, - 'type' => $f['type'] ?? null, - 'function' => $f['function'] ?? null, - ] + $frames[$i - 1], - false, - true - ); - $f = self::castFrameStub($frame, [], $frame, true); - if (isset($f[$prefix.'src'])) { - foreach ($f[$prefix.'src']->value as $label => $frame) { - if (str_starts_with($label, "\0~collapse=0")) { - if ($collapse) { - $label = substr_replace($label, '1', 11, 1); - } else { - $collapse = true; - } - } - $label = substr_replace($label, "title=Stack level $j.&", 2, 0); - } - $f = $frames[$i - 1]; - if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) { - $frame->value['arguments'] = new ArgsStub($f['args'], $f['function'] ?? null, $f['class'] ?? null); - } - } elseif ('???' !== $lastCall) { - $label = new ClassStub($lastCall); - if (isset($label->attr['ellipsis'])) { - $label->attr['ellipsis'] += 2; - $label = substr_replace($prefix, "ellipsis-type=class&ellipsis={$label->attr['ellipsis']}&ellipsis-tail=1&title=Stack level $j.", 2, 0).$label->value.'()'; - } else { - $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$label->value.'()'; - } - } else { - $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall; - } - $a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame; - - $lastCall = $call; - } - if (null !== $trace->sliceLength) { - $a = \array_slice($a, 0, $trace->sliceLength, true); - } - - return $a; - } - - /** - * @return array - */ - public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, bool $isNested) - { - if (!$isNested) { - return $a; - } - $f = $frame->value; - $prefix = Caster::PREFIX_VIRTUAL; - - if (isset($f['file'], $f['line'])) { - $cacheKey = $f; - unset($cacheKey['object'], $cacheKey['args']); - $cacheKey[] = self::$srcContext; - $cacheKey = implode('-', $cacheKey); - - if (isset(self::$framesCache[$cacheKey])) { - $a[$prefix.'src'] = self::$framesCache[$cacheKey]; - } else { - if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) { - $f['file'] = substr($f['file'], 0, -\strlen($match[0])); - $f['line'] = (int) $match[1]; - } - $src = $f['line']; - $srcKey = $f['file']; - $ellipsis = new LinkStub($srcKey, 0); - $srcAttr = 'collapse='.(int) $ellipsis->inVendor; - $ellipsisTail = $ellipsis->attr['ellipsis-tail'] ?? 0; - $ellipsis = $ellipsis->attr['ellipsis'] ?? 0; - - if (is_file($f['file']) && 0 <= self::$srcContext) { - if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) { - $template = null; - if (isset($f['object'])) { - $template = $f['object']; - } elseif ((new \ReflectionClass($f['class']))->isInstantiable()) { - $template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class'])); - } - if (null !== $template) { - $ellipsis = 0; - $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : ''); - $templateInfo = $template->getDebugInfo(); - if (isset($templateInfo[$f['line']])) { - if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) { - $templatePath = null; - } - if ($templateSrc) { - $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f); - $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']]; - } - } - } - } - if ($srcKey == $f['file']) { - $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f); - $srcKey .= ':'.$f['line']; - if ($ellipsis) { - $ellipsis += 1 + \strlen($f['line']); - } - } - $srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']); - } else { - $srcAttr .= '&separator=:'; - } - $srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : ''; - self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(["\0~$srcAttr\0$srcKey" => $src]); - } - } - - unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']); - if ($frame->inTraceStub) { - unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']); - } - foreach ($a as $k => $v) { - if (!$v) { - unset($a[$k]); - } - } - if ($frame->keepArgs && !empty($f['args'])) { - $a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']); - } - - return $a; - } - - /** - * @return array - */ - public static function castFlattenException(FlattenException $e, array $a, Stub $stub, bool $isNested) - { - if ($isNested) { - $k = sprintf(Caster::PATTERN_PRIVATE, FlattenException::class, 'traceAsString'); - $a[$k] = new CutStub($a[$k]); - } - - return $a; - } - - private static function filterExceptionArray(string $xClass, array $a, string $xPrefix, int $filter): array - { - if (isset($a[$xPrefix.'trace'])) { - $trace = $a[$xPrefix.'trace']; - unset($a[$xPrefix.'trace']); // Ensures the trace is always last - } else { - $trace = []; - } - - if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) { - if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { - self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); - } - $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs); - } - if (empty($a[$xPrefix.'previous'])) { - unset($a[$xPrefix.'previous']); - } - unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message']); - - if (isset($a[Caster::PREFIX_PROTECTED.'message']) && str_contains($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) { - $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $a[Caster::PREFIX_PROTECTED.'message']); - } - - if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { - $a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); - } - - return $a; - } - - private static function traceUnshift(array &$trace, ?string $class, string $file, int $line): void - { - if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) { - return; - } - array_unshift($trace, [ - 'function' => $class ? 'new '.$class : null, - 'file' => $file, - 'line' => $line, - ]); - } - - private static function extractSource(string $srcLines, int $line, int $srcContext, string $lang, ?string $file, array $frame): EnumStub - { - $srcLines = explode("\n", $srcLines); - $src = []; - - for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) { - $src[] = ($srcLines[$i] ?? '')."\n"; - } - - if ($frame['function'] ?? false) { - $stub = new CutStub(new \stdClass()); - $stub->class = (isset($frame['class']) ? $frame['class'].$frame['type'] : '').$frame['function']; - $stub->type = Stub::TYPE_OBJECT; - $stub->attr['cut_hash'] = true; - $stub->attr['file'] = $frame['file']; - $stub->attr['line'] = $frame['line']; - - try { - $caller = isset($frame['class']) ? new \ReflectionMethod($frame['class'], $frame['function']) : new \ReflectionFunction($frame['function']); - $stub->class .= ReflectionCaster::getSignature(ReflectionCaster::castFunctionAbstract($caller, [], $stub, true, Caster::EXCLUDE_VERBOSE)); - - if ($f = $caller->getFileName()) { - $stub->attr['file'] = $f; - $stub->attr['line'] = $caller->getStartLine(); - } - } catch (\ReflectionException) { - // ignore fake class/function - } - - $srcLines = ["\0~separator=\0" => $stub]; - } else { - $stub = null; - $srcLines = []; - } - - $ltrim = 0; - do { - $pad = null; - for ($i = $srcContext << 1; $i >= 0; --$i) { - if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) { - $pad ??= $c; - if ((' ' !== $c && "\t" !== $c) || $pad !== $c) { - break; - } - } - } - ++$ltrim; - } while (0 > $i && null !== $pad); - - --$ltrim; - - foreach ($src as $i => $c) { - if ($ltrim) { - $c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t"); - } - $c = substr($c, 0, -1); - if ($i !== $srcContext) { - $c = new ConstStub('default', $c); - } else { - $c = new ConstStub($c, $stub ? 'in '.$stub->class : ''); - if (null !== $file) { - $c->attr['file'] = $file; - $c->attr['line'] = $line; - } - } - $c->attr['lang'] = $lang; - $srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c; - } - - return new EnumStub($srcLines); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FFICaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FFICaster.php deleted file mode 100644 index f1984eef3..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FFICaster.php +++ /dev/null @@ -1,161 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use FFI\CData; -use FFI\CType; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts FFI extension classes to array representation. - * - * @author Nesmeyanov Kirill - */ -final class FFICaster -{ - /** - * In case of "char*" contains a string, the length of which depends on - * some other parameter, then during the generation of the string it is - * possible to go beyond the allowable memory area. - * - * This restriction serves to ensure that processing does not take - * up the entire allowable PHP memory limit. - */ - private const MAX_STRING_LENGTH = 255; - - public static function castCTypeOrCData(CData|CType $data, array $args, Stub $stub): array - { - if ($data instanceof CType) { - $type = $data; - $data = null; - } else { - $type = \FFI::typeof($data); - } - - $stub->class = sprintf('%s<%s> size %d align %d', ($data ?? $type)::class, $type->getName(), $type->getSize(), $type->getAlignment()); - - return match ($type->getKind()) { - CType::TYPE_FLOAT, - CType::TYPE_DOUBLE, - \defined('\FFI\CType::TYPE_LONGDOUBLE') ? CType::TYPE_LONGDOUBLE : -1, - CType::TYPE_UINT8, - CType::TYPE_SINT8, - CType::TYPE_UINT16, - CType::TYPE_SINT16, - CType::TYPE_UINT32, - CType::TYPE_SINT32, - CType::TYPE_UINT64, - CType::TYPE_SINT64, - CType::TYPE_BOOL, - CType::TYPE_CHAR, - CType::TYPE_ENUM => null !== $data ? [Caster::PREFIX_VIRTUAL.'cdata' => $data->cdata] : [], - CType::TYPE_POINTER => self::castFFIPointer($stub, $type, $data), - CType::TYPE_STRUCT => self::castFFIStructLike($type, $data), - CType::TYPE_FUNC => self::castFFIFunction($stub, $type), - default => $args, - }; - } - - private static function castFFIFunction(Stub $stub, CType $type): array - { - $arguments = []; - - for ($i = 0, $count = $type->getFuncParameterCount(); $i < $count; ++$i) { - $param = $type->getFuncParameterType($i); - - $arguments[] = $param->getName(); - } - - $abi = match ($type->getFuncABI()) { - CType::ABI_DEFAULT, - CType::ABI_CDECL => '[cdecl]', - CType::ABI_FASTCALL => '[fastcall]', - CType::ABI_THISCALL => '[thiscall]', - CType::ABI_STDCALL => '[stdcall]', - CType::ABI_PASCAL => '[pascal]', - CType::ABI_REGISTER => '[register]', - CType::ABI_MS => '[ms]', - CType::ABI_SYSV => '[sysv]', - CType::ABI_VECTORCALL => '[vectorcall]', - default => '[unknown abi]' - }; - - $returnType = $type->getFuncReturnType(); - - $stub->class = $abi.' callable('.implode(', ', $arguments).'): ' - .$returnType->getName(); - - return [Caster::PREFIX_VIRTUAL.'returnType' => $returnType]; - } - - private static function castFFIPointer(Stub $stub, CType $type, ?CData $data = null): array - { - $ptr = $type->getPointerType(); - - if (null === $data) { - return [Caster::PREFIX_VIRTUAL.'0' => $ptr]; - } - - return match ($ptr->getKind()) { - CType::TYPE_CHAR => [Caster::PREFIX_VIRTUAL.'cdata' => self::castFFIStringValue($data)], - CType::TYPE_FUNC => self::castFFIFunction($stub, $ptr), - default => [Caster::PREFIX_VIRTUAL.'cdata' => $data[0]], - }; - } - - private static function castFFIStringValue(CData $data): string|CutStub - { - $result = []; - - for ($i = 0; $i < self::MAX_STRING_LENGTH; ++$i) { - $result[$i] = $data[$i]; - - if ("\0" === $result[$i]) { - return implode('', $result); - } - } - - $string = implode('', $result); - $stub = new CutStub($string); - $stub->cut = -1; - $stub->value = $string; - - return $stub; - } - - private static function castFFIStructLike(CType $type, ?CData $data = null): array - { - $isUnion = ($type->getAttributes() & CType::ATTR_UNION) === CType::ATTR_UNION; - - $result = []; - - foreach ($type->getStructFieldNames() as $name) { - $field = $type->getStructFieldType($name); - - // Retrieving the value of a field from a union containing - // a pointer is not a safe operation, because may contain - // incorrect data. - $isUnsafe = $isUnion && CType::TYPE_POINTER === $field->getKind(); - - if ($isUnsafe) { - $result[Caster::PREFIX_VIRTUAL.$name.'?'] = $field; - } elseif (null === $data) { - $result[Caster::PREFIX_VIRTUAL.$name] = $field; - } else { - $fieldName = $data->{$name} instanceof CData ? '' : $field->getName().' '; - $result[Caster::PREFIX_VIRTUAL.$fieldName.$name] = $data->{$name}; - } - } - - return $result; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FiberCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FiberCaster.php deleted file mode 100644 index b797dbd63..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FiberCaster.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Fiber related classes to array representation. - * - * @author Grégoire Pineau - */ -final class FiberCaster -{ - /** - * @return array - */ - public static function castFiber(\Fiber $fiber, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; - - if ($fiber->isTerminated()) { - $status = 'terminated'; - } elseif ($fiber->isRunning()) { - $status = 'running'; - } elseif ($fiber->isSuspended()) { - $status = 'suspended'; - } elseif ($fiber->isStarted()) { - $status = 'started'; - } else { - $status = 'not started'; - } - - $a[$prefix.'status'] = $status; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php deleted file mode 100644 index 878675528..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/FrameStub.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -/** - * Represents a single backtrace frame as returned by debug_backtrace() or Exception->getTrace(). - * - * @author Nicolas Grekas - */ -class FrameStub extends EnumStub -{ - public $keepArgs; - public $inTraceStub; - - public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false) - { - $this->value = $frame; - $this->keepArgs = $keepArgs; - $this->inTraceStub = $inTraceStub; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php deleted file mode 100644 index b018cc7f8..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/GmpCaster.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts GMP objects to array representation. - * - * @author Hamza Amrouche - * @author Nicolas Grekas - * - * @final - */ -class GmpCaster -{ - public static function castGmp(\GMP $gmp, array $a, Stub $stub, bool $isNested, int $filter): array - { - $a[Caster::PREFIX_VIRTUAL.'value'] = new ConstStub(gmp_strval($gmp), gmp_strval($gmp)); - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php deleted file mode 100644 index d1289da33..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImagineCaster.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Imagine\Image\ImageInterface; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Grégoire Pineau - */ -final class ImagineCaster -{ - public static function castImage(ImageInterface $c, array $a, Stub $stub, bool $isNested): array - { - $imgData = $c->get('png'); - if (\strlen($imgData) > 1 * 1000 * 1000) { - $a += [ - Caster::PREFIX_VIRTUAL.'image' => new ConstStub($c->getSize()), - ]; - } else { - $a += [ - Caster::PREFIX_VIRTUAL.'image' => new ImgStub($imgData, 'image/png', $c->getSize()), - ]; - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php deleted file mode 100644 index a16681f73..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ImgStub.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -/** - * @author Grégoire Pineau - */ -class ImgStub extends ConstStub -{ - public function __construct(string $data, string $contentType, string $size = '') - { - $this->value = ''; - $this->attr['img-data'] = $data; - $this->attr['img-size'] = $size; - $this->attr['content-type'] = $contentType; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php deleted file mode 100644 index a4590f4b5..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/IntlCaster.php +++ /dev/null @@ -1,187 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Nicolas Grekas - * @author Jan Schädlich - * - * @final - */ -class IntlCaster -{ - /** - * @return array - */ - public static function castMessageFormatter(\MessageFormatter $c, array $a, Stub $stub, bool $isNested) - { - $a += [ - Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), - Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), - ]; - - return self::castError($c, $a); - } - - /** - * @return array - */ - public static function castNumberFormatter(\NumberFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $a += [ - Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), - Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), - ]; - - if ($filter & Caster::EXCLUDE_VERBOSE) { - $stub->cut += 3; - - return self::castError($c, $a); - } - - $a += [ - Caster::PREFIX_VIRTUAL.'attributes' => new EnumStub( - [ - 'PARSE_INT_ONLY' => $c->getAttribute(\NumberFormatter::PARSE_INT_ONLY), - 'GROUPING_USED' => $c->getAttribute(\NumberFormatter::GROUPING_USED), - 'DECIMAL_ALWAYS_SHOWN' => $c->getAttribute(\NumberFormatter::DECIMAL_ALWAYS_SHOWN), - 'MAX_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_INTEGER_DIGITS), - 'MIN_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_INTEGER_DIGITS), - 'INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::INTEGER_DIGITS), - 'MAX_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_FRACTION_DIGITS), - 'MIN_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_FRACTION_DIGITS), - 'FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::FRACTION_DIGITS), - 'MULTIPLIER' => $c->getAttribute(\NumberFormatter::MULTIPLIER), - 'GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::GROUPING_SIZE), - 'ROUNDING_MODE' => $c->getAttribute(\NumberFormatter::ROUNDING_MODE), - 'ROUNDING_INCREMENT' => $c->getAttribute(\NumberFormatter::ROUNDING_INCREMENT), - 'FORMAT_WIDTH' => $c->getAttribute(\NumberFormatter::FORMAT_WIDTH), - 'PADDING_POSITION' => $c->getAttribute(\NumberFormatter::PADDING_POSITION), - 'SECONDARY_GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE), - 'SIGNIFICANT_DIGITS_USED' => $c->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED), - 'MIN_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS), - 'MAX_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS), - 'LENIENT_PARSE' => $c->getAttribute(\NumberFormatter::LENIENT_PARSE), - ] - ), - Caster::PREFIX_VIRTUAL.'text_attributes' => new EnumStub( - [ - 'POSITIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX), - 'POSITIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_SUFFIX), - 'NEGATIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_PREFIX), - 'NEGATIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_SUFFIX), - 'PADDING_CHARACTER' => $c->getTextAttribute(\NumberFormatter::PADDING_CHARACTER), - 'CURRENCY_CODE' => $c->getTextAttribute(\NumberFormatter::CURRENCY_CODE), - 'DEFAULT_RULESET' => $c->getTextAttribute(\NumberFormatter::DEFAULT_RULESET), - 'PUBLIC_RULESETS' => $c->getTextAttribute(\NumberFormatter::PUBLIC_RULESETS), - ] - ), - Caster::PREFIX_VIRTUAL.'symbols' => new EnumStub( - [ - 'DECIMAL_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL), - 'GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL), - 'PATTERN_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::PATTERN_SEPARATOR_SYMBOL), - 'PERCENT_SYMBOL' => $c->getSymbol(\NumberFormatter::PERCENT_SYMBOL), - 'ZERO_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::ZERO_DIGIT_SYMBOL), - 'DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::DIGIT_SYMBOL), - 'MINUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::MINUS_SIGN_SYMBOL), - 'PLUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::PLUS_SIGN_SYMBOL), - 'CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::CURRENCY_SYMBOL), - 'INTL_CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL), - 'MONETARY_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL), - 'EXPONENTIAL_SYMBOL' => $c->getSymbol(\NumberFormatter::EXPONENTIAL_SYMBOL), - 'PERMILL_SYMBOL' => $c->getSymbol(\NumberFormatter::PERMILL_SYMBOL), - 'PAD_ESCAPE_SYMBOL' => $c->getSymbol(\NumberFormatter::PAD_ESCAPE_SYMBOL), - 'INFINITY_SYMBOL' => $c->getSymbol(\NumberFormatter::INFINITY_SYMBOL), - 'NAN_SYMBOL' => $c->getSymbol(\NumberFormatter::NAN_SYMBOL), - 'SIGNIFICANT_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL), - 'MONETARY_GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL), - ] - ), - ]; - - return self::castError($c, $a); - } - - /** - * @return array - */ - public static function castIntlTimeZone(\IntlTimeZone $c, array $a, Stub $stub, bool $isNested) - { - $a += [ - Caster::PREFIX_VIRTUAL.'display_name' => $c->getDisplayName(), - Caster::PREFIX_VIRTUAL.'id' => $c->getID(), - Caster::PREFIX_VIRTUAL.'raw_offset' => $c->getRawOffset(), - ]; - - if ($c->useDaylightTime()) { - $a += [ - Caster::PREFIX_VIRTUAL.'dst_savings' => $c->getDSTSavings(), - ]; - } - - return self::castError($c, $a); - } - - /** - * @return array - */ - public static function castIntlCalendar(\IntlCalendar $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $a += [ - Caster::PREFIX_VIRTUAL.'type' => $c->getType(), - Caster::PREFIX_VIRTUAL.'first_day_of_week' => $c->getFirstDayOfWeek(), - Caster::PREFIX_VIRTUAL.'minimal_days_in_first_week' => $c->getMinimalDaysInFirstWeek(), - Caster::PREFIX_VIRTUAL.'repeated_wall_time_option' => $c->getRepeatedWallTimeOption(), - Caster::PREFIX_VIRTUAL.'skipped_wall_time_option' => $c->getSkippedWallTimeOption(), - Caster::PREFIX_VIRTUAL.'time' => $c->getTime(), - Caster::PREFIX_VIRTUAL.'in_daylight_time' => $c->inDaylightTime(), - Caster::PREFIX_VIRTUAL.'is_lenient' => $c->isLenient(), - Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(), - ]; - - return self::castError($c, $a); - } - - /** - * @return array - */ - public static function castIntlDateFormatter(\IntlDateFormatter $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $a += [ - Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), - Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), - Caster::PREFIX_VIRTUAL.'calendar' => $c->getCalendar(), - Caster::PREFIX_VIRTUAL.'time_zone_id' => $c->getTimeZoneId(), - Caster::PREFIX_VIRTUAL.'time_type' => $c->getTimeType(), - Caster::PREFIX_VIRTUAL.'date_type' => $c->getDateType(), - Caster::PREFIX_VIRTUAL.'calendar_object' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getCalendarObject()) : $c->getCalendarObject(), - Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(), - ]; - - return self::castError($c, $a); - } - - private static function castError(object $c, array $a): array - { - if ($errorCode = $c->getErrorCode()) { - $a += [ - Caster::PREFIX_VIRTUAL.'error_code' => $errorCode, - Caster::PREFIX_VIRTUAL.'error_message' => $c->getErrorMessage(), - ]; - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php deleted file mode 100644 index 4930436df..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/LinkStub.php +++ /dev/null @@ -1,105 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -/** - * Represents a file or a URL. - * - * @author Nicolas Grekas - */ -class LinkStub extends ConstStub -{ - public $inVendor = false; - - private static array $vendorRoots; - private static array $composerRoots = []; - - public function __construct(string $label, int $line = 0, ?string $href = null) - { - $this->value = $label; - - if (!\is_string($href ??= $label)) { - return; - } - if (str_starts_with($href, 'file://')) { - if ($href === $label) { - $label = substr($label, 7); - } - $href = substr($href, 7); - } elseif (str_contains($href, '://')) { - $this->attr['href'] = $href; - - return; - } - if (!is_file($href)) { - return; - } - if ($line) { - $this->attr['line'] = $line; - } - if ($label !== $this->attr['file'] = realpath($href) ?: $href) { - return; - } - if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) { - $this->attr['ellipsis'] = \strlen($href) - \strlen($composerRoot) + 1; - $this->attr['ellipsis-type'] = 'path'; - $this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + \strlen(implode('', \array_slice(explode(\DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0); - } elseif (3 < \count($ellipsis = explode(\DIRECTORY_SEPARATOR, $href))) { - $this->attr['ellipsis'] = 2 + \strlen(implode('', \array_slice($ellipsis, -2))); - $this->attr['ellipsis-type'] = 'path'; - $this->attr['ellipsis-tail'] = 1; - } - } - - private function getComposerRoot(string $file, bool &$inVendor): string|false - { - if (!isset(self::$vendorRoots)) { - self::$vendorRoots = []; - - foreach (get_declared_classes() as $class) { - if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) { - $r = new \ReflectionClass($class); - $v = \dirname($r->getFileName(), 2); - if (is_file($v.'/composer/installed.json')) { - self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR; - } - } - } - } - $inVendor = false; - - if (isset(self::$composerRoots[$dir = \dirname($file)])) { - return self::$composerRoots[$dir]; - } - - foreach (self::$vendorRoots as $root) { - if ($inVendor = str_starts_with($file, $root)) { - return $root; - } - } - - $parent = $dir; - while (!@is_file($parent.'/composer.json')) { - if (!@file_exists($parent)) { - // open_basedir restriction in effect - break; - } - if ($parent === \dirname($parent)) { - return self::$composerRoots[$dir] = false; - } - - $parent = \dirname($parent); - } - - return self::$composerRoots[$dir] = $parent.\DIRECTORY_SEPARATOR; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php deleted file mode 100644 index 2f161e8cb..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MemcachedCaster.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Jan Schädlich - * - * @final - */ -class MemcachedCaster -{ - private static array $optionConstants; - private static array $defaultOptions; - - /** - * @return array - */ - public static function castMemcached(\Memcached $c, array $a, Stub $stub, bool $isNested) - { - $a += [ - Caster::PREFIX_VIRTUAL.'servers' => $c->getServerList(), - Caster::PREFIX_VIRTUAL.'options' => new EnumStub( - self::getNonDefaultOptions($c) - ), - ]; - - return $a; - } - - private static function getNonDefaultOptions(\Memcached $c): array - { - self::$defaultOptions ??= self::discoverDefaultOptions(); - self::$optionConstants ??= self::getOptionConstants(); - - $nonDefaultOptions = []; - foreach (self::$optionConstants as $constantKey => $value) { - if (self::$defaultOptions[$constantKey] !== $option = $c->getOption($value)) { - $nonDefaultOptions[$constantKey] = $option; - } - } - - return $nonDefaultOptions; - } - - private static function discoverDefaultOptions(): array - { - $defaultMemcached = new \Memcached(); - $defaultMemcached->addServer('127.0.0.1', 11211); - - $defaultOptions = []; - self::$optionConstants ??= self::getOptionConstants(); - - foreach (self::$optionConstants as $constantKey => $value) { - $defaultOptions[$constantKey] = $defaultMemcached->getOption($value); - } - - return $defaultOptions; - } - - private static function getOptionConstants(): array - { - $reflectedMemcached = new \ReflectionClass(\Memcached::class); - - $optionConstants = []; - foreach ($reflectedMemcached->getConstants() as $constantKey => $value) { - if (str_starts_with($constantKey, 'OPT_')) { - $optionConstants[$constantKey] = $value; - } - } - - return $optionConstants; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MysqliCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MysqliCaster.php deleted file mode 100644 index bfe6f0822..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/MysqliCaster.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Nicolas Grekas - * - * @internal - */ -final class MysqliCaster -{ - public static function castMysqliDriver(\mysqli_driver $c, array $a, Stub $stub, bool $isNested): array - { - foreach ($a as $k => $v) { - if (isset($c->$k)) { - $a[$k] = $c->$k; - } - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php deleted file mode 100644 index d68eae216..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PdoCaster.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts PDO related classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class PdoCaster -{ - private const PDO_ATTRIBUTES = [ - 'CASE' => [ - \PDO::CASE_LOWER => 'LOWER', - \PDO::CASE_NATURAL => 'NATURAL', - \PDO::CASE_UPPER => 'UPPER', - ], - 'ERRMODE' => [ - \PDO::ERRMODE_SILENT => 'SILENT', - \PDO::ERRMODE_WARNING => 'WARNING', - \PDO::ERRMODE_EXCEPTION => 'EXCEPTION', - ], - 'TIMEOUT', - 'PREFETCH', - 'AUTOCOMMIT', - 'PERSISTENT', - 'DRIVER_NAME', - 'SERVER_INFO', - 'ORACLE_NULLS' => [ - \PDO::NULL_NATURAL => 'NATURAL', - \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING', - \PDO::NULL_TO_STRING => 'TO_STRING', - ], - 'CLIENT_VERSION', - 'SERVER_VERSION', - 'STATEMENT_CLASS', - 'EMULATE_PREPARES', - 'CONNECTION_STATUS', - 'STRINGIFY_FETCHES', - 'DEFAULT_FETCH_MODE' => [ - \PDO::FETCH_ASSOC => 'ASSOC', - \PDO::FETCH_BOTH => 'BOTH', - \PDO::FETCH_LAZY => 'LAZY', - \PDO::FETCH_NUM => 'NUM', - \PDO::FETCH_OBJ => 'OBJ', - ], - ]; - - /** - * @return array - */ - public static function castPdo(\PDO $c, array $a, Stub $stub, bool $isNested) - { - $attr = []; - $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE); - $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - foreach (self::PDO_ATTRIBUTES as $k => $v) { - if (!isset($k[0])) { - $k = $v; - $v = []; - } - - try { - $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k)); - if ($v && isset($v[$attr[$k]])) { - $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]); - } - } catch (\Exception) { - } - } - if (isset($attr[$k = 'STATEMENT_CLASS'][1])) { - if ($attr[$k][1]) { - $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]); - } - $attr[$k][0] = new ClassStub($attr[$k][0]); - } - - $prefix = Caster::PREFIX_VIRTUAL; - $a += [ - $prefix.'inTransaction' => method_exists($c, 'inTransaction'), - $prefix.'errorInfo' => $c->errorInfo(), - $prefix.'attributes' => new EnumStub($attr), - ]; - - if ($a[$prefix.'inTransaction']) { - $a[$prefix.'inTransaction'] = $c->inTransaction(); - } else { - unset($a[$prefix.'inTransaction']); - } - - if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { - unset($a[$prefix.'errorInfo']); - } - - $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode); - - return $a; - } - - /** - * @return array - */ - public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $a[$prefix.'errorInfo'] = $c->errorInfo(); - - if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { - unset($a[$prefix.'errorInfo']); - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php deleted file mode 100644 index 0d8b3d919..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/PgSqlCaster.php +++ /dev/null @@ -1,165 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts pqsql resources to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class PgSqlCaster -{ - private const PARAM_CODES = [ - 'server_encoding', - 'client_encoding', - 'is_superuser', - 'session_authorization', - 'DateStyle', - 'TimeZone', - 'IntervalStyle', - 'integer_datetimes', - 'application_name', - 'standard_conforming_strings', - ]; - - private const TRANSACTION_STATUS = [ - \PGSQL_TRANSACTION_IDLE => 'PGSQL_TRANSACTION_IDLE', - \PGSQL_TRANSACTION_ACTIVE => 'PGSQL_TRANSACTION_ACTIVE', - \PGSQL_TRANSACTION_INTRANS => 'PGSQL_TRANSACTION_INTRANS', - \PGSQL_TRANSACTION_INERROR => 'PGSQL_TRANSACTION_INERROR', - \PGSQL_TRANSACTION_UNKNOWN => 'PGSQL_TRANSACTION_UNKNOWN', - ]; - - private const RESULT_STATUS = [ - \PGSQL_EMPTY_QUERY => 'PGSQL_EMPTY_QUERY', - \PGSQL_COMMAND_OK => 'PGSQL_COMMAND_OK', - \PGSQL_TUPLES_OK => 'PGSQL_TUPLES_OK', - \PGSQL_COPY_OUT => 'PGSQL_COPY_OUT', - \PGSQL_COPY_IN => 'PGSQL_COPY_IN', - \PGSQL_BAD_RESPONSE => 'PGSQL_BAD_RESPONSE', - \PGSQL_NONFATAL_ERROR => 'PGSQL_NONFATAL_ERROR', - \PGSQL_FATAL_ERROR => 'PGSQL_FATAL_ERROR', - ]; - - private const DIAG_CODES = [ - 'severity' => \PGSQL_DIAG_SEVERITY, - 'sqlstate' => \PGSQL_DIAG_SQLSTATE, - 'message' => \PGSQL_DIAG_MESSAGE_PRIMARY, - 'detail' => \PGSQL_DIAG_MESSAGE_DETAIL, - 'hint' => \PGSQL_DIAG_MESSAGE_HINT, - 'statement position' => \PGSQL_DIAG_STATEMENT_POSITION, - 'internal position' => \PGSQL_DIAG_INTERNAL_POSITION, - 'internal query' => \PGSQL_DIAG_INTERNAL_QUERY, - 'context' => \PGSQL_DIAG_CONTEXT, - 'file' => \PGSQL_DIAG_SOURCE_FILE, - 'line' => \PGSQL_DIAG_SOURCE_LINE, - 'function' => \PGSQL_DIAG_SOURCE_FUNCTION, - ]; - - /** - * @return array - */ - public static function castLargeObject($lo, array $a, Stub $stub, bool $isNested) - { - $a['seek position'] = pg_lo_tell($lo); - - return $a; - } - - /** - * @return array - */ - public static function castLink($link, array $a, Stub $stub, bool $isNested) - { - $a['status'] = pg_connection_status($link); - $a['status'] = new ConstStub(\PGSQL_CONNECTION_OK === $a['status'] ? 'PGSQL_CONNECTION_OK' : 'PGSQL_CONNECTION_BAD', $a['status']); - $a['busy'] = pg_connection_busy($link); - - $a['transaction'] = pg_transaction_status($link); - if (isset(self::TRANSACTION_STATUS[$a['transaction']])) { - $a['transaction'] = new ConstStub(self::TRANSACTION_STATUS[$a['transaction']], $a['transaction']); - } - - $a['pid'] = pg_get_pid($link); - $a['last error'] = pg_last_error($link); - $a['last notice'] = pg_last_notice($link); - $a['host'] = pg_host($link); - $a['port'] = pg_port($link); - $a['dbname'] = pg_dbname($link); - $a['options'] = pg_options($link); - $a['version'] = pg_version($link); - - foreach (self::PARAM_CODES as $v) { - if (false !== $s = pg_parameter_status($link, $v)) { - $a['param'][$v] = $s; - } - } - - $a['param']['client_encoding'] = pg_client_encoding($link); - $a['param'] = new EnumStub($a['param']); - - return $a; - } - - /** - * @return array - */ - public static function castResult($result, array $a, Stub $stub, bool $isNested) - { - $a['num rows'] = pg_num_rows($result); - $a['status'] = pg_result_status($result); - if (isset(self::RESULT_STATUS[$a['status']])) { - $a['status'] = new ConstStub(self::RESULT_STATUS[$a['status']], $a['status']); - } - $a['command-completion tag'] = pg_result_status($result, \PGSQL_STATUS_STRING); - - if (-1 === $a['num rows']) { - foreach (self::DIAG_CODES as $k => $v) { - $a['error'][$k] = pg_result_error_field($result, $v); - } - } - - $a['affected rows'] = pg_affected_rows($result); - $a['last OID'] = pg_last_oid($result); - - $fields = pg_num_fields($result); - - for ($i = 0; $i < $fields; ++$i) { - $field = [ - 'name' => pg_field_name($result, $i), - 'table' => sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)), - 'type' => sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)), - 'nullable' => (bool) pg_field_is_null($result, $i), - 'storage' => pg_field_size($result, $i).' bytes', - 'display' => pg_field_prtlen($result, $i).' chars', - ]; - if (' (OID: )' === $field['table']) { - $field['table'] = null; - } - if ('-1 bytes' === $field['storage']) { - $field['storage'] = 'variable size'; - } elseif ('1 bytes' === $field['storage']) { - $field['storage'] = '1 byte'; - } - if ('1 chars' === $field['display']) { - $field['display'] = '1 char'; - } - $a['fields'][] = new EnumStub($field); - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php deleted file mode 100644 index eb6c88db6..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use ProxyManager\Proxy\ProxyInterface; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Nicolas Grekas - * - * @final - */ -class ProxyManagerCaster -{ - /** - * @return array - */ - public static function castProxy(ProxyInterface $c, array $a, Stub $stub, bool $isNested) - { - if ($parent = get_parent_class($c)) { - $stub->class .= ' - '.$parent; - } - $stub->class .= '@proxy'; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php deleted file mode 100644 index fcaa1b768..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php +++ /dev/null @@ -1,222 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use RdKafka\Conf; -use RdKafka\Exception as RdKafkaException; -use RdKafka\KafkaConsumer; -use RdKafka\Message; -use RdKafka\Metadata\Broker as BrokerMetadata; -use RdKafka\Metadata\Collection as CollectionMetadata; -use RdKafka\Metadata\Partition as PartitionMetadata; -use RdKafka\Metadata\Topic as TopicMetadata; -use RdKafka\Topic; -use RdKafka\TopicConf; -use RdKafka\TopicPartition; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts RdKafka related classes to array representation. - * - * @author Romain Neutron - */ -class RdKafkaCaster -{ - /** - * @return array - */ - public static function castKafkaConsumer(KafkaConsumer $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - try { - $assignment = $c->getAssignment(); - } catch (RdKafkaException) { - $assignment = []; - } - - $a += [ - $prefix.'subscription' => $c->getSubscription(), - $prefix.'assignment' => $assignment, - ]; - - $a += self::extractMetadata($c); - - return $a; - } - - /** - * @return array - */ - public static function castTopic(Topic $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'name' => $c->getName(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castTopicPartition(TopicPartition $c, array $a) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'offset' => $c->getOffset(), - $prefix.'partition' => $c->getPartition(), - $prefix.'topic' => $c->getTopic(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castMessage(Message $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'errstr' => $c->errstr(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castConf(Conf $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - foreach ($c->dump() as $key => $value) { - $a[$prefix.$key] = $value; - } - - return $a; - } - - /** - * @return array - */ - public static function castTopicConf(TopicConf $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - foreach ($c->dump() as $key => $value) { - $a[$prefix.$key] = $value; - } - - return $a; - } - - /** - * @return array - */ - public static function castRdKafka(\RdKafka $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'out_q_len' => $c->getOutQLen(), - ]; - - $a += self::extractMetadata($c); - - return $a; - } - - /** - * @return array - */ - public static function castCollectionMetadata(CollectionMetadata $c, array $a, Stub $stub, bool $isNested) - { - $a += iterator_to_array($c); - - return $a; - } - - /** - * @return array - */ - public static function castTopicMetadata(TopicMetadata $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'name' => $c->getTopic(), - $prefix.'partitions' => $c->getPartitions(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castPartitionMetadata(PartitionMetadata $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'id' => $c->getId(), - $prefix.'err' => $c->getErr(), - $prefix.'leader' => $c->getLeader(), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castBrokerMetadata(BrokerMetadata $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - $a += [ - $prefix.'id' => $c->getId(), - $prefix.'host' => $c->getHost(), - $prefix.'port' => $c->getPort(), - ]; - - return $a; - } - - /** - * @return array - */ - private static function extractMetadata(KafkaConsumer|\RdKafka $c) - { - $prefix = Caster::PREFIX_VIRTUAL; - - try { - $m = $c->getMetadata(true, null, 500); - } catch (RdKafkaException) { - return []; - } - - return [ - $prefix.'orig_broker_id' => $m->getOrigBrokerId(), - $prefix.'orig_broker_name' => $m->getOrigBrokerName(), - $prefix.'brokers' => $m->getBrokers(), - $prefix.'topics' => $m->getTopics(), - ]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php deleted file mode 100644 index 6ff046754..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/RedisCaster.php +++ /dev/null @@ -1,159 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Relay\Relay; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Redis class from ext-redis to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class RedisCaster -{ - private const SERIALIZERS = [ - 0 => 'NONE', // Redis::SERIALIZER_NONE - 1 => 'PHP', // Redis::SERIALIZER_PHP - 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY - ]; - - private const MODES = [ - 0 => 'ATOMIC', // Redis::ATOMIC - 1 => 'MULTI', // Redis::MULTI - 2 => 'PIPELINE', // Redis::PIPELINE - ]; - - private const COMPRESSION_MODES = [ - 0 => 'NONE', // Redis::COMPRESSION_NONE - 1 => 'LZF', // Redis::COMPRESSION_LZF - ]; - - private const FAILOVER_OPTIONS = [ - \RedisCluster::FAILOVER_NONE => 'NONE', - \RedisCluster::FAILOVER_ERROR => 'ERROR', - \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE', - \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES', - ]; - - /** - * @return array - */ - public static function castRedis(\Redis|Relay $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - if (!$connected = $c->isConnected()) { - return $a + [ - $prefix.'isConnected' => $connected, - ]; - } - - $mode = $c->getMode(); - - return $a + [ - $prefix.'isConnected' => $connected, - $prefix.'host' => $c->getHost(), - $prefix.'port' => $c->getPort(), - $prefix.'auth' => $c->getAuth(), - $prefix.'mode' => isset(self::MODES[$mode]) ? new ConstStub(self::MODES[$mode], $mode) : $mode, - $prefix.'dbNum' => $c->getDbNum(), - $prefix.'timeout' => $c->getTimeout(), - $prefix.'lastError' => $c->getLastError(), - $prefix.'persistentId' => $c->getPersistentID(), - $prefix.'options' => self::getRedisOptions($c), - ]; - } - - /** - * @return array - */ - public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - return $a + [ - $prefix.'hosts' => $c->_hosts(), - $prefix.'function' => ClassStub::wrapCallable($c->_function()), - $prefix.'lastError' => $c->getLastError(), - $prefix.'options' => self::getRedisOptions($c), - ]; - } - - /** - * @return array - */ - public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER); - - $a += [ - $prefix.'_masters' => $c->_masters(), - $prefix.'_redir' => $c->_redir(), - $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()), - $prefix.'lastError' => $c->getLastError(), - $prefix.'options' => self::getRedisOptions($c, [ - 'SLAVE_FAILOVER' => isset(self::FAILOVER_OPTIONS[$failover]) ? new ConstStub(self::FAILOVER_OPTIONS[$failover], $failover) : $failover, - ]), - ]; - - return $a; - } - - private static function getRedisOptions(\Redis|Relay|\RedisArray|\RedisCluster $redis, array $options = []): EnumStub - { - $serializer = $redis->getOption(\defined('Redis::OPT_SERIALIZER') ? \Redis::OPT_SERIALIZER : 1); - if (\is_array($serializer)) { - foreach ($serializer as &$v) { - if (isset(self::SERIALIZERS[$v])) { - $v = new ConstStub(self::SERIALIZERS[$v], $v); - } - } - } elseif (isset(self::SERIALIZERS[$serializer])) { - $serializer = new ConstStub(self::SERIALIZERS[$serializer], $serializer); - } - - $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0; - if (\is_array($compression)) { - foreach ($compression as &$v) { - if (isset(self::COMPRESSION_MODES[$v])) { - $v = new ConstStub(self::COMPRESSION_MODES[$v], $v); - } - } - } elseif (isset(self::COMPRESSION_MODES[$compression])) { - $compression = new ConstStub(self::COMPRESSION_MODES[$compression], $compression); - } - - $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0; - if (\is_array($retry)) { - foreach ($retry as &$v) { - $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v); - } - } else { - $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry); - } - - $options += [ - 'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : Relay::OPT_TCP_KEEPALIVE, - 'READ_TIMEOUT' => $redis->getOption(\defined('Redis::OPT_READ_TIMEOUT') ? \Redis::OPT_READ_TIMEOUT : Relay::OPT_READ_TIMEOUT), - 'COMPRESSION' => $compression, - 'SERIALIZER' => $serializer, - 'PREFIX' => $redis->getOption(\defined('Redis::OPT_PREFIX') ? \Redis::OPT_PREFIX : Relay::OPT_PREFIX), - 'SCAN' => $retry, - ]; - - return new EnumStub($options); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php deleted file mode 100644 index 4adb9bc9f..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ReflectionCaster.php +++ /dev/null @@ -1,485 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts Reflector related classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class ReflectionCaster -{ - public const UNSET_CLOSURE_FILE_INFO = ['Closure' => __CLASS__.'::unsetClosureFileInfo']; - - private const EXTRA_MAP = [ - 'docComment' => 'getDocComment', - 'extension' => 'getExtensionName', - 'isDisabled' => 'isDisabled', - 'isDeprecated' => 'isDeprecated', - 'isInternal' => 'isInternal', - 'isUserDefined' => 'isUserDefined', - 'isGenerator' => 'isGenerator', - 'isVariadic' => 'isVariadic', - ]; - - /** - * @return array - */ - public static function castClosure(\Closure $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; - $c = new \ReflectionFunction($c); - - $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter); - - if (!str_contains($c->name, '{closure}')) { - $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name; - unset($a[$prefix.'class']); - } - unset($a[$prefix.'extra']); - - $stub->class .= self::getSignature($a); - - if ($f = $c->getFileName()) { - $stub->attr['file'] = $f; - $stub->attr['line'] = $c->getStartLine(); - } - - unset($a[$prefix.'parameters']); - - if ($filter & Caster::EXCLUDE_VERBOSE) { - $stub->cut += ($c->getFileName() ? 2 : 0) + \count($a); - - return []; - } - - if ($f) { - $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine()); - $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine(); - } - - return $a; - } - - /** - * @return array - */ - public static function unsetClosureFileInfo(\Closure $c, array $a) - { - unset($a[Caster::PREFIX_VIRTUAL.'file'], $a[Caster::PREFIX_VIRTUAL.'line']); - - return $a; - } - - public static function castGenerator(\Generator $c, array $a, Stub $stub, bool $isNested): array - { - // Cannot create ReflectionGenerator based on a terminated Generator - try { - $reflectionGenerator = new \ReflectionGenerator($c); - } catch (\Exception) { - $a[Caster::PREFIX_VIRTUAL.'closed'] = true; - - return $a; - } - - return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested); - } - - /** - * @return array - */ - public static function castType(\ReflectionType $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - if ($c instanceof \ReflectionNamedType) { - $a += [ - $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c, - $prefix.'allowsNull' => $c->allowsNull(), - $prefix.'isBuiltin' => $c->isBuiltin(), - ]; - } elseif ($c instanceof \ReflectionUnionType || $c instanceof \ReflectionIntersectionType) { - $a[$prefix.'allowsNull'] = $c->allowsNull(); - self::addMap($a, $c, [ - 'types' => 'getTypes', - ]); - } else { - $a[$prefix.'allowsNull'] = $c->allowsNull(); - } - - return $a; - } - - /** - * @return array - */ - public static function castAttribute(\ReflectionAttribute $c, array $a, Stub $stub, bool $isNested) - { - self::addMap($a, $c, [ - 'name' => 'getName', - 'arguments' => 'getArguments', - ]); - - return $a; - } - - /** - * @return array - */ - public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - if ($c->getThis()) { - $a[$prefix.'this'] = new CutStub($c->getThis()); - } - $function = $c->getFunction(); - $frame = [ - 'class' => $function->class ?? null, - 'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null, - 'function' => $function->name, - 'file' => $c->getExecutingFile(), - 'line' => $c->getExecutingLine(), - ]; - if ($trace = $c->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)) { - $function = new \ReflectionGenerator($c->getExecutingGenerator()); - array_unshift($trace, [ - 'function' => 'yield', - 'file' => $function->getExecutingFile(), - 'line' => $function->getExecutingLine(), - ]); - $trace[] = $frame; - $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1); - } else { - $function = new FrameStub($frame, false, true); - $function = ExceptionCaster::castFrameStub($function, [], $function, true); - $a[$prefix.'executing'] = $function[$prefix.'src']; - } - - $a[Caster::PREFIX_VIRTUAL.'closed'] = false; - - return $a; - } - - /** - * @return array - */ - public static function castClass(\ReflectionClass $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; - - if ($n = \Reflection::getModifierNames($c->getModifiers())) { - $a[$prefix.'modifiers'] = implode(' ', $n); - } - - self::addMap($a, $c, [ - 'extends' => 'getParentClass', - 'implements' => 'getInterfaceNames', - 'constants' => 'getReflectionConstants', - ]); - - foreach ($c->getProperties() as $n) { - $a[$prefix.'properties'][$n->name] = $n; - } - - foreach ($c->getMethods() as $n) { - $a[$prefix.'methods'][$n->name] = $n; - } - - self::addAttributes($a, $c, $prefix); - - if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { - self::addExtra($a, $c); - } - - return $a; - } - - /** - * @return array - */ - public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, bool $isNested, int $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; - - self::addMap($a, $c, [ - 'returnsReference' => 'returnsReference', - 'returnType' => 'getReturnType', - 'class' => \PHP_VERSION_ID >= 80111 ? 'getClosureCalledClass' : 'getClosureScopeClass', - 'this' => 'getClosureThis', - ]); - - if (isset($a[$prefix.'returnType'])) { - $v = $a[$prefix.'returnType']; - $v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v; - $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']); - } - if (isset($a[$prefix.'class'])) { - $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']); - } - if (isset($a[$prefix.'this'])) { - $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); - } - - foreach ($c->getParameters() as $v) { - $k = '$'.$v->name; - if ($v->isVariadic()) { - $k = '...'.$k; - } - if ($v->isPassedByReference()) { - $k = '&'.$k; - } - $a[$prefix.'parameters'][$k] = $v; - } - if (isset($a[$prefix.'parameters'])) { - $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']); - } - - self::addAttributes($a, $c, $prefix); - - if (!($filter & Caster::EXCLUDE_VERBOSE) && $v = $c->getStaticVariables()) { - foreach ($v as $k => &$v) { - if (\is_object($v)) { - $a[$prefix.'use']['$'.$k] = new CutStub($v); - } else { - $a[$prefix.'use']['$'.$k] = &$v; - } - } - unset($v); - $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']); - } - - if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { - self::addExtra($a, $c); - } - - return $a; - } - - /** - * @return array - */ - public static function castClassConstant(\ReflectionClassConstant $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); - $a[Caster::PREFIX_VIRTUAL.'value'] = $c->getValue(); - - self::addAttributes($a, $c); - - return $a; - } - - /** - * @return array - */ - public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); - - return $a; - } - - /** - * @return array - */ - public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - - self::addMap($a, $c, [ - 'position' => 'getPosition', - 'isVariadic' => 'isVariadic', - 'byReference' => 'isPassedByReference', - 'allowsNull' => 'allowsNull', - ]); - - self::addAttributes($a, $c, $prefix); - - if ($v = $c->getType()) { - $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v; - } - - if (isset($a[$prefix.'typeHint'])) { - $v = $a[$prefix.'typeHint']; - $a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']); - } else { - unset($a[$prefix.'allowsNull']); - } - - if ($c->isOptional()) { - try { - $a[$prefix.'default'] = $v = $c->getDefaultValue(); - if ($c->isDefaultValueConstant() && !\is_object($v)) { - $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); - } - if (null === $v) { - unset($a[$prefix.'allowsNull']); - } - } catch (\ReflectionException) { - } - } - - return $a; - } - - /** - * @return array - */ - public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); - - self::addAttributes($a, $c); - self::addExtra($a, $c); - - return $a; - } - - /** - * @return array - */ - public static function castReference(\ReflectionReference $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'id'] = $c->getId(); - - return $a; - } - - /** - * @return array - */ - public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, bool $isNested) - { - self::addMap($a, $c, [ - 'version' => 'getVersion', - 'dependencies' => 'getDependencies', - 'iniEntries' => 'getIniEntries', - 'isPersistent' => 'isPersistent', - 'isTemporary' => 'isTemporary', - 'constants' => 'getConstants', - 'functions' => 'getFunctions', - 'classes' => 'getClasses', - ]); - - return $a; - } - - /** - * @return array - */ - public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, bool $isNested) - { - self::addMap($a, $c, [ - 'version' => 'getVersion', - 'author' => 'getAuthor', - 'copyright' => 'getCopyright', - 'url' => 'getURL', - ]); - - return $a; - } - - /** - * @return string - */ - public static function getSignature(array $a) - { - $prefix = Caster::PREFIX_VIRTUAL; - $signature = ''; - - if (isset($a[$prefix.'parameters'])) { - foreach ($a[$prefix.'parameters']->value as $k => $param) { - $signature .= ', '; - if ($type = $param->getType()) { - if (!$type instanceof \ReflectionNamedType) { - $signature .= $type.' '; - } else { - if (!$param->isOptional() && $param->allowsNull() && 'mixed' !== $type->getName()) { - $signature .= '?'; - } - $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' '; - } - } - $signature .= $k; - - if (!$param->isDefaultValueAvailable()) { - continue; - } - $v = $param->getDefaultValue(); - $signature .= ' = '; - - if ($param->isDefaultValueConstant()) { - $signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1); - } elseif (null === $v) { - $signature .= 'null'; - } elseif (\is_array($v)) { - $signature .= $v ? '[…'.\count($v).']' : '[]'; - } elseif (\is_string($v)) { - $signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'"; - } elseif (\is_bool($v)) { - $signature .= $v ? 'true' : 'false'; - } elseif (\is_object($v)) { - $signature .= 'new '.substr(strrchr('\\'.get_debug_type($v), '\\'), 1); - } else { - $signature .= $v; - } - } - } - $signature = (empty($a[$prefix.'returnsReference']) ? '' : '&').'('.substr($signature, 2).')'; - - if (isset($a[$prefix.'returnType'])) { - $signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1); - } - - return $signature; - } - - private static function addExtra(array &$a, \Reflector $c): void - { - $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : []; - - if (method_exists($c, 'getFileName') && $m = $c->getFileName()) { - $x['file'] = new LinkStub($m, $c->getStartLine()); - $x['line'] = $c->getStartLine().' to '.$c->getEndLine(); - } - - self::addMap($x, $c, self::EXTRA_MAP, ''); - - if ($x) { - $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x); - } - } - - private static function addMap(array &$a, object $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL): void - { - foreach ($map as $k => $m) { - if ('isDisabled' === $k) { - continue; - } - - if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) { - $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m; - } - } - } - - private static function addAttributes(array &$a, \Reflector $c, string $prefix = Caster::PREFIX_VIRTUAL): void - { - foreach ($c->getAttributes() as $n) { - $a[$prefix.'attributes'][] = $n; - } - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php deleted file mode 100644 index f3bbf3be4..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ResourceCaster.php +++ /dev/null @@ -1,106 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts common resource types to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class ResourceCaster -{ - public static function castCurl(\CurlHandle $h, array $a, Stub $stub, bool $isNested): array - { - return curl_getinfo($h); - } - - /** - * @return array - */ - public static function castDba($dba, array $a, Stub $stub, bool $isNested) - { - $list = dba_list(); - $a['file'] = $list[(int) $dba]; - - return $a; - } - - /** - * @return array - */ - public static function castProcess($process, array $a, Stub $stub, bool $isNested) - { - return proc_get_status($process); - } - - public static function castStream($stream, array $a, Stub $stub, bool $isNested): array - { - $a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested); - if ($a['uri'] ?? false) { - $a['uri'] = new LinkStub($a['uri']); - } - - return $a; - } - - /** - * @return array - */ - public static function castStreamContext($stream, array $a, Stub $stub, bool $isNested) - { - return @stream_context_get_params($stream) ?: $a; - } - - /** - * @return array - */ - public static function castGd($gd, array $a, Stub $stub, bool $isNested) - { - $a['size'] = imagesx($gd).'x'.imagesy($gd); - $a['trueColor'] = imageistruecolor($gd); - - return $a; - } - - /** - * @return array - */ - public static function castOpensslX509($h, array $a, Stub $stub, bool $isNested) - { - $stub->cut = -1; - $info = openssl_x509_parse($h, false); - - $pin = openssl_pkey_get_public($h); - $pin = openssl_pkey_get_details($pin)['key']; - $pin = \array_slice(explode("\n", $pin), 1, -2); - $pin = base64_decode(implode('', $pin)); - $pin = base64_encode(hash('sha256', $pin, true)); - - $a += [ - 'subject' => new EnumStub(array_intersect_key($info['subject'], ['organizationName' => true, 'commonName' => true])), - 'issuer' => new EnumStub(array_intersect_key($info['issuer'], ['organizationName' => true, 'commonName' => true])), - 'expiry' => new ConstStub(date(\DateTimeInterface::ISO8601, $info['validTo_time_t']), $info['validTo_time_t']), - 'fingerprint' => new EnumStub([ - 'md5' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'md5')), 2, ':', true)), - 'sha1' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha1')), 2, ':', true)), - 'sha256' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha256')), 2, ':', true)), - 'pin-sha256' => new ConstStub($pin), - ]), - ]; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ScalarStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ScalarStub.php deleted file mode 100644 index 3bb1935b8..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/ScalarStub.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents any arbitrary value. - * - * @author Alexandre Daubois - */ -class ScalarStub extends Stub -{ - public function __construct(mixed $value) - { - $this->value = $value; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php deleted file mode 100644 index 814d824d1..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SplCaster.php +++ /dev/null @@ -1,286 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts SPL related classes to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class SplCaster -{ - private const SPL_FILE_OBJECT_FLAGS = [ - \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE', - \SplFileObject::READ_AHEAD => 'READ_AHEAD', - \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY', - \SplFileObject::READ_CSV => 'READ_CSV', - ]; - - /** - * @return array - */ - public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, bool $isNested) - { - return self::castSplArray($c, $a, $stub, $isNested); - } - - /** - * @return array - */ - public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, bool $isNested) - { - return self::castSplArray($c, $a, $stub, $isNested); - } - - /** - * @return array - */ - public static function castHeap(\Iterator $c, array $a, Stub $stub, bool $isNested) - { - $a += [ - Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c), - ]; - - return $a; - } - - /** - * @return array - */ - public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, bool $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $mode = $c->getIteratorMode(); - $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE); - - $a += [ - $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode), - $prefix.'dllist' => iterator_to_array($c), - ]; - $c->setIteratorMode($mode); - - return $a; - } - - /** - * @return array - */ - public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, bool $isNested) - { - static $map = [ - 'path' => 'getPath', - 'filename' => 'getFilename', - 'basename' => 'getBasename', - 'pathname' => 'getPathname', - 'extension' => 'getExtension', - 'realPath' => 'getRealPath', - 'aTime' => 'getATime', - 'mTime' => 'getMTime', - 'cTime' => 'getCTime', - 'inode' => 'getInode', - 'size' => 'getSize', - 'perms' => 'getPerms', - 'owner' => 'getOwner', - 'group' => 'getGroup', - 'type' => 'getType', - 'writable' => 'isWritable', - 'readable' => 'isReadable', - 'executable' => 'isExecutable', - 'file' => 'isFile', - 'dir' => 'isDir', - 'link' => 'isLink', - 'linkTarget' => 'getLinkTarget', - ]; - - $prefix = Caster::PREFIX_VIRTUAL; - unset($a["\0SplFileInfo\0fileName"]); - unset($a["\0SplFileInfo\0pathName"]); - - try { - $c->isReadable(); - } catch (\RuntimeException $e) { - if ('Object not initialized' !== $e->getMessage()) { - throw $e; - } - - $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; - - return $a; - } catch (\Error $e) { - if ('Object not initialized' !== $e->getMessage()) { - throw $e; - } - - $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; - - return $a; - } - - foreach ($map as $key => $accessor) { - try { - $a[$prefix.$key] = $c->$accessor(); - } catch (\Exception) { - } - } - - if ($a[$prefix.'realPath'] ?? false) { - $a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']); - } - - if (isset($a[$prefix.'perms'])) { - $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']); - } - - static $mapDate = ['aTime', 'mTime', 'cTime']; - foreach ($mapDate as $key) { - if (isset($a[$prefix.$key])) { - $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]); - } - } - - return $a; - } - - /** - * @return array - */ - public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, bool $isNested) - { - static $map = [ - 'csvControl' => 'getCsvControl', - 'flags' => 'getFlags', - 'maxLineLen' => 'getMaxLineLen', - 'fstat' => 'fstat', - 'eof' => 'eof', - 'key' => 'key', - ]; - - $prefix = Caster::PREFIX_VIRTUAL; - - foreach ($map as $key => $accessor) { - try { - $a[$prefix.$key] = $c->$accessor(); - } catch (\Exception) { - } - } - - if (isset($a[$prefix.'flags'])) { - $flagsArray = []; - foreach (self::SPL_FILE_OBJECT_FLAGS as $value => $name) { - if ($a[$prefix.'flags'] & $value) { - $flagsArray[] = $name; - } - } - $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']); - } - - if (isset($a[$prefix.'fstat'])) { - $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], ['dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks']); - } - - return $a; - } - - /** - * @return array - */ - public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, bool $isNested) - { - $storage = []; - unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967 - unset($a["\0SplObjectStorage\0storage"]); - - $clone = clone $c; - foreach ($clone as $obj) { - $storage[] = new EnumStub([ - 'object' => $obj, - 'info' => $clone->getInfo(), - ]); - } - - $a += [ - Caster::PREFIX_VIRTUAL.'storage' => $storage, - ]; - - return $a; - } - - /** - * @return array - */ - public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator(); - - return $a; - } - - /** - * @return array - */ - public static function castWeakReference(\WeakReference $c, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'object'] = $c->get(); - - return $a; - } - - /** - * @return array - */ - public static function castWeakMap(\WeakMap $c, array $a, Stub $stub, bool $isNested) - { - $map = []; - - foreach (clone $c as $obj => $data) { - $map[] = new EnumStub([ - 'object' => $obj, - 'data' => $data, - ]); - } - - $a += [ - Caster::PREFIX_VIRTUAL.'map' => $map, - ]; - - return $a; - } - - private static function castSplArray(\ArrayObject|\ArrayIterator $c, array $a, Stub $stub, bool $isNested): array - { - $prefix = Caster::PREFIX_VIRTUAL; - $flags = $c->getFlags(); - - if (!($flags & \ArrayObject::STD_PROP_LIST)) { - $c->setFlags(\ArrayObject::STD_PROP_LIST); - $a = Caster::castObject($c, $c::class, method_exists($c, '__debugInfo'), $stub->class); - $c->setFlags($flags); - } - - unset($a["\0ArrayObject\0storage"], $a["\0ArrayIterator\0storage"]); - - $a += [ - $prefix.'storage' => $c->getArrayCopy(), - $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST), - $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS), - ]; - if ($c instanceof \ArrayObject) { - $a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass()); - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php deleted file mode 100644 index 4b93ff76f..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/StubCaster.php +++ /dev/null @@ -1,107 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts a caster's Stub. - * - * @author Nicolas Grekas - * - * @final - */ -class StubCaster -{ - /** - * @return array - */ - public static function castStub(Stub $c, array $a, Stub $stub, bool $isNested) - { - if ($isNested) { - $stub->type = $c->type; - $stub->class = $c->class; - $stub->value = $c->value; - $stub->handle = $c->handle; - $stub->cut = $c->cut; - $stub->attr = $c->attr; - - if (Stub::TYPE_REF === $c->type && !$c->class && \is_string($c->value) && !preg_match('//u', $c->value)) { - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_BINARY; - } - - $a = []; - } - - return $a; - } - - /** - * @return array - */ - public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, bool $isNested) - { - return $isNested ? $c->preservedSubset : $a; - } - - /** - * @return array - */ - public static function cutInternals($obj, array $a, Stub $stub, bool $isNested) - { - if ($isNested) { - $stub->cut += \count($a); - - return []; - } - - return $a; - } - - /** - * @return array - */ - public static function castEnum(EnumStub $c, array $a, Stub $stub, bool $isNested) - { - if ($isNested) { - $stub->class = $c->dumpKeys ? '' : null; - $stub->handle = 0; - $stub->value = null; - $stub->cut = $c->cut; - $stub->attr = $c->attr; - - $a = []; - - if ($c->value) { - foreach (array_keys($c->value) as $k) { - $keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k; - } - // Preserve references with array_combine() - $a = array_combine($keys, $c->value); - } - } - - return $a; - } - - /** - * @return array - */ - public static function castScalar(ScalarStub $scalarStub, array $a, Stub $stub) - { - $stub->type = Stub::TYPE_SCALAR; - $stub->attr['value'] = $scalarStub->value; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php deleted file mode 100644 index ebc00f90e..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/SymfonyCaster.php +++ /dev/null @@ -1,139 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Uid\Ulid; -use Symfony\Component\Uid\Uuid; -use Symfony\Component\VarDumper\Cloner\Stub; -use Symfony\Component\VarExporter\Internal\LazyObjectState; - -/** - * @final - */ -class SymfonyCaster -{ - private const REQUEST_GETTERS = [ - 'pathInfo' => 'getPathInfo', - 'requestUri' => 'getRequestUri', - 'baseUrl' => 'getBaseUrl', - 'basePath' => 'getBasePath', - 'method' => 'getMethod', - 'format' => 'getRequestFormat', - ]; - - /** - * @return array - */ - public static function castRequest(Request $request, array $a, Stub $stub, bool $isNested) - { - $clone = null; - - foreach (self::REQUEST_GETTERS as $prop => $getter) { - $key = Caster::PREFIX_PROTECTED.$prop; - if (\array_key_exists($key, $a) && null === $a[$key]) { - $clone ??= clone $request; - $a[Caster::PREFIX_VIRTUAL.$prop] = $clone->{$getter}(); - } - } - - return $a; - } - - /** - * @return array - */ - public static function castHttpClient($client, array $a, Stub $stub, bool $isNested) - { - $multiKey = sprintf("\0%s\0multi", $client::class); - if (isset($a[$multiKey])) { - $a[$multiKey] = new CutStub($a[$multiKey]); - } - - return $a; - } - - /** - * @return array - */ - public static function castHttpClientResponse($response, array $a, Stub $stub, bool $isNested) - { - $stub->cut += \count($a); - $a = []; - - foreach ($response->getInfo() as $k => $v) { - $a[Caster::PREFIX_VIRTUAL.$k] = $v; - } - - return $a; - } - - /** - * @return array - */ - public static function castLazyObjectState($state, array $a, Stub $stub, bool $isNested) - { - if (!$isNested) { - return $a; - } - - $stub->cut += \count($a) - 1; - - $instance = $a['realInstance'] ?? null; - - $a = ['status' => new ConstStub(match ($a['status']) { - LazyObjectState::STATUS_INITIALIZED_FULL => 'INITIALIZED_FULL', - LazyObjectState::STATUS_INITIALIZED_PARTIAL => 'INITIALIZED_PARTIAL', - LazyObjectState::STATUS_UNINITIALIZED_FULL => 'UNINITIALIZED_FULL', - LazyObjectState::STATUS_UNINITIALIZED_PARTIAL => 'UNINITIALIZED_PARTIAL', - }, $a['status'])]; - - if ($instance) { - $a['realInstance'] = $instance; - --$stub->cut; - } - - return $a; - } - - /** - * @return array - */ - public static function castUuid(Uuid $uuid, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'toBase58'] = $uuid->toBase58(); - $a[Caster::PREFIX_VIRTUAL.'toBase32'] = $uuid->toBase32(); - - // symfony/uid >= 5.3 - if (method_exists($uuid, 'getDateTime')) { - $a[Caster::PREFIX_VIRTUAL.'time'] = $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C'); - } - - return $a; - } - - /** - * @return array - */ - public static function castUlid(Ulid $ulid, array $a, Stub $stub, bool $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'toBase58'] = $ulid->toBase58(); - $a[Caster::PREFIX_VIRTUAL.'toRfc4122'] = $ulid->toRfc4122(); - - // symfony/uid >= 5.3 - if (method_exists($ulid, 'getDateTime')) { - $a[Caster::PREFIX_VIRTUAL.'time'] = $ulid->getDateTime()->format('Y-m-d H:i:s.v \U\T\C'); - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php deleted file mode 100644 index d215d8db0..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/TraceStub.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Represents a backtrace as returned by debug_backtrace() or Exception->getTrace(). - * - * @author Nicolas Grekas - */ -class TraceStub extends Stub -{ - public $keepArgs; - public $sliceOffset; - public $sliceLength; - public $numberingOffset; - - public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, ?int $sliceLength = null, int $numberingOffset = 0) - { - $this->value = $trace; - $this->keepArgs = $keepArgs; - $this->sliceOffset = $sliceOffset; - $this->sliceLength = $sliceLength; - $this->numberingOffset = $numberingOffset; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UninitializedStub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UninitializedStub.php deleted file mode 100644 index a9bdd9b81..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UninitializedStub.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -/** - * Represents an uninitialized property. - * - * @author Nicolas Grekas - */ -class UninitializedStub extends ConstStub -{ - public function __construct(\ReflectionProperty $property) - { - parent::__construct('?'.($property->hasType() ? ' '.$property->getType() : ''), 'Uninitialized property'); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php deleted file mode 100644 index b10277457..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/UuidCaster.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Ramsey\Uuid\UuidInterface; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * @author Grégoire Pineau - */ -final class UuidCaster -{ - public static function castRamseyUuid(UuidInterface $c, array $a, Stub $stub, bool $isNested): array - { - $a += [ - Caster::PREFIX_VIRTUAL.'uuid' => (string) $c, - ]; - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php deleted file mode 100644 index 1cfcf4dd8..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts XmlReader class to array representation. - * - * @author Baptiste Clavié - * - * @final - */ -class XmlReaderCaster -{ - private const NODE_TYPES = [ - \XMLReader::NONE => 'NONE', - \XMLReader::ELEMENT => 'ELEMENT', - \XMLReader::ATTRIBUTE => 'ATTRIBUTE', - \XMLReader::TEXT => 'TEXT', - \XMLReader::CDATA => 'CDATA', - \XMLReader::ENTITY_REF => 'ENTITY_REF', - \XMLReader::ENTITY => 'ENTITY', - \XMLReader::PI => 'PI (Processing Instruction)', - \XMLReader::COMMENT => 'COMMENT', - \XMLReader::DOC => 'DOC', - \XMLReader::DOC_TYPE => 'DOC_TYPE', - \XMLReader::DOC_FRAGMENT => 'DOC_FRAGMENT', - \XMLReader::NOTATION => 'NOTATION', - \XMLReader::WHITESPACE => 'WHITESPACE', - \XMLReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE', - \XMLReader::END_ELEMENT => 'END_ELEMENT', - \XMLReader::END_ENTITY => 'END_ENTITY', - \XMLReader::XML_DECLARATION => 'XML_DECLARATION', - ]; - - /** - * @return array - */ - public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, bool $isNested) - { - try { - $properties = [ - 'LOADDTD' => @$reader->getParserProperty(\XMLReader::LOADDTD), - 'DEFAULTATTRS' => @$reader->getParserProperty(\XMLReader::DEFAULTATTRS), - 'VALIDATE' => @$reader->getParserProperty(\XMLReader::VALIDATE), - 'SUBST_ENTITIES' => @$reader->getParserProperty(\XMLReader::SUBST_ENTITIES), - ]; - } catch (\Error) { - $properties = [ - 'LOADDTD' => false, - 'DEFAULTATTRS' => false, - 'VALIDATE' => false, - 'SUBST_ENTITIES' => false, - ]; - } - - $props = Caster::PREFIX_VIRTUAL.'parserProperties'; - $info = [ - 'localName' => $reader->localName, - 'prefix' => $reader->prefix, - 'nodeType' => new ConstStub(self::NODE_TYPES[$reader->nodeType], $reader->nodeType), - 'depth' => $reader->depth, - 'isDefault' => $reader->isDefault, - 'isEmptyElement' => \XMLReader::NONE === $reader->nodeType ? null : $reader->isEmptyElement, - 'xmlLang' => $reader->xmlLang, - 'attributeCount' => $reader->attributeCount, - 'value' => $reader->value, - 'namespaceURI' => $reader->namespaceURI, - 'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI, - $props => $properties, - ]; - - if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) { - $info[$props] = new EnumStub($info[$props]); - $info[$props]->cut = $count; - } - - $a = Caster::filter($a, Caster::EXCLUDE_UNINITIALIZED, [], $count); - $info = Caster::filter($info, Caster::EXCLUDE_EMPTY, [], $count); - // +2 because hasValue and hasAttributes are always filtered - $stub->cut += $count + 2; - - return $a + $info; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php b/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php deleted file mode 100644 index 0cf42584a..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Caster; - -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * Casts XML resources to array representation. - * - * @author Nicolas Grekas - * - * @final - */ -class XmlResourceCaster -{ - private const XML_ERRORS = [ - \XML_ERROR_NONE => 'XML_ERROR_NONE', - \XML_ERROR_NO_MEMORY => 'XML_ERROR_NO_MEMORY', - \XML_ERROR_SYNTAX => 'XML_ERROR_SYNTAX', - \XML_ERROR_NO_ELEMENTS => 'XML_ERROR_NO_ELEMENTS', - \XML_ERROR_INVALID_TOKEN => 'XML_ERROR_INVALID_TOKEN', - \XML_ERROR_UNCLOSED_TOKEN => 'XML_ERROR_UNCLOSED_TOKEN', - \XML_ERROR_PARTIAL_CHAR => 'XML_ERROR_PARTIAL_CHAR', - \XML_ERROR_TAG_MISMATCH => 'XML_ERROR_TAG_MISMATCH', - \XML_ERROR_DUPLICATE_ATTRIBUTE => 'XML_ERROR_DUPLICATE_ATTRIBUTE', - \XML_ERROR_JUNK_AFTER_DOC_ELEMENT => 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT', - \XML_ERROR_PARAM_ENTITY_REF => 'XML_ERROR_PARAM_ENTITY_REF', - \XML_ERROR_UNDEFINED_ENTITY => 'XML_ERROR_UNDEFINED_ENTITY', - \XML_ERROR_RECURSIVE_ENTITY_REF => 'XML_ERROR_RECURSIVE_ENTITY_REF', - \XML_ERROR_ASYNC_ENTITY => 'XML_ERROR_ASYNC_ENTITY', - \XML_ERROR_BAD_CHAR_REF => 'XML_ERROR_BAD_CHAR_REF', - \XML_ERROR_BINARY_ENTITY_REF => 'XML_ERROR_BINARY_ENTITY_REF', - \XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF => 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF', - \XML_ERROR_MISPLACED_XML_PI => 'XML_ERROR_MISPLACED_XML_PI', - \XML_ERROR_UNKNOWN_ENCODING => 'XML_ERROR_UNKNOWN_ENCODING', - \XML_ERROR_INCORRECT_ENCODING => 'XML_ERROR_INCORRECT_ENCODING', - \XML_ERROR_UNCLOSED_CDATA_SECTION => 'XML_ERROR_UNCLOSED_CDATA_SECTION', - \XML_ERROR_EXTERNAL_ENTITY_HANDLING => 'XML_ERROR_EXTERNAL_ENTITY_HANDLING', - ]; - - /** - * @return array - */ - public static function castXml($h, array $a, Stub $stub, bool $isNested) - { - $a['current_byte_index'] = xml_get_current_byte_index($h); - $a['current_column_number'] = xml_get_current_column_number($h); - $a['current_line_number'] = xml_get_current_line_number($h); - $a['error_code'] = xml_get_error_code($h); - - if (isset(self::XML_ERRORS[$a['error_code']])) { - $a['error_code'] = new ConstStub(self::XML_ERRORS[$a['error_code']], $a['error_code']); - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php deleted file mode 100644 index fc330bae2..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/AbstractCloner.php +++ /dev/null @@ -1,397 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -use Symfony\Component\VarDumper\Caster\Caster; -use Symfony\Component\VarDumper\Exception\ThrowingCasterException; - -/** - * AbstractCloner implements a generic caster mechanism for objects and resources. - * - * @author Nicolas Grekas - */ -abstract class AbstractCloner implements ClonerInterface -{ - public static $defaultCasters = [ - '__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster', 'castPhpIncompleteClass'], - - 'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'], - 'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'], - 'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'], - 'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'], - 'Symfony\Component\VarDumper\Caster\ScalarStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castScalar'], - - 'Fiber' => ['Symfony\Component\VarDumper\Caster\FiberCaster', 'castFiber'], - - 'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'], - 'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'], - 'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'], - 'ReflectionAttribute' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castAttribute'], - 'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReflectionGenerator'], - 'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClass'], - 'ReflectionClassConstant' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClassConstant'], - 'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castFunctionAbstract'], - 'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castMethod'], - 'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castParameter'], - 'ReflectionProperty' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castProperty'], - 'ReflectionReference' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReference'], - 'ReflectionExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castExtension'], - 'ReflectionZendExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castZendExtension'], - - 'Doctrine\Common\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Doctrine\Common\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castCommonProxy'], - 'Doctrine\ORM\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castOrmProxy'], - 'Doctrine\ORM\PersistentCollection' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castPersistentCollection'], - 'Doctrine\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - - 'DOMException' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castException'], - 'DOMStringList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], - 'DOMNameList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], - 'DOMImplementation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castImplementation'], - 'DOMImplementationList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], - 'DOMNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNode'], - 'DOMNameSpaceNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNameSpaceNode'], - 'DOMDocument' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocument'], - 'DOMNodeList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], - 'DOMNamedNodeMap' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], - 'DOMCharacterData' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castCharacterData'], - 'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castAttr'], - 'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castElement'], - 'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castText'], - 'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocumentType'], - 'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNotation'], - 'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castEntity'], - 'DOMProcessingInstruction' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castProcessingInstruction'], - 'DOMXPath' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castXPath'], - - 'XMLReader' => ['Symfony\Component\VarDumper\Caster\XmlReaderCaster', 'castXmlReader'], - - 'ErrorException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castErrorException'], - 'Exception' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castException'], - 'Error' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castError'], - 'Symfony\Bridge\Monolog\Logger' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Symfony\Component\EventDispatcher\EventDispatcherInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Symfony\Component\HttpClient\AmpHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], - 'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], - 'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], - 'Symfony\Component\HttpClient\Response\AmpResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'], - 'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'], - 'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'], - 'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'], - 'Symfony\Component\Uid\Ulid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUlid'], - 'Symfony\Component\Uid\Uuid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUuid'], - 'Symfony\Component\VarExporter\Internal\LazyObjectState' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castLazyObjectState'], - 'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'], - 'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'], - 'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'], - 'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Symfony\Component\ErrorHandler\Exception\FlattenException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFlattenException'], - 'Symfony\Component\ErrorHandler\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castSilencedErrorContext'], - - 'Imagine\Image\ImageInterface' => ['Symfony\Component\VarDumper\Caster\ImagineCaster', 'castImage'], - - 'Ramsey\Uuid\UuidInterface' => ['Symfony\Component\VarDumper\Caster\UuidCaster', 'castRamseyUuid'], - - 'ProxyManager\Proxy\ProxyInterface' => ['Symfony\Component\VarDumper\Caster\ProxyManagerCaster', 'castProxy'], - 'PHPUnit_Framework_MockObject_MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'PHPUnit\Framework\MockObject\MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'PHPUnit\Framework\MockObject\Stub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Prophecy\Prophecy\ProphecySubjectInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - 'Mockery\MockInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], - - 'PDO' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdo'], - 'PDOStatement' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdoStatement'], - - 'AMQPConnection' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castConnection'], - 'AMQPChannel' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castChannel'], - 'AMQPQueue' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castQueue'], - 'AMQPExchange' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castExchange'], - 'AMQPEnvelope' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castEnvelope'], - - 'ArrayObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayObject'], - 'ArrayIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayIterator'], - 'SplDoublyLinkedList' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castDoublyLinkedList'], - 'SplFileInfo' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileInfo'], - 'SplFileObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileObject'], - 'SplHeap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'], - 'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castObjectStorage'], - 'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'], - 'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castOuterIterator'], - 'WeakMap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakMap'], - 'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakReference'], - - 'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'], - 'Relay\Relay' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'], - 'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'], - 'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisCluster'], - - 'DateTimeInterface' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'], - 'DateInterval' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castInterval'], - 'DateTimeZone' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castTimeZone'], - 'DatePeriod' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castPeriod'], - - 'GMP' => ['Symfony\Component\VarDumper\Caster\GmpCaster', 'castGmp'], - - 'MessageFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castMessageFormatter'], - 'NumberFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castNumberFormatter'], - 'IntlTimeZone' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlTimeZone'], - 'IntlCalendar' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlCalendar'], - 'IntlDateFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlDateFormatter'], - - 'Memcached' => ['Symfony\Component\VarDumper\Caster\MemcachedCaster', 'castMemcached'], - - 'Ds\Collection' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castCollection'], - 'Ds\Map' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castMap'], - 'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPair'], - 'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPairStub'], - - 'mysqli_driver' => ['Symfony\Component\VarDumper\Caster\MysqliCaster', 'castMysqliDriver'], - - 'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'], - - ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], - ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], - - 'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'], - ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'], - - ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'], - ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'], - ':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'], - ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castResult'], - ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castProcess'], - ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], - - 'OpenSSLCertificate' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'], - ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'], - - ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], - ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStreamContext'], - - 'XmlParser' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'], - ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'], - - 'RdKafka' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castRdKafka'], - 'RdKafka\Conf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castConf'], - 'RdKafka\KafkaConsumer' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castKafkaConsumer'], - 'RdKafka\Metadata\Broker' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castBrokerMetadata'], - 'RdKafka\Metadata\Collection' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castCollectionMetadata'], - 'RdKafka\Metadata\Partition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castPartitionMetadata'], - 'RdKafka\Metadata\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicMetadata'], - 'RdKafka\Message' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castMessage'], - 'RdKafka\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopic'], - 'RdKafka\TopicPartition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicPartition'], - 'RdKafka\TopicConf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicConf'], - - 'FFI\CData' => ['Symfony\Component\VarDumper\Caster\FFICaster', 'castCTypeOrCData'], - 'FFI\CType' => ['Symfony\Component\VarDumper\Caster\FFICaster', 'castCTypeOrCData'], - ]; - - protected $maxItems = 2500; - protected $maxString = -1; - protected $minDepth = 1; - - /** - * @var array> - */ - private array $casters = []; - - /** - * @var callable|null - */ - private $prevErrorHandler; - - private array $classInfo = []; - private int $filter = 0; - - /** - * @param callable[]|null $casters A map of casters - * - * @see addCasters - */ - public function __construct(?array $casters = null) - { - $this->addCasters($casters ?? static::$defaultCasters); - } - - /** - * Adds casters for resources and objects. - * - * Maps resources or objects types to a callback. - * Types are in the key, with a callable caster for value. - * Resource types are to be prefixed with a `:`, - * see e.g. static::$defaultCasters. - * - * @param callable[] $casters A map of casters - * - * @return void - */ - public function addCasters(array $casters) - { - foreach ($casters as $type => $callback) { - $this->casters[$type][] = $callback; - } - } - - /** - * Sets the maximum number of items to clone past the minimum depth in nested structures. - * - * @return void - */ - public function setMaxItems(int $maxItems) - { - $this->maxItems = $maxItems; - } - - /** - * Sets the maximum cloned length for strings. - * - * @return void - */ - public function setMaxString(int $maxString) - { - $this->maxString = $maxString; - } - - /** - * Sets the minimum tree depth where we are guaranteed to clone all the items. After this - * depth is reached, only setMaxItems items will be cloned. - * - * @return void - */ - public function setMinDepth(int $minDepth) - { - $this->minDepth = $minDepth; - } - - /** - * Clones a PHP variable. - * - * @param int $filter A bit field of Caster::EXCLUDE_* constants - */ - public function cloneVar(mixed $var, int $filter = 0): Data - { - $this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) { - if (\E_RECOVERABLE_ERROR === $type || \E_USER_ERROR === $type) { - // Cloner never dies - throw new \ErrorException($msg, 0, $type, $file, $line); - } - - if ($this->prevErrorHandler) { - return ($this->prevErrorHandler)($type, $msg, $file, $line, $context); - } - - return false; - }); - $this->filter = $filter; - - if ($gc = gc_enabled()) { - gc_disable(); - } - try { - return new Data($this->doClone($var)); - } finally { - if ($gc) { - gc_enable(); - } - restore_error_handler(); - $this->prevErrorHandler = null; - } - } - - /** - * Effectively clones the PHP variable. - */ - abstract protected function doClone(mixed $var): array; - - /** - * Casts an object to an array representation. - * - * @param bool $isNested True if the object is nested in the dumped structure - */ - protected function castObject(Stub $stub, bool $isNested): array - { - $obj = $stub->value; - $class = $stub->class; - - if (str_contains($class, "@anonymous\0")) { - $stub->class = get_debug_type($obj); - } - if (isset($this->classInfo[$class])) { - [$i, $parents, $hasDebugInfo, $fileInfo] = $this->classInfo[$class]; - } else { - $i = 2; - $parents = [$class]; - $hasDebugInfo = method_exists($class, '__debugInfo'); - - foreach (class_parents($class) as $p) { - $parents[] = $p; - ++$i; - } - foreach (class_implements($class) as $p) { - $parents[] = $p; - ++$i; - } - $parents[] = '*'; - - $r = new \ReflectionClass($class); - $fileInfo = $r->isInternal() || $r->isSubclassOf(Stub::class) ? [] : [ - 'file' => $r->getFileName(), - 'line' => $r->getStartLine(), - ]; - - $this->classInfo[$class] = [$i, $parents, $hasDebugInfo, $fileInfo]; - } - - $stub->attr += $fileInfo; - $a = Caster::castObject($obj, $class, $hasDebugInfo, $stub->class); - - try { - while ($i--) { - if (!empty($this->casters[$p = $parents[$i]])) { - foreach ($this->casters[$p] as $callback) { - $a = $callback($obj, $a, $stub, $isNested, $this->filter); - } - } - } - } catch (\Exception $e) { - $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a; - } - - return $a; - } - - /** - * Casts a resource to an array representation. - * - * @param bool $isNested True if the object is nested in the dumped structure - */ - protected function castResource(Stub $stub, bool $isNested): array - { - $a = []; - $res = $stub->value; - $type = $stub->class; - - try { - if (!empty($this->casters[':'.$type])) { - foreach ($this->casters[':'.$type] as $callback) { - $a = $callback($res, $a, $stub, $isNested, $this->filter); - } - } - } catch (\Exception $e) { - $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a; - } - - return $a; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php deleted file mode 100644 index 5a8e2e4c5..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/ClonerInterface.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * @author Nicolas Grekas - */ -interface ClonerInterface -{ - /** - * Clones a PHP variable. - */ - public function cloneVar(mixed $var): Data; -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php deleted file mode 100644 index 1fd796d67..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Cursor.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * Represents the current state of a dumper while dumping. - * - * @author Nicolas Grekas - */ -class Cursor -{ - public const HASH_INDEXED = Stub::ARRAY_INDEXED; - public const HASH_ASSOC = Stub::ARRAY_ASSOC; - public const HASH_OBJECT = Stub::TYPE_OBJECT; - public const HASH_RESOURCE = Stub::TYPE_RESOURCE; - - public $depth = 0; - public $refIndex = 0; - public $softRefTo = 0; - public $softRefCount = 0; - public $softRefHandle = 0; - public $hardRefTo = 0; - public $hardRefCount = 0; - public $hardRefHandle = 0; - public $hashType; - public $hashKey; - public $hashKeyIsBinary; - public $hashIndex = 0; - public $hashLength = 0; - public $hashCut = 0; - public $stop = false; - public $attr = []; - public $skipChildren = false; -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php deleted file mode 100644 index 16f51b0c7..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Data.php +++ /dev/null @@ -1,434 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -use Symfony\Component\VarDumper\Caster\Caster; -use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; - -/** - * @author Nicolas Grekas - */ -class Data implements \ArrayAccess, \Countable, \IteratorAggregate, \Stringable -{ - private array $data; - private int $position = 0; - private int|string $key = 0; - private int $maxDepth = 20; - private int $maxItemsPerDepth = -1; - private int $useRefHandles = -1; - private array $context = []; - - /** - * @param array $data An array as returned by ClonerInterface::cloneVar() - */ - public function __construct(array $data) - { - $this->data = $data; - } - - public function getType(): ?string - { - $item = $this->data[$this->position][$this->key]; - - if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { - $item = $item->value; - } - if (!$item instanceof Stub) { - return \gettype($item); - } - if (Stub::TYPE_STRING === $item->type) { - return 'string'; - } - if (Stub::TYPE_ARRAY === $item->type) { - return 'array'; - } - if (Stub::TYPE_OBJECT === $item->type) { - return $item->class; - } - if (Stub::TYPE_RESOURCE === $item->type) { - return $item->class.' resource'; - } - - return null; - } - - /** - * Returns a native representation of the original value. - * - * @param array|bool $recursive Whether values should be resolved recursively or not - * - * @return string|int|float|bool|array|Data[]|null - */ - public function getValue(array|bool $recursive = false): string|int|float|bool|array|null - { - $item = $this->data[$this->position][$this->key]; - - if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { - $item = $item->value; - } - if (!($item = $this->getStub($item)) instanceof Stub) { - return $item; - } - if (Stub::TYPE_STRING === $item->type) { - return $item->value; - } - - $children = $item->position ? $this->data[$item->position] : []; - - foreach ($children as $k => $v) { - if ($recursive && !($v = $this->getStub($v)) instanceof Stub) { - continue; - } - $children[$k] = clone $this; - $children[$k]->key = $k; - $children[$k]->position = $item->position; - - if ($recursive) { - if (Stub::TYPE_REF === $v->type && ($v = $this->getStub($v->value)) instanceof Stub) { - $recursive = (array) $recursive; - if (isset($recursive[$v->position])) { - continue; - } - $recursive[$v->position] = true; - } - $children[$k] = $children[$k]->getValue($recursive); - } - } - - return $children; - } - - public function count(): int - { - return \count($this->getValue()); - } - - public function getIterator(): \Traversable - { - if (!\is_array($value = $this->getValue())) { - throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value))); - } - - yield from $value; - } - - /** - * @return mixed - */ - public function __get(string $key) - { - if (null !== $data = $this->seek($key)) { - $item = $this->getStub($data->data[$data->position][$data->key]); - - return $item instanceof Stub || [] === $item ? $data : $item; - } - - return null; - } - - public function __isset(string $key): bool - { - return null !== $this->seek($key); - } - - public function offsetExists(mixed $key): bool - { - return $this->__isset($key); - } - - public function offsetGet(mixed $key): mixed - { - return $this->__get($key); - } - - public function offsetSet(mixed $key, mixed $value): void - { - throw new \BadMethodCallException(self::class.' objects are immutable.'); - } - - public function offsetUnset(mixed $key): void - { - throw new \BadMethodCallException(self::class.' objects are immutable.'); - } - - public function __toString(): string - { - $value = $this->getValue(); - - if (!\is_array($value)) { - return (string) $value; - } - - return sprintf('%s (count=%d)', $this->getType(), \count($value)); - } - - /** - * Returns a depth limited clone of $this. - */ - public function withMaxDepth(int $maxDepth): static - { - $data = clone $this; - $data->maxDepth = $maxDepth; - - return $data; - } - - /** - * Limits the number of elements per depth level. - */ - public function withMaxItemsPerDepth(int $maxItemsPerDepth): static - { - $data = clone $this; - $data->maxItemsPerDepth = $maxItemsPerDepth; - - return $data; - } - - /** - * Enables/disables objects' identifiers tracking. - * - * @param bool $useRefHandles False to hide global ref. handles - */ - public function withRefHandles(bool $useRefHandles): static - { - $data = clone $this; - $data->useRefHandles = $useRefHandles ? -1 : 0; - - return $data; - } - - public function withContext(array $context): static - { - $data = clone $this; - $data->context = $context; - - return $data; - } - - public function getContext(): array - { - return $this->context; - } - - /** - * Seeks to a specific key in nested data structures. - */ - public function seek(string|int $key): ?static - { - $item = $this->data[$this->position][$this->key]; - - if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { - $item = $item->value; - } - if (!($item = $this->getStub($item)) instanceof Stub || !$item->position) { - return null; - } - $keys = [$key]; - - switch ($item->type) { - case Stub::TYPE_OBJECT: - $keys[] = Caster::PREFIX_DYNAMIC.$key; - $keys[] = Caster::PREFIX_PROTECTED.$key; - $keys[] = Caster::PREFIX_VIRTUAL.$key; - $keys[] = "\0$item->class\0$key"; - // no break - case Stub::TYPE_ARRAY: - case Stub::TYPE_RESOURCE: - break; - default: - return null; - } - - $data = null; - $children = $this->data[$item->position]; - - foreach ($keys as $key) { - if (isset($children[$key]) || \array_key_exists($key, $children)) { - $data = clone $this; - $data->key = $key; - $data->position = $item->position; - break; - } - } - - return $data; - } - - /** - * Dumps data with a DumperInterface dumper. - * - * @return void - */ - public function dump(DumperInterface $dumper) - { - $refs = [0]; - $cursor = new Cursor(); - $cursor->hashType = -1; - $cursor->attr = $this->context[SourceContextProvider::class] ?? []; - $label = $this->context['label'] ?? ''; - - if ($cursor->attr || '' !== $label) { - $dumper->dumpScalar($cursor, 'label', $label); - } - $cursor->hashType = 0; - $this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]); - } - - /** - * Depth-first dumping of items. - * - * @param mixed $item A Stub object or the original value being dumped - */ - private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, mixed $item): void - { - $cursor->refIndex = 0; - $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0; - $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0; - $firstSeen = true; - - if (!$item instanceof Stub) { - $cursor->attr = []; - $type = \gettype($item); - if ($item && 'array' === $type) { - $item = $this->getStub($item); - } - } elseif (Stub::TYPE_REF === $item->type) { - if ($item->handle) { - if (!isset($refs[$r = $item->handle - (\PHP_INT_MAX >> 1)])) { - $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; - } else { - $firstSeen = false; - } - $cursor->hardRefTo = $refs[$r]; - $cursor->hardRefHandle = $this->useRefHandles & $item->handle; - $cursor->hardRefCount = 0 < $item->handle ? $item->refCount : 0; - } - $cursor->attr = $item->attr; - $type = $item->class ?: \gettype($item->value); - $item = $this->getStub($item->value); - } - if ($item instanceof Stub) { - if ($item->refCount) { - if (!isset($refs[$r = $item->handle])) { - $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; - } else { - $firstSeen = false; - } - $cursor->softRefTo = $refs[$r]; - } - $cursor->softRefHandle = $this->useRefHandles & $item->handle; - $cursor->softRefCount = $item->refCount; - $cursor->attr = $item->attr; - $cut = $item->cut; - - if ($item->position && $firstSeen) { - $children = $this->data[$item->position]; - - if ($cursor->stop) { - if ($cut >= 0) { - $cut += \count($children); - } - $children = []; - } - } else { - $children = []; - } - switch ($item->type) { - case Stub::TYPE_STRING: - $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut); - break; - - case Stub::TYPE_ARRAY: - $item = clone $item; - $item->type = $item->class; - $item->class = $item->value; - // no break - case Stub::TYPE_OBJECT: - case Stub::TYPE_RESOURCE: - $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth; - $dumper->enterHash($cursor, $item->type, $item->class, $withChildren); - if ($withChildren) { - if ($cursor->skipChildren) { - $withChildren = false; - $cut = -1; - } else { - $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class); - } - } elseif ($children && 0 <= $cut) { - $cut += \count($children); - } - $cursor->skipChildren = false; - $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut); - break; - - case Stub::TYPE_SCALAR: - $dumper->dumpScalar($cursor, 'default', $item->attr['value']); - break; - - default: - throw new \RuntimeException(sprintf('Unexpected Stub type: "%s".', $item->type)); - } - } elseif ('array' === $type) { - $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false); - $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0); - } elseif ('string' === $type) { - $dumper->dumpString($cursor, $item, false, 0); - } else { - $dumper->dumpScalar($cursor, $type, $item); - } - } - - /** - * Dumps children of hash structures. - * - * @return int The final number of removed items - */ - private function dumpChildren(DumperInterface $dumper, Cursor $parentCursor, array &$refs, array $children, int $hashCut, int $hashType, bool $dumpKeys): int - { - $cursor = clone $parentCursor; - ++$cursor->depth; - $cursor->hashType = $hashType; - $cursor->hashIndex = 0; - $cursor->hashLength = \count($children); - $cursor->hashCut = $hashCut; - foreach ($children as $key => $child) { - $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key); - $cursor->hashKey = $dumpKeys ? $key : null; - $this->dumpItem($dumper, $cursor, $refs, $child); - if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) { - $parentCursor->stop = true; - - return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut; - } - } - - return $hashCut; - } - - private function getStub(mixed $item): mixed - { - if (!$item || !\is_array($item)) { - return $item; - } - - $stub = new Stub(); - $stub->type = Stub::TYPE_ARRAY; - foreach ($item as $stub->class => $stub->position) { - } - if (isset($item[0])) { - $stub->cut = $item[0]; - } - $stub->value = $stub->cut + ($stub->position ? \count($this->data[$stub->position]) : 0); - - return $stub; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php deleted file mode 100644 index 4c5b315b6..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/DumperInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * DumperInterface used by Data objects. - * - * @author Nicolas Grekas - */ -interface DumperInterface -{ - /** - * Dumps a scalar value. - * - * @return void - */ - public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value); - - /** - * Dumps a string. - * - * @param string $str The string being dumped - * @param bool $bin Whether $str is UTF-8 or binary encoded - * @param int $cut The number of characters $str has been cut by - * - * @return void - */ - public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut); - - /** - * Dumps while entering an hash. - * - * @param int $type A Cursor::HASH_* const for the type of hash - * @param string|int|null $class The object class, resource type or array count - * @param bool $hasChild When the dump of the hash has child item - * - * @return void - */ - public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild); - - /** - * Dumps while leaving an hash. - * - * @param int $type A Cursor::HASH_* const for the type of hash - * @param string|int|null $class The object class, resource type or array count - * @param bool $hasChild When the dump of the hash has child item - * @param int $cut The number of items the hash has been cut by - * - * @return void - */ - public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut); -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php deleted file mode 100644 index 0c2a4b9d0..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/Stub.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * Represents the main properties of a PHP variable. - * - * @author Nicolas Grekas - */ -class Stub -{ - public const TYPE_REF = 1; - public const TYPE_STRING = 2; - public const TYPE_ARRAY = 3; - public const TYPE_OBJECT = 4; - public const TYPE_RESOURCE = 5; - public const TYPE_SCALAR = 6; - - public const STRING_BINARY = 1; - public const STRING_UTF8 = 2; - - public const ARRAY_ASSOC = 1; - public const ARRAY_INDEXED = 2; - - public $type = self::TYPE_REF; - public $class = ''; - public $value; - public $cut = 0; - public $handle = 0; - public $refCount = 0; - public $position = 0; - public $attr = []; - - private static array $defaultProperties = []; - - /** - * @internal - */ - public function __sleep(): array - { - $properties = []; - - if (!isset(self::$defaultProperties[$c = static::class])) { - self::$defaultProperties[$c] = get_class_vars($c); - - foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) { - unset(self::$defaultProperties[$c][$k]); - } - } - - foreach (self::$defaultProperties[$c] as $k => $v) { - if ($this->$k !== $v) { - $properties[] = $k; - } - } - - return $properties; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php b/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php deleted file mode 100644 index e168d0d3b..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Cloner/VarCloner.php +++ /dev/null @@ -1,243 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Cloner; - -/** - * @author Nicolas Grekas - */ -class VarCloner extends AbstractCloner -{ - private static array $arrayCache = []; - - protected function doClone(mixed $var): array - { - $len = 1; // Length of $queue - $pos = 0; // Number of cloned items past the minimum depth - $refsCounter = 0; // Hard references counter - $queue = [[$var]]; // This breadth-first queue is the return value - $hardRefs = []; // Map of original zval ids to stub objects - $objRefs = []; // Map of original object handles to their stub object counterpart - $objects = []; // Keep a ref to objects to ensure their handle cannot be reused while cloning - $resRefs = []; // Map of original resource handles to their stub object counterpart - $values = []; // Map of stub objects' ids to original values - $maxItems = $this->maxItems; - $maxString = $this->maxString; - $minDepth = $this->minDepth; - $currentDepth = 0; // Current tree depth - $currentDepthFinalIndex = 0; // Final $queue index for current tree depth - $minimumDepthReached = 0 === $minDepth; // Becomes true when minimum tree depth has been reached - $cookie = (object) []; // Unique object used to detect hard references - $a = null; // Array cast for nested structures - $stub = null; // Stub capturing the main properties of an original item value - // or null if the original value is used directly - - $arrayStub = new Stub(); - $arrayStub->type = Stub::TYPE_ARRAY; - $fromObjCast = false; - - for ($i = 0; $i < $len; ++$i) { - // Detect when we move on to the next tree depth - if ($i > $currentDepthFinalIndex) { - ++$currentDepth; - $currentDepthFinalIndex = $len - 1; - if ($currentDepth >= $minDepth) { - $minimumDepthReached = true; - } - } - - $refs = $vals = $queue[$i]; - foreach ($vals as $k => $v) { - // $v is the original value or a stub object in case of hard references - - $zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null; - - if ($zvalRef) { - $vals[$k] = &$stub; // Break hard references to make $queue completely - unset($stub); // independent from the original structure - if (null !== $vals[$k] = $hardRefs[$zvalRef] ?? null) { - $v = $vals[$k]; - if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { - ++$v->value->refCount; - } - ++$v->refCount; - continue; - } - $vals[$k] = new Stub(); - $vals[$k]->value = $v; - $vals[$k]->handle = ++$refsCounter; - $hardRefs[$zvalRef] = $vals[$k]; - } - // Create $stub when the original value $v cannot be used directly - // If $v is a nested structure, put that structure in array $a - switch (true) { - case null === $v: - case \is_bool($v): - case \is_int($v): - case \is_float($v): - continue 2; - case \is_string($v): - if ('' === $v) { - continue 2; - } - if (!preg_match('//u', $v)) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_BINARY; - if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) { - $stub->cut = $cut; - $stub->value = substr($v, 0, -$cut); - } else { - $stub->value = $v; - } - } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_UTF8; - $stub->cut = $cut; - $stub->value = mb_substr($v, 0, $maxString, 'UTF-8'); - } else { - continue 2; - } - $a = null; - break; - - case \is_array($v): - if (!$v) { - continue 2; - } - $stub = $arrayStub; - - $stub->class = array_is_list($v) ? Stub::ARRAY_INDEXED : Stub::ARRAY_ASSOC; - $a = $v; - break; - - case \is_object($v): - if (empty($objRefs[$h = spl_object_id($v)])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_OBJECT; - $stub->class = $v::class; - $stub->value = $v; - $stub->handle = $h; - $a = $this->castObject($stub, 0 < $i); - if ($v !== $stub->value) { - if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { - break; - } - $stub->handle = $h = spl_object_id($stub->value); - } - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) { - $stub->cut = \count($a); - $a = null; - } - } - if (empty($objRefs[$h])) { - $objRefs[$h] = $stub; - $objects[] = $v; - } else { - $stub = $objRefs[$h]; - ++$stub->refCount; - $a = null; - } - break; - - default: // resource - if (empty($resRefs[$h = (int) $v])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_RESOURCE; - if ('Unknown' === $stub->class = @get_resource_type($v)) { - $stub->class = 'Closed'; - } - $stub->value = $v; - $stub->handle = $h; - $a = $this->castResource($stub, 0 < $i); - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) { - $stub->cut = \count($a); - $a = null; - } - } - if (empty($resRefs[$h])) { - $resRefs[$h] = $stub; - } else { - $stub = $resRefs[$h]; - ++$stub->refCount; - $a = null; - } - break; - } - - if ($a) { - if (!$minimumDepthReached || 0 > $maxItems) { - $queue[$len] = $a; - $stub->position = $len++; - } elseif ($pos < $maxItems) { - if ($maxItems < $pos += \count($a)) { - $a = \array_slice($a, 0, $maxItems - $pos, true); - if ($stub->cut >= 0) { - $stub->cut += $pos - $maxItems; - } - } - $queue[$len] = $a; - $stub->position = $len++; - } elseif ($stub->cut >= 0) { - $stub->cut += \count($a); - $stub->position = 0; - } - } - - if ($arrayStub === $stub) { - if ($arrayStub->cut) { - $stub = [$arrayStub->cut, $arrayStub->class => $arrayStub->position]; - $arrayStub->cut = 0; - } elseif (isset(self::$arrayCache[$arrayStub->class][$arrayStub->position])) { - $stub = self::$arrayCache[$arrayStub->class][$arrayStub->position]; - } else { - self::$arrayCache[$arrayStub->class][$arrayStub->position] = $stub = [$arrayStub->class => $arrayStub->position]; - } - } - - if (!$zvalRef) { - $vals[$k] = $stub; - } else { - $hardRefs[$zvalRef]->value = $stub; - } - } - - if ($fromObjCast) { - $fromObjCast = false; - $refs = $vals; - $vals = []; - $j = -1; - foreach ($queue[$i] as $k => $v) { - foreach ([$k => true] as $gk => $gv) { - } - if ($gk !== $k) { - $vals = (object) $vals; - $vals->{$k} = $refs[++$j]; - $vals = (array) $vals; - } else { - $vals[$k] = $refs[++$j]; - } - } - } - - $queue[$i] = $vals; - } - - foreach ($values as $h => $v) { - $hardRefs[$h] = $v; - } - - return $queue; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php b/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php deleted file mode 100644 index 4450fe986..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php +++ /dev/null @@ -1,79 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Command\Descriptor; - -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\CliDumper; - -/** - * Describe collected data clones for cli output. - * - * @author Maxime Steinhausser - * - * @final - */ -class CliDescriptor implements DumpDescriptorInterface -{ - private CliDumper $dumper; - private mixed $lastIdentifier = null; - - public function __construct(CliDumper $dumper) - { - $this->dumper = $dumper; - } - - public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void - { - $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput([]), $output); - $this->dumper->setColors($output->isDecorated()); - - $rows = [['date', date('r', (int) $context['timestamp'])]]; - $lastIdentifier = $this->lastIdentifier; - $this->lastIdentifier = $clientId; - - $section = "Received from client #$clientId"; - if (isset($context['request'])) { - $request = $context['request']; - $this->lastIdentifier = $request['identifier']; - $section = sprintf('%s %s', $request['method'], $request['uri']); - if ($controller = $request['controller']) { - $rows[] = ['controller', rtrim($this->dumper->dump($controller, true), "\n")]; - } - } elseif (isset($context['cli'])) { - $this->lastIdentifier = $context['cli']['identifier']; - $section = '$ '.$context['cli']['command_line']; - } - - if ($this->lastIdentifier !== $lastIdentifier) { - $io->section($section); - } - - if (isset($context['source'])) { - $source = $context['source']; - $sourceInfo = sprintf('%s on line %d', $source['name'], $source['line']); - if ($fileLink = $source['file_link'] ?? null) { - $sourceInfo = sprintf('%s', $fileLink, $sourceInfo); - } - $rows[] = ['source', $sourceInfo]; - $file = $source['file_relative'] ?? $source['file']; - $rows[] = ['file', $file]; - } - - $io->table([], $rows); - - $this->dumper->dump($data); - $io->newLine(); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php b/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php deleted file mode 100644 index 267d27bfa..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Command\Descriptor; - -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\VarDumper\Cloner\Data; - -/** - * @author Maxime Steinhausser - */ -interface DumpDescriptorInterface -{ - public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void; -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php b/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php deleted file mode 100644 index 98f150a5e..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php +++ /dev/null @@ -1,119 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Command\Descriptor; - -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\HtmlDumper; - -/** - * Describe collected data clones for html output. - * - * @author Maxime Steinhausser - * - * @final - */ -class HtmlDescriptor implements DumpDescriptorInterface -{ - private HtmlDumper $dumper; - private bool $initialized = false; - - public function __construct(HtmlDumper $dumper) - { - $this->dumper = $dumper; - } - - public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void - { - if (!$this->initialized) { - $styles = file_get_contents(__DIR__.'/../../Resources/css/htmlDescriptor.css'); - $scripts = file_get_contents(__DIR__.'/../../Resources/js/htmlDescriptor.js'); - $output->writeln(""); - $this->initialized = true; - } - - $title = '-'; - if (isset($context['request'])) { - $request = $context['request']; - $controller = "{$this->dumper->dump($request['controller'], true, ['maxDepth' => 0])}"; - $title = sprintf('%s %s', $request['method'], $uri = $request['uri'], $uri); - $dedupIdentifier = $request['identifier']; - } elseif (isset($context['cli'])) { - $title = '$ '.$context['cli']['command_line']; - $dedupIdentifier = $context['cli']['identifier']; - } else { - $dedupIdentifier = uniqid('', true); - } - - $sourceDescription = ''; - if (isset($context['source'])) { - $source = $context['source']; - $projectDir = $source['project_dir'] ?? null; - $sourceDescription = sprintf('%s on line %d', $source['name'], $source['line']); - if (isset($source['file_link'])) { - $sourceDescription = sprintf('%s', $source['file_link'], $sourceDescription); - } - } - - $isoDate = $this->extractDate($context, 'c'); - $tags = array_filter([ - 'controller' => $controller ?? null, - 'project dir' => $projectDir ?? null, - ]); - - $output->writeln(<< -
-
-

$title

- -
- {$this->renderTags($tags)} -
-
-

- $sourceDescription -

- {$this->dumper->dump($data, true)} -
- -HTML - ); - } - - private function extractDate(array $context, string $format = 'r'): string - { - return date($format, (int) $context['timestamp']); - } - - private function renderTags(array $tags): string - { - if (!$tags) { - return ''; - } - - $renderedTags = ''; - foreach ($tags as $key => $value) { - $renderedTags .= sprintf('
  • %s%s
  • ', $key, $value); - } - - return << -
      - $renderedTags -
    - -HTML; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php b/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php deleted file mode 100644 index b64a884b9..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Command/ServerDumpCommand.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Command; - -use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Completion\CompletionInput; -use Symfony\Component\Console\Completion\CompletionSuggestions; -use Symfony\Component\Console\Exception\InvalidArgumentException; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Command\Descriptor\CliDescriptor; -use Symfony\Component\VarDumper\Command\Descriptor\DumpDescriptorInterface; -use Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor; -use Symfony\Component\VarDumper\Dumper\CliDumper; -use Symfony\Component\VarDumper\Dumper\HtmlDumper; -use Symfony\Component\VarDumper\Server\DumpServer; - -/** - * Starts a dump server to collect and output dumps on a single place with multiple formats support. - * - * @author Maxime Steinhausser - * - * @final - */ -#[AsCommand(name: 'server:dump', description: 'Start a dump server that collects and displays dumps in a single place')] -class ServerDumpCommand extends Command -{ - private DumpServer $server; - - /** @var DumpDescriptorInterface[] */ - private array $descriptors; - - public function __construct(DumpServer $server, array $descriptors = []) - { - $this->server = $server; - $this->descriptors = $descriptors + [ - 'cli' => new CliDescriptor(new CliDumper()), - 'html' => new HtmlDescriptor(new HtmlDumper()), - ]; - - parent::__construct(); - } - - protected function configure(): void - { - $this - ->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', implode(', ', $this->getAvailableFormats())), 'cli') - ->setHelp(<<<'EOF' -%command.name% starts a dump server that collects and displays -dumps in a single place for debugging you application: - - php %command.full_name% - -You can consult dumped data in HTML format in your browser by providing the --format=html option -and redirecting the output to a file: - - php %command.full_name% --format="html" > dump.html - -EOF - ) - ; - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $io = new SymfonyStyle($input, $output); - $format = $input->getOption('format'); - - if (!$descriptor = $this->descriptors[$format] ?? null) { - throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $format)); - } - - $errorIo = $io->getErrorStyle(); - $errorIo->title('Symfony Var Dumper Server'); - - $this->server->start(); - - $errorIo->success(sprintf('Server listening on %s', $this->server->getHost())); - $errorIo->comment('Quit the server with CONTROL-C.'); - - $this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) { - $descriptor->describe($io, $data, $context, $clientId); - }); - - return 0; - } - - public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void - { - if ($input->mustSuggestOptionValuesFor('format')) { - $suggestions->suggestValues($this->getAvailableFormats()); - } - } - - private function getAvailableFormats(): array - { - return array_keys($this->descriptors); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php deleted file mode 100644 index 53165ba64..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/AbstractDumper.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Cloner\DumperInterface; - -/** - * Abstract mechanism for dumping a Data object. - * - * @author Nicolas Grekas - */ -abstract class AbstractDumper implements DataDumperInterface, DumperInterface -{ - public const DUMP_LIGHT_ARRAY = 1; - public const DUMP_STRING_LENGTH = 2; - public const DUMP_COMMA_SEPARATOR = 4; - public const DUMP_TRAILING_COMMA = 8; - - /** @var callable|resource|string|null */ - public static $defaultOutput = 'php://output'; - - protected $line = ''; - /** @var callable|null */ - protected $lineDumper; - /** @var resource|null */ - protected $outputStream; - protected $decimalPoint = '.'; - protected $indentPad = ' '; - protected $flags; - - private string $charset = ''; - - /** - * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput - * @param string|null $charset The default character encoding to use for non-UTF8 strings - * @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation - */ - public function __construct($output = null, ?string $charset = null, int $flags = 0) - { - $this->flags = $flags; - $this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8'); - $this->setOutput($output ?: static::$defaultOutput); - if (!$output && \is_string(static::$defaultOutput)) { - static::$defaultOutput = $this->outputStream; - } - } - - /** - * Sets the output destination of the dumps. - * - * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path - * - * @return callable|resource|string|null The previous output destination - */ - public function setOutput($output) - { - $prev = $this->outputStream ?? $this->lineDumper; - - if (\is_callable($output)) { - $this->outputStream = null; - $this->lineDumper = $output; - } else { - if (\is_string($output)) { - $output = fopen($output, 'w'); - } - $this->outputStream = $output; - $this->lineDumper = $this->echoLine(...); - } - - return $prev; - } - - /** - * Sets the default character encoding to use for non-UTF8 strings. - * - * @return string The previous charset - */ - public function setCharset(string $charset): string - { - $prev = $this->charset; - - $charset = strtoupper($charset); - $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset; - - $this->charset = $charset; - - return $prev; - } - - /** - * Sets the indentation pad string. - * - * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level - * - * @return string The previous indent pad - */ - public function setIndentPad(string $pad): string - { - $prev = $this->indentPad; - $this->indentPad = $pad; - - return $prev; - } - - /** - * Dumps a Data object. - * - * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump - * - * @return string|null The dump as string when $output is true - */ - public function dump(Data $data, $output = null): ?string - { - if ($locale = $this->flags & (self::DUMP_COMMA_SEPARATOR | self::DUMP_TRAILING_COMMA) ? setlocale(\LC_NUMERIC, 0) : null) { - setlocale(\LC_NUMERIC, 'C'); - } - - if ($returnDump = true === $output) { - $output = fopen('php://memory', 'r+'); - } - if ($output) { - $prevOutput = $this->setOutput($output); - } - try { - $data->dump($this); - $this->dumpLine(-1); - - if ($returnDump) { - $result = stream_get_contents($output, -1, 0); - fclose($output); - - return $result; - } - } finally { - if ($output) { - $this->setOutput($prevOutput); - } - if ($locale) { - setlocale(\LC_NUMERIC, $locale); - } - } - - return null; - } - - /** - * Dumps the current line. - * - * @param int $depth The recursive depth in the dumped structure for the line being dumped, - * or -1 to signal the end-of-dump to the line dumper callable - * - * @return void - */ - protected function dumpLine(int $depth) - { - ($this->lineDumper)($this->line, $depth, $this->indentPad); - $this->line = ''; - } - - /** - * Generic line dumper callback. - * - * @return void - */ - protected function echoLine(string $line, int $depth, string $indentPad) - { - if (-1 !== $depth) { - fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n"); - } - } - - /** - * Converts a non-UTF-8 string to UTF-8. - */ - protected function utf8Encode(?string $s): ?string - { - if (null === $s || preg_match('//u', $s)) { - return $s; - } - - if (!\function_exists('iconv')) { - throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); - } - - if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) { - return $c; - } - if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) { - return $c; - } - - return iconv('CP850', 'UTF-8', $s); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php deleted file mode 100644 index af9637072..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/CliDumper.php +++ /dev/null @@ -1,677 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Cursor; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * CliDumper dumps variables for command line output. - * - * @author Nicolas Grekas - */ -class CliDumper extends AbstractDumper -{ - public static $defaultColors; - /** @var callable|resource|string|null */ - public static $defaultOutput = 'php://stdout'; - - protected $colors; - protected $maxStringWidth = 0; - protected $styles = [ - // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - 'default' => '0;38;5;208', - 'num' => '1;38;5;38', - 'const' => '1;38;5;208', - 'str' => '1;38;5;113', - 'note' => '38;5;38', - 'ref' => '38;5;247', - 'public' => '', - 'protected' => '', - 'private' => '', - 'meta' => '38;5;170', - 'key' => '38;5;113', - 'index' => '38;5;38', - ]; - - protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/'; - protected static $controlCharsMap = [ - "\t" => '\t', - "\n" => '\n', - "\v" => '\v', - "\f" => '\f', - "\r" => '\r', - "\033" => '\e', - ]; - protected static $unicodeCharsRx = "/[\u{00A0}\u{00AD}\u{034F}\u{061C}\u{115F}\u{1160}\u{17B4}\u{17B5}\u{180E}\u{2000}-\u{200F}\u{202F}\u{205F}\u{2060}-\u{2064}\u{206A}-\u{206F}\u{3000}\u{2800}\u{3164}\u{FEFF}\u{FFA0}\u{1D159}\u{1D173}-\u{1D17A}]/u"; - - protected $collapseNextHash = false; - protected $expandNextHash = false; - - private array $displayOptions = [ - 'fileLinkFormat' => null, - ]; - - private bool $handlesHrefGracefully; - - public function __construct($output = null, ?string $charset = null, int $flags = 0) - { - parent::__construct($output, $charset, $flags); - - if ('\\' === \DIRECTORY_SEPARATOR && !$this->isWindowsTrueColor()) { - // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI - $this->setStyles([ - 'default' => '31', - 'num' => '1;34', - 'const' => '1;31', - 'str' => '1;32', - 'note' => '34', - 'ref' => '1;30', - 'meta' => '35', - 'key' => '32', - 'index' => '34', - ]); - } - - $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l'; - } - - /** - * Enables/disables colored output. - * - * @return void - */ - public function setColors(bool $colors) - { - $this->colors = $colors; - } - - /** - * Sets the maximum number of characters per line for dumped strings. - * - * @return void - */ - public function setMaxStringWidth(int $maxStringWidth) - { - $this->maxStringWidth = $maxStringWidth; - } - - /** - * Configures styles. - * - * @param array $styles A map of style names to style definitions - * - * @return void - */ - public function setStyles(array $styles) - { - $this->styles = $styles + $this->styles; - } - - /** - * Configures display options. - * - * @param array $displayOptions A map of display options to customize the behavior - * - * @return void - */ - public function setDisplayOptions(array $displayOptions) - { - $this->displayOptions = $displayOptions + $this->displayOptions; - } - - /** - * @return void - */ - public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value) - { - $this->dumpKey($cursor); - $this->collapseNextHash = $this->expandNextHash = false; - - $style = 'const'; - $attr = $cursor->attr; - - switch ($type) { - case 'default': - $style = 'default'; - break; - - case 'label': - $this->styles += ['label' => $this->styles['default']]; - $style = 'label'; - break; - - case 'integer': - $style = 'num'; - - if (isset($this->styles['integer'])) { - $style = 'integer'; - } - - break; - - case 'double': - $style = 'num'; - - if (isset($this->styles['float'])) { - $style = 'float'; - } - - $value = match (true) { - \INF === $value => 'INF', - -\INF === $value => '-INF', - is_nan($value) => 'NAN', - default => !str_contains($value = (string) $value, $this->decimalPoint) ? $value .= $this->decimalPoint.'0' : $value, - }; - break; - - case 'NULL': - $value = 'null'; - break; - - case 'boolean': - $value = $value ? 'true' : 'false'; - break; - - default: - $attr += ['value' => $this->utf8Encode($value)]; - $value = $this->utf8Encode($type); - break; - } - - $this->line .= $this->style($style, $value, $attr); - - $this->endValue($cursor); - } - - /** - * @return void - */ - public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut) - { - $this->dumpKey($cursor); - $this->collapseNextHash = $this->expandNextHash = false; - $attr = $cursor->attr; - - if ($bin) { - $str = $this->utf8Encode($str); - } - if ('' === $str) { - $this->line .= '""'; - if ($cut) { - $this->line .= '…'.$cut; - } - $this->endValue($cursor); - } else { - $attr += [ - 'length' => 0 <= $cut ? mb_strlen($str, 'UTF-8') + $cut : 0, - 'binary' => $bin, - ]; - $str = $bin && str_contains($str, "\0") ? [$str] : explode("\n", $str); - if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) { - unset($str[1]); - $str[0] .= "\n"; - } - $m = \count($str) - 1; - $i = $lineCut = 0; - - if (self::DUMP_STRING_LENGTH & $this->flags) { - $this->line .= '('.$attr['length'].') '; - } - if ($bin) { - $this->line .= 'b'; - } - - if ($m) { - $this->line .= '"""'; - $this->dumpLine($cursor->depth); - } else { - $this->line .= '"'; - } - - foreach ($str as $str) { - if ($i < $m) { - $str .= "\n"; - } - if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = mb_strlen($str, 'UTF-8')) { - $str = mb_substr($str, 0, $this->maxStringWidth, 'UTF-8'); - $lineCut = $len - $this->maxStringWidth; - } - if ($m && 0 < $cursor->depth) { - $this->line .= $this->indentPad; - } - if ('' !== $str) { - $this->line .= $this->style('str', $str, $attr); - } - if ($i++ == $m) { - if ($m) { - if ('' !== $str) { - $this->dumpLine($cursor->depth); - if (0 < $cursor->depth) { - $this->line .= $this->indentPad; - } - } - $this->line .= '"""'; - } else { - $this->line .= '"'; - } - if ($cut < 0) { - $this->line .= '…'; - $lineCut = 0; - } elseif ($cut) { - $lineCut += $cut; - } - } - if ($lineCut) { - $this->line .= '…'.$lineCut; - $lineCut = 0; - } - - if ($i > $m) { - $this->endValue($cursor); - } else { - $this->dumpLine($cursor->depth); - } - } - } - } - - /** - * @return void - */ - public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild) - { - $this->colors ??= $this->supportsColors(); - - $this->dumpKey($cursor); - $this->expandNextHash = false; - $attr = $cursor->attr; - - if ($this->collapseNextHash) { - $cursor->skipChildren = true; - $this->collapseNextHash = $hasChild = false; - } - - $class = $this->utf8Encode($class); - if (Cursor::HASH_OBJECT === $type) { - $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class, $attr).(empty($attr['cut_hash']) ? ' {' : '') : '{'; - } elseif (Cursor::HASH_RESOURCE === $type) { - $prefix = $this->style('note', $class.' resource', $attr).($hasChild ? ' {' : ' '); - } else { - $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class).' [' : '['; - } - - if (($cursor->softRefCount || 0 < $cursor->softRefHandle) && empty($attr['cut_hash'])) { - $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), ['count' => $cursor->softRefCount]); - } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) { - $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, ['count' => $cursor->hardRefCount]); - } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) { - $prefix = substr($prefix, 0, -1); - } - - $this->line .= $prefix; - - if ($hasChild) { - $this->dumpLine($cursor->depth); - } - } - - /** - * @return void - */ - public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut) - { - if (empty($cursor->attr['cut_hash'])) { - $this->dumpEllipsis($cursor, $hasChild, $cut); - $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : '')); - } - - $this->endValue($cursor); - } - - /** - * Dumps an ellipsis for cut children. - * - * @param bool $hasChild When the dump of the hash has child item - * @param int $cut The number of items the hash has been cut by - * - * @return void - */ - protected function dumpEllipsis(Cursor $cursor, bool $hasChild, int $cut) - { - if ($cut) { - $this->line .= ' …'; - if (0 < $cut) { - $this->line .= $cut; - } - if ($hasChild) { - $this->dumpLine($cursor->depth + 1); - } - } - } - - /** - * Dumps a key in a hash structure. - * - * @return void - */ - protected function dumpKey(Cursor $cursor) - { - if (null !== $key = $cursor->hashKey) { - if ($cursor->hashKeyIsBinary) { - $key = $this->utf8Encode($key); - } - $attr = ['binary' => $cursor->hashKeyIsBinary]; - $bin = $cursor->hashKeyIsBinary ? 'b' : ''; - $style = 'key'; - switch ($cursor->hashType) { - default: - case Cursor::HASH_INDEXED: - if (self::DUMP_LIGHT_ARRAY & $this->flags) { - break; - } - $style = 'index'; - // no break - case Cursor::HASH_ASSOC: - if (\is_int($key)) { - $this->line .= $this->style($style, $key).' => '; - } else { - $this->line .= $bin.'"'.$this->style($style, $key).'" => '; - } - break; - - case Cursor::HASH_RESOURCE: - $key = "\0~\0".$key; - // no break - case Cursor::HASH_OBJECT: - if (!isset($key[0]) || "\0" !== $key[0]) { - $this->line .= '+'.$bin.$this->style('public', $key).': '; - } elseif (0 < strpos($key, "\0", 1)) { - $key = explode("\0", substr($key, 1), 2); - - switch ($key[0][0]) { - case '+': // User inserted keys - $attr['dynamic'] = true; - $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": '; - break 2; - case '~': - $style = 'meta'; - if (isset($key[0][1])) { - parse_str(substr($key[0], 1), $attr); - $attr += ['binary' => $cursor->hashKeyIsBinary]; - } - break; - case '*': - $style = 'protected'; - $bin = '#'.$bin; - break; - default: - $attr['class'] = $key[0]; - $style = 'private'; - $bin = '-'.$bin; - break; - } - - if (isset($attr['collapse'])) { - if ($attr['collapse']) { - $this->collapseNextHash = true; - } else { - $this->expandNextHash = true; - } - } - - $this->line .= $bin.$this->style($style, $key[1], $attr).($attr['separator'] ?? ': '); - } else { - // This case should not happen - $this->line .= '-'.$bin.'"'.$this->style('private', $key, ['class' => '']).'": '; - } - break; - } - - if ($cursor->hardRefTo) { - $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), ['count' => $cursor->hardRefCount]).' '; - } - } - } - - /** - * Decorates a value with some style. - * - * @param string $style The type of style being applied - * @param string $value The value being styled - * @param array $attr Optional context information - */ - protected function style(string $style, string $value, array $attr = []): string - { - $this->colors ??= $this->supportsColors(); - - $this->handlesHrefGracefully ??= 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR') - && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100) - && !isset($_SERVER['IDEA_INITIAL_DIRECTORY']); - - if (isset($attr['ellipsis'], $attr['ellipsis-type'])) { - $prefix = substr($value, 0, -$attr['ellipsis']); - if ('cli' === \PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === \DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && str_starts_with($prefix, $_SERVER[$pwd])) { - $prefix = '.'.substr($prefix, \strlen($_SERVER[$pwd])); - } - if (!empty($attr['ellipsis-tail'])) { - $prefix .= substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']); - $value = substr($value, -$attr['ellipsis'] + $attr['ellipsis-tail']); - } else { - $value = substr($value, -$attr['ellipsis']); - } - - $value = $this->style('default', $prefix).$this->style($style, $value); - - goto href; - } - - $map = static::$controlCharsMap; - $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : ''; - $endCchr = $this->colors ? "\033[m\033[{$this->styles[$style]}m" : ''; - $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) { - $s = $startCchr; - $c = $c[$i = 0]; - do { - $s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i])); - } while (isset($c[++$i])); - - return $s.$endCchr; - }, $value, -1, $cchrCount); - - if (!($attr['binary'] ?? false)) { - $value = preg_replace_callback(static::$unicodeCharsRx, function ($c) use (&$cchrCount, $startCchr, $endCchr) { - ++$cchrCount; - - return $startCchr.'\u{'.strtoupper(dechex(mb_ord($c[0]))).'}'.$endCchr; - }, $value); - } - - if ($this->colors && '' !== $value) { - if ($cchrCount && "\033" === $value[0]) { - $value = substr($value, \strlen($startCchr)); - } else { - $value = "\033[{$this->styles[$style]}m".$value; - } - if ($cchrCount && str_ends_with($value, $endCchr)) { - $value = substr($value, 0, -\strlen($endCchr)); - } else { - $value .= "\033[{$this->styles['default']}m"; - } - } - - href: - if ($this->colors && $this->handlesHrefGracefully) { - if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) { - if ('note' === $style) { - $value .= "\033]8;;{$href}\033\\^\033]8;;\033\\"; - } else { - $attr['href'] = $href; - } - } - if (isset($attr['href'])) { - if ('label' === $style) { - $value .= '^'; - } - $value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\"; - } - } - - if ('label' === $style && '' !== $value) { - $value .= ' '; - } - - return $value; - } - - protected function supportsColors(): bool - { - if ($this->outputStream !== static::$defaultOutput) { - return $this->hasColorSupport($this->outputStream); - } - if (isset(static::$defaultColors)) { - return static::$defaultColors; - } - if (isset($_SERVER['argv'][1])) { - $colors = $_SERVER['argv']; - $i = \count($colors); - while (--$i > 0) { - if (isset($colors[$i][5])) { - switch ($colors[$i]) { - case '--ansi': - case '--color': - case '--color=yes': - case '--color=force': - case '--color=always': - case '--colors=always': - return static::$defaultColors = true; - - case '--no-ansi': - case '--color=no': - case '--color=none': - case '--color=never': - case '--colors=never': - return static::$defaultColors = false; - } - } - } - } - - $h = stream_get_meta_data($this->outputStream) + ['wrapper_type' => null]; - $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'w') : $this->outputStream; - - return static::$defaultColors = $this->hasColorSupport($h); - } - - /** - * @return void - */ - protected function dumpLine(int $depth, bool $endOfValue = false) - { - if (null === $this->colors) { - $this->colors = $this->supportsColors(); - } - - if ($this->colors) { - $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line); - } - parent::dumpLine($depth); - } - - /** - * @return void - */ - protected function endValue(Cursor $cursor) - { - if (-1 === $cursor->hashType) { - return; - } - - if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) { - if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) { - $this->line .= ','; - } elseif (self::DUMP_COMMA_SEPARATOR & $this->flags && 1 < $cursor->hashLength - $cursor->hashIndex) { - $this->line .= ','; - } - } - - $this->dumpLine($cursor->depth, true); - } - - /** - * Returns true if the stream supports colorization. - * - * Reference: Composer\XdebugHandler\Process::supportsColor - * https://github.com/composer/xdebug-handler - */ - private function hasColorSupport(mixed $stream): bool - { - if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) { - return false; - } - - // Follow https://no-color.org/ - if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) { - return false; - } - - if ('Hyper' === getenv('TERM_PROGRAM')) { - return true; - } - - if (\DIRECTORY_SEPARATOR === '\\') { - return (\function_exists('sapi_windows_vt100_support') - && @sapi_windows_vt100_support($stream)) - || false !== getenv('ANSICON') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM'); - } - - return stream_isatty($stream); - } - - /** - * Returns true if the Windows terminal supports true color. - * - * Note that this does not check an output stream, but relies on environment - * variables from known implementations, or a PHP and Windows version that - * supports true color. - */ - private function isWindowsTrueColor(): bool - { - $result = 183 <= getenv('ANSICON_VER') - || 'ON' === getenv('ConEmuANSI') - || 'xterm' === getenv('TERM') - || 'Hyper' === getenv('TERM_PROGRAM'); - - if (!$result) { - $version = sprintf( - '%s.%s.%s', - PHP_WINDOWS_VERSION_MAJOR, - PHP_WINDOWS_VERSION_MINOR, - PHP_WINDOWS_VERSION_BUILD - ); - $result = $version >= '10.0.15063'; - } - - return $result; - } - - private function getSourceLink(string $file, int $line): string|false - { - if ($fmt = $this->displayOptions['fileLinkFormat']) { - return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file.'#L'.$line); - } - - return false; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php deleted file mode 100644 index 38f878971..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper\ContextProvider; - -/** - * Tries to provide context on CLI. - * - * @author Maxime Steinhausser - */ -final class CliContextProvider implements ContextProviderInterface -{ - public function getContext(): ?array - { - if ('cli' !== \PHP_SAPI) { - return null; - } - - return [ - 'command_line' => $commandLine = implode(' ', $_SERVER['argv'] ?? []), - 'identifier' => hash('crc32b', $commandLine.$_SERVER['REQUEST_TIME_FLOAT']), - ]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php deleted file mode 100644 index 532aa0f96..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper\ContextProvider; - -/** - * Interface to provide contextual data about dump data clones sent to a server. - * - * @author Maxime Steinhausser - */ -interface ContextProviderInterface -{ - public function getContext(): ?array; -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php deleted file mode 100644 index 69dff067b..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper\ContextProvider; - -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\VarDumper\Caster\ReflectionCaster; -use Symfony\Component\VarDumper\Cloner\VarCloner; - -/** - * Tries to provide context from a request. - * - * @author Maxime Steinhausser - */ -final class RequestContextProvider implements ContextProviderInterface -{ - private RequestStack $requestStack; - private VarCloner $cloner; - - public function __construct(RequestStack $requestStack) - { - $this->requestStack = $requestStack; - $this->cloner = new VarCloner(); - $this->cloner->setMaxItems(0); - $this->cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO); - } - - public function getContext(): ?array - { - if (null === $request = $this->requestStack->getCurrentRequest()) { - return null; - } - - $controller = $request->attributes->get('_controller'); - - return [ - 'uri' => $request->getUri(), - 'method' => $request->getMethod(), - 'controller' => $controller ? $this->cloner->cloneVar($controller) : $controller, - 'identifier' => spl_object_hash($request), - ]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php deleted file mode 100644 index cadddfac4..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php +++ /dev/null @@ -1,127 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper\ContextProvider; - -use Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter; -use Symfony\Component\HttpKernel\Debug\FileLinkFormatter as LegacyFileLinkFormatter; -use Symfony\Component\VarDumper\Cloner\VarCloner; -use Symfony\Component\VarDumper\Dumper\HtmlDumper; -use Symfony\Component\VarDumper\VarDumper; -use Twig\Template; - -/** - * Tries to provide context from sources (class name, file, line, code excerpt, ...). - * - * @author Nicolas Grekas - * @author Maxime Steinhausser - */ -final class SourceContextProvider implements ContextProviderInterface -{ - private int $limit; - private ?string $charset; - private ?string $projectDir; - private FileLinkFormatter|LegacyFileLinkFormatter|null $fileLinkFormatter; - - public function __construct(?string $charset = null, ?string $projectDir = null, FileLinkFormatter|LegacyFileLinkFormatter|null $fileLinkFormatter = null, int $limit = 9) - { - $this->charset = $charset; - $this->projectDir = $projectDir; - $this->fileLinkFormatter = $fileLinkFormatter; - $this->limit = $limit; - } - - public function getContext(): ?array - { - $trace = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, $this->limit); - - $file = $trace[1]['file']; - $line = $trace[1]['line']; - $name = '-' === $file || 'Standard input code' === $file ? 'Standard input code' : false; - $fileExcerpt = false; - - for ($i = 2; $i < $this->limit; ++$i) { - if (isset($trace[$i]['class'], $trace[$i]['function']) - && 'dump' === $trace[$i]['function'] - && VarDumper::class === $trace[$i]['class'] - ) { - $file = $trace[$i]['file'] ?? $file; - $line = $trace[$i]['line'] ?? $line; - - while (++$i < $this->limit) { - if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && !str_starts_with($trace[$i]['function'], 'call_user_func')) { - $file = $trace[$i]['file']; - $line = $trace[$i]['line']; - - break; - } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof Template) { - $template = $trace[$i]['object']; - $name = $template->getTemplateName(); - $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false); - $info = $template->getDebugInfo(); - if (isset($info[$trace[$i - 1]['line']])) { - $line = $info[$trace[$i - 1]['line']]; - $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : null; - - if ($src) { - $src = explode("\n", $src); - $fileExcerpt = []; - - for ($i = max($line - 3, 1), $max = min($line + 3, \count($src)); $i <= $max; ++$i) { - $fileExcerpt[] = ''.$this->htmlEncode($src[$i - 1]).''; - } - - $fileExcerpt = '
      '.implode("\n", $fileExcerpt).'
    '; - } - } - break; - } - } - break; - } - } - - if (false === $name) { - $name = str_replace('\\', '/', $file); - $name = substr($name, strrpos($name, '/') + 1); - } - - $context = ['name' => $name, 'file' => $file, 'line' => $line]; - $context['file_excerpt'] = $fileExcerpt; - - if (null !== $this->projectDir) { - $context['project_dir'] = $this->projectDir; - if (str_starts_with($file, $this->projectDir)) { - $context['file_relative'] = ltrim(substr($file, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - } - } - - if ($this->fileLinkFormatter && $fileLink = $this->fileLinkFormatter->format($context['file'], $context['line'])) { - $context['file_link'] = $fileLink; - } - - return $context; - } - - private function htmlEncode(string $s): string - { - $html = ''; - - $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset); - $dumper->setDumpHeader(''); - $dumper->setDumpBoundaries('', ''); - - $cloner = new VarCloner(); - $dumper->dump($cloner->cloneVar($s)); - - return substr(strip_tags($html), 1, -1); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php deleted file mode 100644 index 84cfb4259..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; - -/** - * @author Kévin Thérage - */ -class ContextualizedDumper implements DataDumperInterface -{ - private DataDumperInterface $wrappedDumper; - private array $contextProviders; - - /** - * @param ContextProviderInterface[] $contextProviders - */ - public function __construct(DataDumperInterface $wrappedDumper, array $contextProviders) - { - $this->wrappedDumper = $wrappedDumper; - $this->contextProviders = $contextProviders; - } - - /** - * @return string|null - */ - public function dump(Data $data) - { - $context = $data->getContext(); - foreach ($this->contextProviders as $contextProvider) { - $context[$contextProvider::class] = $contextProvider->getContext(); - } - - return $this->wrappedDumper->dump($data->withContext($context)); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php deleted file mode 100644 index df05b6af5..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Data; - -/** - * DataDumperInterface for dumping Data objects. - * - * @author Nicolas Grekas - */ -interface DataDumperInterface -{ - /** - * @return string|null - */ - public function dump(Data $data); -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php deleted file mode 100644 index ea09e6819..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/HtmlDumper.php +++ /dev/null @@ -1,998 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Cursor; -use Symfony\Component\VarDumper\Cloner\Data; - -/** - * HtmlDumper dumps variables as HTML. - * - * @author Nicolas Grekas - */ -class HtmlDumper extends CliDumper -{ - /** @var callable|resource|string|null */ - public static $defaultOutput = 'php://output'; - - protected static $themes = [ - 'dark' => [ - 'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all', - 'num' => 'font-weight:bold; color:#1299DA', - 'const' => 'font-weight:bold', - 'str' => 'font-weight:bold; color:#56DB3A', - 'note' => 'color:#1299DA', - 'ref' => 'color:#A0A0A0', - 'public' => 'color:#FFFFFF', - 'protected' => 'color:#FFFFFF', - 'private' => 'color:#FFFFFF', - 'meta' => 'color:#B729D9', - 'key' => 'color:#56DB3A', - 'index' => 'color:#1299DA', - 'ellipsis' => 'color:#FF8400', - 'ns' => 'user-select:none;', - ], - 'light' => [ - 'default' => 'background:none; color:#CC7832; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all', - 'num' => 'font-weight:bold; color:#1299DA', - 'const' => 'font-weight:bold', - 'str' => 'font-weight:bold; color:#629755;', - 'note' => 'color:#6897BB', - 'ref' => 'color:#6E6E6E', - 'public' => 'color:#262626', - 'protected' => 'color:#262626', - 'private' => 'color:#262626', - 'meta' => 'color:#B729D9', - 'key' => 'color:#789339', - 'index' => 'color:#1299DA', - 'ellipsis' => 'color:#CC7832', - 'ns' => 'user-select:none;', - ], - ]; - - protected $dumpHeader; - protected $dumpPrefix = '
    ';
    -    protected $dumpSuffix = '
    '; - protected $dumpId = 'sf-dump'; - protected $colors = true; - protected $headerIsDumped = false; - protected $lastDepth = -1; - protected $styles; - - private array $displayOptions = [ - 'maxDepth' => 1, - 'maxStringLength' => 160, - 'fileLinkFormat' => null, - ]; - private array $extraDisplayOptions = []; - - public function __construct($output = null, ?string $charset = null, int $flags = 0) - { - AbstractDumper::__construct($output, $charset, $flags); - $this->dumpId = 'sf-dump-'.mt_rand(); - $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); - $this->styles = static::$themes['dark'] ?? self::$themes['dark']; - } - - /** - * @return void - */ - public function setStyles(array $styles) - { - $this->headerIsDumped = false; - $this->styles = $styles + $this->styles; - } - - /** - * @return void - */ - public function setTheme(string $themeName) - { - if (!isset(static::$themes[$themeName])) { - throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class)); - } - - $this->setStyles(static::$themes[$themeName]); - } - - /** - * Configures display options. - * - * @param array $displayOptions A map of display options to customize the behavior - * - * @return void - */ - public function setDisplayOptions(array $displayOptions) - { - $this->headerIsDumped = false; - $this->displayOptions = $displayOptions + $this->displayOptions; - } - - /** - * Sets an HTML header that will be dumped once in the output stream. - * - * @return void - */ - public function setDumpHeader(?string $header) - { - $this->dumpHeader = $header; - } - - /** - * Sets an HTML prefix and suffix that will encapse every single dump. - * - * @return void - */ - public function setDumpBoundaries(string $prefix, string $suffix) - { - $this->dumpPrefix = $prefix; - $this->dumpSuffix = $suffix; - } - - public function dump(Data $data, $output = null, array $extraDisplayOptions = []): ?string - { - $this->extraDisplayOptions = $extraDisplayOptions; - $result = parent::dump($data, $output); - $this->dumpId = 'sf-dump-'.mt_rand(); - - return $result; - } - - /** - * Dumps the HTML header. - * - * @return string - */ - protected function getDumpHeader() - { - $this->headerIsDumped = $this->outputStream ?? $this->lineDumper; - - if (null !== $this->dumpHeader) { - return $this->dumpHeader; - } - - $line = str_replace('{$options}', json_encode($this->displayOptions, \JSON_FORCE_OBJECT), <<<'EOHTML' -'.$this->dumpHeader; - } - - /** - * @return void - */ - public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut) - { - if ('' === $str && isset($cursor->attr['img-data'], $cursor->attr['content-type'])) { - $this->dumpKey($cursor); - $this->line .= $this->style('default', $cursor->attr['img-size'] ?? '', []); - $this->line .= $cursor->depth >= $this->displayOptions['maxDepth'] ? ' ' : ' '; - $this->endValue($cursor); - $this->line .= $this->indentPad; - $this->line .= sprintf('', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data'])); - $this->endValue($cursor); - } else { - parent::dumpString($cursor, $str, $bin, $cut); - } - } - - /** - * @return void - */ - public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild) - { - if (Cursor::HASH_OBJECT === $type) { - $cursor->attr['depth'] = $cursor->depth; - } - parent::enterHash($cursor, $type, $class, false); - - if ($cursor->skipChildren || $cursor->depth >= $this->displayOptions['maxDepth']) { - $cursor->skipChildren = false; - $eol = ' class=sf-dump-compact>'; - } else { - $this->expandNextHash = false; - $eol = ' class=sf-dump-expanded>'; - } - - if ($hasChild) { - $this->line .= 'dumpId, $r); - } - $this->line .= $eol; - $this->dumpLine($cursor->depth); - } - } - - /** - * @return void - */ - public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut) - { - $this->dumpEllipsis($cursor, $hasChild, $cut); - if ($hasChild) { - $this->line .= ''; - } - parent::leaveHash($cursor, $type, $class, $hasChild, 0); - } - - protected function style(string $style, string $value, array $attr = []): string - { - if ('' === $value && ('label' !== $style || !isset($attr['file']) && !isset($attr['href']))) { - return ''; - } - - $v = esc($value); - - if ('ref' === $style) { - if (empty($attr['count'])) { - return sprintf('%s', $v); - } - $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1); - - return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v); - } - - if ('const' === $style && isset($attr['value'])) { - $style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); - } elseif ('public' === $style) { - $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); - } elseif ('str' === $style && 1 < $attr['length']) { - $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); - } elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) { - $style .= ' title=""'; - $attr += [ - 'ellipsis' => \strlen($value) - $c, - 'ellipsis-type' => 'note', - 'ellipsis-tail' => 1, - ]; - } elseif ('protected' === $style) { - $style .= ' title="Protected property"'; - } elseif ('meta' === $style && isset($attr['title'])) { - $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title']))); - } elseif ('private' === $style) { - $style .= sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class']))); - } - - if (isset($attr['ellipsis'])) { - $class = 'sf-dump-ellipsis'; - if (isset($attr['ellipsis-type'])) { - $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']); - } - $label = esc(substr($value, -$attr['ellipsis'])); - $style = str_replace(' title="', " title=\"$v\n", $style); - $v = sprintf('%s', $class, substr($v, 0, -\strlen($label))); - - if (!empty($attr['ellipsis-tail'])) { - $tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']))); - $v .= sprintf('%s%s', $class, substr($label, 0, $tail), substr($label, $tail)); - } else { - $v .= $label; - } - } - - $map = static::$controlCharsMap; - $v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { - $s = $b = ''; - }, $v).''; - - if (!($attr['binary'] ?? false)) { - $v = preg_replace_callback(static::$unicodeCharsRx, function ($c) { - return '\u{'.strtoupper(dechex(mb_ord($c[0]))).'}'; - }, $v); - } - - if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) { - $attr['href'] = $href; - } - if (isset($attr['href'])) { - if ('label' === $style) { - $v .= '^'; - } - $target = isset($attr['file']) ? '' : ' target="_blank"'; - $v = sprintf('%s', esc($this->utf8Encode($attr['href'])), $target, $v); - } - if (isset($attr['lang'])) { - $v = sprintf('%s', esc($attr['lang']), $v); - } - if ('label' === $style) { - $v .= ' '; - } - - return $v; - } - - /** - * @return void - */ - protected function dumpLine(int $depth, bool $endOfValue = false) - { - if (-1 === $this->lastDepth) { - $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line; - } - if ($this->headerIsDumped !== ($this->outputStream ?? $this->lineDumper)) { - $this->line = $this->getDumpHeader().$this->line; - } - - if (-1 === $depth) { - $args = ['"'.$this->dumpId.'"']; - if ($this->extraDisplayOptions) { - $args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT); - } - // Replace is for BC - $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args)); - } - $this->lastDepth = $depth; - - $this->line = mb_encode_numericentity($this->line, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'); - - if (-1 === $depth) { - AbstractDumper::dumpLine(0); - } - AbstractDumper::dumpLine($depth); - } - - private function getSourceLink(string $file, int $line): string|false - { - $options = $this->extraDisplayOptions + $this->displayOptions; - - if ($fmt = $options['fileLinkFormat']) { - return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line); - } - - return false; - } -} - -function esc(string $str): string -{ - return htmlspecialchars($str, \ENT_QUOTES, 'UTF-8'); -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php deleted file mode 100644 index 60fdd7ac3..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Dumper/ServerDumper.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Dumper; - -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; -use Symfony\Component\VarDumper\Server\Connection; - -/** - * ServerDumper forwards serialized Data clones to a server. - * - * @author Maxime Steinhausser - */ -class ServerDumper implements DataDumperInterface -{ - private Connection $connection; - private ?DataDumperInterface $wrappedDumper; - - /** - * @param string $host The server host - * @param DataDumperInterface|null $wrappedDumper A wrapped instance used whenever we failed contacting the server - * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name - */ - public function __construct(string $host, ?DataDumperInterface $wrappedDumper = null, array $contextProviders = []) - { - $this->connection = new Connection($host, $contextProviders); - $this->wrappedDumper = $wrappedDumper; - } - - public function getContextProviders(): array - { - return $this->connection->getContextProviders(); - } - - /** - * @return string|null - */ - public function dump(Data $data) - { - if (!$this->connection->write($data) && $this->wrappedDumper) { - return $this->wrappedDumper->dump($data); - } - - return null; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php b/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php deleted file mode 100644 index fd8eca9f1..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Exception; - -/** - * @author Nicolas Grekas - */ -class ThrowingCasterException extends \Exception -{ - /** - * @param \Throwable $prev The exception thrown from the caster - */ - public function __construct(\Throwable $prev) - { - parent::__construct('Unexpected '.$prev::class.' thrown from a caster: '.$prev->getMessage(), 0, $prev); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/README.md b/data/web/inc/lib/vendor/symfony/var-dumper/README.md deleted file mode 100644 index a0da8c9ab..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/README.md +++ /dev/null @@ -1,15 +0,0 @@ -VarDumper Component -=================== - -The VarDumper component provides mechanisms for walking through any arbitrary -PHP variable. It provides a better `dump()` function that you can use instead -of `var_dump()`. - -Resources ---------- - - * [Documentation](https://symfony.com/doc/current/components/var_dumper/introduction.html) - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server deleted file mode 100755 index f398fcef7..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/bin/var-dump-server +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env php - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if ('cli' !== PHP_SAPI) { - throw new Exception('This script must be run from the command line.'); -} - -/** - * Starts a dump server to collect and output dumps on a single place with multiple formats support. - * - * @author Maxime Steinhausser - */ - -use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Application; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Logger\ConsoleLogger; -use Symfony\Component\Console\Output\ConsoleOutput; -use Symfony\Component\VarDumper\Command\ServerDumpCommand; -use Symfony\Component\VarDumper\Server\DumpServer; - -function includeIfExists(string $file): bool -{ - return file_exists($file) && include $file; -} - -if ( - !includeIfExists(__DIR__ . '/../../../../autoload.php') && - !includeIfExists(__DIR__ . '/../../vendor/autoload.php') && - !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php') -) { - fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL); - exit(1); -} - -if (!class_exists(Application::class)) { - fwrite(STDERR, 'You need the "symfony/console" component in order to run the VarDumper server.'.PHP_EOL); - exit(1); -} - -$input = new ArgvInput(); -$output = new ConsoleOutput(); -$defaultHost = '127.0.0.1:9912'; -$host = $input->getParameterOption(['--host'], $_SERVER['VAR_DUMPER_SERVER'] ?? $defaultHost, true); -$logger = interface_exists(LoggerInterface::class) ? new ConsoleLogger($output->getErrorOutput()) : null; - -$app = new Application(); - -$app->getDefinition()->addOption( - new InputOption('--host', null, InputOption::VALUE_REQUIRED, 'The address the server should listen to', $defaultHost) -); - -$app->add($command = new ServerDumpCommand(new DumpServer($host, $logger))) - ->getApplication() - ->setDefaultCommand($command->getName(), true) - ->run($input, $output) -; diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css b/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css deleted file mode 100644 index 8f706d640..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css +++ /dev/null @@ -1,130 +0,0 @@ -body { - display: flex; - flex-direction: column-reverse; - justify-content: flex-end; - max-width: 1140px; - margin: auto; - padding: 15px; - word-wrap: break-word; - background-color: #F9F9F9; - color: #222; - font-family: Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.4; -} -p { - margin: 0; -} -a { - color: #218BC3; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -.text-small { - font-size: 12px !important; -} -article { - margin: 5px; - margin-bottom: 10px; -} -article > header > .row { - display: flex; - flex-direction: row; - align-items: baseline; - margin-bottom: 10px; -} -article > header > .row > .col { - flex: 1; - display: flex; - align-items: baseline; -} -article > header > .row > h2 { - font-size: 14px; - color: #222; - font-weight: normal; - font-family: "Lucida Console", monospace, sans-serif; - word-break: break-all; - margin: 20px 5px 0 0; - user-select: all; -} -article > header > .row > h2 > code { - white-space: nowrap; - user-select: none; - color: #cc2255; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; - border-radius: 3px; - margin-right: 5px; - padding: 0 3px; -} -article > header > .row > time.col { - flex: 0; - text-align: right; - white-space: nowrap; - color: #999; - font-style: italic; -} -article > header ul.tags { - list-style: none; - padding: 0; - margin: 0; - font-size: 12px; -} -article > header ul.tags > li { - user-select: all; - margin-bottom: 2px; -} -article > header ul.tags > li > span.badge { - display: inline-block; - padding: .25em .4em; - margin-right: 5px; - border-radius: 4px; - background-color: #6c757d3b; - color: #524d4d; - font-size: 12px; - text-align: center; - font-weight: 700; - line-height: 1; - white-space: nowrap; - vertical-align: baseline; - user-select: none; -} -article > section.body { - border: 1px solid #d8d8d8; - background: #FFF; - padding: 10px; - border-radius: 3px; -} -pre.sf-dump { - border-radius: 3px; - margin-bottom: 0; -} -.hidden { - display: none !important; -} -.dumped-tag > .sf-dump { - display: inline-block; - margin: 0; - padding: 1px 5px; - line-height: 1.4; - vertical-align: top; - background-color: transparent; - user-select: auto; -} -.dumped-tag > pre.sf-dump, -.dumped-tag > .sf-dump-default { - color: #CC7832; - background: none; -} -.dumped-tag > .sf-dump .sf-dump-str { color: #629755; } -.dumped-tag > .sf-dump .sf-dump-private, -.dumped-tag > .sf-dump .sf-dump-protected, -.dumped-tag > .sf-dump .sf-dump-public { color: #262626; } -.dumped-tag > .sf-dump .sf-dump-note { color: #6897BB; } -.dumped-tag > .sf-dump .sf-dump-key { color: #789339; } -.dumped-tag > .sf-dump .sf-dump-ref { color: #6E6E6E; } -.dumped-tag > .sf-dump .sf-dump-ellipsis { color: #CC7832; max-width: 100em; } -.dumped-tag > .sf-dump .sf-dump-ellipsis-path { max-width: 5em; } -.dumped-tag > .sf-dump .sf-dump-ns { user-select: none; } diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php b/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php deleted file mode 100644 index f2ff74c0c..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/functions/dump.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Component\VarDumper\Caster\ScalarStub; -use Symfony\Component\VarDumper\VarDumper; - -if (!function_exists('dump')) { - /** - * @author Nicolas Grekas - * @author Alexandre Daubois - */ - function dump(mixed ...$vars): mixed - { - if (!$vars) { - VarDumper::dump(new ScalarStub('🐛')); - - return null; - } - - if (array_key_exists(0, $vars) && 1 === count($vars)) { - VarDumper::dump($vars[0]); - $k = 0; - } else { - foreach ($vars as $k => $v) { - VarDumper::dump($v, is_int($k) ? 1 + $k : $k); - } - } - - if (1 < count($vars)) { - return $vars; - } - - return $vars[$k]; - } -} - -if (!function_exists('dd')) { - function dd(mixed ...$vars): never - { - if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) && !headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - - if (array_key_exists(0, $vars) && 1 === count($vars)) { - VarDumper::dump($vars[0]); - } else { - foreach ($vars as $k => $v) { - VarDumper::dump($v, is_int($k) ? 1 + $k : $k); - } - } - - exit(1); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js b/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js deleted file mode 100644 index 63101e57c..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js +++ /dev/null @@ -1,10 +0,0 @@ -document.addEventListener('DOMContentLoaded', function() { - let prev = null; - Array.from(document.getElementsByTagName('article')).reverse().forEach(function (article) { - const dedupId = article.dataset.dedupId; - if (dedupId === prev) { - article.getElementsByTagName('header')[0].classList.add('hidden'); - } - prev = dedupId; - }); -}); diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php b/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php deleted file mode 100644 index 4383278c9..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Server/Connection.php +++ /dev/null @@ -1,97 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Server; - -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; - -/** - * Forwards serialized Data clones to a server. - * - * @author Maxime Steinhausser - */ -class Connection -{ - private string $host; - private array $contextProviders; - - /** - * @var resource|null - */ - private $socket; - - /** - * @param string $host The server host - * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name - */ - public function __construct(string $host, array $contextProviders = []) - { - if (!str_contains($host, '://')) { - $host = 'tcp://'.$host; - } - - $this->host = $host; - $this->contextProviders = $contextProviders; - } - - public function getContextProviders(): array - { - return $this->contextProviders; - } - - public function write(Data $data): bool - { - $socketIsFresh = !$this->socket; - if (!$this->socket = $this->socket ?: $this->createSocket()) { - return false; - } - - $context = ['timestamp' => microtime(true)]; - foreach ($this->contextProviders as $name => $provider) { - $context[$name] = $provider->getContext(); - } - $context = array_filter($context); - $encodedPayload = base64_encode(serialize([$data, $context]))."\n"; - - set_error_handler(static fn () => null); - try { - if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) { - return true; - } - if (!$socketIsFresh) { - stream_socket_shutdown($this->socket, \STREAM_SHUT_RDWR); - fclose($this->socket); - $this->socket = $this->createSocket(); - } - if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) { - return true; - } - } finally { - restore_error_handler(); - } - - return false; - } - - /** - * @return resource|null - */ - private function createSocket() - { - set_error_handler(static fn () => null); - try { - return stream_socket_client($this->host, $errno, $errstr, 3) ?: null; - } finally { - restore_error_handler(); - } - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php b/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php deleted file mode 100644 index a9228a2ef..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Server/DumpServer.php +++ /dev/null @@ -1,109 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Server; - -use Psr\Log\LoggerInterface; -use Symfony\Component\VarDumper\Cloner\Data; -use Symfony\Component\VarDumper\Cloner\Stub; - -/** - * A server collecting Data clones sent by a ServerDumper. - * - * @author Maxime Steinhausser - * - * @final - */ -class DumpServer -{ - private string $host; - private ?LoggerInterface $logger; - - /** - * @var resource|null - */ - private $socket; - - public function __construct(string $host, ?LoggerInterface $logger = null) - { - if (!str_contains($host, '://')) { - $host = 'tcp://'.$host; - } - - $this->host = $host; - $this->logger = $logger; - } - - public function start(): void - { - if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) { - throw new \RuntimeException(sprintf('Server start failed on "%s": ', $this->host).$errstr.' '.$errno); - } - } - - public function listen(callable $callback): void - { - if (null === $this->socket) { - $this->start(); - } - - foreach ($this->getMessages() as $clientId => $message) { - $this->logger?->info('Received a payload from client {clientId}', ['clientId' => $clientId]); - - $payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]); - - // Impossible to decode the message, give up. - if (false === $payload) { - $this->logger?->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]); - - continue; - } - - if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) { - $this->logger?->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]); - - continue; - } - - [$data, $context] = $payload; - - $callback($data, $context, $clientId); - } - } - - public function getHost(): string - { - return $this->host; - } - - private function getMessages(): iterable - { - $sockets = [(int) $this->socket => $this->socket]; - $write = []; - - while (true) { - $read = $sockets; - stream_select($read, $write, $write, null); - - foreach ($read as $stream) { - if ($this->socket === $stream) { - $stream = stream_socket_accept($this->socket); - $sockets[(int) $stream] = $stream; - } elseif (feof($stream)) { - unset($sockets[(int) $stream]); - fclose($stream); - } else { - yield (int) $stream => fgets($stream); - } - } - } - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php b/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php deleted file mode 100644 index 4475efd12..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper\Test; - -use Symfony\Component\VarDumper\Cloner\VarCloner; -use Symfony\Component\VarDumper\Dumper\CliDumper; - -/** - * @author Nicolas Grekas - */ -trait VarDumperTestTrait -{ - /** - * @internal - */ - private array $varDumperConfig = [ - 'casters' => [], - 'flags' => null, - ]; - - protected function setUpVarDumper(array $casters, ?int $flags = null): void - { - $this->varDumperConfig['casters'] = $casters; - $this->varDumperConfig['flags'] = $flags; - } - - /** - * @after - */ - protected function tearDownVarDumper(): void - { - $this->varDumperConfig['casters'] = []; - $this->varDumperConfig['flags'] = null; - } - - public function assertDumpEquals(mixed $expected, mixed $data, int $filter = 0, string $message = '') - { - $this->assertSame($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message); - } - - public function assertDumpMatchesFormat(mixed $expected, mixed $data, int $filter = 0, string $message = '') - { - $this->assertStringMatchesFormat($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message); - } - - protected function getDump(mixed $data, string|int|null $key = null, int $filter = 0): ?string - { - if (null === $flags = $this->varDumperConfig['flags']) { - $flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0; - $flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0; - $flags |= getenv('DUMP_COMMA_SEPARATOR') ? CliDumper::DUMP_COMMA_SEPARATOR : 0; - } - - $cloner = new VarCloner(); - $cloner->addCasters($this->varDumperConfig['casters']); - $cloner->setMaxItems(-1); - $dumper = new CliDumper(null, null, $flags); - $dumper->setColors(false); - $data = $cloner->cloneVar($data, $filter)->withRefHandles(false); - if (null !== $key && null === $data = $data->seek($key)) { - return null; - } - - return rtrim($dumper->dump($data, true)); - } - - private function prepareExpectation(mixed $expected, int $filter): string - { - if (!\is_string($expected)) { - $expected = $this->getDump($expected, null, $filter); - } - - return rtrim($expected); - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php b/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php deleted file mode 100644 index e1400f150..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/VarDumper.php +++ /dev/null @@ -1,127 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\VarDumper; - -use Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\VarDumper\Caster\ReflectionCaster; -use Symfony\Component\VarDumper\Cloner\VarCloner; -use Symfony\Component\VarDumper\Dumper\CliDumper; -use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider; -use Symfony\Component\VarDumper\Dumper\ContextProvider\RequestContextProvider; -use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider; -use Symfony\Component\VarDumper\Dumper\ContextualizedDumper; -use Symfony\Component\VarDumper\Dumper\HtmlDumper; -use Symfony\Component\VarDumper\Dumper\ServerDumper; - -// Load the global dump() function -require_once __DIR__.'/Resources/functions/dump.php'; - -/** - * @author Nicolas Grekas - */ -class VarDumper -{ - /** - * @var callable|null - */ - private static $handler; - - /** - * @param string|null $label - * - * @return mixed - */ - public static function dump(mixed $var/* , string $label = null */) - { - $label = 2 <= \func_num_args() ? func_get_arg(1) : null; - if (null === self::$handler) { - self::register(); - } - - return (self::$handler)($var, $label); - } - - public static function setHandler(?callable $callable = null): ?callable - { - if (1 > \func_num_args()) { - trigger_deprecation('symfony/var-dumper', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); - } - $prevHandler = self::$handler; - - // Prevent replacing the handler with expected format as soon as the env var was set: - if (isset($_SERVER['VAR_DUMPER_FORMAT'])) { - return $prevHandler; - } - - self::$handler = $callable; - - return $prevHandler; - } - - private static function register(): void - { - $cloner = new VarCloner(); - $cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO); - - $format = $_SERVER['VAR_DUMPER_FORMAT'] ?? null; - switch (true) { - case 'html' === $format: - $dumper = new HtmlDumper(); - break; - case 'cli' === $format: - $dumper = new CliDumper(); - break; - case 'server' === $format: - case $format && 'tcp' === parse_url($format, \PHP_URL_SCHEME): - $host = 'server' === $format ? $_SERVER['VAR_DUMPER_SERVER'] ?? '127.0.0.1:9912' : $format; - $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) ? new CliDumper() : new HtmlDumper(); - $dumper = new ServerDumper($host, $dumper, self::getDefaultContextProviders()); - break; - default: - $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) ? new CliDumper() : new HtmlDumper(); - } - - if (!$dumper instanceof ServerDumper) { - $dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]); - } - - self::$handler = function ($var, ?string $label = null) use ($cloner, $dumper) { - $var = $cloner->cloneVar($var); - - if (null !== $label) { - $var = $var->withContext(['label' => $label]); - } - - $dumper->dump($var); - }; - } - - private static function getDefaultContextProviders(): array - { - $contextProviders = []; - - if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) && class_exists(Request::class)) { - $requestStack = new RequestStack(); - $requestStack->push(Request::createFromGlobals()); - $contextProviders['request'] = new RequestContextProvider($requestStack); - } - - $fileLinkFormatter = class_exists(FileLinkFormatter::class) ? new FileLinkFormatter(null, $requestStack ?? null) : null; - - return $contextProviders + [ - 'cli' => new CliContextProvider(), - 'source' => new SourceContextProvider(null, null, $fileLinkFormatter), - ]; - } -} diff --git a/data/web/inc/lib/vendor/symfony/var-dumper/composer.json b/data/web/inc/lib/vendor/symfony/var-dumper/composer.json deleted file mode 100644 index e6166f86d..000000000 --- a/data/web/inc/lib/vendor/symfony/var-dumper/composer.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "symfony/var-dumper", - "type": "library", - "description": "Provides mechanisms for walking through any arbitrary PHP variable", - "keywords": ["dump", "debug"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" - }, - "conflict": { - "symfony/console": "<5.4" - }, - "autoload": { - "files": [ "Resources/functions/dump.php" ], - "psr-4": { "Symfony\\Component\\VarDumper\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "minimum-stability": "dev" -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/.github/workflows/run-tests.yml b/data/web/inc/lib/vendor/tightenco/collect/.github/workflows/run-tests.yml deleted file mode 100644 index 406c40049..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/.github/workflows/run-tests.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Run tests - -on: - push: - branches: [laravel-9-ongoing, laravel-8-ongoing] - pull_request: - -jobs: - tests: - strategy: - matrix: - os: [Ubuntu, macOS] - php: [8.0, 8.1, 8.2] - - include: - - os: Ubuntu - os-version: ubuntu-latest - - - os: macOS - os-version: macos-latest - - name: ${{ matrix.os }} - PHP ${{ matrix.php }} - - runs-on: ${{ matrix.os-version }} - - steps: - - name: Checkout code - uses: actions/checkout@v1 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: posix, dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick - coverage: none - - - name: Install dependencies - run: composer update --prefer-stable --prefer-dist --no-interaction - - - name: Run tests - run: bash upgrade.sh diff --git a/data/web/inc/lib/vendor/tightenco/collect/branch-commit-push.sh b/data/web/inc/lib/vendor/tightenco/collect/branch-commit-push.sh deleted file mode 100755 index 124e58331..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/branch-commit-push.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - - -GREEN='\033[0;32m' -RED='\033[0;31m' -WHITE='\033[0;37m' -RESET='\033[0m' - -function validateVersion() -{ - echo "" - passedVersion=$1 - echo -e "${WHITE}-- Validating tag '$passedVersion'...${RESET}" - - # Todo: validate the version here using a regex; if fail, just exit - # ... expect 8.75.0, with no v in front of it - - if [[ $passedVersion == '' ]]; then - echo -e "\n-- Invalid tag. Tags should be structured without v; e.g. 8.57.0" - exit - fi - - echo -e "${WHITE}-- Tag valid.${RESET}" - echo "" -} - -# Exit script if any command fails (e.g. phpunit) -set -e - - -# Require confirmation it's set up corrctly -echo -echo -e "${WHITE}-- This script is meant to be run after running upgrade.sh, BEFORE committing to Git.${RESET}" - -while true; do - echo -e "${GREEN}-- Is that the current state of your local project?${RESET}" - read -p "-- (y/n) " yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) echo "Please answer y or n.";; - esac -done - -# Get the version and exit if not valid -validateVersion $1 - -# Create official v prefaced version -version="v$1" - -# Run tests (and bail if they fail) -phpunit -echo -e "\n${WHITE}-- Tests succeeded.${RESET}" - -# Branch -echo -e "\n${WHITE}-- Creating a Git branch '$version-changes'...${RESET}\n" -git checkout -b $version-changes - -# Add and commit, with "v8.57.0 changes" as the commit name -git add -A -git commit -m "$version changes" - -echo -echo -e "${WHITE}-- Git committed.${RESET}" - -# Push -git push -u origin $version-changes diff --git a/data/web/inc/lib/vendor/tightenco/collect/composer.json b/data/web/inc/lib/vendor/tightenco/collect/composer.json deleted file mode 100644 index 949635dcd..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/composer.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "tightenco/collect", - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": ["laravel", "collection"], - "license": "MIT", - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "require": { - "php": "^8.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0 || ^6.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^8.3", - "nesbot/carbon": "^2.23.0" - }, - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "autoload-dev": { - "files": [ - "tests/files/Support/Carbon.php", - "tests/files/Support/HtmlString.php", - "tests/files/Support/HigherOrderTapProxy.php", - "tests/files/Support/Str.php", - "tests/files/Support/Stringable.php", - "tests/files/Support/ItemNotFoundException.php", - "tests/files/Support/MultipleItemsFoundException.php", - "tests/Support/Concerns/CountsEnumerations.php" - ] - }, - "scripts": { - "test": [ - "@composer install", - "phpunit" - ] - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/framework-.zip b/data/web/inc/lib/vendor/tightenco/collect/framework-.zip deleted file mode 100644 index e69de29bb..000000000 diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php b/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php deleted file mode 100755 index 190bb9bc3..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/Arrayable.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - public function toArray(); -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/CanBeEscapedWhenCastToString.php b/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/CanBeEscapedWhenCastToString.php deleted file mode 100644 index 6f3ba0025..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Contracts/Support/CanBeEscapedWhenCastToString.php +++ /dev/null @@ -1,14 +0,0 @@ - $needles - * @param bool $ignoreCase - * @return bool - */ - public static function contains($haystack, $needles, $ignoreCase = false) - { - if ($ignoreCase) { - $haystack = mb_strtolower($haystack); - } - - if (! is_iterable($needles)) { - $needles = (array) $needles; - } - - foreach ($needles as $needle) { - if ($ignoreCase) { - $needle = mb_strtolower($needle); - } - - if ($needle !== '' && str_contains($haystack, $needle)) { - return true; - } - } - - return false; - } - - /** - * Determine if a given string contains all array values. - * - * @param string $haystack - * @param iterable $needles - * @param bool $ignoreCase - * @return bool - */ - public static function containsAll($haystack, $needles, $ignoreCase = false) - { - foreach ($needles as $needle) { - if (! static::contains($haystack, $needle, $ignoreCase)) { - return false; - } - } - - return true; - } - - /** - * Determine if a given string ends with a given substring. - * - * @param string $haystack - * @param string|iterable $needles - * @return bool - */ - public static function endsWith($haystack, $needles) - { - if (! is_iterable($needles)) { - $needles = (array) $needles; - } - - foreach ($needles as $needle) { - if ((string) $needle !== '' && str_ends_with($haystack, $needle)) { - return true; - } - } - - return false; - } - - /** - * Extracts an excerpt from text that matches the first instance of a phrase. - * - * @param string $text - * @param string $phrase - * @param array $options - * @return string|null - */ - public static function excerpt($text, $phrase = '', $options = []) - { - $radius = $options['radius'] ?? 100; - $omission = $options['omission'] ?? '...'; - - preg_match('/^(.*?)('.preg_quote((string) $phrase).')(.*)$/iu', (string) $text, $matches); - - if (empty($matches)) { - return null; - } - - $start = ltrim($matches[1]); - - $start = str(mb_substr($start, max(mb_strlen($start, 'UTF-8') - $radius, 0), $radius, 'UTF-8'))->ltrim()->unless( - fn ($startWithRadius) => $startWithRadius->exactly($start), - fn ($startWithRadius) => $startWithRadius->prepend($omission), - ); - - $end = rtrim($matches[3]); - - $end = str(mb_substr($end, 0, $radius, 'UTF-8'))->rtrim()->unless( - fn ($endWithRadius) => $endWithRadius->exactly($end), - fn ($endWithRadius) => $endWithRadius->append($omission), - ); - - return $start->append($matches[2], $end)->toString(); - } - - /** - * Cap a string with a single instance of a given value. - * - * @param string $value - * @param string $cap - * @return string - */ - public static function finish($value, $cap) - { - $quoted = preg_quote($cap, '/'); - - return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap; - } - - /** - * Wrap the string with the given strings. - * - * @param string $value - * @param string $before - * @param string|null $after - * @return string - */ - public static function wrap($value, $before, $after = null) - { - return $before.$value.($after ??= $before); - } - - /** - * Determine if a given string matches a given pattern. - * - * @param string|iterable $pattern - * @param string $value - * @return bool - */ - public static function is($pattern, $value) - { - $value = (string) $value; - - if (! is_iterable($pattern)) { - $pattern = [$pattern]; - } - - foreach ($pattern as $pattern) { - $pattern = (string) $pattern; - - // If the given value is an exact match we can of course return true right - // from the beginning. Otherwise, we will translate asterisks and do an - // actual pattern match against the two strings to see if they match. - if ($pattern === $value) { - return true; - } - - $pattern = preg_quote($pattern, '#'); - - // Asterisks are translated into zero-or-more regular expression wildcards - // to make it convenient to check if the strings starts with the given - // pattern such as "library/*", making any string check convenient. - $pattern = str_replace('\*', '.*', $pattern); - - if (preg_match('#^'.$pattern.'\z#u', $value) === 1) { - return true; - } - } - - return false; - } - - /** - * Determine if a given string is 7 bit ASCII. - * - * @param string $value - * @return bool - */ - public static function isAscii($value) - { - return ASCII::is_ascii((string) $value); - } - - /** - * Determine if a given string is valid JSON. - * - * @param string $value - * @return bool - */ - public static function isJson($value) - { - if (! is_string($value)) { - return false; - } - - try { - json_decode($value, true, 512, JSON_THROW_ON_ERROR); - } catch (JsonException) { - return false; - } - - return true; - } - - /** - * Determine if a given string is a valid UUID. - * - * @param string $value - * @return bool - */ - public static function isUuid($value) - { - if (! is_string($value)) { - return false; - } - - return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; - } - - /** - * Determine if a given string is a valid ULID. - * - * @param string $value - * @return bool - */ - public static function isUlid($value) - { - if (! is_string($value)) { - return false; - } - - return Ulid::isValid($value); - } - - /** - * Convert a string to kebab case. - * - * @param string $value - * @return string - */ - public static function kebab($value) - { - return static::snake($value, '-'); - } - - /** - * Return the length of the given string. - * - * @param string $value - * @param string|null $encoding - * @return int - */ - public static function length($value, $encoding = null) - { - if ($encoding) { - return mb_strlen($value, $encoding); - } - - return mb_strlen($value); - } - - /** - * Limit the number of characters in a string. - * - * @param string $value - * @param int $limit - * @param string $end - * @return string - */ - public static function limit($value, $limit = 100, $end = '...') - { - if (mb_strwidth($value, 'UTF-8') <= $limit) { - return $value; - } - - return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end; - } - - /** - * Convert the given string to lower-case. - * - * @param string $value - * @return string - */ - public static function lower($value) - { - return mb_strtolower($value, 'UTF-8'); - } - - /** - * Limit the number of words in a string. - * - * @param string $value - * @param int $words - * @param string $end - * @return string - */ - public static function words($value, $words = 100, $end = '...') - { - preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches); - - if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) { - return $value; - } - - return rtrim($matches[0]).$end; - } - - /** - * Converts GitHub flavored Markdown into HTML. - * - * @param string $string - * @param array $options - * @return string - */ - public static function markdown($string, array $options = []) - { - $converter = new GithubFlavoredMarkdownConverter($options); - - return (string) $converter->convert($string); - } - - /** - * Converts inline Markdown into HTML. - * - * @param string $string - * @param array $options - * @return string - */ - public static function inlineMarkdown($string, array $options = []) - { - $environment = new Environment($options); - - $environment->addExtension(new GithubFlavoredMarkdownExtension()); - $environment->addExtension(new InlinesOnlyExtension()); - - $converter = new MarkdownConverter($environment); - - return (string) $converter->convert($string); - } - - /** - * Masks a portion of a string with a repeated character. - * - * @param string $string - * @param string $character - * @param int $index - * @param int|null $length - * @param string $encoding - * @return string - */ - public static function mask($string, $character, $index, $length = null, $encoding = 'UTF-8') - { - if ($character === '') { - return $string; - } - - $segment = mb_substr($string, $index, $length, $encoding); - - if ($segment === '') { - return $string; - } - - $strlen = mb_strlen($string, $encoding); - $startIndex = $index; - - if ($index < 0) { - $startIndex = $index < -$strlen ? 0 : $strlen + $index; - } - - $start = mb_substr($string, 0, $startIndex, $encoding); - $segmentLen = mb_strlen($segment, $encoding); - $end = mb_substr($string, $startIndex + $segmentLen); - - return $start.str_repeat(mb_substr($character, 0, 1, $encoding), $segmentLen).$end; - } - - /** - * Get the string matching the given pattern. - * - * @param string $pattern - * @param string $subject - * @return string - */ - public static function match($pattern, $subject) - { - preg_match($pattern, $subject, $matches); - - if (! $matches) { - return ''; - } - - return $matches[1] ?? $matches[0]; - } - - /** - * Get the string matching the given pattern. - * - * @param string $pattern - * @param string $subject - * @return \Tightenco\Collect\Support\Collection - */ - public static function matchAll($pattern, $subject) - { - preg_match_all($pattern, $subject, $matches); - - if (empty($matches[0])) { - return collect(); - } - - return collect($matches[1] ?? $matches[0]); - } - - /** - * Pad both sides of a string with another. - * - * @param string $value - * @param int $length - * @param string $pad - * @return string - */ - public static function padBoth($value, $length, $pad = ' ') - { - $short = max(0, $length - mb_strlen($value)); - $shortLeft = floor($short / 2); - $shortRight = ceil($short / 2); - - return mb_substr(str_repeat($pad, $shortLeft), 0, $shortLeft). - $value. - mb_substr(str_repeat($pad, $shortRight), 0, $shortRight); - } - - /** - * Pad the left side of a string with another. - * - * @param string $value - * @param int $length - * @param string $pad - * @return string - */ - public static function padLeft($value, $length, $pad = ' ') - { - $short = max(0, $length - mb_strlen($value)); - - return mb_substr(str_repeat($pad, $short), 0, $short).$value; - } - - /** - * Pad the right side of a string with another. - * - * @param string $value - * @param int $length - * @param string $pad - * @return string - */ - public static function padRight($value, $length, $pad = ' ') - { - $short = max(0, $length - mb_strlen($value)); - - return $value.mb_substr(str_repeat($pad, $short), 0, $short); - } - - /** - * Parse a Class[@]method style callback into class and method. - * - * @param string $callback - * @param string|null $default - * @return array - */ - public static function parseCallback($callback, $default = null) - { - return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default]; - } - - /** - * Get the plural form of an English word. - * - * @param string $value - * @param int|array|\Countable $count - * @return string - */ - public static function plural($value, $count = 2) - { - return Pluralizer::plural($value, $count); - } - - /** - * Pluralize the last word of an English, studly caps case string. - * - * @param string $value - * @param int|array|\Countable $count - * @return string - */ - public static function pluralStudly($value, $count = 2) - { - $parts = preg_split('/(.)(?=[A-Z])/u', $value, -1, PREG_SPLIT_DELIM_CAPTURE); - - $lastWord = array_pop($parts); - - return implode('', $parts).self::plural($lastWord, $count); - } - - /** - * Generate a more truly "random" alpha-numeric string. - * - * @param int $length - * @return string - */ - public static function random($length = 16) - { - return (static::$randomStringFactory ?? function ($length) { - $string = ''; - - while (($len = strlen($string)) < $length) { - $size = $length - $len; - - $bytesSize = (int) ceil($size / 3) * 3; - - $bytes = random_bytes($bytesSize); - - $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); - } - - return $string; - })($length); - } - - /** - * Set the callable that will be used to generate random strings. - * - * @param callable|null $factory - * @return void - */ - public static function createRandomStringsUsing(callable $factory = null) - { - static::$randomStringFactory = $factory; - } - - /** - * Set the sequence that will be used to generate random strings. - * - * @param array $sequence - * @param callable|null $whenMissing - * @return void - */ - public static function createRandomStringsUsingSequence(array $sequence, $whenMissing = null) - { - $next = 0; - - $whenMissing ??= function ($length) use (&$next) { - $factoryCache = static::$randomStringFactory; - - static::$randomStringFactory = null; - - $randomString = static::random($length); - - static::$randomStringFactory = $factoryCache; - - $next++; - - return $randomString; - }; - - static::createRandomStringsUsing(function ($length) use (&$next, $sequence, $whenMissing) { - if (array_key_exists($next, $sequence)) { - return $sequence[$next++]; - } - - return $whenMissing($length); - }); - } - - /** - * Indicate that random strings should be created normally and not using a custom factory. - * - * @return void - */ - public static function createRandomStringsNormally() - { - static::$randomStringFactory = null; - } - - /** - * Repeat the given string. - * - * @param string $string - * @param int $times - * @return string - */ - public static function repeat(string $string, int $times) - { - return str_repeat($string, $times); - } - - /** - * Replace a given value in the string sequentially with an array. - * - * @param string $search - * @param iterable $replace - * @param string $subject - * @return string - */ - public static function replaceArray($search, $replace, $subject) - { - if ($replace instanceof Traversable) { - $replace = collect($replace)->all(); - } - - $segments = explode($search, $subject); - - $result = array_shift($segments); - - foreach ($segments as $segment) { - $result .= (array_shift($replace) ?? $search).$segment; - } - - return $result; - } - - /** - * Replace the given value in the given string. - * - * @param string|iterable $search - * @param string|iterable $replace - * @param string|iterable $subject - * @return string - */ - public static function replace($search, $replace, $subject) - { - if ($search instanceof Traversable) { - $search = collect($search)->all(); - } - - if ($replace instanceof Traversable) { - $replace = collect($replace)->all(); - } - - if ($subject instanceof Traversable) { - $subject = collect($subject)->all(); - } - - return str_replace($search, $replace, $subject); - } - - /** - * Replace the first occurrence of a given value in the string. - * - * @param string $search - * @param string $replace - * @param string $subject - * @return string - */ - public static function replaceFirst($search, $replace, $subject) - { - $search = (string) $search; - - if ($search === '') { - return $subject; - } - - $position = strpos($subject, $search); - - if ($position !== false) { - return substr_replace($subject, $replace, $position, strlen($search)); - } - - return $subject; - } - - /** - * Replace the last occurrence of a given value in the string. - * - * @param string $search - * @param string $replace - * @param string $subject - * @return string - */ - public static function replaceLast($search, $replace, $subject) - { - if ($search === '') { - return $subject; - } - - $position = strrpos($subject, $search); - - if ($position !== false) { - return substr_replace($subject, $replace, $position, strlen($search)); - } - - return $subject; - } - - /** - * Remove any occurrence of the given string in the subject. - * - * @param string|iterable $search - * @param string $subject - * @param bool $caseSensitive - * @return string - */ - public static function remove($search, $subject, $caseSensitive = true) - { - if ($search instanceof Traversable) { - $search = collect($search)->all(); - } - - $subject = $caseSensitive - ? str_replace($search, '', $subject) - : str_ireplace($search, '', $subject); - - return $subject; - } - - /** - * Reverse the given string. - * - * @param string $value - * @return string - */ - public static function reverse(string $value) - { - return implode(array_reverse(mb_str_split($value))); - } - - /** - * Begin a string with a single instance of a given value. - * - * @param string $value - * @param string $prefix - * @return string - */ - public static function start($value, $prefix) - { - $quoted = preg_quote($prefix, '/'); - - return $prefix.preg_replace('/^(?:'.$quoted.')+/u', '', $value); - } - - /** - * Convert the given string to upper-case. - * - * @param string $value - * @return string - */ - public static function upper($value) - { - return mb_strtoupper($value, 'UTF-8'); - } - - /** - * Convert the given string to title case. - * - * @param string $value - * @return string - */ - public static function title($value) - { - return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8'); - } - - /** - * Convert the given string to title case for each word. - * - * @param string $value - * @return string - */ - public static function headline($value) - { - $parts = explode(' ', $value); - - $parts = count($parts) > 1 - ? array_map([static::class, 'title'], $parts) - : array_map([static::class, 'title'], static::ucsplit(implode('_', $parts))); - - $collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts)); - - return implode(' ', array_filter(explode('_', $collapsed))); - } - - /** - * Get the singular form of an English word. - * - * @param string $value - * @return string - */ - public static function singular($value) - { - return Pluralizer::singular($value); - } - - /** - * Generate a URL friendly "slug" from a given string. - * - * @param string $title - * @param string $separator - * @param string|null $language - * @param array $dictionary - * @return string - */ - public static function slug($title, $separator = '-', $language = 'en', $dictionary = ['@' => 'at']) - { - $title = $language ? static::ascii($title, $language) : $title; - - // Convert all dashes/underscores into separator - $flip = $separator === '-' ? '_' : '-'; - - $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title); - - // Replace dictionary words - foreach ($dictionary as $key => $value) { - $dictionary[$key] = $separator.$value.$separator; - } - - $title = str_replace(array_keys($dictionary), array_values($dictionary), $title); - - // Remove all characters that are not the separator, letters, numbers, or whitespace - $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', static::lower($title)); - - // Replace all separator characters and whitespace by a single separator - $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title); - - return trim($title, $separator); - } - - /** - * Convert a string to snake case. - * - * @param string $value - * @param string $delimiter - * @return string - */ - public static function snake($value, $delimiter = '_') - { - $key = $value; - - if (isset(static::$snakeCache[$key][$delimiter])) { - return static::$snakeCache[$key][$delimiter]; - } - - if (! ctype_lower($value)) { - $value = preg_replace('/\s+/u', '', ucwords($value)); - - $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value)); - } - - return static::$snakeCache[$key][$delimiter] = $value; - } - - /** - * Remove all "extra" blank space from the given string. - * - * @param string $value - * @return string - */ - public static function squish($value) - { - return preg_replace('~(\s|\x{3164})+~u', ' ', preg_replace('~^[\s\x{FEFF}]+|[\s\x{FEFF}]+$~u', '', $value)); - } - - /** - * Determine if a given string starts with a given substring. - * - * @param string $haystack - * @param string|iterable $needles - * @return bool - */ - public static function startsWith($haystack, $needles) - { - if (! is_iterable($needles)) { - $needles = [$needles]; - } - - foreach ($needles as $needle) { - if ((string) $needle !== '' && str_starts_with($haystack, $needle)) { - return true; - } - } - - return false; - } - - /** - * Convert a value to studly caps case. - * - * @param string $value - * @return string - */ - public static function studly($value) - { - $key = $value; - - if (isset(static::$studlyCache[$key])) { - return static::$studlyCache[$key]; - } - - $words = explode(' ', static::replace(['-', '_'], ' ', $value)); - - $studlyWords = array_map(fn ($word) => static::ucfirst($word), $words); - - return static::$studlyCache[$key] = implode($studlyWords); - } - - /** - * Returns the portion of the string specified by the start and length parameters. - * - * @param string $string - * @param int $start - * @param int|null $length - * @param string $encoding - * @return string - */ - public static function substr($string, $start, $length = null, $encoding = 'UTF-8') - { - return mb_substr($string, $start, $length, $encoding); - } - - /** - * Returns the number of substring occurrences. - * - * @param string $haystack - * @param string $needle - * @param int $offset - * @param int|null $length - * @return int - */ - public static function substrCount($haystack, $needle, $offset = 0, $length = null) - { - if (! is_null($length)) { - return substr_count($haystack, $needle, $offset, $length); - } - - return substr_count($haystack, $needle, $offset); - } - - /** - * Replace text within a portion of a string. - * - * @param string|string[] $string - * @param string|string[] $replace - * @param int|int[] $offset - * @param int|int[]|null $length - * @return string|string[] - */ - public static function substrReplace($string, $replace, $offset = 0, $length = null) - { - if ($length === null) { - $length = strlen($string); - } - - return substr_replace($string, $replace, $offset, $length); - } - - /** - * Swap multiple keywords in a string with other keywords. - * - * @param array $map - * @param string $subject - * @return string - */ - public static function swap(array $map, $subject) - { - return strtr($subject, $map); - } - - /** - * Make a string's first character lowercase. - * - * @param string $string - * @return string - */ - public static function lcfirst($string) - { - return static::lower(static::substr($string, 0, 1)).static::substr($string, 1); - } - - /** - * Make a string's first character uppercase. - * - * @param string $string - * @return string - */ - public static function ucfirst($string) - { - return static::upper(static::substr($string, 0, 1)).static::substr($string, 1); - } - - /** - * Split a string into pieces by uppercase characters. - * - * @param string $string - * @return string[] - */ - public static function ucsplit($string) - { - return preg_split('/(?=\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY); - } - - /** - * Get the number of words a string contains. - * - * @param string $string - * @param string|null $characters - * @return int - */ - public static function wordCount($string, $characters = null) - { - return str_word_count($string, 0, $characters); - } - - /** - * Generate a UUID (version 4). - * - * @return \Ramsey\Uuid\UuidInterface - */ - public static function uuid() - { - return static::$uuidFactory - ? call_user_func(static::$uuidFactory) - : Uuid::uuid4(); - } - - /** - * Generate a time-ordered UUID (version 4). - * - * @return \Ramsey\Uuid\UuidInterface - */ - public static function orderedUuid() - { - if (static::$uuidFactory) { - return call_user_func(static::$uuidFactory); - } - - $factory = new UuidFactory; - - $factory->setRandomGenerator(new CombGenerator( - $factory->getRandomGenerator(), - $factory->getNumberConverter() - )); - - $factory->setCodec(new TimestampFirstCombCodec( - $factory->getUuidBuilder() - )); - - return $factory->uuid4(); - } - - /** - * Set the callable that will be used to generate UUIDs. - * - * @param callable|null $factory - * @return void - */ - public static function createUuidsUsing(callable $factory = null) - { - static::$uuidFactory = $factory; - } - - /** - * Set the sequence that will be used to generate UUIDs. - * - * @param array $sequence - * @param callable|null $whenMissing - * @return void - */ - public static function createUuidsUsingSequence(array $sequence, $whenMissing = null) - { - $next = 0; - - $whenMissing ??= function () use (&$next) { - $factoryCache = static::$uuidFactory; - - static::$uuidFactory = null; - - $uuid = static::uuid(); - - static::$uuidFactory = $factoryCache; - - $next++; - - return $uuid; - }; - - static::createUuidsUsing(function () use (&$next, $sequence, $whenMissing) { - if (array_key_exists($next, $sequence)) { - return $sequence[$next++]; - } - - return $whenMissing(); - }); - } - - /** - * Always return the same UUID when generating new UUIDs. - * - * @param \Closure|null $callback - * @return \Ramsey\Uuid\UuidInterface - */ - public static function freezeUuids(Closure $callback = null) - { - $uuid = Str::uuid(); - - Str::createUuidsUsing(fn () => $uuid); - - if ($callback !== null) { - try { - $callback($uuid); - } finally { - Str::createUuidsNormally(); - } - } - - return $uuid; - } - - /** - * Indicate that UUIDs should be created normally and not using a custom factory. - * - * @return void - */ - public static function createUuidsNormally() - { - static::$uuidFactory = null; - } - - /** - * Generate a ULID. - * - * @return \Symfony\Component\Uid\Ulid - */ - public static function ulid() - { - return new Ulid(); - } - - /** - * Remove all strings from the casing caches. - * - * @return void - */ - public static function flushCache() - { - static::$snakeCache = []; - static::$camelCache = []; - static::$studlyCache = []; - } -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/Tappable.php b/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/Tappable.php deleted file mode 100644 index 9d75d26fb..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Traits/Tappable.php +++ /dev/null @@ -1,17 +0,0 @@ - Illuminate\Contracts\Support\Arrayable::class, - Tightenco\Collect\Contracts\Support\Jsonable::class => Illuminate\Contracts\Support\Jsonable::class, - Tightenco\Collect\Contracts\Support\Htmlable::class => Illuminate\Contracts\Support\Htmlable::class, - Tightenco\Collect\Contracts\Support\CanBeEscapedWhenCastToString::class => Illuminate\Contracts\Support\CanBeEscapedWhenCastToString::class, - Tightenco\Collect\Support\Arr::class => Illuminate\Support\Arr::class, - Tightenco\Collect\Support\Collection::class => Illuminate\Support\Collection::class, - Tightenco\Collect\Support\Enumerable::class => Illuminate\Support\Enumerable::class, - Tightenco\Collect\Support\HigherOrderCollectionProxy::class => Illuminate\Support\HigherOrderCollectionProxy::class, - Tightenco\Collect\Support\LazyCollection::class => Illuminate\Support\LazyCollection::class, - Tightenco\Collect\Support\Traits\EnumeratesValues::class => Illuminate\Support\Traits\EnumeratesValues::class, -]; - -# echo "\n\n-- Aliasing....\n---------------------------------------------\n\n"; - -foreach ($aliases as $tighten => $illuminate) { - if (! class_exists($illuminate) && ! interface_exists($illuminate) && ! trait_exists($illuminate)) { - # echo "Aliasing {$tighten} to {$illuminate}.\n"; - class_alias($tighten, $illuminate); - } -} diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/helpers.php b/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/helpers.php deleted file mode 100644 index 886a1414c..000000000 --- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/helpers.php +++ /dev/null @@ -1,122 +0,0 @@ - $segment) { - unset($key[$i]); - - if (is_null($segment)) { - return $target; - } - - if ($segment === '*') { - if ($target instanceof Collection) { - $target = $target->all(); - } elseif (! is_array($target)) { - return value($default); - } - - $result = []; - - foreach ($target as $item) { - $result[] = data_get($item, $key); - } - - return in_array('*', $key) ? Arr::collapse($result) : $result; - } - - if (Arr::accessible($target) && Arr::exists($target, $segment)) { - $target = $target[$segment]; - } elseif (is_object($target) && isset($target->{$segment})) { - $target = $target->{$segment}; - } else { - return value($default); - } - } - - return $target; - } - } - - if (! function_exists('tap')) { - /** - * Call the given Closure with the given value then return the value. - * - * @param mixed $value - * @param callable|null $callback - * @return mixed - */ - function tap($value, $callback = null) - { - if (is_null($callback)) { - return new HigherOrderTapProxy($value); - } - - $callback($value); - - return $value; - } - } - - if (! function_exists('class_basename')) { - /** - * Get the class "basename" of the given object / class. - * - * @param string|object $class - * @return string - */ - function class_basename($class) - { - $class = is_object($class) ? get_class($class) : $class; - - return basename(str_replace('\\', '/', $class)); - } - } -} diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 198e675aa..5e57a4d41 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -47,7 +47,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/CSSminifierExtended.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/array_merge_real.php'; // T/HOTP API -$qrprovider = new RobThree\Auth\Providers\Qr\QRServerProvider(); +$qrprovider = new RobThree\Auth\Providers\Qr\BaconQrCodeProvider(); $tfa = new RobThree\Auth\TwoFactorAuth($OTP_LABEL, 6, 30, 'sha1', $qrprovider); // FIDO2