From daf948237c82548c4dfe5c5738393ed420c52a72 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:06:36 +0200 Subject: [PATCH 01/36] feat: add get method to http client wrapper --- src/Support/HTTPClient.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Support/HTTPClient.php b/src/Support/HTTPClient.php index 782d9ee..4a01ab3 100644 --- a/src/Support/HTTPClient.php +++ b/src/Support/HTTPClient.php @@ -1,4 +1,5 @@ client->request('GET', $endpoint, [ + 'headers' => $headers, + 'query' => $query + ]); + + if ($response->getstatusCode() == 401) { + throw new UnauthorizedException('Unauthorized: Access is denied due to invalid credentials'); + } + + if ($response->getStatusCode() == 500) { + throw new InternalServerErrorException("Internal Server Error"); + } + + if ($this->isXML($response->getHeader("Content-Type"))) { + return $this->parseResponse($response); + } + + return $response; + } + /** * Parse xml response. * @param ResponseInterface $response From 6ed541d67f9c6e4a10edaee413838563e90d27c7 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:07:54 +0200 Subject: [PATCH 02/36] feat: add stub env file --- src/Console/GenerateSMSServiceProviderEnvVariablesCommand.php | 4 ++++ stubs/vectory_link.env.stub | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 stubs/vectory_link.env.stub diff --git a/src/Console/GenerateSMSServiceProviderEnvVariablesCommand.php b/src/Console/GenerateSMSServiceProviderEnvVariablesCommand.php index 28697b2..c5939fc 100644 --- a/src/Console/GenerateSMSServiceProviderEnvVariablesCommand.php +++ b/src/Console/GenerateSMSServiceProviderEnvVariablesCommand.php @@ -105,5 +105,9 @@ private function getStubContent(): string if ($this->argument('driver') == "infobip") { return File::get(__DIR__ . "/../../stubs/infobip.env.stub"); } + + if ($this->argument('driver') == "vectory_link") { + return File::get(__DIR__ . "/../../stubs/vectory_link.env.stub"); + } } } diff --git a/stubs/vectory_link.env.stub b/stubs/vectory_link.env.stub new file mode 100644 index 0000000..d9b2d56 --- /dev/null +++ b/stubs/vectory_link.env.stub @@ -0,0 +1,4 @@ +VECTORY_LINK_USERNAME= +VECTORY_LINK_PASSWORD= +VECTORY_LINK_SENDER_NAME= +VECTORY_LINK_END_POINT=https://smsvas.vlserv.com/KannelSending/service.asmx/SendSMS From 45f665520321ee14f38b22e9cbe2efaa46c1b7c6 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:10:37 +0200 Subject: [PATCH 03/36] feat: add vectory link configs --- config/resala.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/config/resala.php b/config/resala.php index 78b8ca7..3758b07 100644 --- a/config/resala.php +++ b/config/resala.php @@ -3,6 +3,7 @@ use RobustTools\SMS\Drivers\ConnekioDriver; use RobustTools\SMS\Drivers\InfobipDriver; use RobustTools\SMS\Drivers\VodafoneDriver; +use RobustTools\SMS\Drivers\VectoryLinkDriver; return [ @@ -46,6 +47,14 @@ 'password' => env('INFOBIP_PASSWORD'), 'sender_name' => env('INFOBIP_SENDER_NAME', 'Infobip') ], + + 'vectory_link' => [ + 'end_point' => env('VECTORY_LINK_END_POINT'), + 'username' => env('VECTORY_LINK_USERNAME'), + 'password' => env('VECTORY_LINK_PASSWORD'), + 'sender_name' => env('VECTORY_LINK_SENDER_NAME', 'Vectory Link'), + 'lang' => env('VECTORY_LINK_LANG', 'E') + ], ], /* @@ -59,6 +68,7 @@ 'map' => [ 'vodafone' => VodafoneDriver::class, 'connekio' => ConnekioDriver::class, - 'infobip' => InfobipDriver::class + 'infobip' => InfobipDriver::class, + 'vectory_link' => VectoryLinkDriver::class ], ]; From db30fae9f0f0f0fe6a502cfac0516a5c1475e37c Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:11:29 +0200 Subject: [PATCH 04/36] feat: add vectory link driver --- src/Drivers/VectoryLinkDriver.php | 121 ++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/Drivers/VectoryLinkDriver.php diff --git a/src/Drivers/VectoryLinkDriver.php b/src/Drivers/VectoryLinkDriver.php new file mode 100644 index 0000000..aea2d8a --- /dev/null +++ b/src/Drivers/VectoryLinkDriver.php @@ -0,0 +1,121 @@ +username = $config["username"]; + $this->password = $config["password"]; + $this->senderName = $config["sender_name"]; + $this->endPoint = $config["end_point"]; + $this->lang = $config["lang"]; + } + + /** + * @param string|array $recipient + * @return string|array + */ + public function to($recipient) + { + return $this->recipient = $recipient; + } + + /** + * @param string $message + * @return string + */ + public function message(string $message): string + { + return $this->message = $message; + } + + /** + * Build Infobip request payload. + * + * @return string + */ + public function payload(): string + { + return json_encode([ + "SMSText" => $this->message, + "SMSReceiver" => $this->recipient, + "SMSSender" => $this->senderName, + 'SMSLang' => $this->lang, + 'UserName' => $this->username, + 'Password' => $this->password + ]); + } + + /** + * Set Infobip Driver request headers. + * + * @return array|string[] + */ + public function headers(): array + { + return [ + 'Content-Type' => 'text/xml', + 'Content-Length' => 0 + ]; + } + + /** + * @return string + * @throws UnauthorizedException|InternalServerErrorException + */ + public function send(): string + { + $response = (new HTTPClient())->get($this->endPoint, $this->headers(), json_decode($this->payload(), true)); + + return ($response->getstatusCode() == 200) + ? "Message sent successfully" + : "Message couldn't be sent"; + } +} From ffc6662ac98d819fd7556d6fa9a1b89880c65642 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:12:39 +0200 Subject: [PATCH 05/36] feat: update reademe file --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 48f4547..a023d3e 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,14 @@ return [ 'password' => env('INFOBIP_PASSWORD'), 'sender_name' => env('INFOBIP_SENDER_NAME', 'Infobip') ], + + 'vectory_link' => [ + 'end_point' => env('VECTORY_LINK_END_POINT'), + 'username' => env('VECTORY_LINK_USERNAME'), + 'password' => env('VECTORY_LINK_PASSWORD'), + 'sender_name' => env('VECTORY_LINK_SENDER_NAME', 'Vectory Link'), + 'lang' => env('VECTORY_LINK_LANG', 'E') + ], ], /* @@ -88,7 +96,8 @@ return [ 'map' => [ 'vodafone' => VodafoneDriver::class, 'connekio' => ConnekioDriver::class, - 'infobip' => InfobipDriver::class + 'infobip' => InfobipDriver::class, + 'vectory_link' => VectoryLink::class ], ]; ``` @@ -108,6 +117,11 @@ php artisan resala:make infobip ``` This adds infobip environment variables to your .env file. +```bash +php artisan resala:make vectory_link +``` +This adds vectory link environment variables to your .env file. + ## Usage ``` php @@ -130,6 +144,11 @@ SMS::via('infobip') ->to('2012xxxxxxxx') ->message("Hello World") ->send(); + +SMS::via('vectory_link') + ->to('2012xxxxxxxx') + ->message("Hello World") + ->send(); ``` #Outside Laravel From 43bf0a6b8747346bb20556ff78d2793e5c7a83d3 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 19:39:49 +0200 Subject: [PATCH 06/36] update readme file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a023d3e..d149135 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ - Vodafone SMS Gateway - Connekio SMS Gateway - InfoPib SMS Gateway +- Vectory Link SMS Gateway ## Installation From 6eb5889cd3cae8943734bb7a13d38fb26f5f0b6e Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Sun, 13 Sep 2020 20:39:55 +0200 Subject: [PATCH 07/36] refactor: http client wrapper --- src/Support/HTTPClient.php | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Support/HTTPClient.php b/src/Support/HTTPClient.php index 4a01ab3..b32389e 100644 --- a/src/Support/HTTPClient.php +++ b/src/Support/HTTPClient.php @@ -35,19 +35,7 @@ public function post(string $endpoint, array $headers, $payload) 'body' => $payload ]); - if ($response->getstatusCode() == 401) { - throw new UnauthorizedException('Unauthorized: Access is denied due to invalid credentials'); - } - - if ($response->getStatusCode() == 500) { - throw new InternalServerErrorException("Internal Server Error"); - } - - if ($this->isXML($response->getHeader("Content-Type"))) { - return $this->parseResponse($response); - } - - return $response; + return $this->handleResponse($response); } @@ -66,6 +54,16 @@ public function get(string $endpoint, array $headers, array $query) 'query' => $query ]); + return $this->handleResponse($response); + } + + /** + * Handle response. + * @param ResponseInterface $response + * @return ResponseInterface|SimpleXMLElement + */ + private function handleResponse(ResponseInterface $response) + { if ($response->getstatusCode() == 401) { throw new UnauthorizedException('Unauthorized: Access is denied due to invalid credentials'); } From c80c4e2ad74a23500ef953062a127d30f8b08106 Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Mon, 14 Sep 2020 13:26:01 +0200 Subject: [PATCH 08/36] update readme file --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d149135..b03ba16 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # PHP & Laravel SMS Gateway Integration Package [![Latest Version on Packagist](https://img.shields.io/packagist/v/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) -[![Build Status](https://img.shields.io/travis/robust-tools/resala/master.svg?style=flat-square)](https://travis-ci.org/robust-tools/resala) -[![Quality Score](https://img.shields.io/scrutinizer/g/robust-tools/resala.svg?style=flat-square)](https://scrutinizer-ci.com/g/robust-tools/resala) [![Total Downloads](https://img.shields.io/packagist/dt/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) **Resala** is a PHP & Laravel Package, (Designed to add support to your laravel or just native php app for sending SMS using local operators in the MENA region Like `Vodafone`, `Infopib`, `Conneckio`). From bf68e817cd320ac060edb04784657709ededd2ed Mon Sep 17 00:00:00 2001 From: "olfat.mostafa" Date: Mon, 14 Sep 2020 13:48:17 +0200 Subject: [PATCH 09/36] feat: add vector link response handler --- src/Drivers/VectoryLinkDriver.php | 37 +++++++++------ src/Support/HTTPClient.php | 4 +- src/Support/VectoryLinkResponseHandler.php | 53 ++++++++++++++++++++++ 3 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 src/Support/VectoryLinkResponseHandler.php diff --git a/src/Drivers/VectoryLinkDriver.php b/src/Drivers/VectoryLinkDriver.php index aea2d8a..c1367e8 100644 --- a/src/Drivers/VectoryLinkDriver.php +++ b/src/Drivers/VectoryLinkDriver.php @@ -7,6 +7,7 @@ use RobustTools\SMS\Exceptions\InternalServerErrorException; use RobustTools\SMS\Exceptions\UnauthorizedException; use RobustTools\SMS\Support\HTTPClient; +use RobustTools\SMS\Support\VectoryLinkResponseHandler; final class VectoryLinkDriver extends Driver implements SMSServiceProviderDriverInterface { @@ -83,14 +84,26 @@ public function message(string $message): string */ public function payload(): string { - return json_encode([ - "SMSText" => $this->message, - "SMSReceiver" => $this->recipient, - "SMSSender" => $this->senderName, - 'SMSLang' => $this->lang, - 'UserName' => $this->username, - 'Password' => $this->password - ]); + return ''; + } + + + /** + * Build Vectory Link request parameters. + * + * @return array + */ + private function parameters(): array + { + return + [ + "SMSText" => $this->message, + "SMSReceiver" => $this->recipient, + "SMSSender" => $this->senderName, + 'SMSLang' => $this->lang, + 'UserName' => $this->username, + 'Password' => $this->password + ]; } /** @@ -101,7 +114,7 @@ public function payload(): string public function headers(): array { return [ - 'Content-Type' => 'text/xml', + 'Content-Type' => 'text/xml; charset=utf-8', 'Content-Length' => 0 ]; } @@ -112,10 +125,8 @@ public function headers(): array */ public function send(): string { - $response = (new HTTPClient())->get($this->endPoint, $this->headers(), json_decode($this->payload(), true)); + $response = (new HTTPClient())->get($this->endPoint, $this->headers(), $this->parameters()); - return ($response->getstatusCode() == 200) - ? "Message sent successfully" - : "Message couldn't be sent"; + return VectoryLinkResponseHandler::respond($response); } } diff --git a/src/Support/HTTPClient.php b/src/Support/HTTPClient.php index b32389e..37d6e43 100644 --- a/src/Support/HTTPClient.php +++ b/src/Support/HTTPClient.php @@ -47,7 +47,7 @@ public function post(string $endpoint, array $headers, $payload) * @throws InternalServerErrorException * @throws UnauthorizedException */ - public function get(string $endpoint, array $headers, array $query) + public function get(string $endpoint, ?array $headers = [], ?array $query = []) { $response = $this->client->request('GET', $endpoint, [ 'headers' => $headers, @@ -96,6 +96,6 @@ private function parseResponse(ResponseInterface $response): SimpleXMLElement */ private function isXML($contentType): bool { - return array_pop($contentType) == "application/xml"; + return (array_pop($contentType) == "text/xml; charset=utf-8") || (array_pop($contentType) == "application/xml"); } } diff --git a/src/Support/VectoryLinkResponseHandler.php b/src/Support/VectoryLinkResponseHandler.php new file mode 100644 index 0000000..0a80172 --- /dev/null +++ b/src/Support/VectoryLinkResponseHandler.php @@ -0,0 +1,53 @@ + Date: Wed, 14 Apr 2021 19:58:36 +0200 Subject: [PATCH 10/36] Provides compatibility for Laravel 8 (#8) * Provides compatibility for Laravel 8. * ci upgrade php version * upgrade php cs fixer --- .github/workflows/formats.yml | 2 +- composer.json | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/formats.yml b/.github/workflows/formats.yml index ca67d46..344ac3d 100644 --- a/.github/workflows/formats.yml +++ b/.github/workflows/formats.yml @@ -10,7 +10,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - php: [7.2] + php: [7.3] dependency-version: [prefer-lowest, prefer-stable] name: Formats P${{ matrix.php }} - ${{ matrix.os }} - ${{ matrix.dependency-version }} diff --git a/composer.json b/composer.json index 48dc7b7..a436e25 100644 --- a/composer.json +++ b/composer.json @@ -17,17 +17,17 @@ } ], "require": { - "php": "^7.2", + "php": "^7.3|^8.0", "ext-dom": "*", + "ext-json": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.5", - "illuminate/support": "^6.18|^7.0", - "ext-json": "*" + "guzzlehttp/guzzle": "^7.0.1", + "illuminate/support": "^6.18|^7.0|^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", + "friendsofphp/php-cs-fixer": "^2.18", "orchestra/testbench": "^4.6.0", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^9.0" }, "autoload": { "psr-4": { From 6b29c25abecd813266f34855ac87b758313f5a4b Mon Sep 17 00:00:00 2001 From: OlfatMostafa <35943416+OlfatMostafa@users.noreply.github.com> Date: Thu, 22 Apr 2021 14:56:22 +0200 Subject: [PATCH 11/36] feat: update connekio auth header format (#9) Co-authored-by: robusta --- src/Drivers/ConnekioDriver.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Drivers/ConnekioDriver.php b/src/Drivers/ConnekioDriver.php index 0a18eea..45926a2 100644 --- a/src/Drivers/ConnekioDriver.php +++ b/src/Drivers/ConnekioDriver.php @@ -1,4 +1,5 @@ username . $this->password . $this->accountId); + return base64_encode($this->username . ':' . $this->password . ':' . $this->accountId); } /** From 64c4991a65bec167b2d4987e42b7fdd47c942218 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sat, 6 Nov 2021 16:56:51 +0200 Subject: [PATCH 12/36] feat: inspect sms provider response * feat: handle vodafone response * feat: handle infobip response * feat: handle connekio response * feat: rename sms manager * build: github actions workflow * build: github actions workflow * build: github actions workflow * build: github actions workflow * build: github actions workflow * build: github actions workflow * build: github actions workflow * build: github actions workflow * linter.yml * build: github actions workflow * build: fix php cs fixer config file * build: fix php cs fixer config file * build: fix php cs fixer config file * fix code style * ignore php cs fixer cache file * update readme file --- .github/workflows/formats.yml | 41 ------ .github/workflows/linter.yml | 41 ++++++ .gitignore | 5 +- .php-cs-fixer.cache | 1 + .php_cs => .php_cs.dist.php | 17 ++- README.md | 38 +++-- composer.json | 17 ++- config/resala.php | 8 +- src/Abstracts/Driver.php | 37 ++--- ...=> PublishProviderEnvVariablesCommand.php} | 42 +----- src/Contracts/SMSDriverInterface.php | 17 +++ src/Contracts/SMSDriverResponseInterface.php | 13 ++ .../SMSServiceProviderDriverInterface.php | 26 ---- src/Drivers/ConnekioDriver.php | 132 +++++------------- src/Drivers/InfobipDriver.php | 87 +++--------- src/Drivers/VectoryLinkDriver.php | 102 ++++---------- src/Drivers/VodafoneDriver.php | 99 ++++--------- .../ConfigFileNotFoundException.php | 8 -- .../InternalServerErrorException.php | 9 -- src/Exceptions/UnauthorizedException.php | 9 -- src/Exceptions/UndefinedDriver.php | 9 -- src/Facades/SMS.php | 16 ++- src/Factories/SMSDriverFactory.php | 19 +++ src/Response/ConnekioResponse.php | 29 ++++ src/Response/InfobipResponse.php | 36 +++++ src/Response/VectoryLinkResponse.php | 58 ++++++++ src/Response/VodafoneResponse.php | 47 +++++++ src/SMS.php | 42 ++++++ src/SMSManager.php | 111 --------------- src/SMSServiceProvider.php | 8 +- src/Support/Config.php | 49 ++----- src/Support/ConfigRepository.php | 119 +++------------- src/Support/HTTP.php | 31 ++++ src/Support/HTTPClient.php | 101 -------------- src/Support/VectoryLinkResponseHandler.php | 53 ------- ...Builder.php => VodafonePayloadBuilder.php} | 132 +++++------------- tests/ExampleTest.php | 4 +- 37 files changed, 587 insertions(+), 1026 deletions(-) delete mode 100644 .github/workflows/formats.yml create mode 100644 .github/workflows/linter.yml create mode 100644 .php-cs-fixer.cache rename .php_cs => .php_cs.dist.php (84%) rename src/Console/{GenerateSMSServiceProviderEnvVariablesCommand.php => PublishProviderEnvVariablesCommand.php} (67%) create mode 100644 src/Contracts/SMSDriverInterface.php create mode 100644 src/Contracts/SMSDriverResponseInterface.php delete mode 100644 src/Contracts/SMSServiceProviderDriverInterface.php delete mode 100644 src/Exceptions/ConfigFileNotFoundException.php delete mode 100644 src/Exceptions/InternalServerErrorException.php delete mode 100644 src/Exceptions/UnauthorizedException.php delete mode 100644 src/Exceptions/UndefinedDriver.php create mode 100644 src/Factories/SMSDriverFactory.php create mode 100644 src/Response/ConnekioResponse.php create mode 100644 src/Response/InfobipResponse.php create mode 100644 src/Response/VectoryLinkResponse.php create mode 100644 src/Response/VodafoneResponse.php create mode 100644 src/SMS.php delete mode 100644 src/SMSManager.php create mode 100644 src/Support/HTTP.php delete mode 100644 src/Support/HTTPClient.php delete mode 100644 src/Support/VectoryLinkResponseHandler.php rename src/Support/{VodafoneXMLRequestBodyBuilder.php => VodafonePayloadBuilder.php} (51%) diff --git a/.github/workflows/formats.yml b/.github/workflows/formats.yml deleted file mode 100644 index 344ac3d..0000000 --- a/.github/workflows/formats.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Formats (PHP) - -on: ['push', 'pull_request'] - -jobs: - ci: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ubuntu-latest] - php: [7.3] - dependency-version: [prefer-lowest, prefer-stable] - - name: Formats P${{ matrix.php }} - ${{ matrix.os }} - ${{ matrix.dependency-version }} - - steps: - - - name: Checkout - uses: actions/checkout@v2 - - - name: Cache dependencies - uses: actions/cache@v1 - 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: dom, mbstring, zip - tools: prestissimo - coverage: pcov - - - name: Install Composer dependencies - run: composer update --${{ matrix.dependency-version }} --no-interaction --prefer-dist - - - name: Coding Style Checks - run: ./vendor/bin/php-cs-fixer fix diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 0000000..6ddd642 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,41 @@ +# This is a basic workflow to help you get started with Actions + +name: Formats (PHP) + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + php-cs-fixer: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Run php-cs-fixer + uses: docker://oskarstark/php-cs-fixer-ga + with: + args: --config=.php_cs.dist.php + + - name: Extract branch name + shell: bash + run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" + id: extract_branch + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: fix code style diff --git a/.gitignore b/.gitignore index 9412281..f2ebbfe 100644 --- a/.gitignore +++ b/.gitignore @@ -9,14 +9,15 @@ coverage .idea # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - +.php-cs-fixer.cache # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf - +.DS_Store +src/.DS_Store # Generated files .idea/**/contentModel.xml diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache new file mode 100644 index 0000000..9d50495 --- /dev/null +++ b/.php-cs-fixer.cache @@ -0,0 +1 @@ +{"php":"8.0.12","version":"3.2.1","indent":" ","lineEnding":"\n","rules":{"align_multiline_comment":true,"array_indentation":true,"array_syntax":{"syntax":"short"},"ordered_imports":{"sort_algorithm":"alpha"},"no_unused_imports":true,"blank_line_after_namespace":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":true,"ternary_operator_spaces":true,"ternary_to_null_coalescing":true,"multiline_whitespace_before_semicolons":true,"no_leading_namespace_whitespace":true,"braces":true,"cast_spaces":true,"compact_nullable_typehint":true,"concat_space":{"spacing":"one"},"constant_case":true,"declare_equal_normalize":true,"elseif":true,"encoding":true,"full_opening_tag":true,"function_declaration":true,"function_typehint_space":true,"global_namespace_import":{"import_classes":true},"linebreak_after_opening_tag":true,"lowercase_cast":true,"method_chaining_indentation":true,"multiline_comment_opening_closing":true,"no_empty_comment":true,"no_closing_tag":true,"no_blank_lines_before_namespace":true,"no_blank_lines_after_phpdoc":true,"no_blank_lines_after_class_opening":true,"no_empty_statement":true,"no_short_bool_cast":true,"no_useless_return":true,"ordered_class_elements":true,"phpdoc_add_missing_param_annotation":{"only_untyped":false},"group_import":true},"hashes":{"src\/Support\/ConfigRepository.php":1365459125,"src\/Support\/Config.php":1151255251,"src\/Support\/VodafonePayloadBuilder.php":1684215544,"src\/Support\/HTTP.php":1472831189,"src\/Drivers\/VectoryLinkDriver.php":406252964,"src\/Drivers\/VodafoneDriver.php":1238341100,"src\/Drivers\/InfobipDriver.php":335530869,"src\/Drivers\/ConnekioDriver.php":1571531796,"src\/SMSServiceProvider.php":640350770,"src\/Contracts\/SMSDriverInterface.php":1059122010,"src\/Contracts\/SMSDriverResponseInterface.php":995418700,"src\/Console\/PublishProviderEnvVariablesCommand.php":388730900,"src\/Factories\/SMSDriverFactory.php":344756343,"src\/Facades\/SMS.php":4164255274,"src\/Response\/VodafoneResponse.php":3599722771,"src\/Response\/VectoryLinkResponse.php":3456073796,"src\/Response\/InfobipResponse.php":1942728911,"src\/Response\/ConnekioResponse.php":1613338647,"src\/SMS.php":3977839681,"src\/Abstracts\/Driver.php":2206463311,"tests\/ExampleTest.php":339107738}} \ No newline at end of file diff --git a/.php_cs b/.php_cs.dist.php similarity index 84% rename from .php_cs rename to .php_cs.dist.php index 24a9500..75757bf 100644 --- a/.php_cs +++ b/.php_cs.dist.php @@ -4,7 +4,7 @@ 'align_multiline_comment' => true, 'array_indentation' => true, 'array_syntax' => ['syntax' => 'short'], - 'ordered_imports' => ['sortAlgorithm' => 'alpha'], + 'ordered_imports' => ['sort_algorithm' => 'alpha'], 'no_unused_imports' => true, 'blank_line_after_namespace' => true, 'blank_line_after_opening_tag' => true, @@ -24,11 +24,10 @@ 'full_opening_tag' => true, 'function_declaration' => true, 'function_typehint_space' => true, - 'global_namespace_import' => true, + 'global_namespace_import' => ['import_classes' => true], 'linebreak_after_opening_tag' => true, 'lowercase_cast' => true, 'method_chaining_indentation' => true, - 'class_attributes_separation' => true, 'multiline_comment_opening_closing' => true, 'no_empty_comment' => true, 'no_closing_tag' => true, @@ -40,17 +39,21 @@ 'no_useless_return' => true, 'ordered_class_elements' => true, 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], + 'group_import' => true ]; $finder = Symfony\Component\Finder\Finder::create() ->exclude("vendor") - ->in(__DIR__) + ->in([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) ->name('*.php') + ->notName('*.blade.php') ->ignoreDotFiles(true) - ->ignoreVCS(true) - ->append(['.php_cs']); + ->ignoreVCS(true); -return PhpCsFixer\Config::create() +return (new PhpCsFixer\Config()) ->setUsingCache(true) ->setRules($rules) ->setFinder($finder); diff --git a/README.md b/README.md index b03ba16..24a7c6c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Latest Version on Packagist](https://img.shields.io/packagist/v/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) [![Total Downloads](https://img.shields.io/packagist/dt/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) -**Resala** is a PHP & Laravel Package, (Designed to add support to your laravel or just native php app for sending SMS using local operators in the MENA region Like `Vodafone`, `Infopib`, `Conneckio`). +**Resala** is a PHP & Laravel Package, (Designed to add support to your laravel or just native php app for sending SMS using local operators in the MENA region Like `Vodafone`, `Infopib`, `Conneckio`, `VectoryLink). **Resala** not just tied to use inside Laravel you can hook it up in any php code ## Supported Providers @@ -26,7 +26,7 @@ composer require robust-tools/resala publish the config file with: ```bash -php artisan vendor:publish --provider="RobustTools\SMS\SMSServiceProvider" --tag="config" +php artisan vendor:publish --provider="RobustTools\Resala\SMSServiceProvider" --tag="config" ``` This is the contents of the published config file: @@ -100,26 +100,27 @@ return [ ], ]; ``` +## Available Commands: +This adds `vodafone` environment variables to your .env file. ```bash php artisan resala:make vodafone ``` -This adds vodafone environment variables to your .env file. - + +This adds `connekio` environment variables to your .env file. ```bash php artisan resala:make connekio ``` -This adds connekio environment variables to your .env file. +This adds `infobip` environment variables to your .env file. ```bash php artisan resala:make infobip ``` -This adds infobip environment variables to your .env file. +This adds `vectory_link` environment variables to your .env file. ```bash php artisan resala:make vectory_link ``` -This adds vectory link environment variables to your .env file. ## Usage @@ -132,6 +133,18 @@ SMS::to(['010xxxxxxxx', '011xxxxxxxx']) ->message("Hello World") ->send(); ``` + +You can inspect the returned response from your sms provider through: + +```php +$response = SMS::to(['010xxxxxxxx', '011xxxxxxxx']) + ->message("Hello World") + ->send(); + +$response->success() // returns bool true on success, false on failure. +$response->body() // returns the returned string response body from the sms provider. +``` + you can optionally change the driver using the `via` method ```php SMS::via('connekio') @@ -157,21 +170,16 @@ just replace the `env(values)` with your driver config values. ##Usage ```php -use RobustTools\SMS\SMSManager; +use RobustTools\Resala\SMS; $configFile = __DIR__ . "/config/resala.php"; -(new SMSManager($configFile))->to(['010995162378', '012345522']) +(new SMS($configFile))->to(['010995162378', '012345522']) ->message("Hello World") ->send(); ``` -IF no configuration file is being passed a `ConfigFileNotFoundException` will be thrown. - -### Changelog - - -Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. +IF no configuration file is being passed a `InvalidArgumentException` will be thrown. ## Contributing diff --git a/composer.json b/composer.json index a436e25..6ed7ed3 100644 --- a/composer.json +++ b/composer.json @@ -17,26 +17,25 @@ } ], "require": { - "php": "^7.3|^8.0", + "php": "^7.4|^8.0", "ext-dom": "*", "ext-json": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^7.0.1", - "illuminate/support": "^6.18|^7.0|^8.0" + "guzzlehttp/guzzle": "^7.4", + "illuminate/support": "^6.0|^7.0|^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.18", "orchestra/testbench": "^4.6.0", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^8.0" }, "autoload": { "psr-4": { - "RobustTools\\SMS\\": "src" + "RobustTools\\Resala\\": "src" } }, "autoload-dev": { "psr-4": { - "RobustTools\\SMS\\Tests\\": "tests" + "RobustTools\\Resala\\Tests\\": "tests" } }, "scripts": { @@ -50,10 +49,10 @@ "extra": { "laravel": { "providers": [ - "RobustTools\\SMS\\SMSServiceProvider" + "RobustTools\\Resala\\SMSServiceProvider" ], "aliases": { - "SMS": "RobustTools\\SMS\\Facades\\SMS" + "SMS": "RobustTools\\Resala\\Facades\\SMS" } } } diff --git a/config/resala.php b/config/resala.php index 3758b07..0f94bc6 100644 --- a/config/resala.php +++ b/config/resala.php @@ -1,9 +1,9 @@ argument('driver'); @@ -46,14 +40,16 @@ public function handle() return; } - if (File::exists($this->getEnvPath()) && ! $this->variablesAlreadySet()) { + if (File::exists($this->getEnvPath())) { $content = $this->getStubContent(); File::append($this->getEnvPath(), $content); $this->info("environment variables set successfully..."); return; } - $this->warn("check if the .env file exists or vodafone variables might already exists"); + + $this->error(".env file does not exist"); + } /** @@ -66,32 +62,6 @@ private function getEnvPath() return $this->laravel->basePath() . DIRECTORY_SEPARATOR . '.env'; } - /** - * @return string - */ - private function getEnvFileContents() - { - return File::get($this->getEnvPath()); - } - - /** - * Check if vodafone env variables already set. - * - * @return bool - */ - private function variablesAlreadySet(): bool - { - $variables = explode('=', $this->getStubContent()); - foreach ($variables as $variable) { - return Str::contains($this->getEnvFileContents(), $variable); - } - - return false; - } - - /** - * @return string - */ private function getStubContent(): string { if ($this->argument('driver') == 'vodafone') { diff --git a/src/Contracts/SMSDriverInterface.php b/src/Contracts/SMSDriverInterface.php new file mode 100644 index 0000000..05c0db7 --- /dev/null +++ b/src/Contracts/SMSDriverInterface.php @@ -0,0 +1,17 @@ +message = $message; } - /** - * Build connekio request payload. - * - * @return string - */ - public function payload(): string + public function send(): SMSDriverResponseInterface { - if (!$this->isSendingToMultipleRecipients($this->recipients)) { - json_encode([ - "account_id" => $this->accountId, - "text" => $this->message, - "msisdn" => $this->recipients, - "sender" => $this->senderName - ]); - } - - foreach ($this->recipients as $recipient) { - $mobileList[]['msisdn'] = $recipient; - } - - return json_encode([ - "account_id" => $this->accountId, - "text" => $this->message, - "sender" => $this->senderName, - "mobile_list" => $mobileList, - ]); + $response = HTTP::post($this->endpoint(), $this->headers(), $this->payload()); + + return new ConnekioResponse($response); } - /** - * Set connekio request headers. - * - * @return array|string[] - */ - public function headers(): array + protected function payload(): string { - return [ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - 'Authorization' => 'Basic ' . $this->authorization() + $payload = [ + "account_id" => $this->accountId, + "text" => $this->message, + "sender" => $this->senderName ]; - } - /** - * @return string - * @throws UnauthorizedException|InternalServerErrorException - */ - public function send(): string - { - $response = (new HTTPClient())->post($this->endpoint(), $this->headers(), $this->payload()); + $this->toMultiple($this->recipients) + ? $payload['mobile_list'] = array_map(fn ($recipient) => ['msisdn' => $recipient], $this->recipients) + : $payload["msisdn"] = $this->recipients; - return ($response->getstatusCode() == 200) - ? "Message sent successfully" - : "Message couldn't be sent"; + return json_encode($payload); } - /** - * Encode authorization credentials using base64. - * - * @return string - */ - private function authorization() + protected function headers(): array { - return base64_encode($this->username . ':' . $this->password . ':' . $this->accountId); + return [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => sprintf("Basic %s", base64_encode($this->username . ':' . $this->password . ':' . $this->accountId)) + ]; } - /** - * Specify request endpoint based on is it sing or batch. - * - * @return string - */ private function endpoint(): string { - return $this->isSendingToMultipleRecipients($this->recipients) + return $this->toMultiple($this->recipients) ? $this->batchSmsEndPoint : $this->singleSmsEndPoint; } diff --git a/src/Drivers/InfobipDriver.php b/src/Drivers/InfobipDriver.php index bbd371d..42cba3a 100644 --- a/src/Drivers/InfobipDriver.php +++ b/src/Drivers/InfobipDriver.php @@ -1,48 +1,28 @@ username = $config["username"]; @@ -60,21 +40,19 @@ public function to($recipients) return $this->recipients = $recipients; } - /** - * @param string $message - * @return string - */ public function message(string $message): string { return $this->message = $message; } - /** - * Build Infobip request payload. - * - * @return string - */ - public function payload(): string + public function send(): SMSDriverResponseInterface + { + $response = (new HTTP())->post($this->endPoint, $this->headers(), $this->payload()); + + return new InfobipResponse($response); + } + + protected function payload(): string { return json_encode([ "text" => $this->message, @@ -88,35 +66,12 @@ public function payload(): string * * @return array|string[] */ - public function headers(): array + protected function headers(): array { return [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', - 'Authorization' => 'Basic ' . $this->authorization() + 'Authorization' => sprintf("Basic %s", base64_encode($this->username . ':' . $this->password)) ]; } - - /** - * @return string - * @throws UnauthorizedException|InternalServerErrorException - */ - public function send(): string - { - $response = (new HTTPClient())->post($this->endPoint, $this->headers(), $this->payload()); - - return ($response->getstatusCode() == 200) - ? "Message sent successfully" - : "Message couldn't be sent"; - } - - /** - * Encode authorization credentials using base64. - * - * @return string - */ - private function authorization() - { - return base64_encode($this->username . ':' . $this->password); - } } diff --git a/src/Drivers/VectoryLinkDriver.php b/src/Drivers/VectoryLinkDriver.php index c1367e8..ba0cc4b 100644 --- a/src/Drivers/VectoryLinkDriver.php +++ b/src/Drivers/VectoryLinkDriver.php @@ -1,55 +1,30 @@ username = $config["username"]; @@ -60,45 +35,34 @@ public function __construct(array $config) } /** - * @param string|array $recipient + * @param string|array $recipients * @return string|array */ - public function to($recipient) + public function to($recipients) { - return $this->recipient = $recipient; + return $this->recipients = $this->toMultiple($recipients) + ? implode(', ', $recipients) + : $recipients; } - /** - * @param string $message - * @return string - */ public function message(string $message): string { return $this->message = $message; } - /** - * Build Infobip request payload. - * - * @return string - */ - public function payload(): string + public function send(): SMSDriverResponseInterface { - return ''; - } + $response = HTTP::get($this->endPoint, $this->headers(), $this->payload()); + return new VectoryLinkResponse($response); + } - /** - * Build Vectory Link request parameters. - * - * @return array - */ - private function parameters(): array + protected function payload(): array { return [ "SMSText" => $this->message, - "SMSReceiver" => $this->recipient, + "SMSReceiver" => $this->recipients, "SMSSender" => $this->senderName, 'SMSLang' => $this->lang, 'UserName' => $this->username, @@ -106,27 +70,11 @@ private function parameters(): array ]; } - /** - * Set Infobip Driver request headers. - * - * @return array|string[] - */ - public function headers(): array + protected function headers(): array { return [ 'Content-Type' => 'text/xml; charset=utf-8', 'Content-Length' => 0 ]; } - - /** - * @return string - * @throws UnauthorizedException|InternalServerErrorException - */ - public function send(): string - { - $response = (new HTTPClient())->get($this->endPoint, $this->headers(), $this->parameters()); - - return VectoryLinkResponseHandler::respond($response); - } } diff --git a/src/Drivers/VodafoneDriver.php b/src/Drivers/VodafoneDriver.php index fc642a5..f1de4f9 100644 --- a/src/Drivers/VodafoneDriver.php +++ b/src/Drivers/VodafoneDriver.php @@ -1,54 +1,27 @@ accountId = $config["account_id"]; @@ -67,29 +40,25 @@ public function to($recipients) return $this->recipients = $recipients; } - /** - * @param string $message - * @return string - */ public function message(string $message): string { return $this->message = $message; } - /** - * Build Vodafone request payload. - * - * @return string - */ - public function payload(): string + public function send(): SMSDriverResponseInterface { - $secureHash = strtoupper(hash_hmac('SHA256', $this->hashableKey(), $this->secureHash)); + $response = HTTP::post($this->endPoint, $this->headers(), $this->payload()); + + return new VodafoneResponse($response); + } - return (new VodafoneXMLRequestBodyBuilder( + protected function payload(): string + { + return (new VodafonePayloadBuilder( $this->accountId, $this->password, $this->senderName, - $secureHash, + strtoupper(hash_hmac('SHA256', $this->hashableKey(), $this->secureHash)), $this->recipients, $this->message ))->build(); @@ -100,37 +69,23 @@ public function payload(): string * * @return array|string[] */ - public function headers(): array + protected function headers(): array { return ['Content-Type' => 'application/xml; charset=UTF8']; } - /** - * @return string - * @throws UnauthorizedException|InternalServerErrorException - */ - public function send(): string - { - $response = (new HTTPClient())->post($this->endPoint, $this->headers(), $this->payload()); - - return $response->Description; - } - - /** - * @return string - */ private function hashableKey(): string { - $hashableKey = "AccountId=" . $this->accountId . "&Password=" . $this->password; + $hashableKey = sprintf("AccountId=%s&Password=%s", $this->accountId, $this->password); - if ($this->isSendingToMultipleRecipients($this->recipients)) { + if ($this->toMultiple($this->recipients)) { foreach ($this->recipients as $recipient) { - $hashableKey .= "&SenderName=" . $this->senderName . "&ReceiverMSISDN=" . $recipient . "&SMSText=" . $this->message; + $hashableKey .= sprintf("&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", $this->senderName, $recipient, $this->message); } return $hashableKey; } else { - return "AccountId=" . $this->accountId . "&Password=" . $this->password . "&SenderName=" . $this->senderName . "&ReceiverMSISDN=" . $this->recipients . "&SMSText=" . $this->message; + return sprintf("AccountId=%s&Password=%s&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", $this->accountId, $this->password, $this->senderName, $this->recipients, $this->message); } } } diff --git a/src/Exceptions/ConfigFileNotFoundException.php b/src/Exceptions/ConfigFileNotFoundException.php deleted file mode 100644 index d513dc2..0000000 --- a/src/Exceptions/ConfigFileNotFoundException.php +++ /dev/null @@ -1,8 +0,0 @@ -get('map'); + $driverName = $driver ?? $config->get('default'); + $driver = $drivers[$driverName]; + + return new $driver($config->get('drivers')[$driverName]); + } +} diff --git a/src/Response/ConnekioResponse.php b/src/Response/ConnekioResponse.php new file mode 100644 index 0000000..5991e60 --- /dev/null +++ b/src/Response/ConnekioResponse.php @@ -0,0 +1,29 @@ +response = $response->getReasonPhrase(); + + $this->statusCode = $response->getStatusCode(); + } + + public function success(): bool + { + return $this->statusCode >= 200 && $this->statusCode < 300; + } + + public function body(): string + { + return $this->response; + } +} diff --git a/src/Response/InfobipResponse.php b/src/Response/InfobipResponse.php new file mode 100644 index 0000000..949aacd --- /dev/null +++ b/src/Response/InfobipResponse.php @@ -0,0 +1,36 @@ +response = json_decode($response->getBody()->getContents(), true); + $this->statusCode = $response->getStatusCode(); + } + + public function body(): string + { + if ($this->success()) { + $message = $this->response['messages'][0]; + + return $message['status']['name'] . ": " . $message['status']['description']; + } else { + $error = $this->response['requestError']['serviceException']; + + return $error['messageId'] . ": " . $error['text']; + } + } + + public function success(): bool + { + return $this->statusCode >= 200 && $this->statusCode < 300; + } +} diff --git a/src/Response/VectoryLinkResponse.php b/src/Response/VectoryLinkResponse.php new file mode 100644 index 0000000..c1006d0 --- /dev/null +++ b/src/Response/VectoryLinkResponse.php @@ -0,0 +1,58 @@ +response = new SimpleXMLElement($response->getBody()); + $this->status = (int) current($this->response); + } + + public function success(): bool + { + return $this->status === self::OK + || $this->status === self::OK_QUEUED; + } + + public function body(): string + { + return [ + self::OK => 'Message Sent Successfully', + self::USER_ERR => 'User is not subscribed', + self::CREDIT_ERR => 'Out of credit.', + self::OK_QUEUED => 'Queued Message, no need to send it again.', + self::LANG_ERR => 'Invalid language.', + self::SMS_ERR => 'SMS is empty.', + self::SENDER_ERR => 'Invalid fake sender exceeded 12 chars or empty.', + self::SENDING_RATE_ERR => 'Sending rate greater than receiving rate (only for send/receive accounts).', + self::GENERIC_ERR => 'Other error', + ][$this->status] ?? 'Something wrong happened'; + } +} diff --git a/src/Response/VodafoneResponse.php b/src/Response/VodafoneResponse.php new file mode 100644 index 0000000..aa427d1 --- /dev/null +++ b/src/Response/VodafoneResponse.php @@ -0,0 +1,47 @@ +response = new SimpleXMLElement($response->getBody()); + $this->resultStatus = $this->response->ResultStatus; + $this->smsStatus = $this->response->SMSStatus; + } + + public function body(): string + { + return $this->response->Description; + } + + public function success(): bool + { + return $this->resultStatus === self::OK + && $this->smsStatus === self::SUBMITTED; + } +} diff --git a/src/SMS.php b/src/SMS.php new file mode 100644 index 0000000..dd20dc4 --- /dev/null +++ b/src/SMS.php @@ -0,0 +1,42 @@ +driver = SMSDriverFactory::create($driver, $filePath); + } + + public function via(string $driver): self + { + $this->driver = SMSDriverFactory::create($driver); + + return $this; + } + + public function to($recipients): self + { + $this->driver->to($recipients); + + return $this; + } + + public function message(string $message): self + { + $this->driver->message($message); + + return $this; + } + + public function send(): SMSDriverResponseInterface + { + return $this->driver->send(); + } +} + diff --git a/src/SMSManager.php b/src/SMSManager.php deleted file mode 100644 index f17ec3a..0000000 --- a/src/SMSManager.php +++ /dev/null @@ -1,111 +0,0 @@ -config = new Config($configFilePath); - $this->smsServiceProviderDriver = $this->getDriverInstance($this->config->get('default')); - } - - /** - * @param string $smsServiceProviderDriver - * @return SMSManager - * @throws UndefinedDriver - * @throws ReflectionException - */ - public function via(string $smsServiceProviderDriver): SMSManager - { - $this->smsServiceProviderDriver = $this->getDriverInstance($smsServiceProviderDriver); - - return $this; - } - - /** - * @param string|array $recipients - * @return $this - */ - public function to($recipients): SMSManager - { - $this->smsServiceProviderDriver->to($recipients); - - return $this; - } - - /** - * @param string $message - * @return $this - */ - public function message(string $message): SMSManager - { - $this->smsServiceProviderDriver->message($message); - - return $this; - } - - /** - * @return string - */ - public function send(): string - { - return $this->smsServiceProviderDriver->send(); - } - - /** - * Validate the given driver. - * - * @param string $driver - * @throws ReflectionException - * @throws UndefinedDriver - * @throws Exception - */ - private function driverValidation(string $driver) - { - if (!array_key_exists($driver, $this->config->get('map'))) { - throw new UndefinedDriver("Unknown Driver"); - } - - if (!(new ReflectionClass($this->config->get('map')[$driver]))->implementsInterface(SMSServiceProviderDriverInterface::class)) { - throw new Exception("Provided driver must respect SMSServiceProviderDriverInterface contract"); - } - } - - /** - * @param string $driver - * @return SMSServiceProviderDriverInterface - * @throws ReflectionException - * @throws UndefinedDriver - */ - private function getDriverInstance(string $driver): SMSServiceProviderDriverInterface - { - $this->driverValidation($driver); - $class = $this->config->get('map')[$driver]; - - return new $class($this->config->get('drivers')[$driver]); - } -} - diff --git a/src/SMSServiceProvider.php b/src/SMSServiceProvider.php index 198e14c..8e421b0 100644 --- a/src/SMSServiceProvider.php +++ b/src/SMSServiceProvider.php @@ -1,8 +1,8 @@ config_path('resala.php'), ], 'config'); $this->commands([ - GenerateSMSServiceProviderEnvVariablesCommand::class + PublishProviderEnvVariablesCommand::class ]); } } @@ -30,7 +30,7 @@ public function register() // Register the main class to use with the facade $this->app->singleton('sms', function () { - return new SMSManager; + return new SMS; }); } } diff --git a/src/Support/Config.php b/src/Support/Config.php index 33934b4..189442e 100644 --- a/src/Support/Config.php +++ b/src/Support/Config.php @@ -1,50 +1,27 @@ configurations($configFilePath); - $this->config = new ConfigRepository($config); + $this->config = new ConfigRepository( + $this->configurations($filepath) + ); } - /** - * @param $key - * - * @return mixed - */ public function get($key) { return $this->config->get($key); } - /** - * return the correct config directory path - * - * @param null $configFilePath - * @return mixed|string - * @throws ConfigFileNotFoundException - */ - private function configurations($configFilePath = null) + private function configurations(?string $filepath = null) { // check if this laravel context (means this package is used inside laravel framework). // If so then try to load the laravel resala config file if it exist. @@ -52,10 +29,10 @@ private function configurations($configFilePath = null) return config(self::CONFIG_FILE_NAME); } - if (is_null($configFilePath) || !file_exists($configFilePath)) { - throw new ConfigFileNotFoundException(); + if (is_null($filepath) || !file_exists($filepath)) { + throw new InvalidArgumentException("config file [$filepath] not found"); } - return require $configFilePath; + return require $filepath; } } diff --git a/src/Support/ConfigRepository.php b/src/Support/ConfigRepository.php index d43df3a..403db56 100644 --- a/src/Support/ConfigRepository.php +++ b/src/Support/ConfigRepository.php @@ -1,48 +1,24 @@ items = $items; } - /** - * Determine if the given configuration value exists. - * - * @param string $key - * @return bool - */ - public function has($key) + public function has($key): bool { return Arr::has($this->items, $key); } - /** - * Get the specified configuration value. - * - * @param array|string $key - * @param mixed $default - * @return mixed - */ - public function get($key, $default = null) + public function get($key, ?string $default = null) { if (is_array($key)) { return $this->getMany($key); @@ -51,13 +27,7 @@ public function get($key, $default = null) return Arr::get($this->items, $key, $default); } - /** - * Get many configuration values. - * - * @param array $keys - * @return array - */ - public function getMany($keys) + public function getMany(array $keys): array { $config = []; @@ -72,14 +42,7 @@ public function getMany($keys) return $config; } - /** - * Set a given configuration value. - * - * @param array|string $key - * @param mixed $value - * @return void - */ - public function set($key, $value = null) + public function set($key, $value = null): void { $keys = is_array($key) ? $key : [$key => $value]; @@ -88,14 +51,7 @@ public function set($key, $value = null) } } - /** - * Prepend a value onto an array configuration value. - * - * @param string $key - * @param mixed $value - * @return void - */ - public function prepend($key, $value) + public function prepend(string $key, $value): void { $array = $this->get($key); @@ -104,14 +60,7 @@ public function prepend($key, $value) $this->set($key, $array); } - /** - * Push a value onto an array configuration value. - * - * @param string $key - * @param mixed $value - * @return void - */ - public function push($key, $value) + public function push(string $key, $value): void { $array = $this->get($key); @@ -120,58 +69,28 @@ public function push($key, $value) $this->set($key, $array); } - /** - * Get all of the configuration items for the application. - * - * @return array - */ - public function all() + public function all(): array { return $this->items; } - /** - * Determine if the given configuration option exists. - * - * @param string $key - * @return bool - */ - public function offsetExists($key) + public function offsetExists($offset): bool { - return $this->has($key); + return $this->has($offset); } - /** - * Get a configuration option. - * - * @param string $key - * @return mixed - */ - public function offsetGet($key) + public function offsetGet($offset) { - return $this->get($key); + return $this->get($offset); } - /** - * Set a configuration option. - * - * @param string $key - * @param mixed $value - * @return void - */ - public function offsetSet($key, $value) + public function offsetSet($offset, $value): void { - $this->set($key, $value); + $this->set($offset, $value); } - /** - * Unset a configuration option. - * - * @param string $key - * @return void - */ - public function offsetUnset($key) + public function offsetUnset($offset): void { - $this->set($key, null); + $this->set($offset, null); } } diff --git a/src/Support/HTTP.php b/src/Support/HTTP.php new file mode 100644 index 0000000..4ae4b21 --- /dev/null +++ b/src/Support/HTTP.php @@ -0,0 +1,31 @@ +client = new Client(['http_errors' => false]); + } + + public static function post(string $endpoint, array $headers, $payload): ResponseInterface + { + return (new self())->client->request('POST', $endpoint, [ + 'headers' => $headers, + 'body' => $payload + ]); + } + + public static function get(string $endpoint, array $headers = [], array $query = []): ResponseInterface + { + return (new self())->client->request('GET', $endpoint, [ + 'headers' => $headers, + 'query' => $query + ]); + } +} diff --git a/src/Support/HTTPClient.php b/src/Support/HTTPClient.php deleted file mode 100644 index 37d6e43..0000000 --- a/src/Support/HTTPClient.php +++ /dev/null @@ -1,101 +0,0 @@ -client = new Client(['http_errors' => false]); - } - - /** - * @param string $endpoint - * @param array $headers - * @param $payload - * @return ResponseInterface|SimpleXMLElement - * @throws InternalServerErrorException - * @throws UnauthorizedException - */ - public function post(string $endpoint, array $headers, $payload) - { - $response = $this->client->request('POST', $endpoint, [ - 'headers' => $headers, - 'body' => $payload - ]); - - return $this->handleResponse($response); - } - - - /** - * @param string $endpoint - * @param array $headers - * @param array $query - * @return ResponseInterface|SimpleXMLElement - * @throws InternalServerErrorException - * @throws UnauthorizedException - */ - public function get(string $endpoint, ?array $headers = [], ?array $query = []) - { - $response = $this->client->request('GET', $endpoint, [ - 'headers' => $headers, - 'query' => $query - ]); - - return $this->handleResponse($response); - } - - /** - * Handle response. - * @param ResponseInterface $response - * @return ResponseInterface|SimpleXMLElement - */ - private function handleResponse(ResponseInterface $response) - { - if ($response->getstatusCode() == 401) { - throw new UnauthorizedException('Unauthorized: Access is denied due to invalid credentials'); - } - - if ($response->getStatusCode() == 500) { - throw new InternalServerErrorException("Internal Server Error"); - } - - if ($this->isXML($response->getHeader("Content-Type"))) { - return $this->parseResponse($response); - } - - return $response; - } - - /** - * Parse xml response. - * @param ResponseInterface $response - * @return SimpleXMLElement - */ - private function parseResponse(ResponseInterface $response): SimpleXMLElement - { - return new SimpleXMLElement($response->getBody()->getContents()); - } - - /** - * Detect response content type. - * @param $contentType - * @return bool - */ - private function isXML($contentType): bool - { - return (array_pop($contentType) == "text/xml; charset=utf-8") || (array_pop($contentType) == "application/xml"); - } -} diff --git a/src/Support/VectoryLinkResponseHandler.php b/src/Support/VectoryLinkResponseHandler.php deleted file mode 100644 index 0a80172..0000000 --- a/src/Support/VectoryLinkResponseHandler.php +++ /dev/null @@ -1,53 +0,0 @@ -secureHash = $secureHash; $this->accountId = $accountId; $this->password = $password; @@ -65,12 +42,7 @@ public function __construct(string $accountId, string $password, string $senderN $this->recipients = $recipients; } - /** - * Build request XML Body - * - * @return string - */ - public function build() + public function build(): string { $root = $this->rootElement(); $this->setRootElementAttributes($root); @@ -78,36 +50,21 @@ public function build() $this->generatePasswordElement($root); $this->generateSecureHashElement($root); - if (is_array($this->recipients)) { - foreach ($this->recipients as $recipient) { - $this->generateSMSListElement($root, $recipient); - } - } else { - $this->generateSMSListElement($root, $this->recipients); - } + is_array($this->recipients) + ? array_map(fn ($recipient) => $this->generateSMSListElement($root, $recipient), $this->recipients) + : $this->generateSMSListElement($root, $this->recipients); $this->domDocument->appendChild($root); return $this->domDocument->saveXML(); } - /** - * Generate root node. - * - * @return DOMElement - */ private function rootElement() : DOMElement { return $this->domDocument->createElement('SubmitSMSRequest'); } - /** - * Set root node attributes - * - * @param DOMElement $rootElement - * @return void - */ - private function setRootElementAttributes($rootElement) : void + private function setRootElementAttributes(DOMElement $rootElement) : void { $attr_xmlns = new DOMAttr('xmlns:', "http://www.edafa.com/web2sms/sms/model/"); $attr_xmlns_xsi = new DOMAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); @@ -120,47 +77,22 @@ private function setRootElementAttributes($rootElement) : void $rootElement->setAttributeNode($attr_xsi_type); } - /** - * Generate Account Id element. - * - * @param DOMElement $rootElement - * @return void - */ - private function generateAccountIdElement($rootElement) : void + private function generateAccountIdElement(DOMElement $rootElement) : void { $rootElement->appendChild($this->domDocument->createElement('AccountId', $this->accountId)); } - /** - * Generate Password element. - * - * @param DOMElement $rootElement - * @return void - */ - private function generatePasswordElement($rootElement) : void + private function generatePasswordElement(DOMElement $rootElement) : void { $rootElement->appendChild($this->domDocument->createElement('Password', $this->password)); } - /** - * Generate SecureHash element. - * - * @param DOMElement $rootElement - * @return void - */ - private function generateSecureHashElement($rootElement) : void + private function generateSecureHashElement(DOMElement $rootElement) : void { $rootElement->appendChild($this->domDocument->createElement('SecureHash', $this->secureHash)); } - /** - * Generate SMSList element. - * - * @param DOMElement $rootElement - * @param $recipient - * @return void - */ - private function generateSMSListElement($rootElement, $recipient) : void + private function generateSMSListElement(DOMElement $rootElement, string $recipient) : void { $sms_list_node = $rootElement->appendChild($this->domDocument->createElement("SMSList")); $sms_list_node->appendChild($this->domDocument->createElement("SenderName", $this->senderName)); diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index 2aaa50e..dca2143 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -1,8 +1,8 @@ Date: Sat, 6 Nov 2021 17:01:56 +0200 Subject: [PATCH 13/36] update .gitignore file --- .editorconfig | 15 --------- .gitignore | 85 ++++++++++++++++++++++++++++++++++++++++++++++++--- .travis.yml | 21 ------------- CHANGELOG.md | 7 ----- 4 files changed, 81 insertions(+), 47 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .travis.yml delete mode 100644 CHANGELOG.md diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index cd8eb86..0000000 --- a/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -; This file is for unifying the coding style for different editors and IDEs. -; More information at http://editorconfig.org - -root = true - -[*] -charset = utf-8 -indent_size = 4 -indent_style = space -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 9412281..0f98a24 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,13 @@ composer.lock docs vendor coverage -.php_cs.cache +.php-cs-fixer.cache -### PhpStorm ### -.idea -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Created by https://www.toptal.com/developers/gitignore/api/phpstorm+all +# Edit at https://www.toptal.com/developers/gitignore?templates=phpstorm+all + +### PhpStorm+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff @@ -17,6 +19,9 @@ coverage .idea/**/dictionaries .idea/**/shelf +# AWS User-specific +.idea/**/aws.xml + # Generated files .idea/**/contentModel.xml @@ -28,3 +33,75 @@ coverage .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### PhpStorm+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +# End of https://www.toptal.com/developers/gitignore/api/phpstorm+all + +.DS_Store +src/.DS_Store +.editorconfig \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 24c2d6c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: php - -php: - - 7.1 - - 7.2 - - 7.3 - -env: - matrix: - - COMPOSER_FLAGS="--prefer-lowest" - - COMPOSER_FLAGS="" - -before_script: - - travis_retry composer self-update - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source - -script: - - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - php vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index b651a6b..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# Changelog - -All notable changes to `sms` will be documented in this file - -## 1.0.0 - 2020-02-22 - -- initial release From f672abfc64e7525de7ea48125bc9cb4287f09f7b Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sat, 6 Nov 2021 17:06:45 +0200 Subject: [PATCH 14/36] Delete .php-cs-fixer.cache --- .php-cs-fixer.cache | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .php-cs-fixer.cache diff --git a/.php-cs-fixer.cache b/.php-cs-fixer.cache deleted file mode 100644 index 9d50495..0000000 --- a/.php-cs-fixer.cache +++ /dev/null @@ -1 +0,0 @@ -{"php":"8.0.12","version":"3.2.1","indent":" ","lineEnding":"\n","rules":{"align_multiline_comment":true,"array_indentation":true,"array_syntax":{"syntax":"short"},"ordered_imports":{"sort_algorithm":"alpha"},"no_unused_imports":true,"blank_line_after_namespace":true,"blank_line_after_opening_tag":true,"blank_line_before_statement":true,"ternary_operator_spaces":true,"ternary_to_null_coalescing":true,"multiline_whitespace_before_semicolons":true,"no_leading_namespace_whitespace":true,"braces":true,"cast_spaces":true,"compact_nullable_typehint":true,"concat_space":{"spacing":"one"},"constant_case":true,"declare_equal_normalize":true,"elseif":true,"encoding":true,"full_opening_tag":true,"function_declaration":true,"function_typehint_space":true,"global_namespace_import":{"import_classes":true},"linebreak_after_opening_tag":true,"lowercase_cast":true,"method_chaining_indentation":true,"multiline_comment_opening_closing":true,"no_empty_comment":true,"no_closing_tag":true,"no_blank_lines_before_namespace":true,"no_blank_lines_after_phpdoc":true,"no_blank_lines_after_class_opening":true,"no_empty_statement":true,"no_short_bool_cast":true,"no_useless_return":true,"ordered_class_elements":true,"phpdoc_add_missing_param_annotation":{"only_untyped":false},"group_import":true},"hashes":{"src\/Support\/ConfigRepository.php":1365459125,"src\/Support\/Config.php":1151255251,"src\/Support\/VodafonePayloadBuilder.php":1684215544,"src\/Support\/HTTP.php":1472831189,"src\/Drivers\/VectoryLinkDriver.php":406252964,"src\/Drivers\/VodafoneDriver.php":1238341100,"src\/Drivers\/InfobipDriver.php":335530869,"src\/Drivers\/ConnekioDriver.php":1571531796,"src\/SMSServiceProvider.php":640350770,"src\/Contracts\/SMSDriverInterface.php":1059122010,"src\/Contracts\/SMSDriverResponseInterface.php":995418700,"src\/Console\/PublishProviderEnvVariablesCommand.php":388730900,"src\/Factories\/SMSDriverFactory.php":344756343,"src\/Facades\/SMS.php":4164255274,"src\/Response\/VodafoneResponse.php":3599722771,"src\/Response\/VectoryLinkResponse.php":3456073796,"src\/Response\/InfobipResponse.php":1942728911,"src\/Response\/ConnekioResponse.php":1613338647,"src\/SMS.php":3977839681,"src\/Abstracts\/Driver.php":2206463311,"tests\/ExampleTest.php":339107738}} \ No newline at end of file From a45bb4fcf9a606fdc92c8fd16e393cfd0d431e30 Mon Sep 17 00:00:00 2001 From: mohabdelaziz95 Date: Sat, 6 Nov 2021 15:07:00 +0000 Subject: [PATCH 15/36] fix code style --- src/Console/PublishProviderEnvVariablesCommand.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Console/PublishProviderEnvVariablesCommand.php b/src/Console/PublishProviderEnvVariablesCommand.php index a08d274..0a2328b 100644 --- a/src/Console/PublishProviderEnvVariablesCommand.php +++ b/src/Console/PublishProviderEnvVariablesCommand.php @@ -49,7 +49,6 @@ public function handle() } $this->error(".env file does not exist"); - } /** From 6a6c65eb825293c765041392db4b276c191475c1 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sat, 6 Nov 2021 17:07:48 +0200 Subject: [PATCH 16/36] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24a7c6c..7fffb0f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Latest Version on Packagist](https://img.shields.io/packagist/v/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) [![Total Downloads](https://img.shields.io/packagist/dt/robust-tools/resala.svg?style=flat-square)](https://packagist.org/packages/robust-tools/resala) -**Resala** is a PHP & Laravel Package, (Designed to add support to your laravel or just native php app for sending SMS using local operators in the MENA region Like `Vodafone`, `Infopib`, `Conneckio`, `VectoryLink). +**Resala** is a PHP & Laravel Package, (Designed to add support to your laravel or just native php app for sending SMS using local operators in the MENA region Like `Vodafone`, `Infopib`, `Conneckio`, `VectoryLink`). **Resala** not just tied to use inside Laravel you can hook it up in any php code ## Supported Providers From 2794c1f5a7f95e3204116bb31860de164caa1c7f Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sat, 6 Nov 2021 18:46:57 +0200 Subject: [PATCH 17/36] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7fffb0f..4d14107 100644 --- a/README.md +++ b/README.md @@ -163,12 +163,10 @@ SMS::via('vectory_link') ->send(); ``` -#Outside Laravel -You need to add a config file named `resala.php` in your project directory the contents of the config file must match the schema of the package config file you can find it [HERE](https://github.com/RobustaStudio/Resala/blob/master/config/resala.php). +## Outside Laravel +You need to add a config file named `resala.php` in your project directory the contents of the config file must match the schema of the package config file you can find it [HERE](https://github.com/RobustaStudio/Resala/blob/master/config/resala.php). just replace the `env(values)` with your driver config values. -##Usage - ```php use RobustTools\Resala\SMS; From db7bf870f9de26c4dadebc624b0730c9700ae376 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sun, 7 Nov 2021 10:59:04 +0200 Subject: [PATCH 18/36] Update README.md --- README.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4d14107..fc10759 100644 --- a/README.md +++ b/README.md @@ -147,20 +147,10 @@ $response->body() // returns the returned string response body from the sms prov you can optionally change the driver using the `via` method ```php -SMS::via('connekio') +SMS::via('vodafone') ->to('010xxxxxxxx') ->message("Hello World") ->send(); - -SMS::via('infobip') - ->to('2012xxxxxxxx') - ->message("Hello World") - ->send(); - -SMS::via('vectory_link') - ->to('2012xxxxxxxx') - ->message("Hello World") - ->send(); ``` ## Outside Laravel @@ -172,7 +162,7 @@ use RobustTools\Resala\SMS; $configFile = __DIR__ . "/config/resala.php"; -(new SMS($configFile))->to(['010995162378', '012345522']) +(new SMS($driver, $configFile))->to(['010995162378', '012345522']) ->message("Hello World") ->send(); ``` From 217fc0711a25bf6a7d92aa03b3b8574c334647c6 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Sun, 7 Nov 2021 11:00:37 +0200 Subject: [PATCH 19/36] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc10759..586d697 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,8 @@ $response = SMS::to(['010xxxxxxxx', '011xxxxxxxx']) ->message("Hello World") ->send(); -$response->success() // returns bool true on success, false on failure. -$response->body() // returns the returned string response body from the sms provider. +$response->success(); // returns bool +$response->body(); // returns string ``` you can optionally change the driver using the `via` method From 586412e4fd45e5b2fb088de1299302c096f6b577 Mon Sep 17 00:00:00 2001 From: Mustafa Aboulfotouh <35197335+maboulfotouh@users.noreply.github.com> Date: Mon, 7 Nov 2022 09:08:28 +0200 Subject: [PATCH 20/36] feat: support laravel 9 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6ed7ed3..bded07d 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "ext-json": "*", "ext-simplexml": "*", "guzzlehttp/guzzle": "^7.4", - "illuminate/support": "^6.0|^7.0|^8.0" + "illuminate/support": "^6.0|^7.0|^8.0|^9.0" }, "require-dev": { "orchestra/testbench": "^4.6.0", From ba96f6feac6f932465631e8da686d0748a1700c5 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Mon, 27 Feb 2023 21:33:38 +0200 Subject: [PATCH 21/36] add gatewaysa sms (#13) * add gatewaysa sms * fix code style --- config/resala.php | 13 +++++- src/Drivers/GatewaySA.php | 70 ++++++++++++++++++++++++++++++ src/Response/GatewaySAResponse.php | 29 +++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/Drivers/GatewaySA.php create mode 100644 src/Response/GatewaySAResponse.php diff --git a/config/resala.php b/config/resala.php index 0f94bc6..b37b406 100644 --- a/config/resala.php +++ b/config/resala.php @@ -1,6 +1,7 @@ env('VECTORY_LINK_SENDER_NAME', 'Vectory Link'), 'lang' => env('VECTORY_LINK_LANG', 'E') ], + + 'gateway_sa' => [ + 'end_point' => env('GATEWAYSA_END_POINT', 'http://REST.GATEWAY.SA/api/SendSMS'), + 'api_id' => env('GATEWAYSA_API_ID'), + 'api_password' => env('GATEWAYSA_API_PASSWORD'), + 'sms_type' => env('GATEWAYSA_SMS_TYPE', 'T'), + 'encoding' => env('GATEWAYSA_ENCODING', 'T'), + 'sender_id' => env('GATEWAYSA_SENDER_ID'), + ], ], /* @@ -69,6 +79,7 @@ 'vodafone' => VodafoneDriver::class, 'connekio' => ConnekioDriver::class, 'infobip' => InfobipDriver::class, - 'vectory_link' => VectoryLinkDriver::class + 'vectory_link' => VectoryLinkDriver::class, + 'gateway_sa' => GatewaySA::class ], ]; diff --git a/src/Drivers/GatewaySA.php b/src/Drivers/GatewaySA.php new file mode 100644 index 0000000..a9c92f6 --- /dev/null +++ b/src/Drivers/GatewaySA.php @@ -0,0 +1,70 @@ +endPoint = $config['endpoint']; + } + + /** + * @param string|array $recipients + * @return string|array + */ + public function to($recipients): array|string + { + return $this->recipients = $recipients; + } + + /** + * @param string $message + * @return string + */ + public function message(string $message): string + { + return $this->message = $message; + } + + /** + * @return SMSDriverResponseInterface + */ + public function send(): SMSDriverResponseInterface + { + $response = (new HTTP())->get($this->endPoint, $this->headers(), $this->payload()); + + return new GatewaySAResponse($response); + } + + /** + * @return array + */ + protected function payload(): array + { + return [ + 'api_id' => $this->config['api_id'], + 'api_password' => $this->config['api_password'], + 'sender_id' => $this->config['sender_id'], + 'sms_type' => $this->config['sms_type'], + 'encoding' => $this->config['encoding'], + 'phonenumber' => $this->recipients, + 'textmessage' => $this->message, + ]; + } + + protected function headers(): array + { + return ['Accept' => 'application/json']; + } +} \ No newline at end of file diff --git a/src/Response/GatewaySAResponse.php b/src/Response/GatewaySAResponse.php new file mode 100644 index 0000000..8d2e91d --- /dev/null +++ b/src/Response/GatewaySAResponse.php @@ -0,0 +1,29 @@ +response = json_decode($response->getBody()->getContents(), true); + + $this->statusCode = $this->response['status']; + } + + public function body(): string + { + return $this->response['remarks'] ?? ""; + } + + public function success(): bool + { + return $this->statusCode == 'S'; + } +} From 2014a64fad955f60cee49810f4a5dc30ffeaa645 Mon Sep 17 00:00:00 2001 From: Mohamed AbdElaziz Date: Mon, 13 Mar 2023 14:09:39 +0200 Subject: [PATCH 22/36] wip --- config/resala.php | 1 + src/Drivers/GatewaySA.php | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/resala.php b/config/resala.php index b37b406..8505fd4 100644 --- a/config/resala.php +++ b/config/resala.php @@ -64,6 +64,7 @@ 'sms_type' => env('GATEWAYSA_SMS_TYPE', 'T'), 'encoding' => env('GATEWAYSA_ENCODING', 'T'), 'sender_id' => env('GATEWAYSA_SENDER_ID'), + 'templateid' => env('GATEWAYSA_TEMPLATE_ID'), ], ], diff --git a/src/Drivers/GatewaySA.php b/src/Drivers/GatewaySA.php index a9c92f6..690ac7f 100644 --- a/src/Drivers/GatewaySA.php +++ b/src/Drivers/GatewaySA.php @@ -55,11 +55,12 @@ protected function payload(): array return [ 'api_id' => $this->config['api_id'], 'api_password' => $this->config['api_password'], - 'sender_id' => $this->config['sender_id'], 'sms_type' => $this->config['sms_type'], 'encoding' => $this->config['encoding'], + 'sender_id' => $this->config['sender_id'], + 'templateid' => $this->config['templateid'], 'phonenumber' => $this->recipients, - 'textmessage' => $this->message, + 'v1' => $this->message, ]; } From d46121800167f44f2c8a85fd0ca47428dc0d8c44 Mon Sep 17 00:00:00 2001 From: Muhammad Hassan Date: Thu, 16 Mar 2023 12:05:20 +0200 Subject: [PATCH 23/36] PHP 8.2 Support (#15) * add support for PHP V8.1 and remove older versions * fix PHPUnit configuration issue and ignore its cache * build: change PHP version --------- Co-authored-by: muhamadhhassan --- .gitignore | 3 ++- composer.json | 10 +++++----- phpunit.xml.dist | 38 ++++++++++---------------------------- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 0f98a24..351e4cd 100644 --- a/.gitignore +++ b/.gitignore @@ -104,4 +104,5 @@ modules.xml .DS_Store src/.DS_Store -.editorconfig \ No newline at end of file +.editorconfig +.phpunit.result.cache \ No newline at end of file diff --git a/composer.json b/composer.json index bded07d..ba177c3 100644 --- a/composer.json +++ b/composer.json @@ -17,16 +17,16 @@ } ], "require": { - "php": "^7.4|^8.0", + "php": "^8.1|8.2", "ext-dom": "*", "ext-json": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^7.4", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0" + "guzzlehttp/guzzle": "^7.5", + "illuminate/support": "^9.0|^10" }, "require-dev": { - "orchestra/testbench": "^4.6.0", - "phpunit/phpunit": "^8.0" + "orchestra/testbench": "^8.0.8", + "phpunit/phpunit": "^10.0" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 22fe879..02fb293 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,29 +1,11 @@ - - - - tests - - - - - src/ - - - - - - - - - - + + + + + + \ No newline at end of file From eaa25c2c70285e37a6d88c4921ee584bbdceedf6 Mon Sep 17 00:00:00 2001 From: Marwan Atef Date: Thu, 16 Mar 2023 15:48:27 +0200 Subject: [PATCH 24/36] fix: connekio driver accepts phone numbers preceeded by 2 to be in their international format --- src/Drivers/ConnekioDriver.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Drivers/ConnekioDriver.php b/src/Drivers/ConnekioDriver.php index 8b51dec..94db516 100644 --- a/src/Drivers/ConnekioDriver.php +++ b/src/Drivers/ConnekioDriver.php @@ -65,8 +65,8 @@ protected function payload(): string ]; $this->toMultiple($this->recipients) - ? $payload['mobile_list'] = array_map(fn ($recipient) => ['msisdn' => $recipient], $this->recipients) - : $payload["msisdn"] = $this->recipients; + ? $payload['mobile_list'] = array_map(fn ($recipient) => ['msisdn' => $this->formatPhoneNumber($recipient)], $this->recipients) + : $payload["msisdn"] = $this->formatPhoneNumber($this->recipients); return json_encode($payload); } @@ -86,4 +86,13 @@ private function endpoint(): string ? $this->batchSmsEndPoint : $this->singleSmsEndPoint; } + + protected function formatPhoneNumber($phoneNumber): string + { + if (substr($phoneNumber, 0, 1) == '0') { + $phoneNumber = '2' . $phoneNumber; + } + + return $phoneNumber; + } } From 0704be5a3ffe0e90cea016683502fbaa26b6a39b Mon Sep 17 00:00:00 2001 From: Mostafa Tarek <109668729+Mostafa7000@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:22:31 +0300 Subject: [PATCH 25/36] FIX: avoid using current() on objects because it's deprecated Use `get_mangled_object_vars()` with the `current()` method to avoid a deprecation warning caused by using an object with `current()` function --- src/Response/VectoryLinkResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Response/VectoryLinkResponse.php b/src/Response/VectoryLinkResponse.php index c1006d0..08041d7 100644 --- a/src/Response/VectoryLinkResponse.php +++ b/src/Response/VectoryLinkResponse.php @@ -32,7 +32,7 @@ final class VectoryLinkResponse implements SMSDriverResponseInterface public function __construct(ResponseInterface $response) { $this->response = new SimpleXMLElement($response->getBody()); - $this->status = (int) current($this->response); + $this->status = (int) current(get_mangled_object_vars($this->response)); } public function success(): bool From 3ad30586a49e1ed13e3e2ce55b88ea6542d447d0 Mon Sep 17 00:00:00 2001 From: Mostafa Tarek <109668729+Mostafa7000@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:15:00 +0300 Subject: [PATCH 26/36] fix: use `x-www-form-urlencoded` type instead of `text/xml` This is tested using the following URL: https://smsvas.vlserv.com/KannelSending/service.asmx/SendSMS --- src/Drivers/VectoryLinkDriver.php | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Drivers/VectoryLinkDriver.php b/src/Drivers/VectoryLinkDriver.php index ba0cc4b..e71acce 100644 --- a/src/Drivers/VectoryLinkDriver.php +++ b/src/Drivers/VectoryLinkDriver.php @@ -1,4 +1,5 @@ endPoint, $this->headers(), $this->payload()); + $response = HTTP::post($this->endPoint, $this->headers(), $this->payload()); return new VectoryLinkResponse($response); } - protected function payload(): array + protected function payload(): string { - return - [ - "SMSText" => $this->message, - "SMSReceiver" => $this->recipients, - "SMSSender" => $this->senderName, - 'SMSLang' => $this->lang, - 'UserName' => $this->username, - 'Password' => $this->password - ]; + return http_build_query([ + "SMSText" => $this->message, + "SMSReceiver" => $this->recipients, + "SMSSender" => $this->senderName, + 'SMSLang' => $this->lang, + 'UserName' => $this->username, + 'Password' => $this->password + ]); } protected function headers(): array { return [ - 'Content-Type' => 'text/xml; charset=utf-8', - 'Content-Length' => 0 + 'Content-Type' => 'application/x-www-form-urlencoded' ]; } } From 0bd37c564cac99206cce51dac3eba6cb50c2d62a Mon Sep 17 00:00:00 2001 From: Mostafa Tarek <109668729+Mostafa7000@users.noreply.github.com> Date: Thu, 8 Aug 2024 13:16:03 +0300 Subject: [PATCH 27/36] Update ConfigRepository.php add missing return type --- src/Support/ConfigRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Support/ConfigRepository.php b/src/Support/ConfigRepository.php index 403db56..f4ded0e 100644 --- a/src/Support/ConfigRepository.php +++ b/src/Support/ConfigRepository.php @@ -79,7 +79,7 @@ public function offsetExists($offset): bool return $this->has($offset); } - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->get($offset); } From 926037f8aa9aad5349a57b794d7421e8a1e84ca0 Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Wed, 4 Dec 2024 19:11:55 +0200 Subject: [PATCH 28/36] feat: add compatibility for Laravel 11 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ba177c3..66700b9 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "ext-json": "*", "ext-simplexml": "*", "guzzlehttp/guzzle": "^7.5", - "illuminate/support": "^9.0|^10" + "illuminate/support": "^9.0|^10|^11.0" }, "require-dev": { "orchestra/testbench": "^8.0.8", From 866fd2ac175b51c439b7acdfd7db2e937cc9b431 Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Wed, 11 Dec 2024 12:55:03 +0200 Subject: [PATCH 29/36] test: Implement mock testing for SMSDriverFactory --- tests/SMSDriverFactoryTest.php | 32 ++++++++++++++++++++++++++++++++ tests/SMSTest.php | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/SMSDriverFactoryTest.php create mode 100644 tests/SMSTest.php diff --git a/tests/SMSDriverFactoryTest.php b/tests/SMSDriverFactoryTest.php new file mode 100644 index 0000000..7d4d882 --- /dev/null +++ b/tests/SMSDriverFactoryTest.php @@ -0,0 +1,32 @@ +shouldReceive('create') + ->once() + ->andReturn(\Mockery::mock(SMSDriverInterface::class));; + + SMSDriverFactory::create(); + } +} diff --git a/tests/SMSTest.php b/tests/SMSTest.php new file mode 100644 index 0000000..edc0268 --- /dev/null +++ b/tests/SMSTest.php @@ -0,0 +1,32 @@ +smsMock = \Mockery::mock(SMS::class)->shouldReceive('via','to','message','send') + ->andReturn(\Mockery::mock(SMSDriverResponseInterface::class));; + (new SMS)->via('vodafone')->to('01000000000')->message("test")->send(); + + } +} From cd429977bc642612a25eea33a89de075a45b26fd Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Wed, 11 Dec 2024 15:57:45 +0200 Subject: [PATCH 30/36] test: Implement mock test for SMS class --- tests/SMSTest.php | 73 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/tests/SMSTest.php b/tests/SMSTest.php index edc0268..ad53796 100644 --- a/tests/SMSTest.php +++ b/tests/SMSTest.php @@ -1,15 +1,19 @@ smsMock = \Mockery::mock(SMS::class)->shouldReceive('via','to','message','send') - ->andReturn(\Mockery::mock(SMSDriverResponseInterface::class));; - (new SMS)->via('vodafone')->to('01000000000')->message("test")->send(); + $sms = $this->createMockXMLResponse() + ->createMockStream() + ->createMockResponse() + ->mockHTTP() + ->sendSMS(); + + $this->assertInstanceOf(SMSDriverResponseInterface::class, $sms); + + } + + private function createMockXMLResponse(): self + { + $this->mockXmlResponse = << + + + XML; + return $this; + } + + private function createMockStream(): self + { + $this->mockStream = Mockery::mock(StreamInterface::class); + $this->mockStream->shouldReceive('__toString') + ->andReturn($this->mockXmlResponse); + $this->mockStream->shouldReceive('getContents') + ->andReturn($this->mockXmlResponse); + return $this; + } + + private function createMockResponse(): self + { + $this->mockResponse = Mockery::mock(ResponseInterface::class); + $this->mockResponse + ->shouldReceive('getBody') + ->andReturn($this->mockStream); + $this->mockResponse + ->shouldReceive('getStatusCode') + ->andReturn(200); + $this->mockResponse + ->shouldReceive('getHeaders') + ->andReturn([ + 'Content-Type' => ['application/xml; charset=UTF8'] + ]); + return $this; + } + private function mockHTTP(): self + { + Mockery::mock('alias:RobustTools\Resala\Support\HTTP') + ->shouldReceive('post') + ->andReturn($this->mockResponse); + return $this; + } + + private function sendSMS() + { + return SMSFacade::via('vodafone') + ->to('01000000000') + ->message("test") + ->send(); } } From 891a4f2397d8216dbdb7ed1ab3f3efa63299de1d Mon Sep 17 00:00:00 2001 From: Ahmed Elsayed Date: Wed, 11 Dec 2024 16:06:36 +0200 Subject: [PATCH 31/36] chore: Remove unnecessary class imports --- tests/SMSTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/SMSTest.php b/tests/SMSTest.php index ad53796..68ee801 100644 --- a/tests/SMSTest.php +++ b/tests/SMSTest.php @@ -5,7 +5,6 @@ use Orchestra\Testbench\TestCase as OrchestraTestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\StreamInterface; -use RobustTools\Resala\Contracts\SMSDriverInterface; use RobustTools\Resala\Contracts\SMSDriverResponseInterface; use RobustTools\Resala\Facades\SMS as SMSFacade; use RobustTools\Resala\SMSServiceProvider; From 2bd3153eb55b1c30adfb541e143b6693b5c762ec Mon Sep 17 00:00:00 2001 From: omarabdelaziz Date: Wed, 19 Mar 2025 15:01:31 +0200 Subject: [PATCH 32/36] feat: support brandencode sms provider --- config/resala.php | 12 ++- .../PublishProviderEnvVariablesCommand.php | 4 + src/Drivers/BrandEncodeDriver.php | 100 ++++++++++++++++++ src/Response/BrandEncodeResponse.php | 46 ++++++++ stubs/brandencode.env.stub | 5 + 5 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/Drivers/BrandEncodeDriver.php create mode 100644 src/Response/BrandEncodeResponse.php create mode 100644 stubs/brandencode.env.stub diff --git a/config/resala.php b/config/resala.php index 8505fd4..af5051a 100644 --- a/config/resala.php +++ b/config/resala.php @@ -5,6 +5,7 @@ use RobustTools\Resala\Drivers\InfobipDriver; use RobustTools\Resala\Drivers\VodafoneDriver; use RobustTools\Resala\Drivers\VectoryLinkDriver; +use RobustTools\Resala\Drivers\BrandEncodeDriver; return [ @@ -66,6 +67,14 @@ 'sender_id' => env('GATEWAYSA_SENDER_ID'), 'templateid' => env('GATEWAYSA_TEMPLATE_ID'), ], + + 'brandencode' => [ + 'end_point' => env('BRANDENCODE_END_POINT'), + 'username' => env('BRANDENCODE_USERNAME'), + 'password' => env('BRANDENCODE_PASSWORD'), + 'sender_name' => env('BRANDENCODE_SENDER_NAME', 'Brandencode'), + 'lang' => env('BRANDENCODE_LANG', 'E') + ], ], /* @@ -81,6 +90,7 @@ 'connekio' => ConnekioDriver::class, 'infobip' => InfobipDriver::class, 'vectory_link' => VectoryLinkDriver::class, - 'gateway_sa' => GatewaySA::class + 'gateway_sa' => GatewaySA::class, + 'brandencode' => BrandEncodeDriver::class ], ]; diff --git a/src/Console/PublishProviderEnvVariablesCommand.php b/src/Console/PublishProviderEnvVariablesCommand.php index 0a2328b..1a001e4 100644 --- a/src/Console/PublishProviderEnvVariablesCommand.php +++ b/src/Console/PublishProviderEnvVariablesCommand.php @@ -78,5 +78,9 @@ private function getStubContent(): string if ($this->argument('driver') == "vectory_link") { return File::get(__DIR__ . "/../../stubs/vectory_link.env.stub"); } + + if ($this->argument('driver') == "brandencode") { + return File::get(__DIR__ . "/../../stubs/brandencode.env.stub"); + } } } diff --git a/src/Drivers/BrandEncodeDriver.php b/src/Drivers/BrandEncodeDriver.php new file mode 100644 index 0000000..1630070 --- /dev/null +++ b/src/Drivers/BrandEncodeDriver.php @@ -0,0 +1,100 @@ +username = $config["username"]; + $this->password = $config["password"]; + $this->senderName = $config["sender_name"]; + $this->endPoint = $config["end_point"]; + $this->lang = $config["lang"]; + } + + /** + * @param string|array $recipients + * @return string|array + */ + public function to($recipients) + { + return $this->recipients = $this->toMultiple($recipients) + ? implode(', ', $recipients) + : $recipients; + } + + public function message(string $message): string + { + return $this->message = $message; + } + + public function send(): SMSDriverResponseInterface + { + $response = HTTP::get($this->endPoint, $this->headers(), $this->payload()); + + return new BrandEncodeResponse($response); + } + + protected function payload(): array + { + return + [ + "message" => $this->message, + "receiver" => $this->recipients, + "sender" => $this->senderName, + 'language' => $this->lang, + 'username' => $this->username, + 'password' => $this->password + ]; + } + + protected function headers(): array + { + return [ + 'Content-Type' => 'application/json' + ]; + } +} \ No newline at end of file diff --git a/src/Response/BrandEncodeResponse.php b/src/Response/BrandEncodeResponse.php new file mode 100644 index 0000000..10b2fd8 --- /dev/null +++ b/src/Response/BrandEncodeResponse.php @@ -0,0 +1,46 @@ +response = json_decode($response->getBody()->getContents(), true); + $this->statusCode = $response->getStatusCode(); + } + + /** + * @inheritDoc + */ + public function success(): bool + { + return $this->statusCode >= 200 && $this->statusCode < 300 && $this->response['code'] == self::OK; + } + + /** + * @inheritDoc + */ + public function body(): string + { + return $this->response['message']; + } +} diff --git a/stubs/brandencode.env.stub b/stubs/brandencode.env.stub new file mode 100644 index 0000000..c15a6f9 --- /dev/null +++ b/stubs/brandencode.env.stub @@ -0,0 +1,5 @@ +BRANDENCODE_USERNAME= +BRANDENCODE_PASSWORD= +BRANDENCODE_SENDER_NAME= +BRANDENCODE_END_POINT=https://sms.brandencode.com/api/send/sms/dlr +BRANDENCODE_LANG= \ No newline at end of file From f9bf7b703210dcc8662794de5d317ebb28e41838 Mon Sep 17 00:00:00 2001 From: omarabdelaziz Date: Thu, 10 Apr 2025 12:44:24 +0200 Subject: [PATCH 33/36] Resolve lint issues using PSR1 / PSR2 / PSR12 standards --- .php_cs.dist.php | 1 - src/Abstracts/Driver.php | 1 + .../PublishProviderEnvVariablesCommand.php | 6 ++++- src/Contracts/SMSDriverInterface.php | 1 + src/Contracts/SMSDriverResponseInterface.php | 1 + src/Drivers/BrandEncodeDriver.php | 6 +++-- src/Drivers/ConnekioDriver.php | 18 +++++++++----- src/Drivers/GatewaySA.php | 6 +++-- src/Drivers/InfobipDriver.php | 4 +++- src/Drivers/VectoryLinkDriver.php | 3 ++- src/Drivers/VodafoneDriver.php | 24 +++++++++++++++---- src/Facades/SMS.php | 1 + src/Factories/SMSDriverFactory.php | 2 +- src/Response/ConnekioResponse.php | 1 + src/Response/GatewaySAResponse.php | 1 + src/Response/InfobipResponse.php | 1 + src/Response/VectoryLinkResponse.php | 1 + src/Response/VodafoneResponse.php | 1 + src/SMS.php | 5 ++-- src/SMSServiceProvider.php | 3 ++- src/Support/Config.php | 5 ++-- src/Support/ConfigRepository.php | 1 + src/Support/HTTP.php | 1 + src/Support/VodafonePayloadBuilder.php | 20 ++++++++++------ tests/ExampleTest.php | 4 ++-- 25 files changed, 85 insertions(+), 33 deletions(-) diff --git a/.php_cs.dist.php b/.php_cs.dist.php index 75757bf..d82df72 100644 --- a/.php_cs.dist.php +++ b/.php_cs.dist.php @@ -46,7 +46,6 @@ ->exclude("vendor") ->in([ __DIR__ . '/src', - __DIR__ . '/tests', ]) ->name('*.php') ->notName('*.blade.php') diff --git a/src/Abstracts/Driver.php b/src/Abstracts/Driver.php index 1873068..348fcc4 100644 --- a/src/Abstracts/Driver.php +++ b/src/Abstracts/Driver.php @@ -1,4 +1,5 @@ argument('driver'); if (! array_key_exists($driver, config('resala.map'))) { - $this->error("provided driver does not exists, you may check available drivers: " . implode(", ", array_keys(config('resala.map')))); + $this->error( + "provided driver does not exists, you may check available drivers: " . + implode(", ", array_keys(config('resala.map'))) + ); return; } diff --git a/src/Contracts/SMSDriverInterface.php b/src/Contracts/SMSDriverInterface.php index 05c0db7..35913e4 100644 --- a/src/Contracts/SMSDriverInterface.php +++ b/src/Contracts/SMSDriverInterface.php @@ -1,4 +1,5 @@ 'application/json' ]; } -} \ No newline at end of file +} diff --git a/src/Drivers/ConnekioDriver.php b/src/Drivers/ConnekioDriver.php index 94db516..3039749 100644 --- a/src/Drivers/ConnekioDriver.php +++ b/src/Drivers/ConnekioDriver.php @@ -1,8 +1,10 @@ $this->senderName ]; - $this->toMultiple($this->recipients) - ? $payload['mobile_list'] = array_map(fn ($recipient) => ['msisdn' => $this->formatPhoneNumber($recipient)], $this->recipients) - : $payload["msisdn"] = $this->formatPhoneNumber($this->recipients); + $this->toMultiple($this->recipients) ? $payload['mobile_list'] = array_map( + fn($recipient) => ['msisdn' => $this->formatPhoneNumber($recipient)], + $this->recipients + ) : $payload["msisdn"] = $this->formatPhoneNumber($this->recipients); return json_encode($payload); } @@ -76,7 +79,10 @@ protected function headers(): array return [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', - 'Authorization' => sprintf("Basic %s", base64_encode($this->username . ':' . $this->password . ':' . $this->accountId)) + 'Authorization' => sprintf( + "Basic %s", + base64_encode($this->username . ':' . $this->password . ':' . $this->accountId) + ) ]; } @@ -92,7 +98,7 @@ protected function formatPhoneNumber($phoneNumber): string if (substr($phoneNumber, 0, 1) == '0') { $phoneNumber = '2' . $phoneNumber; } - + return $phoneNumber; } } diff --git a/src/Drivers/GatewaySA.php b/src/Drivers/GatewaySA.php index 690ac7f..7197aa2 100644 --- a/src/Drivers/GatewaySA.php +++ b/src/Drivers/GatewaySA.php @@ -1,8 +1,10 @@ 'application/json']; } -} \ No newline at end of file +} diff --git a/src/Drivers/InfobipDriver.php b/src/Drivers/InfobipDriver.php index 42cba3a..0e66cc3 100644 --- a/src/Drivers/InfobipDriver.php +++ b/src/Drivers/InfobipDriver.php @@ -1,8 +1,10 @@ toMultiple($this->recipients)) { foreach ($this->recipients as $recipient) { - $hashableKey .= sprintf("&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", $this->senderName, $recipient, $this->message); + $hashableKey .= sprintf( + "&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", + $this->senderName, + $recipient, + $this->message + ); } return $hashableKey; } else { - return sprintf("AccountId=%s&Password=%s&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", $this->accountId, $this->password, $this->senderName, $this->recipients, $this->message); + return sprintf( + "AccountId=%s&Password=%s&SenderName=%s&ReceiverMSISDN=%s&SMSText=%s", + $this->accountId, + $this->password, + $this->senderName, + $this->recipients, + $this->message + ); } } } diff --git a/src/Facades/SMS.php b/src/Facades/SMS.php index b381dbb..dc3ca64 100644 --- a/src/Facades/SMS.php +++ b/src/Facades/SMS.php @@ -1,4 +1,5 @@ driver->send(); } } - diff --git a/src/SMSServiceProvider.php b/src/SMSServiceProvider.php index 8e421b0..184ec65 100644 --- a/src/SMSServiceProvider.php +++ b/src/SMSServiceProvider.php @@ -1,4 +1,5 @@ app->singleton('sms', function () { - return new SMS; + return new SMS(); }); } } diff --git a/src/Support/Config.php b/src/Support/Config.php index 189442e..74d0925 100644 --- a/src/Support/Config.php +++ b/src/Support/Config.php @@ -1,15 +1,16 @@ config = new ConfigRepository( $this->configurations($filepath) diff --git a/src/Support/ConfigRepository.php b/src/Support/ConfigRepository.php index f4ded0e..18200f1 100644 --- a/src/Support/ConfigRepository.php +++ b/src/Support/ConfigRepository.php @@ -1,4 +1,5 @@ domDocument->saveXML(); } - private function rootElement() : DOMElement + private function rootElement(): DOMElement { return $this->domDocument->createElement('SubmitSMSRequest'); } - private function setRootElementAttributes(DOMElement $rootElement) : void + private function setRootElementAttributes(DOMElement $rootElement): void { $attr_xmlns = new DOMAttr('xmlns:', "http://www.edafa.com/web2sms/sms/model/"); $attr_xmlns_xsi = new DOMAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - $attr_xsi_schemaLocation = new DOMAttr("xsi:schemaLocation", "http://www.edafa.com/web2sms/sms/model/ SMSAPI.xsd"); + + $attr_xsi_schemaLocation = new DOMAttr( + "xsi:schemaLocation", + "http://www.edafa.com/web2sms/sms/model/ SMSAPI.xsd" + ); + $attr_xsi_type = new DOMAttr("xsi:type", "SubmitSMSRequest"); $rootElement->setAttributeNode($attr_xmlns); @@ -77,22 +83,22 @@ private function setRootElementAttributes(DOMElement $rootElement) : void $rootElement->setAttributeNode($attr_xsi_type); } - private function generateAccountIdElement(DOMElement $rootElement) : void + private function generateAccountIdElement(DOMElement $rootElement): void { $rootElement->appendChild($this->domDocument->createElement('AccountId', $this->accountId)); } - private function generatePasswordElement(DOMElement $rootElement) : void + private function generatePasswordElement(DOMElement $rootElement): void { $rootElement->appendChild($this->domDocument->createElement('Password', $this->password)); } - private function generateSecureHashElement(DOMElement $rootElement) : void + private function generateSecureHashElement(DOMElement $rootElement): void { $rootElement->appendChild($this->domDocument->createElement('SecureHash', $this->secureHash)); } - private function generateSMSListElement(DOMElement $rootElement, string $recipient) : void + private function generateSMSListElement(DOMElement $rootElement, string $recipient): void { $sms_list_node = $rootElement->appendChild($this->domDocument->createElement("SMSList")); $sms_list_node->appendChild($this->domDocument->createElement("SenderName", $this->senderName)); diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index dca2143..63a7aeb 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -1,4 +1,5 @@ assertTrue(true); } From 9ca1724f38a5bcd0ed88e9e3ed5ba0ac964c485b Mon Sep 17 00:00:00 2001 From: Marwan Atef Date: Fri, 27 Feb 2026 01:39:07 +0200 Subject: [PATCH 34/36] feat: upgrade to latest vectorylink REST/json APIs & updated response codes --- src/Drivers/VectoryLinkDriver.php | 36 +++++++---- src/Response/VectoryLinkResponse.php | 90 +++++++++++++++++----------- 2 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/Drivers/VectoryLinkDriver.php b/src/Drivers/VectoryLinkDriver.php index 0c0f3f3..9c210cd 100644 --- a/src/Drivers/VectoryLinkDriver.php +++ b/src/Drivers/VectoryLinkDriver.php @@ -3,8 +3,7 @@ namespace RobustTools\Resala\Drivers; use RobustTools\Resala\Abstracts\Driver; -use RobustTools\Resala\Contracts\SMSDriverInterface; -use RobustTools\Resala\Contracts\SMSDriverResponseInterface; +use RobustTools\Resala\Contracts\{SMSDriverInterface, SMSDriverResponseInterface}; use RobustTools\Resala\Response\VectoryLinkResponse; use RobustTools\Resala\Support\HTTP; @@ -54,27 +53,38 @@ public function message(string $message): string public function send(): SMSDriverResponseInterface { - $response = HTTP::post($this->endPoint, $this->headers(), $this->payload()); - - return new VectoryLinkResponse($response); + return new VectoryLinkResponse(HTTP::post($this->endPoint, $this->headers(), json_encode($this->payload()))); } - protected function payload(): string + /** + * @return array + */ + protected function payload(): array { - return http_build_query([ - "SMSText" => $this->message, - "SMSReceiver" => $this->recipients, - "SMSSender" => $this->senderName, + return [ + 'SMSText' => $this->message, + 'SMSReceiver' => $this->recipients, + 'SMSSender' => $this->senderName, 'SMSLang' => $this->lang, 'UserName' => $this->username, - 'Password' => $this->password - ]); + 'Password' => $this->password, + 'SMSID' => $this->generateGuid(), + ]; + } + + private function generateGuid(): string + { + $data = random_bytes(16); + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); + + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } protected function headers(): array { return [ - 'Content-Type' => 'application/x-www-form-urlencoded' + 'Content-Type' => 'application/json', ]; } } diff --git a/src/Response/VectoryLinkResponse.php b/src/Response/VectoryLinkResponse.php index 8bfe48f..d57e2c8 100644 --- a/src/Response/VectoryLinkResponse.php +++ b/src/Response/VectoryLinkResponse.php @@ -4,56 +4,76 @@ use Psr\Http\Message\ResponseInterface; use RobustTools\Resala\Contracts\SMSDriverResponseInterface; -use SimpleXMLElement; final class VectoryLinkResponse implements SMSDriverResponseInterface { - private const OK = 0; - - private const USER_ERR = -1; - - private const CREDIT_ERR = -5; - - private const OK_QUEUED = -10; - - private const LANG_ERR = -11; - - private const SMS_ERR = -12; - - private const SENDER_ERR = -13; - - private const SENDING_RATE_ERR = -25; - - private const GENERIC_ERR = -100; - - private SimpleXMLElement $response; + private const STATUS_SUCCESS = 0; + private const STATUS_INVALID_CREDENTIALS = -1; + private const STATUS_INVALID_ACCOUNT_IP = -2; + private const STATUS_INVALID_ANI_BLACK_LIST = -3; + private const STATUS_OUT_OF_CREDIT = -5; + private const STATUS_DATABASE_DOWN = -6; + private const STATUS_INACTIVE_ACCOUNT = -7; + private const STATUS_ACCOUNT_EXPIRED = -11; + private const STATUS_SMS_EMPTY = -12; + private const STATUS_INVALID_SENDER_WITH_CONNECTION = -13; + private const STATUS_SMS_SENDING_FAILED = -14; + private const STATUS_OTHER_ERROR = -100; + private const STATUS_INVALID_ANI = -18; + private const STATUS_SMS_ID_EXISTS = -19; + private const STATUS_INVALID_ACCOUNT = -21; + private const STATUS_SMS_NOT_VALIDATE = -22; + private const STATUS_INVALID_ACCOUNT_OPERATOR_CONNECTION = -23; + private const STATUS_INVALID_USER_SMS_ID = -26; + private const STATUS_EMPTY_USERNAME_OR_PASSWORD = -29; + private const STATUS_INVALID_SENDER = -30; private int $status; public function __construct(ResponseInterface $response) { - $this->response = new SimpleXMLElement($response->getBody()); - $this->status = (int) current(get_mangled_object_vars($this->response)); + $contents = trim($response->getBody()->getContents()); + $this->status = $this->parseStatus($contents); + } + + private function parseStatus(string $contents): int + { + if ($contents === '' || !is_numeric($contents)) { + return self::STATUS_OTHER_ERROR; + } + return (int) $contents; } public function success(): bool { - return $this->status === self::OK - || $this->status === self::OK_QUEUED; + return $this->status === self::STATUS_SUCCESS; } public function body(): string { - return [ - self::OK => 'Message Sent Successfully', - self::USER_ERR => 'User is not subscribed', - self::CREDIT_ERR => 'Out of credit.', - self::OK_QUEUED => 'Queued Message, no need to send it again.', - self::LANG_ERR => 'Invalid language.', - self::SMS_ERR => 'SMS is empty.', - self::SENDER_ERR => 'Invalid fake sender exceeded 12 chars or empty.', - self::SENDING_RATE_ERR => 'Sending rate greater than receiving rate (only for send/receive accounts).', - self::GENERIC_ERR => 'Other error', - ][$this->status] ?? 'Something wrong happened'; + $messages = [ + self::STATUS_SUCCESS => 'Success', + self::STATUS_INVALID_CREDENTIALS => 'Invalid Credentials', + self::STATUS_INVALID_ACCOUNT_IP => 'Invalid Account IP', + self::STATUS_INVALID_ANI_BLACK_LIST => 'Invalid ANI Black List', + self::STATUS_OUT_OF_CREDIT => 'Out Of Credit', + self::STATUS_DATABASE_DOWN => 'Database Down', + self::STATUS_INACTIVE_ACCOUNT => 'Inactive Account', + self::STATUS_ACCOUNT_EXPIRED => 'Account Is Expired', + self::STATUS_SMS_EMPTY => 'SMS Is Empty', + self::STATUS_INVALID_SENDER_WITH_CONNECTION => 'Invalid Sender With Connection', + self::STATUS_SMS_SENDING_FAILED => 'SMS Sending Failed Try Again', + self::STATUS_OTHER_ERROR => 'Other Error', + self::STATUS_INVALID_ANI => 'Invalid ANI', + self::STATUS_SMS_ID_EXISTS => 'SMS Id Is Exist', + self::STATUS_INVALID_ACCOUNT => 'Invalid Account', + self::STATUS_SMS_NOT_VALIDATE => 'SMS Not Validate', + self::STATUS_INVALID_ACCOUNT_OPERATOR_CONNECTION => 'Invalid Account Operator Connection', + self::STATUS_INVALID_USER_SMS_ID => 'Invalid User SMS Id', + self::STATUS_EMPTY_USERNAME_OR_PASSWORD => 'Empty User Name Or Password', + self::STATUS_INVALID_SENDER => 'Invalid Sender', + ]; + + return $messages[$this->status] ?? 'Something wrong happened'; } } From 383aaadf0dbe4682e50f1604fad760bc7a79394f Mon Sep 17 00:00:00 2001 From: Marwan Atef Date: Thu, 5 Mar 2026 14:29:39 +0200 Subject: [PATCH 35/36] feat: add support for laravel 11 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ba177c3..66700b9 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "ext-json": "*", "ext-simplexml": "*", "guzzlehttp/guzzle": "^7.5", - "illuminate/support": "^9.0|^10" + "illuminate/support": "^9.0|^10|^11.0" }, "require-dev": { "orchestra/testbench": "^8.0.8", From 41e6da4d6d4d978dd48f0babe1538903860084e0 Mon Sep 17 00:00:00 2001 From: Ahmad El-Alfy Date: Sat, 7 Mar 2026 22:18:12 +0200 Subject: [PATCH 36/36] fix: add composer-lock to the repository --- .gitignore | 1 - composer.lock | 8140 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 8140 insertions(+), 1 deletion(-) create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 351e4cd..25b7d73 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ build -composer.lock docs vendor coverage diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..1a4df70 --- /dev/null +++ b/composer.lock @@ -0,0 +1,8140 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "3651f68db596119cc1609404f2c22aa7", + "packages": [ + { + "name": "brick/math", + "version": "0.12.3", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", + "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "6.8.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.12.3" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2025-02-28T13:11:00+00:00" + }, + { + "name": "carbonphp/carbon-doctrine-types", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", + "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "doctrine/dbal": "<3.7.0 || >=4.0.0" + }, + "require-dev": { + "doctrine/dbal": "^3.7.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2023-12-11T17:09:12+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + }, + "time": "2024-07-08T12:26:09+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0 || ^13.0", + "phpstan/phpstan": "^1.12 || ^2.0", + "phpstan/phpstan-phpunit": "^1.4 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", + "phpunit/phpunit": "^8.5 || ^12.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.1.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2025-08-10T19:31:58+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "shasum": "" + }, + "require": { + "php": "^8.2|^8.3|^8.4|^8.5" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.32|^2.1.31", + "phpunit/phpunit": "^8.5.48|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2025-10-31T18:51:33+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "shasum": "" + }, + "require": { + "php": "^8.1", + "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" + }, + "require-dev": { + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2025-12-03T09:33:47+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.4", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.5" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:43:20+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.10.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-08-23T22:36:01+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "481557b130ef3790cf82b713667b43030dc9c957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:34:08+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "21dc724a0583619cd1652f673303492272778051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-08-23T21:21:41+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:27:06+00:00" + }, + { + "name": "laravel/framework", + "version": "10.50.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/3ff39b7a9b83e633383ec9b019827ed54b6d38bc", + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc", + "shasum": "" + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.3.2", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.2", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.1.9", + "laravel/serializable-closure": "^1.3", + "league/commonmark": "^2.2.1", + "league/flysystem": "^3.8.0", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^2.67", + "nunomaduro/termwind": "^1.13", + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^6.2", + "symfony/error-handler": "^6.2", + "symfony/finder": "^6.2", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.2", + "symfony/mailer": "^6.2", + "symfony/mime": "^6.2", + "symfony/process": "^6.2", + "symfony/routing": "^6.2", + "symfony/uid": "^6.2", + "symfony/var-dumper": "^6.2", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "carbonphp/carbon-doctrine-types": ">=3.0", + "doctrine/dbal": ">=4.0", + "mockery/mockery": "1.6.8", + "phpunit/phpunit": ">=11.0.0", + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.235.5", + "doctrine/dbal": "^3.5.1", + "ext-gmp": "*", + "fakerphp/faker": "^1.21", + "guzzlehttp/guzzle": "^7.5", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.5.1", + "nyholm/psr7": "^1.2", + "orchestra/testbench-core": "^8.23.4", + "pda/pheanstalk": "^4.0", + "phpstan/phpstan": "~1.11.11", + "phpunit/phpunit": "^10.0.7", + "predis/predis": "^2.0.2", + "symfony/cache": "^6.2", + "symfony/http-client": "^6.2.4", + "symfony/psr-http-message-bridge": "^2.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.5).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.5.1).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8|^10.0.7).", + "predis/predis": "Required to use the predis connector (^2.0.2).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^6.2).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.2).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.2).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/functions.php", + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2026-02-15T14:12:07+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.1.25", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95", + "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.25" + }, + "time": "2024-08-12T22:06:33+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.3.7", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "4f48ade902b94323ca3be7646db16209ec76be3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/4f48ade902b94323ca3be7646db16209ec76be3d", + "reference": "4f48ade902b94323ca3be7646db16209ec76be3d", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", + "nesbot/carbon": "^2.61|^3.0", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2024-11-14T18:34:49+00:00" + }, + { + "name": "league/commonmark", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "84b1ca48347efdbe775426f108622a42735a6579" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84b1ca48347efdbe775426f108622a42735a6579", + "reference": "84b1ca48347efdbe775426f108622a42735a6579", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.9-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2026-03-05T21:37:03+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.32.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "254b1595b16b22dbddaaef9ed6ca9fdac4956725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/254b1595b16b22dbddaaef9ed6ca9fdac4956725", + "reference": "254b1595b16b22dbddaaef9ed6ca9fdac4956725", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3|^2", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2|^2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.32.0" + }, + "time": "2026-02-25T17:01:41+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.31.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" + }, + "time": "2026-01-23T15:30:45+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.10.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8 || ^2.0", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2026-01-02T08:56:05+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.73.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "*", + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "psr/clock": "^1.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", + "doctrine/orm": "^2.7 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "<6", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2025-01-08T20:10:23+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.5" + }, + "time": "2026-02-23T03:47:12+00:00" + }, + { + "name": "nette/utils", + "version": "v4.1.3", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe", + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.5", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.3" + }, + "time": "2026-02-13T03:05:33+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/5369ef84d8142c1d87e4ec278711d4ece3cbf301", + "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.4.15" + }, + "require-dev": { + "illuminate/console": "^10.48.24", + "illuminate/support": "^10.48.24", + "laravel/pint": "^1.18.2", + "pestphp/pest": "^2.36.0", + "pestphp/pest-plugin-mock": "2.0.0", + "phpstan/phpstan": "^1.12.11", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^6.4.15", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.17.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2024-11-21T10:36:35+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:41:33+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" + }, + "time": "2025-03-22T05:38:12+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.9.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "8429c78ca35a09f27565311b98101e2826affde0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", + "reference": "8429c78ca35a09f27565311b98101e2826affde0", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.2" + }, + "time": "2025-12-14T04:43:48+00:00" + }, + { + "name": "symfony/console", + "version": "v6.4.35", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "49257c96304c508223815ee965c251e7c79e614e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/49257c96304c508223815ee965c251e7c79e614e", + "reference": "49257c96304c508223815ee965c251e7c79e614e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.4.35" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-06T13:31:08+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v8.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "2a178bf80f05dbbe469a337730eba79d61315262" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/2a178bf80f05dbbe469a337730eba79d61315262", + "reference": "2a178bf80f05dbbe469a337730eba79d61315262", + "shasum": "" + }, + "require": { + "php": ">=8.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v8.0.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-17T13:07:04+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.4.32", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8c18400784fcb014dc73c8d5601a9576af7f8ad4", + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.4.32" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-19T19:28:19+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "dc2c0eba1af673e736bb851d747d266108aea746" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dc2c0eba1af673e736bb851d747d266108aea746", + "reference": "dc2c0eba1af673e736bb851d747d266108aea746", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-05T11:45:34+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.4.34" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-28T15:16:37+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.4.35", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cffffd0a2c037117b742b4f8b379a22a2a33f6d2", + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.4.35" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-06T11:15:58+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.4.35", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "ece1a0da7745a5243683f178155c0412c92691eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ece1a0da7745a5243683f178155c0412c92691eb", + "reference": "ece1a0da7745a5243683f178155c0412c92691eb", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.3", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4.1|^7.0.1", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.4.35" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-06T16:28:07+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "01b846f48e53ee4096692a383637a1fa4d577301" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/01b846f48e53ee4096692a383637a1fa4d577301", + "reference": "01b846f48e53ee4096692a383637a1fa4d577301", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.4.34" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-24T09:34:36+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.4.35", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "b5cce719de25bebd6345c7709774f9ac63ff5cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/b5cce719de25bebd6345c7709774f9ac63ff5cdf", + "reference": "b5cce719de25bebd6345c7709774f9ac63ff5cdf", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.4.35" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-05T11:25:28+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-08T02:45:35+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v6.4.33", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/c46e854e79b52d07666e43924a20cb6dc546644e", + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.4.33" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-23T16:02:12+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", + "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<6.2", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12|^2", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.2|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.4.34" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-24T17:34:50+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/string", + "version": "v7.4.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.33", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.4.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-09T09:33:46+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "d07d117db41341511671b0a1a2be48f2772189ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/d07d117db41341511671b0a1a2be48f2772189ce", + "reference": "d07d117db41341511671b0a1a2be48f2772189ce", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.4.34" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-16T20:44:03+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "65a8bc82080447fae78373aa10f8d13b38338977" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", + "reference": "65a8bc82080447fae78373aa10f8d13b38338977", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T13:41:35+00:00" + }, + { + "name": "symfony/uid", + "version": "v6.4.32", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "6b973c385f00341b246f697d82dc01a09107acdd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/6b973c385f00341b246f697d82dc01a09107acdd", + "reference": "6b973c385f00341b246f697d82dc01a09107acdd", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v6.4.32" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-12-23T15:07:59+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.4.32", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "131fc9915e0343052af5ed5040401b481ca192aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/131fc9915e0343052af5ed5040401b481ca192aa", + "reference": "131fc9915e0343052af5ed5040401b481ca192aa", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "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.32" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-01T13:34:06+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41", + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^7.4 || ^8.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.4.0" + }, + "time": "2025-12-02T11:56:42+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.3", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "955e7815d677a3eaa7075231212f2110983adecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", + "reference": "955e7815d677a3eaa7075231212f2110983adecc", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.4", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.5", + "symfony/polyfill-ctype": "^1.26", + "symfony/polyfill-mbstring": "^1.26", + "symfony/polyfill-php80": "^1.26" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2025-12-27T19:49:13+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2024-11-21T01:49:47+00:00" + } + ], + "packages-dev": [ + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" + }, + "time": "2024-11-21T13:46:39+00:00" + }, + { + "name": "filp/whoops", + "version": "2.18.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.18.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2025-08-08T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" + }, + "time": "2025-04-30T06:54:44+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.11.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/c9f80cc835649b5c1842898fb043f8cc098dd741", + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.11.1" + }, + "time": "2026-02-06T14:12:35+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-05-16T03:13:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v7.12.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/995245421d3d7593a6960822063bdba4f5d7cf1a", + "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.17.0", + "nunomaduro/termwind": "^1.17.0", + "php": "^8.1.0", + "symfony/console": "^6.4.17" + }, + "conflict": { + "laravel/framework": ">=11.0.0" + }, + "require-dev": { + "brianium/paratest": "^7.4.8", + "laravel/framework": "^10.48.29", + "laravel/pint": "^1.21.2", + "laravel/sail": "^1.41.0", + "laravel/sanctum": "^3.3.3", + "laravel/tinker": "^2.10.1", + "nunomaduro/larastan": "^2.10.0", + "orchestra/testbench-core": "^8.35.0", + "pestphp/pest": "^2.36.0", + "phpunit/phpunit": "^10.5.36", + "sebastian/environment": "^6.1.0", + "spatie/laravel-ignition": "^2.9.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2025-03-14T22:35:49+00:00" + }, + { + "name": "orchestra/canvas", + "version": "v8.12.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/canvas.git", + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/canvas/zipball/76385dfcf96efae5f8533a4d522d14c3c946ac5a", + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "illuminate/console": "^10.48.25", + "illuminate/database": "^10.48.25", + "illuminate/filesystem": "^10.48.25", + "illuminate/support": "^10.48.25", + "orchestra/canvas-core": "^8.10.2", + "orchestra/testbench-core": "^8.30", + "php": "^8.1", + "symfony/polyfill-php83": "^1.31", + "symfony/yaml": "^6.2" + }, + "require-dev": { + "laravel/framework": "^10.48.25", + "laravel/pint": "^1.17", + "mockery/mockery": "^1.5.1", + "phpstan/phpstan": "^1.11", + "phpunit/phpunit": "^10.5", + "spatie/laravel-ray": "^1.33" + }, + "bin": [ + "canvas" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Orchestra\\Canvas\\LaravelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Orchestra\\Canvas\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Code Generators for Laravel Applications and Packages", + "support": { + "issues": "https://github.com/orchestral/canvas/issues", + "source": "https://github.com/orchestral/canvas/tree/v8.12.0" + }, + "time": "2024-11-30T15:38:25+00:00" + }, + { + "name": "orchestra/canvas-core", + "version": "v8.11.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/canvas-core.git", + "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/609c2eccdd595b4bba21702a7ea46433a28ea611", + "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "illuminate/console": "^10.48.22", + "illuminate/filesystem": "^10.48.22", + "orchestra/sidekick": "~1.1.23|~1.2.20", + "php": "^8.1", + "symfony/polyfill-php83": "^1.28" + }, + "conflict": { + "orchestra/canvas": "<8.11.0", + "orchestra/testbench-core": "<8.2.0" + }, + "require-dev": { + "laravel/framework": "^10.48.22", + "laravel/pint": "^1.17", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^8.19", + "orchestra/workbench": "^8.18.0", + "phpstan/phpstan": "^2.1.17", + "phpunit/phpunit": "^10.1", + "symfony/yaml": "^6.2" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Orchestra\\Canvas\\Core\\LaravelServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "9.0-dev" + } + }, + "autoload": { + "psr-4": { + "Orchestra\\Canvas\\Core\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Code Generators Builder for Laravel Applications and Packages", + "support": { + "issues": "https://github.com/orchestral/canvas/issues", + "source": "https://github.com/orchestral/canvas-core/tree/v8.11.0" + }, + "time": "2026-02-24T13:35:32+00:00" + }, + { + "name": "orchestra/sidekick", + "version": "v1.2.20", + "source": { + "type": "git", + "url": "https://github.com/orchestral/sidekick.git", + "reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/sidekick/zipball/267a71b56cb2fe1a634d69fc99889c671b77ff43", + "reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "php": "^8.1", + "symfony/polyfill-php83": "^1.32" + }, + "require-dev": { + "fakerphp/faker": "^1.21", + "laravel/framework": "^10.48.29|^11.44.7|^12.1.1|^13.0", + "laravel/pint": "^1.4", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^8.37.0|^9.14.0|^10.2.0|^11.0", + "phpstan/phpstan": "^2.1.14", + "phpunit/phpunit": "^10.0|^11.0|^12.0", + "symfony/process": "^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Eloquent/functions.php", + "src/Filesystem/functions.php", + "src/Http/functions.php", + "src/functions.php" + ], + "psr-4": { + "Orchestra\\Sidekick\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Packages Toolkit Utilities and Helpers for Laravel", + "support": { + "issues": "https://github.com/orchestral/sidekick/issues", + "source": "https://github.com/orchestral/sidekick/tree/v1.2.20" + }, + "time": "2026-01-12T11:09:33+00:00" + }, + { + "name": "orchestra/testbench", + "version": "v8.37.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench.git", + "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/c03266385ad996a7c3c9bb6219df8f6558ecea39", + "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "fakerphp/faker": "^1.21", + "laravel/framework": "^10.50.0", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^8.40.0", + "orchestra/workbench": "^8.18.0", + "php": "^8.1", + "phpunit/phpunit": "^9.6|^10.1", + "symfony/process": "^6.2", + "symfony/yaml": "^6.2", + "vlucas/phpdotenv": "^5.4.1" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Laravel Testing Helper for Packages Development", + "homepage": "https://packages.tools/testbench/", + "keywords": [ + "BDD", + "TDD", + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench/tree/v8.37.0" + }, + "time": "2026-01-14T02:47:41+00:00" + }, + { + "name": "orchestra/testbench-core", + "version": "v8.40.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench-core.git", + "reference": "cd85197bcf92a3c12d0dfafd93fdea0d5d067534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/cd85197bcf92a3c12d0dfafd93fdea0d5d067534", + "reference": "cd85197bcf92a3c12d0dfafd93fdea0d5d067534", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "orchestra/sidekick": "~1.1.23|~1.2.20", + "php": "^8.1", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-php83": "^1.33" + }, + "conflict": { + "brianium/paratest": "<6.4.0|>=7.0.0 <7.1.4|>=8.0.0", + "laravel/framework": "<10.50.0|>=11.0.0", + "laravel/serializable-closure": "<1.3.0|>=3.0.0", + "nunomaduro/collision": "<6.4.0|>=7.0.0 <7.4.0|>=8.0.0", + "orchestra/testbench-dusk": "<8.32.0|>=9.0.0", + "orchestra/workbench": "<1.0.0", + "phpunit/phpunit": "<9.6.0|>=10.3.0 <10.3.3|>=10.6.0" + }, + "require-dev": { + "fakerphp/faker": "^1.21", + "laravel/framework": "^10.50.0", + "laravel/pint": "^1.20", + "laravel/serializable-closure": "^1.3|^2.0", + "mockery/mockery": "^1.5.1", + "phpstan/phpstan": "^2.1.33", + "phpunit/phpunit": "^10.1", + "spatie/laravel-ray": "^1.40.2", + "symfony/process": "^6.2", + "symfony/yaml": "^6.2", + "vlucas/phpdotenv": "^5.4.1" + }, + "suggest": { + "brianium/paratest": "Allow using parallel testing (^6.4|^7.1.4).", + "ext-pcntl": "Required to use all features of the console signal trapping.", + "fakerphp/faker": "Allow using Faker for testing (^1.21).", + "laravel/framework": "Required for testing (^10.48.29).", + "mockery/mockery": "Allow using Mockery for testing (^1.5.1).", + "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.4|^7.4).", + "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^8.0).", + "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^8.0).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^9.6|^10.1).", + "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^6.2).", + "symfony/yaml": "Required for Testbench CLI (^6.2).", + "vlucas/phpdotenv": "Required for Testbench CLI (^5.4.1)." + }, + "bin": [ + "testbench" + ], + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Orchestra\\Testbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Testing Helper for Laravel Development", + "homepage": "https://packages.tools/testbench", + "keywords": [ + "BDD", + "TDD", + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench-core" + }, + "time": "2026-01-13T01:04:43+00:00" + }, + { + "name": "orchestra/workbench", + "version": "v8.18.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/workbench.git", + "reference": "ba7ebf976240a49efd736ed86d0fea2183c79b2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/ba7ebf976240a49efd736ed86d0fea2183c79b2b", + "reference": "ba7ebf976240a49efd736ed86d0fea2183c79b2b", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "fakerphp/faker": "^1.21", + "laravel/framework": "^10.48.28", + "laravel/tinker": "^2.8.2", + "nunomaduro/collision": "^6.4|^7.10", + "orchestra/canvas": "^8.12.0", + "orchestra/sidekick": "~1.1.23|~1.2.20", + "orchestra/testbench-core": "^8.35.0", + "php": "^8.1", + "symfony/polyfill-php83": "^1.33", + "symfony/process": "^6.2", + "symfony/yaml": "^6.2" + }, + "require-dev": { + "laravel/pint": "^1.20", + "mockery/mockery": "^1.5.1", + "phpstan/phpstan": "^2.1.33", + "phpunit/phpunit": "^10.1", + "spatie/laravel-ray": "^1.40.2" + }, + "suggest": { + "ext-pcntl": "Required to use all features of the console signal trapping." + }, + "type": "library", + "autoload": { + "psr-4": { + "Orchestra\\Workbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Workbench Companion for Laravel Packages Development", + "keywords": [ + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/workbench/issues", + "source": "https://github.com/orchestral/workbench/tree/v8.18.0" + }, + "time": "2026-01-12T13:55:26+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.63", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "33198268dad71e926626b618f3ec3966661e4d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", + "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.5", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.4", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-01-27T05:48:37+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.21", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4821fab5b7cd8c49a673a9fd5754dc9162bb9e97", + "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "composer/class-map-generator": "^1.6" + }, + "suggest": { + "composer/class-map-generator": "Improved tab completion performance with better class discovery.", + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "https://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.21" + }, + "time": "2026-03-06T21:21:28+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:25:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "0735b90f4da94969541dac1da743446e276defa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:09:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:50:56+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7bca30dabed7900a08c5ad4f1d6483f881a64d0f", + "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.4.34" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-02-06T18:32:11+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.1|8.2", + "ext-dom": "*", + "ext-json": "*", + "ext-simplexml": "*" + }, + "platform-dev": {}, + "plugin-api-version": "2.9.0" +}