diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
new file mode 100644
index 00000000..3098877a
--- /dev/null
+++ b/.github/workflows/bench.yml
@@ -0,0 +1,22 @@
+name: "Benchmarks"
+
+on: [pull_request]
+jobs:
+ lint:
+ name: Benchmarks
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.0'
+
+ - name: Install dependencies
+ run: composer install --prefer-dist
+
+ - name: Run Benchmarks
+ run: composer bench -- --progress=plain
\ No newline at end of file
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 00000000..bcb85b66
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,22 @@
+name: "Linter"
+
+on: [pull_request]
+jobs:
+ lint:
+ name: Linter
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.0'
+
+ - name: Install dependencies
+ run: composer install --prefer-dist
+
+ - name: Run Linter
+ run: composer lint
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..cc41aa6f
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,25 @@
+name: "Tests"
+
+on: [pull_request]
+jobs:
+ lint:
+ name: Tests
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.0'
+
+ - name: Setup Docker
+ run: docker-compose up -d --build
+
+ - name: Wait for Server to be ready
+ run: sleep 10
+
+ - name: Run Tests
+ run: docker compose exec web vendor/bin/phpunit --configuration phpunit.xml
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 14df38c0..00000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-# This file is a template, and might need editing before it works on your project.
-# Select image from https://hub.docker.com/_/php/
-image: php:7.1.1
-
-# Select what we should cache between builds
-cache:
- paths:
- - vendor/
-
-before_script:
-- apt-get update -yqq
-- apt-get install -yqq git
-# Install PHP extensions
-- docker-php-ext-install mbstring json opcache
-# Install & enable Xdebug for code coverage reports
-- pecl install xdebug
-- docker-php-ext-enable xdebug
-# Install and run Composer
-- curl -sS https://getcomposer.org/installer | php
-- php composer.phar install
-
-# Run our tests
-# If Xdebug was installed you can generate a coverage report and see code coverage metrics.
-test:
- script:
- - vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index ef34aadb..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-dist: focal
-
-arch:
- - amd64
-
-os: linux
-
-language: shell
-
-notifications:
- email:
- - team@appwrite.io
-
-services:
- - docker
-
-before_install:
- - curl -fsSL https://get.docker.com | sh
- - echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
- - mkdir -p $HOME/.docker
- - echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
- - sudo service docker start
- - >
- if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then
- echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin
- fi
- - docker --version
-
-install:
- - docker-compose up -d
- - sleep 10
-
-script:
- - docker ps -a
- - docker-compose exec web vendor/bin/phpunit --configuration phpunit.xml
- - docker-compose exec web vendor/bin/psalm --show-info=true
diff --git a/Dockerfile b/Dockerfile
index c9ae2094..54c948a6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -21,7 +21,7 @@ ENV DEBIAN_FRONTEND=noninteractive \
RUN \
apk add --no-cache --virtual .deps \
- supervisor php$PHP_VERSION php$PHP_VERSION-fpm nginx bash
+ supervisor php$PHP_VERSION php$PHP_VERSION-fpm php$PHP_VERSION-mbstring nginx bash
# Nginx Configuration (with self-signed ssl certificates)
@@ -38,7 +38,7 @@ COPY ./tests/docker/start /usr/local/bin/start
COPY ./src /usr/share/nginx/html/src
COPY ./tests /usr/share/nginx/html/tests
COPY ./phpunit.xml /usr/share/nginx/html/phpunit.xml
-COPY ./psalm.xml /usr/share/nginx/html/psalm.xml
+COPY ./phpbench.json /usr/share/nginx/html/phpbench.json
COPY --from=step0 /usr/local/src/vendor /usr/share/nginx/html/vendor
# Supervisord Conf
diff --git a/composer.json b/composer.json
index 3fb769b5..fe84d0d0 100644
--- a/composer.json
+++ b/composer.json
@@ -2,24 +2,32 @@
"name": "utopia-php/framework",
"description": "A simple, light and advanced PHP framework",
"type": "library",
- "keywords": ["php","framework", "upf"],
+ "keywords": [
+ "php",
+ "framework",
+ "upf"
+ ],
"license": "MIT",
"minimum-stability": "stable",
"autoload": {
- "psr-4": {"Utopia\\": "src/"}
+ "psr-4": {
+ "Utopia\\": "src/"
+ }
},
"scripts": {
- "lint": "./vendor/bin/pint --test",
- "format": "./vendor/bin/pint",
- "check": "./vendor/bin/phpstan analyse -l 5 src tests"
+ "lint": "vendor/bin/pint --test",
+ "format": "vendor/bin/pint",
+ "check": "vendor/bin/phpstan analyse -c phpstan.neon",
+ "test": "vendor/bin/phpunit --configuration phpunit.xml",
+ "bench": "vendor/bin/phpbench run --report=benchmark"
},
"require": {
"php": ">=8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5.25",
- "vimeo/psalm": "4.27.0",
"laravel/pint": "^1.2",
- "phpstan/phpstan": "1.9.x-dev"
+ "phpstan/phpstan": "^1.10",
+ "phpbench/phpbench": "^1.2"
}
}
diff --git a/composer.lock b/composer.lock
index 6f8a74f3..812fe97b 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,349 +4,44 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "f89715e407bde4aecfdff0a0961815de",
+ "content-hash": "d41ea47cadd897ad4053410229874733",
"packages": [],
"packages-dev": [
{
- "name": "amphp/amp",
- "version": "v2.6.2",
+ "name": "doctrine/annotations",
+ "version": "2.0.1",
"source": {
"type": "git",
- "url": "https://github.com/amphp/amp.git",
- "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb"
+ "url": "https://github.com/doctrine/annotations.git",
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
- "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
"shasum": ""
},
"require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "dev-master",
- "amphp/phpunit-util": "^1",
- "ext-json": "*",
- "jetbrains/phpstorm-stubs": "^2019.3",
- "phpunit/phpunit": "^7 | ^8 | ^9",
- "psalm/phar": "^3.11@dev",
- "react/promise": "^2"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.x-dev"
- }
- },
- "autoload": {
- "files": [
- "lib/functions.php",
- "lib/Internal/functions.php"
- ],
- "psr-4": {
- "Amp\\": "lib"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Daniel Lowrey",
- "email": "rdlowrey@php.net"
- },
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Bob Weinand",
- "email": "bobwei9@hotmail.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "A non-blocking concurrency framework for PHP applications.",
- "homepage": "https://amphp.org/amp",
- "keywords": [
- "async",
- "asynchronous",
- "awaitable",
- "concurrency",
- "event",
- "event-loop",
- "future",
- "non-blocking",
- "promise"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/amphp",
- "issues": "https://github.com/amphp/amp/issues",
- "source": "https://github.com/amphp/amp/tree/v2.6.2"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2022-02-20T17:52:18+00:00"
- },
- {
- "name": "amphp/byte-stream",
- "version": "v1.8.1",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/byte-stream.git",
- "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd",
- "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^2",
- "php": ">=7.1"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "dev-master",
- "amphp/phpunit-util": "^1.4",
- "friendsofphp/php-cs-fixer": "^2.3",
- "jetbrains/phpstorm-stubs": "^2019.3",
- "phpunit/phpunit": "^6 || ^7 || ^8",
- "psalm/phar": "^3.11.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "files": [
- "lib/functions.php"
- ],
- "psr-4": {
- "Amp\\ByteStream\\": "lib"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "A stream abstraction to make working with non-blocking I/O simple.",
- "homepage": "http://amphp.org/byte-stream",
- "keywords": [
- "amp",
- "amphp",
- "async",
- "io",
- "non-blocking",
- "stream"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/amphp",
- "issues": "https://github.com/amphp/byte-stream/issues",
- "source": "https://github.com/amphp/byte-stream/tree/v1.8.1"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2021-03-30T17:13:30+00:00"
- },
- {
- "name": "composer/package-versions-deprecated",
- "version": "1.11.99.5",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/package-versions-deprecated.git",
- "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d",
- "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1.0 || ^2.0",
- "php": "^7 || ^8"
- },
- "replace": {
- "ocramius/package-versions": "1.11.99"
- },
- "require-dev": {
- "composer/composer": "^1.9.3 || ^2.0@dev",
- "ext-zip": "^1.13",
- "phpunit/phpunit": "^6.5 || ^7"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "PackageVersions\\Installer",
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PackageVersions\\": "src/PackageVersions"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
- "support": {
- "issues": "https://github.com/composer/package-versions-deprecated/issues",
- "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2022-01-17T14:14:24+00:00"
- },
- {
- "name": "composer/pcre",
- "version": "3.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/pcre.git",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
- "shasum": ""
- },
- "require": {
- "php": "^7.4 || ^8.0"
+ "doctrine/lexer": "^2 || ^3",
+ "ext-tokenizer": "*",
+ "php": "^7.2 || ^8.0",
+ "psr/cache": "^1 || ^2 || ^3"
},
"require-dev": {
- "phpstan/phpstan": "^1.3",
- "phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^5"
+ "doctrine/cache": "^2.0",
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.8.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "symfony/cache": "^5.4 || ^6",
+ "vimeo/psalm": "^4.10"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Pcre\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
- "keywords": [
- "PCRE",
- "preg",
- "regex",
- "regular expression"
- ],
- "support": {
- "issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/3.1.0"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2022-11-17T09:50:14+00:00"
- },
- {
- "name": "composer/semver",
- "version": "3.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/semver.git",
- "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
- "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.4",
- "symfony/phpunit-bridge": "^4.2 || ^5"
+ "suggest": {
+ "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Composer\\Semver\\": "src"
+ "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -355,151 +50,38 @@
],
"authors": [
{
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
},
{
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
},
{
- "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": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/3.3.2"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
},
{
- "url": "https://github.com/composer",
- "type": "github"
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
},
{
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2022-04-01T19:23:25+00:00"
- },
- {
- "name": "composer/xdebug-handler",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/xdebug-handler.git",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c",
- "shasum": ""
- },
- "require": {
- "composer/pcre": "^1 || ^2 || ^3",
- "php": "^7.2.5 || ^8.0",
- "psr/log": "^1 || ^2 || ^3"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.0",
- "phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^6.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Composer\\XdebugHandler\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "John Stevenson",
- "email": "john-stevenson@blueyonder.co.uk"
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
}
],
- "description": "Restarts a process without Xdebug.",
+ "description": "Docblock Annotations Parser",
+ "homepage": "https://www.doctrine-project.org/projects/annotations.html",
"keywords": [
- "Xdebug",
- "performance"
+ "annotations",
+ "docblock",
+ "parser"
],
"support": {
- "irc": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ "issues": "https://github.com/doctrine/annotations/issues",
+ "source": "https://github.com/doctrine/annotations/tree/2.0.1"
},
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2022-02-25T21:32:43+00:00"
- },
- {
- "name": "dnoegel/php-xdg-base-dir",
- "version": "v0.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
- "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
- "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "require-dev": {
- "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "XdgBaseDir\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "implementation of xdg base directory specification for php",
- "support": {
- "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
- "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
- },
- "time": "2019-12-04T15:06:13+00:00"
+ "time": "2023-02-02T22:02:53+00:00"
},
{
"name": "doctrine/deprecations",
@@ -546,30 +128,30 @@
},
{
"name": "doctrine/instantiator",
- "version": "2.0.0",
+ "version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
- "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
"shasum": ""
},
"require": {
- "php": "^8.1"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^11",
+ "doctrine/coding-standard": "^9 || ^11",
"ext-pdo": "*",
"ext-phar": "*",
- "phpbench/phpbench": "^1.2",
- "phpstan/phpstan": "^1.9.4",
- "phpstan/phpstan-phpunit": "^1.3",
- "phpunit/phpunit": "^9.5.27",
- "vimeo/psalm": "^5.4"
+ "phpbench/phpbench": "^0.16 || ^1",
+ "phpstan/phpstan": "^1.4",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.30 || ^5.4"
},
"type": "library",
"autoload": {
@@ -596,7 +178,7 @@
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
- "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
+ "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
},
"funding": [
{
@@ -612,121 +194,98 @@
"type": "tidelift"
}
],
- "time": "2022-12-30T00:23:10+00:00"
+ "time": "2022-12-30T00:15:36+00:00"
},
{
- "name": "felixfbecker/advanced-json-rpc",
- "version": "v3.2.1",
+ "name": "doctrine/lexer",
+ "version": "2.1.0",
"source": {
"type": "git",
- "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git",
- "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447"
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447",
- "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
"shasum": ""
},
"require": {
- "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
- "php": "^7.1 || ^8.0",
- "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^7.0 || ^8.0"
+ "doctrine/coding-standard": "^9 || ^10",
+ "phpstan/phpstan": "^1.3",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^4.11 || ^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "AdvancedJsonRpc\\": "lib/"
+ "Doctrine\\Common\\Lexer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "ISC"
+ "MIT"
],
"authors": [
{
- "name": "Felix Becker",
- "email": "felix.b@outlook.com"
- }
- ],
- "description": "A more advanced JSONRPC implementation",
- "support": {
- "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues",
- "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1"
- },
- "time": "2021-06-11T22:34:44+00:00"
- },
- {
- "name": "felixfbecker/language-server-protocol",
- "version": "v1.5.2",
- "source": {
- "type": "git",
- "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
- "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842",
- "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpstan/phpstan": "*",
- "squizlabs/php_codesniffer": "^3.1",
- "vimeo/psalm": "^4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "LanguageServerProtocol\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "ISC"
- ],
- "authors": [
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
- "name": "Felix Becker",
- "email": "felix.b@outlook.com"
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
}
],
- "description": "PHP classes for the Language Server Protocol",
+ "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": [
- "language",
- "microsoft",
- "php",
- "server"
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
],
"support": {
- "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
- "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2"
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/2.1.0"
},
- "time": "2022-03-02T22:36:06+00:00"
+ "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": "2022-12-14T08:49:07+00:00"
},
{
"name": "laravel/pint",
- "version": "v1.8.0",
+ "version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
- "reference": "4b8f2ef22bfcddd1d163cfd282e3f42ee1a5cce2"
+ "reference": "e0a8cef58b74662f27355be9cdea0e726bbac362"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/pint/zipball/4b8f2ef22bfcddd1d163cfd282e3f42ee1a5cce2",
- "reference": "4b8f2ef22bfcddd1d163cfd282e3f42ee1a5cce2",
+ "url": "https://api.github.com/repos/laravel/pint/zipball/e0a8cef58b74662f27355be9cdea0e726bbac362",
+ "reference": "e0a8cef58b74662f27355be9cdea0e726bbac362",
"shasum": ""
},
"require": {
@@ -734,16 +293,16 @@
"ext-mbstring": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
- "php": "^8.1.0"
+ "php": "^8.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^3.16.0",
- "illuminate/view": "^10.5.1",
- "laravel-zero/framework": "^10.0.2",
+ "friendsofphp/php-cs-fixer": "^3.14.4",
+ "illuminate/view": "^9.51.0",
+ "laravel-zero/framework": "^9.2.0",
"mockery/mockery": "^1.5.1",
- "nunomaduro/larastan": "^2.5.1",
+ "nunomaduro/larastan": "^2.4.0",
"nunomaduro/termwind": "^1.15.1",
- "pestphp/pest": "^2.4.0"
+ "pestphp/pest": "^1.22.4"
},
"bin": [
"builds/pint"
@@ -779,7 +338,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
- "time": "2023-04-04T13:08:09+00:00"
+ "time": "2023-02-14T16:31:02+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -840,57 +399,6 @@
],
"time": "2023-03-08T13:26:56+00:00"
},
- {
- "name": "netresearch/jsonmapper",
- "version": "v4.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/cweiske/jsonmapper.git",
- "reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
- "reference": "cfa81ea1d35294d64adb9c68aa4cb9e92400e53f",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "ext-pcre": "*",
- "ext-reflection": "*",
- "ext-spl": "*",
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0",
- "squizlabs/php_codesniffer": "~3.5"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "JsonMapper": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "OSL-3.0"
- ],
- "authors": [
- {
- "name": "Christian Weiske",
- "email": "cweiske@cweiske.de",
- "homepage": "http://github.com/cweiske/jsonmapper/",
- "role": "Developer"
- }
- ],
- "description": "Map nested JSON structures onto PHP classes",
- "support": {
- "email": "cweiske@cweiske.de",
- "issues": "https://github.com/cweiske/jsonmapper/issues",
- "source": "https://github.com/cweiske/jsonmapper/tree/v4.1.0"
- },
- "time": "2022-12-08T20:46:14+00:00"
- },
{
"name": "nikic/php-parser",
"version": "v4.15.4",
@@ -947,59 +455,6 @@
},
"time": "2023-03-05T19:49:14+00:00"
},
- {
- "name": "openlss/lib-array2xml",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/nullivex/lib-array2xml.git",
- "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90",
- "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "LSS": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Bryan Tong",
- "email": "bryan@nullivex.com",
- "homepage": "https://www.nullivex.com"
- },
- {
- "name": "Tony Butler",
- "email": "spudz76@gmail.com",
- "homepage": "https://www.nullivex.com"
- }
- ],
- "description": "Array2XML conversion library credit to lalit.org",
- "homepage": "https://www.nullivex.com",
- "keywords": [
- "array",
- "array conversion",
- "xml",
- "xml conversion"
- ],
- "support": {
- "issues": "https://github.com/nullivex/lib-array2xml/issues",
- "source": "https://github.com/nullivex/lib-array2xml/tree/master"
- },
- "time": "2019-03-29T20:06:56+00:00"
- },
{
"name": "phar-io/manifest",
"version": "2.0.3",
@@ -1112,31 +567,37 @@
"time": "2022-02-21T01:04:05+00:00"
},
{
- "name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
+ "name": "phpbench/container",
+ "version": "2.2.1",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ "url": "https://github.com/phpbench/container.git",
+ "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "url": "https://api.github.com/repos/phpbench/container/zipball/6d555ff7174fca13f9b1ec0b4a089ed41d0ab392",
+ "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "psr/container": "^1.0|^2.0",
+ "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.16",
+ "phpstan/phpstan": "^0.12.52",
+ "phpunit/phpunit": "^8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-2.x": "2.x-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
+ "PhpBench\\DependencyInjection\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1145,59 +606,49 @@
],
"authors": [
{
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
+ "name": "Daniel Leech",
+ "email": "daniel@dantleech.com"
}
],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
- ],
+ "description": "Simple, configurable, service container.",
"support": {
- "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ "issues": "https://github.com/phpbench/container/issues",
+ "source": "https://github.com/phpbench/container/tree/2.2.1"
},
- "time": "2020-06-27T09:03:43+00:00"
+ "time": "2022-01-25T10:17:35+00:00"
},
{
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.3.0",
+ "name": "phpbench/dom",
+ "version": "0.3.3",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
+ "url": "https://github.com/phpbench/dom.git",
+ "reference": "786a96db538d0def931f5b19225233ec42ec7a72"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
- "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
+ "url": "https://api.github.com/repos/phpbench/dom/zipball/786a96db538d0def931f5b19225233ec42ec7a72",
+ "reference": "786a96db538d0def931f5b19225233ec42ec7a72",
"shasum": ""
},
"require": {
- "ext-filter": "*",
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.2",
- "phpdocumentor/type-resolver": "^1.3",
- "webmozart/assert": "^1.9.1"
+ "ext-dom": "*",
+ "php": "^7.3||^8.0"
},
"require-dev": {
- "mockery/mockery": "~1.3.2",
- "psalm/phar": "^4.8"
+ "friendsofphp/php-cs-fixer": "^3.14",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^8.0||^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.x-dev"
+ "dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": "src"
+ "PhpBench\\Dom\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1206,60 +657,82 @@
],
"authors": [
{
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "account@ijaap.nl"
+ "name": "Daniel Leech",
+ "email": "daniel@dantleech.com"
}
],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "description": "DOM wrapper to simplify working with the PHP DOM implementation",
"support": {
- "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
+ "issues": "https://github.com/phpbench/dom/issues",
+ "source": "https://github.com/phpbench/dom/tree/0.3.3"
},
- "time": "2021-10-19T17:43:47+00:00"
+ "time": "2023-03-06T23:46:57+00:00"
},
{
- "name": "phpdocumentor/type-resolver",
- "version": "1.7.1",
+ "name": "phpbench/phpbench",
+ "version": "1.2.10",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "dfc078e8af9c99210337325ff5aa152872c98714"
+ "url": "https://github.com/phpbench/phpbench.git",
+ "reference": "95206f92479674599a75e02b74b9933e2d9883aa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714",
- "reference": "dfc078e8af9c99210337325ff5aa152872c98714",
+ "url": "https://api.github.com/repos/phpbench/phpbench/zipball/95206f92479674599a75e02b74b9933e2d9883aa",
+ "reference": "95206f92479674599a75e02b74b9933e2d9883aa",
"shasum": ""
},
"require": {
- "doctrine/deprecations": "^1.0",
+ "doctrine/annotations": "^1.13 || ^2.0",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0",
- "phpstan/phpdoc-parser": "^1.13"
+ "phpbench/container": "^2.1",
+ "phpbench/dom": "~0.3.3",
+ "psr/log": "^1.1 || ^2.0 || ^3.0",
+ "seld/jsonlint": "^1.1",
+ "symfony/console": "^4.2 || ^5.0 || ^6.0",
+ "symfony/filesystem": "^4.2 || ^5.0 || ^6.0",
+ "symfony/finder": "^4.2 || ^5.0 || ^6.0",
+ "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0",
+ "symfony/process": "^4.2 || ^5.0 || ^6.0",
+ "webmozart/glob": "^4.6"
},
"require-dev": {
- "ext-tokenizer": "*",
- "phpbench/phpbench": "^1.2",
+ "dantleech/invoke": "^2.0",
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "jangregor/phpstan-prophecy": "^1.0",
+ "phpspec/prophecy": "^1.12",
"phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.8",
- "phpstan/phpstan-phpunit": "^1.1",
- "phpunit/phpunit": "^9.5",
- "rector/rector": "^0.13.9",
- "vimeo/psalm": "^4.25"
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^9.0",
+ "symfony/error-handler": "^5.2 || ^6.0",
+ "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0"
+ },
+ "suggest": {
+ "ext-xdebug": "For Xdebug profiling extension."
},
+ "bin": [
+ "bin/phpbench"
+ ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-1.x": "1.x-dev"
+ "dev-master": "1.2-dev"
}
},
"autoload": {
+ "files": [
+ "lib/Report/Func/functions.php"
+ ],
"psr-4": {
- "phpDocumentor\\Reflection\\": "src"
+ "PhpBench\\": "lib/",
+ "PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1268,74 +741,35 @@
],
"authors": [
{
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
+ "name": "Daniel Leech",
+ "email": "daniel@dantleech.com"
}
],
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "description": "PHP Benchmarking Framework",
"support": {
- "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1"
+ "issues": "https://github.com/phpbench/phpbench/issues",
+ "source": "https://github.com/phpbench/phpbench/tree/1.2.10"
},
- "time": "2023-03-27T19:02:04+00:00"
- },
- {
- "name": "phpstan/phpdoc-parser",
- "version": "1.18.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "882eabc9b6a12e25c27091a261397f9c8792e722"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/882eabc9b6a12e25c27091a261397f9c8792e722",
- "reference": "882eabc9b6a12e25c27091a261397f9c8792e722",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "require-dev": {
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "^1.5",
- "phpstan/phpstan-phpunit": "^1.1",
- "phpstan/phpstan-strict-rules": "^1.0",
- "phpunit/phpunit": "^9.5",
- "symfony/process": "^5.2"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "PHPStan\\PhpDocParser\\": [
- "src/"
- ]
+ "funding": [
+ {
+ "url": "https://github.com/dantleech",
+ "type": "github"
}
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
],
- "description": "PHPDoc parser with support for nullable, intersection and generic types",
- "support": {
- "issues": "https://github.com/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/1.18.0"
- },
- "time": "2023-04-06T07:26:43+00:00"
+ "time": "2023-03-24T08:52:55+00:00"
},
{
"name": "phpstan/phpstan",
- "version": "1.9.x-dev",
+ "version": "1.10.14",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "6c0217aa2b146c3e28474e8be3e87188fac55dac"
+ "reference": "d232901b09e67538e5c86a724be841bea5768a7c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6c0217aa2b146c3e28474e8be3e87188fac55dac",
- "reference": "6c0217aa2b146c3e28474e8be3e87188fac55dac",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d232901b09e67538e5c86a724be841bea5768a7c",
+ "reference": "d232901b09e67538e5c86a724be841bea5768a7c",
"shasum": ""
},
"require": {
@@ -1364,8 +798,11 @@
"static analysis"
],
"support": {
+ "docs": "https://phpstan.org/user-guide/getting-started",
+ "forum": "https://github.com/phpstan/phpstan/discussions",
"issues": "https://github.com/phpstan/phpstan/issues",
- "source": "https://github.com/phpstan/phpstan/tree/1.9.x"
+ "security": "https://github.com/phpstan/phpstan/security/policy",
+ "source": "https://github.com/phpstan/phpstan-src"
},
"funding": [
{
@@ -1381,7 +818,7 @@
"type": "tidelift"
}
],
- "time": "2023-02-18T15:01:46+00:00"
+ "time": "2023-04-19T13:47:27+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -1703,16 +1140,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "9.6.6",
+ "version": "9.6.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
+ "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
- "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
+ "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2",
"shasum": ""
},
"require": {
@@ -1786,7 +1223,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7"
},
"funding": [
{
@@ -1798,11 +1235,60 @@
"type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
- "type": "tidelift"
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-04-14T08:58:40+00:00"
+ },
+ {
+ "name": "psr/cache",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "time": "2023-03-27T11:43:46+00:00"
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/3.0.0"
+ },
+ "time": "2021-02-03T23:26:27+00:00"
},
{
"name": "psr/container",
@@ -2799,128 +2285,388 @@
],
"authors": [
{
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
+ "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/3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:13:03+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "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/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:39:44+00:00"
+ },
+ {
+ "name": "seld/jsonlint",
+ "version": "1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/jsonlint.git",
+ "reference": "4211420d25eba80712bff236a98960ef68b866b7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7",
+ "reference": "4211420d25eba80712bff236a98960ef68b866b7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13"
+ },
+ "bin": [
+ "bin/jsonlint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "JSON Linter",
+ "keywords": [
+ "json",
+ "linter",
+ "parser",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/Seldaek/jsonlint/issues",
+ "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Seldaek",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-01T13:37:23+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.0.19",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "c3ebc83d031b71c39da318ca8b7a07ecc67507ed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/c3ebc83d031b71c39da318ca8b7a07ecc67507ed",
+ "reference": "c3ebc83d031b71c39da318ca8b7a07ecc67507ed",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.2",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/string": "^5.4|^6.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",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/lock": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "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.0.19"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-01T08:36:10+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
+ "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "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": "Collection of value objects that represent the types of the PHP type system",
- "homepage": "https://github.com/sebastianbergmann/type",
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
"support": {
- "issues": "https://github.com/sebastianbergmann/type/issues",
- "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2"
},
"funding": [
{
- "url": "https://github.com/sebastianbergmann",
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
"type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "time": "2023-02-03T06:13:03+00:00"
+ "time": "2022-01-02T09:55:41+00:00"
},
{
- "name": "sebastian/version",
- "version": "3.0.2",
+ "name": "symfony/filesystem",
+ "version": "v6.0.19",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
- "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/3d49eec03fda1f0fc19b7349fbbe55ebc1004214",
+ "reference": "3d49eec03fda1f0fc19b7349fbbe55ebc1004214",
"shasum": ""
},
"require": {
- "php": ">=7.3"
+ "php": ">=8.0.2",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
"autoload": {
- "classmap": [
- "src/"
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
- "homepage": "https://github.com/sebastianbergmann/version",
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
"support": {
- "issues": "https://github.com/sebastianbergmann/version/issues",
- "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ "source": "https://github.com/symfony/filesystem/tree/v6.0.19"
},
"funding": [
{
- "url": "https://github.com/sebastianbergmann",
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
"type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "time": "2020-09-28T06:39:44+00:00"
+ "time": "2023-01-20T17:44:14+00:00"
},
{
- "name": "symfony/console",
- "version": "v6.2.8",
+ "name": "symfony/finder",
+ "version": "v6.0.19",
"source": {
"type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b"
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "5cc9cac6586fc0c28cd173780ca696e419fefa11"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b",
- "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/5cc9cac6586fc0c28cd173780ca696e419fefa11",
+ "reference": "5cc9cac6586fc0c28cd173780ca696e419fefa11",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/deprecation-contracts": "^2.1|^3",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/service-contracts": "^1.1|^2|^3",
- "symfony/string": "^5.4|^6.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",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/lock": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/lock": "",
- "symfony/process": ""
+ "php": ">=8.0.2"
},
"type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Console\\": ""
+ "Symfony\\Component\\Finder\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2940,16 +2686,10 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Eases the creation of beautiful and testable command line interfaces",
+ "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
- "keywords": [
- "cli",
- "command-line",
- "console",
- "terminal"
- ],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.2.8"
+ "source": "https://github.com/symfony/finder/tree/v6.0.19"
},
"funding": [
{
@@ -2965,38 +2705,33 @@
"type": "tidelift"
}
],
- "time": "2023-03-29T21:42:15+00:00"
+ "time": "2023-01-20T17:44:14+00:00"
},
{
- "name": "symfony/deprecation-contracts",
- "version": "v3.2.1",
+ "name": "symfony/options-resolver",
+ "version": "v6.0.19",
"source": {
"type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "6a180d1c45e0d9797470ca9eb46215692de00fa3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
- "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/6a180d1c45e0d9797470ca9eb46215692de00fa3",
+ "reference": "6a180d1c45e0d9797470ca9eb46215692de00fa3",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.0.2",
+ "symfony/deprecation-contracts": "^2.1|^3"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.3-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
- }
- },
"autoload": {
- "files": [
- "function.php"
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3005,18 +2740,23 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "A generic function and convention to trigger deprecation notices",
+ "description": "Provides an improved replacement for the array_replace PHP function",
"homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.1"
+ "source": "https://github.com/symfony/options-resolver/tree/v6.0.19"
},
"funding": [
{
@@ -3032,7 +2772,7 @@
"type": "tidelift"
}
],
- "time": "2023-03-01T10:25:55+00:00"
+ "time": "2023-01-01T08:36:10+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -3365,41 +3105,29 @@
"time": "2022-11-03T14:55:06+00:00"
},
{
- "name": "symfony/polyfill-php80",
- "version": "v1.27.0",
+ "name": "symfony/process",
+ "version": "v6.0.19",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936"
+ "url": "https://github.com/symfony/process.git",
+ "reference": "2114fd60f26a296cc403a7939ab91478475a33d4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
- "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936",
+ "url": "https://api.github.com/repos/symfony/process/zipball/2114fd60f26a296cc403a7939ab91478475a33d4",
+ "reference": "2114fd60f26a296cc403a7939ab91478475a33d4",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=8.0.2"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
"autoload": {
- "files": [
- "bootstrap.php"
- ],
"psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
+ "Symfony\\Component\\Process\\": ""
},
- "classmap": [
- "Resources/stubs"
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3408,28 +3136,18 @@
],
"authors": [
{
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0"
+ "source": "https://github.com/symfony/process/tree/v6.0.19"
},
"funding": [
{
@@ -3445,24 +3163,24 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2023-01-01T08:36:10+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.2.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "a8c9cedf55f314f3a186041d19537303766df09a"
+ "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
- "reference": "a8c9cedf55f314f3a186041d19537303766df09a",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66",
+ "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.0.2",
"psr/container": "^2.0"
},
"conflict": {
@@ -3474,7 +3192,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.3-dev"
+ "dev-main": "3.0-dev"
},
"thanks": {
"name": "symfony/contracts",
@@ -3484,10 +3202,7 @@
"autoload": {
"psr-4": {
"Symfony\\Contracts\\Service\\": ""
- },
- "exclude-from-classmap": [
- "/Test/"
- ]
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3514,7 +3229,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.2.1"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.0.2"
},
"funding": [
{
@@ -3530,24 +3245,24 @@
"type": "tidelift"
}
],
- "time": "2023-03-01T10:32:47+00:00"
+ "time": "2022-05-30T19:17:58+00:00"
},
{
"name": "symfony/string",
- "version": "v6.2.8",
+ "version": "v6.0.19",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
+ "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
- "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
+ "url": "https://api.github.com/repos/symfony/string/zipball/d9e72497367c23e08bf94176d2be45b00a9d232a",
+ "reference": "d9e72497367c23e08bf94176d2be45b00a9d232a",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.0.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
@@ -3559,7 +3274,6 @@
"require-dev": {
"symfony/error-handler": "^5.4|^6.0",
"symfony/http-client": "^5.4|^6.0",
- "symfony/intl": "^6.2",
"symfony/translation-contracts": "^2.0|^3.0",
"symfony/var-exporter": "^5.4|^6.0"
},
@@ -3600,7 +3314,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.2.8"
+ "source": "https://github.com/symfony/string/tree/v6.0.19"
},
"funding": [
{
@@ -3616,7 +3330,7 @@
"type": "tidelift"
}
],
- "time": "2023-03-20T16:06:02+00:00"
+ "time": "2023-01-01T08:36:10+00:00"
},
{
"name": "theseer/tokenizer",
@@ -3669,201 +3383,35 @@
"time": "2021-07-28T10:34:58+00:00"
},
{
- "name": "vimeo/psalm",
- "version": "4.27.0",
- "source": {
- "type": "git",
- "url": "https://github.com/vimeo/psalm.git",
- "reference": "faf106e717c37b8c81721845dba9de3d8deed8ff"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/vimeo/psalm/zipball/faf106e717c37b8c81721845dba9de3d8deed8ff",
- "reference": "faf106e717c37b8c81721845dba9de3d8deed8ff",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^2.4.2",
- "amphp/byte-stream": "^1.5",
- "composer/package-versions-deprecated": "^1.8.0",
- "composer/semver": "^1.4 || ^2.0 || ^3.0",
- "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0",
- "dnoegel/php-xdg-base-dir": "^0.1.1",
- "ext-ctype": "*",
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "felixfbecker/advanced-json-rpc": "^3.0.3",
- "felixfbecker/language-server-protocol": "^1.5",
- "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
- "nikic/php-parser": "^4.13",
- "openlss/lib-array2xml": "^1.0",
- "php": "^7.1|^8",
- "sebastian/diff": "^3.0 || ^4.0",
- "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0",
- "symfony/polyfill-php80": "^1.25",
- "webmozart/path-util": "^2.3"
- },
- "provide": {
- "psalm/psalm": "self.version"
- },
- "require-dev": {
- "bamarni/composer-bin-plugin": "^1.2",
- "brianium/paratest": "^4.0||^6.0",
- "ext-curl": "*",
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpdocumentor/reflection-docblock": "^5",
- "phpmyadmin/sql-parser": "5.1.0||dev-master",
- "phpspec/prophecy": ">=1.9.0",
- "phpunit/phpunit": "^9.0",
- "psalm/plugin-phpunit": "^0.16",
- "slevomat/coding-standard": "^7.0",
- "squizlabs/php_codesniffer": "^3.5",
- "symfony/process": "^4.3 || ^5.0 || ^6.0",
- "weirdan/prophecy-shim": "^1.0 || ^2.0"
- },
- "suggest": {
- "ext-curl": "In order to send data to shepherd",
- "ext-igbinary": "^2.0.5 is required, used to serialize caching data"
- },
- "bin": [
- "psalm",
- "psalm-language-server",
- "psalm-plugin",
- "psalm-refactor",
- "psalter"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.x-dev",
- "dev-3.x": "3.x-dev",
- "dev-2.x": "2.x-dev",
- "dev-1.x": "1.x-dev"
- }
- },
- "autoload": {
- "files": [
- "src/functions.php",
- "src/spl_object_id.php"
- ],
- "psr-4": {
- "Psalm\\": "src/Psalm/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Matthew Brown"
- }
- ],
- "description": "A static analysis tool for finding errors in PHP applications",
- "keywords": [
- "code",
- "inspection",
- "php"
- ],
- "support": {
- "issues": "https://github.com/vimeo/psalm/issues",
- "source": "https://github.com/vimeo/psalm/tree/4.27.0"
- },
- "time": "2022-08-31T13:47:09+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.11.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozarts/assert.git",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "shasum": ""
- },
- "require": {
- "ext-ctype": "*",
- "php": "^7.2 || ^8.0"
- },
- "conflict": {
- "phpstan/phpstan": "<0.12.20",
- "vimeo/psalm": "<4.6.1 || 4.6.2"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5.13"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "support": {
- "issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.11.0"
- },
- "time": "2022-06-03T18:03:27+00:00"
- },
- {
- "name": "webmozart/path-util",
- "version": "2.3.0",
+ "name": "webmozart/glob",
+ "version": "4.6.0",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/path-util.git",
- "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725"
+ "url": "https://github.com/webmozarts/glob.git",
+ "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
- "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
+ "url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655",
+ "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "webmozart/assert": "~1.0"
+ "php": "^7.3 || ^8.0.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.6",
- "sebastian/version": "^1.0.1"
+ "phpunit/phpunit": "^9.5",
+ "symfony/filesystem": "^5.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "4.1-dev"
}
},
"autoload": {
"psr-4": {
- "Webmozart\\PathUtil\\": "src/"
+ "Webmozart\\Glob\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -3876,20 +3424,17 @@
"email": "bschussek@gmail.com"
}
],
- "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
+ "description": "A PHP implementation of Ant's glob.",
"support": {
- "issues": "https://github.com/webmozart/path-util/issues",
- "source": "https://github.com/webmozart/path-util/tree/2.3.0"
+ "issues": "https://github.com/webmozarts/glob/issues",
+ "source": "https://github.com/webmozarts/glob/tree/4.6.0"
},
- "abandoned": "symfony/filesystem",
- "time": "2015-12-17T08:42:14+00:00"
+ "time": "2022-05-24T19:45:58+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": {
- "phpstan/phpstan": 20
- },
+ "stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
diff --git a/docker-compose.yml b/docker-compose.yml
index 55ad1dfc..849fa5ec 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,4 +6,5 @@ services:
ports:
- "9020:80"
volumes:
+ - ./src:/usr/share/nginx/html/src
- ./tests:/usr/share/nginx/html/tests
\ No newline at end of file
diff --git a/phpbench.json b/phpbench.json
new file mode 100644
index 00000000..adc40d12
--- /dev/null
+++ b/phpbench.json
@@ -0,0 +1,6 @@
+{
+ "$schema":"vendor/phpbench/phpbench/phpbench.schema.json",
+ "runner.bootstrap": "vendor/autoload.php",
+ "runner.path": "tests",
+ "runner.file_pattern": "*Bench.php"
+}
\ No newline at end of file
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 00000000..a76a8329
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,5 @@
+parameters:
+ level: 5
+ paths:
+ - src
+ - tests
\ No newline at end of file
diff --git a/pint.json b/pint.json
new file mode 100644
index 00000000..c7819336
--- /dev/null
+++ b/pint.json
@@ -0,0 +1,3 @@
+{
+ "preset": "psr12"
+}
\ No newline at end of file
diff --git a/psalm.xml b/psalm.xml
deleted file mode 100644
index 30258a70..00000000
--- a/psalm.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/App.php b/src/App.php
index 2495a369..563d0a6d 100755
--- a/src/App.php
+++ b/src/App.php
@@ -7,41 +7,28 @@ class App
/**
* Request method constants
*/
- const REQUEST_METHOD_GET = 'GET';
+ public const REQUEST_METHOD_GET = 'GET';
- const REQUEST_METHOD_POST = 'POST';
+ public const REQUEST_METHOD_POST = 'POST';
- const REQUEST_METHOD_PUT = 'PUT';
+ public const REQUEST_METHOD_PUT = 'PUT';
- const REQUEST_METHOD_PATCH = 'PATCH';
+ public const REQUEST_METHOD_PATCH = 'PATCH';
- const REQUEST_METHOD_DELETE = 'DELETE';
+ public const REQUEST_METHOD_DELETE = 'DELETE';
- const REQUEST_METHOD_OPTIONS = 'OPTIONS';
+ public const REQUEST_METHOD_OPTIONS = 'OPTIONS';
- const REQUEST_METHOD_HEAD = 'HEAD';
+ public const REQUEST_METHOD_HEAD = 'HEAD';
/**
* Mode Type
*/
- const MODE_TYPE_DEVELOPMENT = 'development';
+ public const MODE_TYPE_DEVELOPMENT = 'development';
- const MODE_TYPE_STAGE = 'stage';
+ public const MODE_TYPE_STAGE = 'stage';
- const MODE_TYPE_PRODUCTION = 'production';
-
- /**
- * Routes
- *
- * @var array
- */
- protected static array $routes = [
- self::REQUEST_METHOD_GET => [],
- self::REQUEST_METHOD_POST => [],
- self::REQUEST_METHOD_PUT => [],
- self::REQUEST_METHOD_PATCH => [],
- self::REQUEST_METHOD_DELETE => [],
- ];
+ public const MODE_TYPE_PRODUCTION = 'production';
/**
* @var array
@@ -98,13 +85,6 @@ class App
*/
protected static array $options = [];
- /**
- * Is Sorted?
- *
- * @var bool
- */
- protected static bool $sorted = false;
-
/**
* Route
*
@@ -122,15 +102,6 @@ class App
*/
protected static ?Route $wildcardRoute = null;
- /**
- * Matches
- *
- * Parameters matched from URL regex
- *
- * @var array
- */
- protected array $matches = [];
-
/**
* App
*
@@ -231,6 +202,7 @@ public static function init(): Hook
{
$hook = new Hook();
$hook->groups(['*']);
+
self::$init[] = $hook;
return $hook;
@@ -247,6 +219,7 @@ public static function shutdown(): Hook
{
$hook = new Hook();
$hook->groups(['*']);
+
self::$shutdown[] = $hook;
return $hook;
@@ -263,6 +236,7 @@ public static function options(): Hook
{
$hook = new Hook();
$hook->groups(['*']);
+
self::$options[] = $hook;
return $hook;
@@ -279,6 +253,7 @@ public static function error(): Hook
{
$hook = new Hook();
$hook->groups(['*']);
+
self::$errors[] = $hook;
return $hook;
@@ -338,9 +313,9 @@ public function getResource(string $name, bool $fresh = false): mixed
return $this;
}
- if (! \array_key_exists($name, $this->resources) || $fresh || self::$resourcesCallbacks[$name]['reset']) {
- if (! \array_key_exists($name, self::$resourcesCallbacks)) {
- throw new Exception('Failed to find resource: "'.$name.'"');
+ if (!\array_key_exists($name, $this->resources) || $fresh || self::$resourcesCallbacks[$name]['reset']) {
+ if (!\array_key_exists($name, self::$resourcesCallbacks)) {
+ throw new Exception('Failed to find resource: "' . $name . '"');
}
$this->resources[$name] = \call_user_func_array(
@@ -428,7 +403,7 @@ public static function isStage(): bool
*/
public static function getRoutes(): array
{
- return self::$routes;
+ return Router::getRoutes();
}
/**
@@ -446,7 +421,7 @@ public function getRoute(): ?Route
*
* @param Route $route
*/
- public function setRoute(Route $route): static
+ public function setRoute(Route $route): self
{
$this->route = $route;
@@ -464,14 +439,9 @@ public function setRoute(Route $route): static
*/
public static function addRoute(string $method, string $url): Route
{
- if (! array_key_exists($method, self::$routes)) {
- throw new Exception('Invalid Request Method');
- }
$route = new Route($method, $url);
- self::$routes[$method][$url] = $route;
-
- self::$sorted = false;
+ Router::addRoute($route);
return $route;
}
@@ -487,7 +457,7 @@ public static function addRoute(string $method, string $url): Route
*/
public function match(Request $request, bool $fresh = false): ?Route
{
- if (null !== $this->route && ! $fresh) {
+ if (null !== $this->route && !$fresh) {
return $this->route;
}
@@ -495,52 +465,7 @@ public function match(Request $request, bool $fresh = false): ?Route
$method = $request->getMethod();
$method = (self::REQUEST_METHOD_HEAD == $method) ? self::REQUEST_METHOD_GET : $method;
- if (! isset(self::$routes[$method])) {
- self::$routes[$method] = [];
- }
-
- foreach (self::$routes[$method] as $routeUrl => $route) {
- /** @var Route $route */
-
- if(str_ends_with($routeUrl, '/') && substr_count($routeUrl, '/') > 1) {
- $routeUrl = rtrim($routeUrl, '/');
- }
-
- if(str_ends_with($url, '/') && substr_count($url, '/') > 1) {
- $url = rtrim($url, '/');
- }
-
- // convert urls like '/users/:uid/posts/:pid' to regular expression
- $regex = '@'.\preg_replace('@:[^/]+@', '([^/]+)', $routeUrl).'@';
-
- // Check if the current request matches the expression
- if (! \preg_match($regex, $url, $this->matches)) {
- continue;
- }
-
- // check for trailing wildcard
- if (!str_ends_with($routeUrl, '/*')) {
- // Check the paths have the same amount of segments
- if (\substr_count($routeUrl, '/') !== \substr_count($url, '/')) {
- continue;
- }
- }
-
- \array_shift($this->matches);
- $this->route = $route;
-
- if (isset($route->getAliases()[$routeUrl])) {
- $this->route->setAliasPath($routeUrl);
- } else {
- $this->route->setAliasPath(null);
- }
-
- break;
- }
-
- if (! empty($this->route) && ('/' === $this->route->getPath()) && ($url != $this->route->getPath())) {
- return null;
- }
+ $this->route = Router::match($method, $url);
return $this->route;
}
@@ -553,25 +478,15 @@ public function match(Request $request, bool $fresh = false): ?Route
*/
public function execute(Route $route, Request $request): static
{
- $keys = [];
$arguments = [];
$groups = $route->getGroups();
+ $pathValues = $route->getPathValues($request);
- // Extract keys from URL
- $url = $route->getIsAlias() ? $route->getAliasPath() : $route->getPath();
- $keyRegex = '@^'.\preg_replace('@:[^/]+@', ':([^/]+)', $url).'$@';
- \preg_match($keyRegex, $url, $keys);
-
- // Remove the first key and value ( corresponding to full regex match )
- \array_shift($keys);
-
- // combine keys and values to one array
- $values = \array_combine($keys, $this->matches);
try {
if ($route->getHook()) {
foreach (self::$init as $hook) { // Global init hooks
if (in_array('*', $hook->getGroups())) {
- $arguments = $this->getArguments($hook, $values, $request->getParams());
+ $arguments = $this->getArguments($hook, $pathValues, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
}
@@ -580,26 +495,21 @@ public function execute(Route $route, Request $request): static
foreach ($groups as $group) {
foreach (self::$init as $hook) { // Group init hooks
if (in_array($group, $hook->getGroups())) {
- $arguments = $this->getArguments($hook, $values, $request->getParams());
+ $arguments = $this->getArguments($hook, $pathValues, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
}
}
- $arguments = $this->getArguments($route, $values, $request->getParams());
-
- // Call the callback with the matched positions as params
- if ($route->getIsActive()) {
- \call_user_func_array($route->getAction(), $arguments);
- }
+ $arguments = $this->getArguments($route, $pathValues, $request->getParams());
- $route->setIsActive(true);
+ // Call the action callback with the matched positions as params
+ \call_user_func_array($route->getAction(), $arguments);
foreach ($groups as $group) {
foreach (self::$shutdown as $hook) { // Group shutdown hooks
- /** @var Hook $hook */
if (in_array($group, $hook->getGroups())) {
- $arguments = $this->getArguments($hook, $values, $request->getParams());
+ $arguments = $this->getArguments($hook, $pathValues, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
}
@@ -607,9 +517,8 @@ public function execute(Route $route, Request $request): static
if ($route->getHook()) {
foreach (self::$shutdown as $hook) { // Group shutdown hooks
- /** @var Hook $hook */
if (in_array('*', $hook->getGroups())) {
- $arguments = $this->getArguments($hook, $values, $request->getParams());
+ $arguments = $this->getArguments($hook, $pathValues, $request->getParams());
\call_user_func_array($hook->getAction(), $arguments);
}
}
@@ -619,26 +528,24 @@ public function execute(Route $route, Request $request): static
foreach ($groups as $group) {
foreach (self::$errors as $error) { // Group error hooks
- /** @var Hook $error */
if (in_array($group, $error->getGroups())) {
try {
- $arguments = $this->getArguments($error, $values, $request->getParams());
+ $arguments = $this->getArguments($error, $pathValues, $request->getParams());
\call_user_func_array($error->getAction(), $arguments);
} catch (\Throwable $e) {
- throw new Exception('Error handler had an error: '.$e->getMessage(), 500, $e);
+ throw new Exception('Error handler had an error: ' . $e->getMessage(), 500, $e);
}
}
}
}
foreach (self::$errors as $error) { // Global error hooks
- /** @var Hook $error */
if (in_array('*', $error->getGroups())) {
try {
- $arguments = $this->getArguments($error, $values, $request->getParams());
+ $arguments = $this->getArguments($error, $pathValues, $request->getParams());
\call_user_func_array($error->getAction(), $arguments);
} catch (\Throwable $e) {
- throw new Exception('Error handler had an error: '.$e->getMessage(), 500, $e);
+ throw new Exception('Error handler had an error: ' . $e->getMessage(), 500, $e);
}
}
}
@@ -668,13 +575,6 @@ protected function getArguments(Hook $hook, array $values, array $requestParams)
$arg = $existsInRequest ? $requestParams[$key] : $param['default'];
$value = $existsInValues ? $values[$key] : $arg;
- if ($hook instanceof Route) {
- if ($hook->getIsAlias() && isset($hook->getAliasParams($hook->getAliasPath())[$key])) {
- $value = $hook->getAliasParams($hook->getAliasPath())[$key];
- $paramExists = true;
- }
- }
-
if (!$param['skipValidation']) {
if (!$paramExists && !$param['optional']) {
throw new Exception('Param "' . $key . '" is not optional.', 400);
@@ -718,39 +618,6 @@ public function run(Request $request, Response $response): static
return $response;
});
- /*
- * Re-order array
- *
- * For route to work with similar links where one is shorter than other
- * but both might match given pattern
- */
- if (! self::$sorted) {
- foreach (self::$routes as $method => $list) { //adding route alias in $routes
- foreach ($list as $key => $route) {
- foreach (array_keys($route->getAliases()) as $path) {
- self::$routes[$method][$path] = $route;
- }
- }
- }
- foreach (self::$routes as $method => $list) {
- \uksort(self::$routes[$method], function (string $a, string $b) {
- return \strlen($b) - \strlen($a);
- });
-
- \uksort(self::$routes[$method], function (string $a, string $b) {
- $result = \count(\explode('/', $b)) - \count(\explode('/', $a));
-
- if ($result === 0) {
- return \substr_count($a, ':') - \substr_count($b, ':');
- }
-
- return $result;
- });
- }
-
- self::$sorted = true;
- }
-
$method = $request->getMethod();
$route = $this->match($request);
$groups = ($route instanceof Route) ? $route->getGroups() : [];
@@ -805,7 +672,6 @@ public function run(Request $request, Response $response): static
try {
foreach ($groups as $group) {
foreach (self::$options as $option) { // Group options hooks
- /** @var Hook $option */
if (in_array($group, $option->getGroups())) {
\call_user_func_array($option->getAction(), $this->getArguments($option, [], $request->getParams()));
}
@@ -813,14 +679,12 @@ public function run(Request $request, Response $response): static
}
foreach (self::$options as $option) { // Global options hooks
- /** @var Hook $option */
if (in_array('*', $option->getGroups())) {
\call_user_func_array($option->getAction(), $this->getArguments($option, [], $request->getParams()));
}
}
} catch (\Throwable $e) {
foreach (self::$errors as $error) { // Global error hooks
- /** @var Hook $error */
if (in_array('*', $error->getGroups())) {
self::setResource('error', function () use ($e) {
return $e;
@@ -872,28 +736,23 @@ protected function validate(string $key, array $param, mixed $value): void
}
if (!$validator->isValid($value)) {
- throw new Exception('Invalid '.$key.': '.$validator->getDescription(), 400);
+ throw new Exception('Invalid ' . $key . ': ' . $validator->getDescription(), 400);
}
}
/**
* Reset all the static variables
+ *
+ * @return void
*/
public static function reset(): void
{
+ Router::reset();
self::$resourcesCallbacks = [];
self::$mode = '';
self::$errors = [];
self::$init = [];
self::$shutdown = [];
self::$options = [];
- self::$sorted = false;
- self::$routes = [
- self::REQUEST_METHOD_GET => [],
- self::REQUEST_METHOD_POST => [],
- self::REQUEST_METHOD_PUT => [],
- self::REQUEST_METHOD_PATCH => [],
- self::REQUEST_METHOD_DELETE => [],
- ];
}
}
diff --git a/src/Request.php b/src/Request.php
index a1e4bd2a..474ca3ce 100755
--- a/src/Request.php
+++ b/src/Request.php
@@ -7,23 +7,23 @@ class Request
/**
* HTTP methods
*/
- const METHOD_OPTIONS = 'OPTIONS';
+ public const METHOD_OPTIONS = 'OPTIONS';
- const METHOD_GET = 'GET';
+ public const METHOD_GET = 'GET';
- const METHOD_HEAD = 'HEAD';
+ public const METHOD_HEAD = 'HEAD';
- const METHOD_POST = 'POST';
+ public const METHOD_POST = 'POST';
- const METHOD_PATCH = 'PATCH';
+ public const METHOD_PATCH = 'PATCH';
- const METHOD_PUT = 'PUT';
+ public const METHOD_PUT = 'PUT';
- const METHOD_DELETE = 'DELETE';
+ public const METHOD_DELETE = 'DELETE';
- const METHOD_TRACE = 'TRACE';
+ public const METHOD_TRACE = 'TRACE';
- const METHOD_CONNECT = 'CONNECT';
+ public const METHOD_CONNECT = 'CONNECT';
/**
* Container for raw php://input parsed stream
diff --git a/src/Response.php b/src/Response.php
index 826a2b07..742efd3b 100755
--- a/src/Response.php
+++ b/src/Response.php
@@ -7,125 +7,125 @@ class Response
/**
* HTTP content types
*/
- const CONTENT_TYPE_TEXT = 'text/plain';
+ public const CONTENT_TYPE_TEXT = 'text/plain';
- const CONTENT_TYPE_HTML = 'text/html';
+ public const CONTENT_TYPE_HTML = 'text/html';
- const CONTENT_TYPE_JSON = 'application/json';
+ public const CONTENT_TYPE_JSON = 'application/json';
- const CONTENT_TYPE_XML = 'text/xml';
+ public const CONTENT_TYPE_XML = 'text/xml';
- const CONTENT_TYPE_JAVASCRIPT = 'text/javascript';
+ public const CONTENT_TYPE_JAVASCRIPT = 'text/javascript';
- const CONTENT_TYPE_IMAGE = 'image/*';
+ public const CONTENT_TYPE_IMAGE = 'image/*';
- const CONTENT_TYPE_IMAGE_JPEG = 'image/jpeg';
+ public const CONTENT_TYPE_IMAGE_JPEG = 'image/jpeg';
- const CONTENT_TYPE_IMAGE_PNG = 'image/png';
+ public const CONTENT_TYPE_IMAGE_PNG = 'image/png';
- const CONTENT_TYPE_IMAGE_GIF = 'image/gif';
+ public const CONTENT_TYPE_IMAGE_GIF = 'image/gif';
- const CONTENT_TYPE_IMAGE_SVG = 'image/svg+xml';
+ public const CONTENT_TYPE_IMAGE_SVG = 'image/svg+xml';
- const CONTENT_TYPE_IMAGE_WEBP = 'image/webp';
+ public const CONTENT_TYPE_IMAGE_WEBP = 'image/webp';
- const CONTENT_TYPE_IMAGE_ICON = 'image/x-icon';
+ public const CONTENT_TYPE_IMAGE_ICON = 'image/x-icon';
- const CONTENT_TYPE_IMAGE_BMP = 'image/bmp';
+ public const CONTENT_TYPE_IMAGE_BMP = 'image/bmp';
/**
* Chrsets
*/
- const CHARSET_UTF8 = 'UTF-8';
+ public const CHARSET_UTF8 = 'UTF-8';
/**
* HTTP response status codes
*/
- const STATUS_CODE_CONTINUE = 100;
+ public const STATUS_CODE_CONTINUE = 100;
- const STATUS_CODE_SWITCHING_PROTOCOLS = 101;
+ public const STATUS_CODE_SWITCHING_PROTOCOLS = 101;
- const STATUS_CODE_OK = 200;
+ public const STATUS_CODE_OK = 200;
- const STATUS_CODE_CREATED = 201;
+ public const STATUS_CODE_CREATED = 201;
- const STATUS_CODE_ACCEPTED = 202;
+ public const STATUS_CODE_ACCEPTED = 202;
- const STATUS_CODE_NON_AUTHORITATIVE_INFORMATION = 203;
+ public const STATUS_CODE_NON_AUTHORITATIVE_INFORMATION = 203;
- const STATUS_CODE_NOCONTENT = 204;
+ public const STATUS_CODE_NOCONTENT = 204;
- const STATUS_CODE_RESETCONTENT = 205;
+ public const STATUS_CODE_RESETCONTENT = 205;
- const STATUS_CODE_PARTIALCONTENT = 206;
+ public const STATUS_CODE_PARTIALCONTENT = 206;
- const STATUS_CODE_MULTIPLE_CHOICES = 300;
+ public const STATUS_CODE_MULTIPLE_CHOICES = 300;
- const STATUS_CODE_MOVED_PERMANENTLY = 301;
+ public const STATUS_CODE_MOVED_PERMANENTLY = 301;
- const STATUS_CODE_FOUND = 302;
+ public const STATUS_CODE_FOUND = 302;
- const STATUS_CODE_SEE_OTHER = 303;
+ public const STATUS_CODE_SEE_OTHER = 303;
- const STATUS_CODE_NOT_MODIFIED = 304;
+ public const STATUS_CODE_NOT_MODIFIED = 304;
- const STATUS_CODE_USE_PROXY = 305;
+ public const STATUS_CODE_USE_PROXY = 305;
- const STATUS_CODE_UNUSED = 306;
+ public const STATUS_CODE_UNUSED = 306;
- const STATUS_CODE_TEMPORARY_REDIRECT = 307;
+ public const STATUS_CODE_TEMPORARY_REDIRECT = 307;
- const STATUS_CODE_BAD_REQUEST = 400;
+ public const STATUS_CODE_BAD_REQUEST = 400;
- const STATUS_CODE_UNAUTHORIZED = 401;
+ public const STATUS_CODE_UNAUTHORIZED = 401;
- const STATUS_CODE_PAYMENT_REQUIRED = 402;
+ public const STATUS_CODE_PAYMENT_REQUIRED = 402;
- const STATUS_CODE_FORBIDDEN = 403;
+ public const STATUS_CODE_FORBIDDEN = 403;
- const STATUS_CODE_NOT_FOUND = 404;
+ public const STATUS_CODE_NOT_FOUND = 404;
- const STATUS_CODE_METHOD_NOT_ALLOWED = 405;
+ public const STATUS_CODE_METHOD_NOT_ALLOWED = 405;
- const STATUS_CODE_NOT_ACCEPTABLE = 406;
+ public const STATUS_CODE_NOT_ACCEPTABLE = 406;
- const STATUS_CODE_PROXY_AUTHENTICATION_REQUIRED = 407;
+ public const STATUS_CODE_PROXY_AUTHENTICATION_REQUIRED = 407;
- const STATUS_CODE_REQUEST_TIMEOUT = 408;
+ public const STATUS_CODE_REQUEST_TIMEOUT = 408;
- const STATUS_CODE_CONFLICT = 409;
+ public const STATUS_CODE_CONFLICT = 409;
- const STATUS_CODE_GONE = 410;
+ public const STATUS_CODE_GONE = 410;
- const STATUS_CODE_LENGTH_REQUIRED = 411;
+ public const STATUS_CODE_LENGTH_REQUIRED = 411;
- const STATUS_CODE_PRECONDITION_FAILED = 412;
+ public const STATUS_CODE_PRECONDITION_FAILED = 412;
- const STATUS_CODE_REQUEST_ENTITY_TOO_LARGE = 413;
+ public const STATUS_CODE_REQUEST_ENTITY_TOO_LARGE = 413;
- const STATUS_CODE_REQUEST_URI_TOO_LONG = 414;
+ public const STATUS_CODE_REQUEST_URI_TOO_LONG = 414;
- const STATUS_CODE_UNSUPPORTED_MEDIA_TYPE = 415;
+ public const STATUS_CODE_UNSUPPORTED_MEDIA_TYPE = 415;
- const STATUS_CODE_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+ public const STATUS_CODE_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
- const STATUS_CODE_EXPECTATION_FAILED = 417;
+ public const STATUS_CODE_EXPECTATION_FAILED = 417;
- const STATUS_CODE_TOO_EARLY = 425;
+ public const STATUS_CODE_TOO_EARLY = 425;
- const STATUS_CODE_TOO_MANY_REQUESTS = 429;
+ public const STATUS_CODE_TOO_MANY_REQUESTS = 429;
- const STATUS_CODE_INTERNAL_SERVER_ERROR = 500;
+ public const STATUS_CODE_INTERNAL_SERVER_ERROR = 500;
- const STATUS_CODE_NOT_IMPLEMENTED = 501;
+ public const STATUS_CODE_NOT_IMPLEMENTED = 501;
- const STATUS_CODE_BAD_GATEWAY = 502;
+ public const STATUS_CODE_BAD_GATEWAY = 502;
- const STATUS_CODE_SERVICE_UNAVAILABLE = 503;
+ public const STATUS_CODE_SERVICE_UNAVAILABLE = 503;
- const STATUS_CODE_GATEWAY_TIMEOUT = 504;
+ public const STATUS_CODE_GATEWAY_TIMEOUT = 504;
- const STATUS_CODE_HTTP_VERSION_NOT_SUPPORTED = 505;
+ public const STATUS_CODE_HTTP_VERSION_NOT_SUPPORTED = 505;
/**
* @var array
@@ -194,13 +194,13 @@ class Response
'application/xml+rss' => true,
];
- const COOKIE_SAMESITE_NONE = 'None';
+ public const COOKIE_SAMESITE_NONE = 'None';
- const COOKIE_SAMESITE_STRICT = 'Strict';
+ public const COOKIE_SAMESITE_STRICT = 'Strict';
- const COOKIE_SAMESITE_LAX = 'Lax';
+ public const COOKIE_SAMESITE_LAX = 'Lax';
- const CHUNK_SIZE = 2000000; //2mb
+ public const CHUNK_SIZE = 2000000; //2mb
/**
* @var int
@@ -526,7 +526,7 @@ protected function end(string $content = null): void
*
* @param string $body
* @param bool $end
- *
+ *
* @return void
*/
public function chunk(string $body = '', bool $end = false): void
diff --git a/src/Route.php b/src/Route.php
index cf6ba482..5936cbbc 100755
--- a/src/Route.php
+++ b/src/Route.php
@@ -26,52 +26,16 @@ class Route extends Hook
protected string $path = '';
/**
- * Alias path
+ * Path params.
*
- * @var null|string
+ * @var array
*/
- protected ?string $aliasPath = null;
+ protected array $pathParams = [];
- /**
- * Array of aliases where key is the path and value is an array of params
- *
- * @var array
- */
- protected array $aliases = [];
-
- /**
- * Is Alias Route?
- *
- * @var bool
- */
- protected bool $isAlias = false;
-
- /**
- * @var int
- */
- public static int $counter = 0;
-
- /**
- * @var int
- */
- protected int $order;
-
- /**
- * @var bool
- */
- protected bool $isActive = true;
-
- /**
- * @param string $method
- * @param string $path
- */
public function __construct(string $method, string $path)
{
- self::$counter++;
-
$this->path($path);
$this->method = $method;
- $this->order = self::$counter;
$this->action = function (): void {
};
}
@@ -79,10 +43,10 @@ public function __construct(string $method, string $path)
/**
* Add path
*
- * @param string $path
- * @return static
+ * @param string $path
+ * @return self
*/
- public function path(string $path): static
+ public function path(string $path): self
{
$this->path = $path;
@@ -92,63 +56,29 @@ public function path(string $path): static
/**
* Add alias
*
- * @param string $path
- * @param array $params
- * @return static
+ * @param string $path
+ * @return self
*/
- public function alias(string $path, array $params = []): static
+ public function alias(string $path): self
{
- $this->aliases[$path] = $params;
+ Router::addRouteAlias($path, $this);
return $this;
}
/**
- * Set isActive
- *
- * @param bool $isActive
- * @return void
- */
- public function setIsActive(bool $isActive): void
- {
- $this->isActive = $isActive;
- }
-
- /**
- * Set isAlias
- *
- * @param bool $isAlias
- * @return void
- */
- public function setIsAlias(bool $isAlias): void
- {
- $this->isAlias = $isAlias;
- }
-
- /**
- * Set hook status
* When set false, hooks for this route will be skipped.
*
- * @param bool $hook
- * @return static
+ * @param bool $hook
+ * @return self
*/
- public function hook(bool $hook = true): static
+ public function hook(bool $hook = true): self
{
$this->hook = $hook;
return $this;
}
- /**
- * When set to false the route will be skipped
- *
- * @return bool
- */
- public function getIsActive(): bool
- {
- return $this->isActive;
- }
-
/**
* Get HTTP Method
*
@@ -170,99 +100,44 @@ public function getPath(): string
}
/**
- * Get Aliases
- *
- * Returns an array where the keys are paths and values are params
- *
- * @return array
- */
- public function getAliases(): array
- {
- return $this->aliases;
- }
-
- /**
- * Get Alias path
- *
- * For backwards compatibility, returns the first alias path
+ * Get hook status
*
- * @return string
+ * @return bool
*/
- public function getAliasPath(): string
+ public function getHook(): bool
{
- if ($this->aliasPath !== null) {
- return $this->aliasPath;
- }
-
- $paths = array_keys($this->aliases);
- if (count($paths) === 0) {
- return '';
- }
-
- return $paths[0];
+ return $this->hook;
}
/**
- * Set Alias path
- *
- * For backwards compatibility, returns the first alias path
+ * Set path param.
*
+ * @param string $key
+ * @param int $index
* @return void
*/
- public function setAliasPath(?string $path): void
+ public function setPathParam(string $key, int $index): void
{
- $this->aliasPath = $path;
- $this->setIsAlias($path !== null);
+ $this->pathParams[$key] = $index;
}
/**
- * Get Alias Params
- *
- * For backwards compatibility, returns the first alias params if no path passed
+ * Get path params.
*
+ * @param \Utopia\Request $request
* @return array
*/
- public function getAliasParams(string $path = null): array
+ public function getPathValues(Request $request): array
{
- if ($path === null) {
- $params = array_values($this->aliases);
- if (count($params) === 0) {
- return [];
- }
+ $pathValues = [];
+ $parts = explode('/', ltrim($request->getURI(), '/'));
- return $params[0];
+ foreach ($this->pathParams as $key => $index) {
+ if (array_key_exists($index, $parts)) {
+ $pathValues[$key] = $parts[$index];
+ }
}
- return $this->aliases[$path];
- }
-
- /**
- * Get is Alias
- *
- * @return bool
- */
- public function getIsAlias(): bool
- {
- return $this->isAlias;
- }
-
- /**
- * Get Route Order ID
- *
- * @return int
- */
- public function getOrder(): int
- {
- return $this->order;
- }
-
- /**
- * Get hook status
- *
- * @return bool
- */
- public function getHook(): bool
- {
- return $this->hook;
+ return $pathValues;
}
}
diff --git a/src/Router.php b/src/Router.php
new file mode 100644
index 00000000..b8820711
--- /dev/null
+++ b/src/Router.php
@@ -0,0 +1,210 @@
+
+ */
+ protected static array $routes = [
+ App::REQUEST_METHOD_GET => [],
+ App::REQUEST_METHOD_POST => [],
+ App::REQUEST_METHOD_PUT => [],
+ App::REQUEST_METHOD_PATCH => [],
+ App::REQUEST_METHOD_DELETE => [],
+ ];
+
+ /**
+ * Contains the positions of all params in the paths of all registered Routes.
+ *
+ * @var array
+ */
+ protected static array $params = [];
+
+ /**
+ * Get all registered routes.
+ *
+ * @return array
+ */
+ public static function getRoutes(): array
+ {
+ return self::$routes;
+ }
+
+ /**
+ * Add route to router.
+ *
+ * @param \Utopia\Route $route
+ * @return void
+ * @throws \Exception
+ */
+ public static function addRoute(Route $route): void
+ {
+ [$path, $params] = self::preparePath($route->getPath());
+
+ if (!array_key_exists($route->getMethod(), self::$routes)) {
+ throw new Exception("Method ({$route->getMethod()}) not supported.");
+ }
+
+ if (array_key_exists($path, self::$routes[$route->getMethod()])) {
+ throw new Exception("Route for ({$route->getMethod()}:{$path}) already registered.");
+ }
+
+ foreach ($params as $key => $index) {
+ $route->setPathParam($key, $index);
+ }
+
+ self::$routes[$route->getMethod()][$path] = $route;
+ }
+
+ /**
+ * Add route to router.
+ *
+ * @param \Utopia\Route $route
+ * @return void
+ * @throws \Exception
+ */
+ public static function addRouteAlias(string $path, Route $route): void
+ {
+ [$alias] = self::preparePath($path);
+
+ if (array_key_exists($alias, self::$routes[$route->getMethod()])) {
+ throw new Exception("Route for ({$route->getMethod()}:{$alias}) already registered.");
+ }
+
+ self::$routes[$route->getMethod()][$alias] = $route;
+ }
+
+ /**
+ * Match route against the method and path.
+ *
+ * @param string $method
+ * @param string $path
+ * @return \Utopia\Route|null
+ */
+ public static function match(string $method, string $path): Route|null
+ {
+ if (!array_key_exists($method, self::$routes)) {
+ return null;
+ }
+
+ $parts = array_values(array_filter(explode('/', $path)));
+ $length = count($parts) - 1;
+ $filteredParams = array_filter(self::$params, fn ($i) => $i <= $length);
+
+ foreach (self::combinations($filteredParams) as $sample) {
+ $sample = array_filter($sample, fn (int $i) => $i <= $length);
+ $match = implode(
+ '/',
+ array_replace(
+ $parts,
+ array_fill_keys($sample, self::PLACEHOLDER_TOKEN)
+ )
+ );
+
+ if (array_key_exists($match, self::$routes[$method])) {
+ return self::$routes[$method][$match];
+ }
+ }
+
+ /**
+ * Match root wildcard.
+ */
+ $match = self::WILDCARD_TOKEN;
+ if (array_key_exists($match, self::$routes[$method])) {
+ return self::$routes[$method][$match];
+ }
+
+ /**
+ * Match wildcard for path segments.
+ */
+ foreach ($parts as $part) {
+ $current = ($current ?? '') . "{$part}/";
+ $match = $current . self::WILDCARD_TOKEN;
+ if (array_key_exists($match, self::$routes[$method])) {
+ return self::$routes[$method][$match];
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all combinations of the given set.
+ *
+ * @param array $set
+ * @return iterable
+ */
+ protected static function combinations(array $set): iterable
+ {
+ yield [];
+
+ $results = [[]];
+
+ foreach ($set as $element) {
+ foreach ($results as $combination) {
+ $ret = array_merge([$element], $combination);
+ $results[] = $ret;
+
+ yield $ret;
+ }
+ }
+ }
+
+ /**
+ * Prepare path for matching
+ *
+ * @param string $path
+ * @return array
+ */
+ protected static function preparePath(string $path): array
+ {
+ $parts = array_values(array_filter(explode('/', $path)));
+ $prepare = '';
+ $params = [];
+
+ foreach ($parts as $key => $part) {
+ if ($key !== 0) {
+ $prepare .= '/';
+ }
+
+ if (str_starts_with($part, ':')) {
+ $prepare .= self::PLACEHOLDER_TOKEN;
+ $params[ltrim($part, ':')] = $key;
+ if (!in_array($key, self::$params)) {
+ self::$params[] = $key;
+ }
+ } else {
+ $prepare .= $part;
+ }
+ }
+
+ return [$prepare, $params];
+ }
+
+ /**
+ * Reset router
+ *
+ * @return void
+ */
+ public static function reset(): void
+ {
+ self::$params = [];
+ self::$routes = [
+ App::REQUEST_METHOD_GET => [],
+ App::REQUEST_METHOD_POST => [],
+ App::REQUEST_METHOD_PUT => [],
+ App::REQUEST_METHOD_PATCH => [],
+ App::REQUEST_METHOD_DELETE => [],
+ ];
+ }
+}
diff --git a/src/Validator.php b/src/Validator.php
index 12544466..d58dfea7 100755
--- a/src/Validator.php
+++ b/src/Validator.php
@@ -4,19 +4,19 @@
abstract class Validator
{
- const TYPE_BOOLEAN = 'boolean';
+ public const TYPE_BOOLEAN = 'boolean';
- const TYPE_INTEGER = 'integer';
+ public const TYPE_INTEGER = 'integer';
- const TYPE_FLOAT = 'double'; /* gettype() returns 'double' for historical reasons */
+ public const TYPE_FLOAT = 'double'; /* gettype() returns 'double' for historical reasons */
- const TYPE_STRING = 'string';
+ public const TYPE_STRING = 'string';
- const TYPE_ARRAY = 'array';
+ public const TYPE_ARRAY = 'array';
- const TYPE_OBJECT = 'object';
+ public const TYPE_OBJECT = 'object';
- const TYPE_MIXED = 'mixed';
+ public const TYPE_MIXED = 'mixed';
/**
* Get Description
diff --git a/src/Validator/Hostname.php b/src/Validator/Hostname.php
index 791b4233..0532baf1 100644
--- a/src/Validator/Hostname.php
+++ b/src/Validator/Hostname.php
@@ -96,13 +96,13 @@ public function isValid(mixed $value): bool
}
// If wildcard symbol used
- if(\str_starts_with($allowedHostname, '*')) {
+ if (\str_starts_with($allowedHostname, '*')) {
// Remove starting * symbol before comparing
$allowedHostname = substr($allowedHostname, 1);
// If rest of hostname match; allow
// Notice allowedHostname still includes starting dot. Root domain is NOT allowed by wildcard.
- if(\str_ends_with($value, $allowedHostname)) {
+ if (\str_ends_with($value, $allowedHostname)) {
return true;
}
}
diff --git a/src/Validator/IP.php b/src/Validator/IP.php
index 3a69dc13..69e1f95c 100644
--- a/src/Validator/IP.php
+++ b/src/Validator/IP.php
@@ -66,7 +66,7 @@ public function isValid($value): bool
if (\filter_var($value, FILTER_VALIDATE_IP)) {
return true;
}
- break;
+ break;
case self::V4:
if (\filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
diff --git a/src/Validator/Nullable.php b/src/Validator/Nullable.php
index a4440e22..3d0d8724 100644
--- a/src/Validator/Nullable.php
+++ b/src/Validator/Nullable.php
@@ -47,7 +47,7 @@ public function getType(): string
}
/**
- * @return Validator
+ * @return Validator
*/
public function getValidator(): Validator
{
diff --git a/src/Validator/Range.php b/src/Validator/Range.php
index d0e7f20f..063d6c8d 100755
--- a/src/Validator/Range.php
+++ b/src/Validator/Range.php
@@ -131,7 +131,7 @@ public function isValid(mixed $value): bool
}
break;
case self::TYPE_FLOAT:
- if (! is_numeric($value) ) {
+ if (! is_numeric($value)) {
return false;
}
$value = $value + 0.0;
diff --git a/src/Validator/Text.php b/src/Validator/Text.php
index 18e6b5ea..49224e70 100644
--- a/src/Validator/Text.php
+++ b/src/Validator/Text.php
@@ -11,11 +11,11 @@
*/
class Text extends Validator
{
- const NUMBERS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
+ public const NUMBERS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
- const ALPHABET_UPPER = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
+ public const ALPHABET_UPPER = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
- const ALPHABET_LOWER = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
+ public const ALPHABET_LOWER = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
/**
* @var int
diff --git a/src/View.php b/src/View.php
index 13e6f802..3445e8d8 100755
--- a/src/View.php
+++ b/src/View.php
@@ -6,9 +6,9 @@
class View
{
- const FILTER_ESCAPE = 'escape';
+ public const FILTER_ESCAPE = 'escape';
- const FILTER_NL2P = 'nl2p';
+ public const FILTER_NL2P = 'nl2p';
/**
* @var self|null
diff --git a/tests/AppTest.php b/tests/AppTest.php
index 2fab7985..33d21d9d 100755
--- a/tests/AppTest.php
+++ b/tests/AppTest.php
@@ -114,19 +114,6 @@ public function testCanGetResources(): void
$this->assertEquals('x-def-y-def-'.$resource, $result);
}
- public function testCanAddRoute(): void
- {
- $getRoute = App::addRoute(App::REQUEST_METHOD_GET, '/addroute');
- $postRoute = App::addRoute(App::REQUEST_METHOD_POST, '/addroute');
-
- $routes = App::getRoutes();
- $this->assertEquals($getRoute, $routes[App::REQUEST_METHOD_GET]['/addroute']);
- $this->assertEquals($postRoute, $routes[App::REQUEST_METHOD_POST]['/addroute']);
-
- $this->expectExceptionMessage('Invalid Request Method');
- App::addRoute('REST', '/addroute');
- }
-
public function testCanExecuteRoute(): void
{
App::setResource('rand', fn () => rand());
@@ -143,7 +130,6 @@ public function testCanExecuteRoute(): void
$route = new Route('GET', '/path');
$route
- ->alias('/path1', ['x' => 'x-def-1', 'y' => 'y-def-1'])
->param('x', 'x-def', new Text(200), 'x param', true)
->param('y', 'y-def', new Text(200), 'y param', true)
->action(function ($x, $y) {
@@ -155,17 +141,6 @@ public function testCanExecuteRoute(): void
$result = \ob_get_contents();
\ob_end_clean();
- // test alias with param override
- $route->setIsAlias(true);
-
- \ob_start();
- $this->app->execute($route, new Request());
- $result1 = \ob_get_contents();
- \ob_end_clean();
-
- $this->assertEquals('x-def-y-def', $result);
- $this->assertEquals('x-def-1-y-def-1', $result1);
-
// With Params
$route = new Route('GET', '/path');
@@ -409,9 +384,7 @@ public function providerRouteMatching(): array
'DELETE request' => [App::REQUEST_METHOD_DELETE, '/path1'],
'1 separators' => [App::REQUEST_METHOD_GET, '/a/'],
'2 separators' => [App::REQUEST_METHOD_GET, '/a/b'],
- '3 separators' => [App::REQUEST_METHOD_GET, '/a/b/c'],
- 'trailing wildcard' => [App::REQUEST_METHOD_GET, '/wildcard/*', '/wildcard/lorem/ipsum'],
- 'trailing wildcard - root' => [App::REQUEST_METHOD_GET, '/wildcard/*', '/wildcard'],
+ '3 separators' => [App::REQUEST_METHOD_GET, '/a/b/c']
];
}
@@ -535,75 +508,6 @@ public function testCanRunRequest(): void
$this->assertStringNotContainsString('HELLO', $result);
}
- public function testCanRunAliasEndpoint(): void
- {
- // Test head requests
- App::get('/storage/buckets/:bucketId/files/:fileId')
- ->alias('/storage/files/:fileId', [
- 'bucketId' => 'default',
- ])
- ->param('bucketId', 'bucketid', new Text(100), 'My id', false)
- ->param('fileId', 'fileId', new Text(100), 'My id', false)
- ->inject('response')
- ->action(function ($bucketId, $fileId, $response) {
- $response->send('HELLO');
- });
-
- $_SERVER['REQUEST_METHOD'] = 'HEAD';
- $_SERVER['REQUEST_URI'] = '/storage/files/myfileid';
-
- // Test Alias
- \ob_start();
- $this->app->run(new Request(), new Response());
- $result1 = \ob_get_contents();
- \ob_end_clean();
-
- $this->assertStringNotContainsString('HELLO', $result1);
- }
-
- public function providerAliases(): array
- {
- return [
- '/real/:param1' => ['/real/p1', 'p1'],
- '/alias' => ['/alias', 'default'],
- '/another/:param1' => ['/another/a', 'a'],
- '/param2' => ['/param2', 'param2'],
- ];
- }
-
- /**
- * @dataProvider providerAliases
- */
- public function testMultipleAliases(string $path, string $expected): void
- {
- App::get('/real/:param1')
- ->alias('/alias', [
- 'param1' => 'default',
- ])
- ->alias('/another/:param1')
- ->alias('/param2', [
- 'param1' => 'param2',
- ])
- ->param('param1', '', new Text(100), 'a param', false)
- ->inject('response')
- ->action(function ($param1, $response) {
- echo $param1;
- });
-
- $routes = App::getRoutes();
- $this->assertContains('/real/:param1', array_keys($routes[App::REQUEST_METHOD_GET]));
-
- $_SERVER['REQUEST_METHOD'] = 'GET';
-
- $_SERVER['REQUEST_URI'] = $path;
- \ob_start();
- $this->app->run(new Request(), new Response());
- $result = \ob_get_contents();
- \ob_end_clean();
-
- $this->assertEquals($expected, $result);
- }
-
public function testWildcardRoute(): void
{
$method = $_SERVER['REQUEST_METHOD'] ?? null;
@@ -664,4 +568,4 @@ public function testWildcardRoute(): void
$_SERVER['REQUEST_URI'] = $uri;
}
-}
\ No newline at end of file
+}
diff --git a/tests/RouteTest.php b/tests/RouteTest.php
index 4f2e5741..cbdea1c3 100755
--- a/tests/RouteTest.php
+++ b/tests/RouteTest.php
@@ -28,51 +28,6 @@ public function testCanGetAndSetPath()
$this->assertEquals('/path', $this->route->getPath());
}
- public function testCanSetAndGetAlias()
- {
- $this->assertEquals('', $this->route->getAliasPath());
- $this->assertEquals([], $this->route->getAliasParams());
-
- $params = [
- 'pathId' => 'hello',
- ];
- $this->route->alias('/path1', $params);
-
- $this->assertEquals('/path1', $this->route->getAliasPath());
- $this->assertEquals($params, $this->route->getAliasParams());
- }
-
- public function testCanSetAndGetAliases()
- {
- $this->assertEquals('', $this->route->getAliasPath());
- $this->assertEquals([], $this->route->getAliasParams());
-
- $path1Params = [
- 'pathId' => 'hello',
- ];
- $this->route->alias('/path1', $path1Params);
-
- $path2Params = [
- 'anotherPathId' => 'world',
- ];
- $this->route->alias('/path2', $path2Params);
-
- $aliases = $this->route->getAliases();
-
- $this->assertEquals(
- [
- '/path1' => $path1Params,
- '/path2' => $path2Params,
- ],
- $aliases
- );
-
- $this->assertEquals('/path1', $this->route->getAliasPath());
- $this->assertEquals($path1Params, $this->route->getAliasParams());
- $this->assertEquals($path1Params, $this->route->getAliasParams('/path1'));
- $this->assertEquals($path2Params, $this->route->getAliasParams('/path2'));
- }
-
public function testCanSetAndGetDescription()
{
$this->assertEquals('', $this->route->getDesc());
@@ -145,17 +100,6 @@ public function testCanSetAndGetHooks()
$this->assertFalse($this->route->getHook());
}
- public function testCanSetAndGetIsActive()
- {
- $this->assertTrue($this->route->getIsActive());
- $this->route->setIsActive(true);
- $this->assertTrue($this->route->getIsActive());
- $this->route->setIsActive(false);
- $this->assertFalse($this->route->getIsActive());
- $this->route->setIsActive(true);
- $this->assertTrue($this->route->getIsActive());
- }
-
public function tearDown(): void
{
$this->route = null;
diff --git a/tests/RouterBench.php b/tests/RouterBench.php
new file mode 100644
index 00000000..466506d6
--- /dev/null
+++ b/tests/RouterBench.php
@@ -0,0 +1,58 @@
+ '/blog',
+ 'nested' => '/blog/authors',
+ 'single param' => '/blog/lorem-ipsum',
+ 'single param with nested' => '/blog/lorem-ipsum/comments',
+ 'multiple params' => '/blog/lorem-ipsum/comments/1337',
+ 'long' => '/blog/lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/Quisque/dolor/nisi/gravida/non/malesuada/eget/tincidunt/vitae/eros/Donec/hendrerit/mollis/purus/non/efficitur/augue/efficitur/sed/Praesent/a/tempus/felis/et/elementum/lorem/Vestibulum/ante/ipsum/primis/in/faucibus/orci/luctus/et/ultrices/posuere/cubilia/curae/Ut/luctus/ultrices/ligula/vulputate/malesuada/magna/pellentesque/eget/Mauris/at/sodales/orci/Mauris/efficitur/volutpat/est/in/faucibus/Donec/non/eleifend/nibh/Nunc/cursus/ornare/sollicitudin/Nullam/pellentesque/placerat/justo/ac/eleifend/tortor/imperdiet/quis/Nullam/tincidunt/non/justo/ut/pulvinar/Suspendisse/laoreet/tempus/nulla/eu/aliquet/Proin/metus/erat/facilisis/in/euismod/sit/amet/mollis/ac/nisi/Nulla/facilisi'
+ ] as $name => $route) {
+ yield $name => ['route' => $route];
+ }
+ }
+
+ #[BeforeMethods('setUpRouter')]
+ #[AfterMethods('tearDown')]
+ #[Iterations(50)]
+ #[Assert('mode(variant.time.avg) < 0.1 ms')]
+ #[ParamProviders('provideRoutesToMatch')]
+ public function benchRouter(array $data): void
+ {
+ Router::match(App::REQUEST_METHOD_GET, $data['route']);
+ }
+}
diff --git a/tests/RouterTest.php b/tests/RouterTest.php
new file mode 100644
index 00000000..fcaa93c2
--- /dev/null
+++ b/tests/RouterTest.php
@@ -0,0 +1,145 @@
+assertEquals($routeIndex, Router::match(App::REQUEST_METHOD_GET, '/'));
+ $this->assertEquals($routeAbout, Router::match(App::REQUEST_METHOD_GET, '/about'));
+ $this->assertEquals($routeAboutMe, Router::match(App::REQUEST_METHOD_GET, '/about/me'));
+ }
+
+ public function testCanMatchUrlWithPlaceholder(): void
+ {
+ $routeBlog = new Route(App::REQUEST_METHOD_GET, '/blog');
+ $routeBlogAuthors = new Route(App::REQUEST_METHOD_GET, '/blog/authors');
+ $routeBlogAuthorsComments = new Route(App::REQUEST_METHOD_GET, '/blog/authors/comments');
+ $routeBlogPost = new Route(App::REQUEST_METHOD_GET, '/blog/:post');
+ $routeBlogPostComments = new Route(App::REQUEST_METHOD_GET, '/blog/:post/comments');
+ $routeBlogPostCommentsSingle = new Route(App::REQUEST_METHOD_GET, '/blog/:post/comments/:comment');
+
+ Router::addRoute($routeBlog);
+ Router::addRoute($routeBlogAuthors);
+ Router::addRoute($routeBlogAuthorsComments);
+ Router::addRoute($routeBlogPost);
+ Router::addRoute($routeBlogPostComments);
+ Router::addRoute($routeBlogPostCommentsSingle);
+
+ $this->assertEquals($routeBlog, Router::match(App::REQUEST_METHOD_GET, '/blog'));
+ $this->assertEquals($routeBlogAuthors, Router::match(App::REQUEST_METHOD_GET, '/blog/authors'));
+ $this->assertEquals($routeBlogAuthorsComments, Router::match(App::REQUEST_METHOD_GET, '/blog/authors/comments'));
+ $this->assertEquals($routeBlogPost, Router::match(App::REQUEST_METHOD_GET, '/blog/test'));
+ $this->assertEquals($routeBlogPostComments, Router::match(App::REQUEST_METHOD_GET, '/blog/test/comments'));
+ $this->assertEquals($routeBlogPostCommentsSingle, Router::match(App::REQUEST_METHOD_GET, '/blog/test/comments/:comment'));
+ }
+
+ public function testCanMatchUrlWithWildcard(): void
+ {
+ $routeIndex = new Route('GET', '/');
+ $routeAbout = new Route('GET', '/about');
+ $routeAboutWildcard = new Route('GET', '/about/*');
+
+ Router::addRoute($routeIndex);
+ Router::addRoute($routeAbout);
+ Router::addRoute($routeAboutWildcard);
+
+ $this->assertEquals($routeIndex, Router::match('GET', '/'));
+ $this->assertEquals($routeAbout, Router::match('GET', '/about'));
+ $this->assertEquals($routeAboutWildcard, Router::match('GET', '/about/me'));
+ $this->assertEquals($routeAboutWildcard, Router::match('GET', '/about/you'));
+ $this->assertEquals($routeAboutWildcard, Router::match('GET', '/about/me/myself/i'));
+ }
+
+ public function testCanMatchHttpMethod(): void
+ {
+ $routeGET = new Route(App::REQUEST_METHOD_GET, '/');
+ $routePOST = new Route(App::REQUEST_METHOD_POST, '/');
+
+ Router::addRoute($routeGET);
+ Router::addRoute($routePOST);
+
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/'));
+ $this->assertEquals($routePOST, Router::match(App::REQUEST_METHOD_POST, '/'));
+
+ $this->assertNotEquals($routeGET, Router::match(App::REQUEST_METHOD_POST, '/'));
+ $this->assertNotEquals($routePOST, Router::match(App::REQUEST_METHOD_GET, '/'));
+ }
+
+ public function testCanMatchAlias(): void
+ {
+ $routeGET = new Route(App::REQUEST_METHOD_GET, '/target');
+ $routeGET
+ ->alias('/alias')
+ ->alias('/alias2');
+
+ Router::addRoute($routeGET);
+
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/target'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/alias'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/alias2'));
+ }
+
+ public function testCanMatchMix(): void
+ {
+ $routeGET = new Route(App::REQUEST_METHOD_GET, '/');
+ $routeGET
+ ->alias('/console/*')
+ ->alias('/auth/*')
+ ->alias('/invite')
+ ->alias('/login')
+ ->alias('/recover')
+ ->alias('/register/*');
+
+ Router::addRoute($routeGET);
+
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/console'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/invite'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/login'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/recover'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/console/lorem/ipsum/dolor'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/auth/lorem/ipsum'));
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/register/lorem/ipsum'));
+ }
+
+ public function testCanMatchFilename(): void
+ {
+ $routeGET = new Route(App::REQUEST_METHOD_GET, '/robots.txt');
+
+ Router::addRoute($routeGET);
+ $this->assertEquals($routeGET, Router::match(App::REQUEST_METHOD_GET, '/robots.txt'));
+ }
+
+ public function testCannotFindUnknownRouteByPath(): void
+ {
+ $this->assertNull(Router::match(App::REQUEST_METHOD_GET, '/404'));
+ }
+
+ public function testCannotFindUnknownRouteByMethod(): void
+ {
+ $route = new Route(App::REQUEST_METHOD_GET, '/404');
+
+ Router::addRoute($route);
+
+ $this->assertEquals($route, Router::match(App::REQUEST_METHOD_GET, '/404'));
+
+ $this->assertNull(Router::match(App::REQUEST_METHOD_POST, '/404'));
+ }
+}
diff --git a/tests/Validator/HostTest.php b/tests/Validator/HostTest.php
index e9efd5ce..6ad38299 100644
--- a/tests/Validator/HostTest.php
+++ b/tests/Validator/HostTest.php
@@ -19,7 +19,7 @@ class HostTest extends TestCase
{
protected Host $host;
- public function setUp():void
+ public function setUp(): void
{
$this->host = new Host(['example.io', 'subdomain.example.test', 'localhost']);
}
diff --git a/tests/Validator/URLTest.php b/tests/Validator/URLTest.php
index 30c17fba..e7bad1b5 100644
--- a/tests/Validator/URLTest.php
+++ b/tests/Validator/URLTest.php
@@ -19,12 +19,12 @@ class URLTest extends TestCase
{
protected ?URL $url;
- public function setUp():void
+ public function setUp(): void
{
$this->url = new URL();
}
- public function tearDown():void
+ public function tearDown(): void
{
$this->url = null;
}
@@ -36,7 +36,7 @@ public function testIsValid(): void
$this->assertEquals(true, $this->url->isValid('https://example.com'));
$this->assertEquals(true, $this->url->isValid('htts://example.com')); // does not validate protocol
$this->assertEquals(false, $this->url->isValid('example.com')); // though, requires some kind of protocol
- $this->assertEquals(false, $this->url->isValid('http:/example.com'));
+ $this->assertEquals(false, $this->url->isValid('http:/example.com'));
$this->assertEquals(true, $this->url->isValid('http://exa-mple.com'));
$this->assertEquals(false, $this->url->isValid('htt@s://example.com'));
$this->assertEquals(true, $this->url->isValid('http://www.example.com/foo%2\u00c2\u00a9zbar'));
diff --git a/tests/e2e/Client.php b/tests/e2e/Client.php
index efec2976..662d860d 100644
--- a/tests/e2e/Client.php
+++ b/tests/e2e/Client.php
@@ -6,23 +6,23 @@
class Client
{
- const METHOD_GET = 'GET';
+ public const METHOD_GET = 'GET';
- const METHOD_POST = 'POST';
+ public const METHOD_POST = 'POST';
- const METHOD_PUT = 'PUT';
+ public const METHOD_PUT = 'PUT';
- const METHOD_PATCH = 'PATCH';
+ public const METHOD_PATCH = 'PATCH';
- const METHOD_DELETE = 'DELETE';
+ public const METHOD_DELETE = 'DELETE';
- const METHOD_HEAD = 'HEAD';
+ public const METHOD_HEAD = 'HEAD';
- const METHOD_OPTIONS = 'OPTIONS';
+ public const METHOD_OPTIONS = 'OPTIONS';
- const METHOD_CONNECT = 'CONNECT';
+ public const METHOD_CONNECT = 'CONNECT';
- const METHOD_TRACE = 'TRACE';
+ public const METHOD_TRACE = 'TRACE';
/**
* Service host name
diff --git a/tests/e2e/ResponseTest.php b/tests/e2e/ResponseTest.php
index a2f684da..878cc23f 100644
--- a/tests/e2e/ResponseTest.php
+++ b/tests/e2e/ResponseTest.php
@@ -20,6 +20,12 @@ public function testResponse()
$this->assertEquals('Hello World!', $response['body']);
}
+ public function testResponseValue()
+ {
+ $response = $this->client->call(Client::METHOD_GET, '/value/123');
+ $this->assertEquals('123', $response['body']);
+ }
+
public function testChunkResponse()
{
$response = $this->client->call(Client::METHOD_GET, '/chunked');
@@ -31,4 +37,10 @@ public function testRedirect()
$response = $this->client->call(Client::METHOD_GET, '/redirect');
$this->assertEquals('Hello World!', $response['body']);
}
+
+ public function testFile()
+ {
+ $response = $this->client->call(Client::METHOD_GET, '/humans.txt');
+ $this->assertEquals(204, $response['headers']['status-code']);
+ }
}
diff --git a/tests/e2e/server.php b/tests/e2e/server.php
index 33cb9f00..cef864ee 100644
--- a/tests/e2e/server.php
+++ b/tests/e2e/server.php
@@ -5,19 +5,27 @@
use Utopia\App;
use Utopia\Request;
use Utopia\Response;
+use Utopia\Validator\Text;
-ini_set('memory_limit', '512M');
-ini_set('display_errors', 1);
-ini_set('display_startup_errors', 1);
-ini_set('display_socket_timeout', -1);
+ini_set('memory_limit', '1024M');
+ini_set('display_errors', '1');
+ini_set('display_startup_errors', '1');
+ini_set('display_socket_timeout', '-1');
error_reporting(E_ALL);
App::get('/')
->inject('response')
- ->action(function ($response) {
+ ->action(function (Response $response) {
$response->send('Hello World!');
});
+App::get('/value/:value')
+ ->param('value', '', new Text(64))
+ ->inject('response')
+ ->action(function (string $value, Response $response) {
+ $response->send($value);
+ });
+
App::get('/chunked')
->inject('response')
->action(function (Response $response) {
@@ -32,6 +40,12 @@
$response->redirect('/');
});
+App::get('/humans.txt')
+ ->inject('response')
+ ->action(function (Response $response) {
+ $response->noContent();
+ });
+
$request = new Request();
$response = new Response();