From e191d6e5d33dad409829e066bcfe671d33259c09 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 9 Jun 2025 14:04:40 +0200 Subject: [PATCH 1/2] tec: Update the dependencie --- composer.lock | 76 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index b417596..99025dd 100644 --- a/composer.lock +++ b/composer.lock @@ -196,16 +196,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", "shasum": "" }, "require": { @@ -248,9 +248,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-05-31T08:24:38+00:00" }, { "name": "phar-io/manifest", @@ -372,16 +372,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.14", + "version": "2.1.17", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2" + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f2e03099cac24ff3b379864d171c5acbfc6b9a2", - "reference": "8f2e03099cac24ff3b379864d171c5acbfc6b9a2", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", "shasum": "" }, "require": { @@ -426,7 +426,7 @@ "type": "github" } ], - "time": "2025-05-02T15:32:28+00:00" + "time": "2025-05-21T20:55:28+00:00" }, { "name": "phpunit/php-code-coverage", @@ -753,16 +753,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.20", + "version": "11.5.22", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f" + "reference": "4cd72faaa8f811e4cc63040cba167757660a5538" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f", - "reference": "e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4cd72faaa8f811e4cc63040cba167757660a5538", + "reference": "4cd72faaa8f811e4cc63040cba167757660a5538", "shasum": "" }, "require": { @@ -785,7 +785,7 @@ "sebastian/code-unit": "^3.0.3", "sebastian/comparator": "^6.3.1", "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.0", + "sebastian/environment": "^7.2.1", "sebastian/exporter": "^6.3.0", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", @@ -834,7 +834,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.22" }, "funding": [ { @@ -858,25 +858,25 @@ "type": "tidelift" } ], - "time": "2025-05-11T06:39:52+00:00" + "time": "2025-06-06T02:48:05+00:00" }, { "name": "rector/rector", - "version": "2.0.16", + "version": "2.0.17", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2" + "reference": "caa4ffda1d48bde44434e6ba95d132ec32e7fd40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", - "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/caa4ffda1d48bde44434e6ba95d132ec32e7fd40", + "reference": "caa4ffda1d48bde44434e6ba95d132ec32e7fd40", "shasum": "" }, "require": { "php": "^7.4|^8.0", - "phpstan/phpstan": "^2.1.14" + "phpstan/phpstan": "^2.1.17" }, "conflict": { "rector/rector-doctrine": "*", @@ -909,7 +909,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.0.16" + "source": "https://github.com/rectorphp/rector/tree/2.0.17" }, "funding": [ { @@ -917,7 +917,7 @@ "type": "github" } ], - "time": "2025-05-12T16:37:16+00:00" + "time": "2025-05-30T10:59:08+00:00" }, { "name": "sebastian/cli-parser", @@ -1296,23 +1296,23 @@ }, { "name": "sebastian/environment", - "version": "7.2.0", + "version": "7.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", - "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "suggest": { "ext-posix": "*" @@ -1348,15 +1348,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2024-07-03T04:54:44+00:00" + "time": "2025-05-21T11:55:47+00:00" }, { "name": "sebastian/exporter", From 3cd2c7bcbf3220313b450129b8641900a5dc7821 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 9 Jun 2025 14:22:32 +0200 Subject: [PATCH 2/2] tec: Upgrade to Minz 2.0 --- composer.json | 2 +- composer.lock | 325 +++++++++++++++++++++++++++++- src/Application.php | 4 +- src/controllers/Home.php | 2 +- src/controllers/Requests.php | 39 ++-- src/models/Content.php | 8 +- tests/models/SubscriptionTest.php | 4 +- 7 files changed, 344 insertions(+), 40 deletions(-) diff --git a/composer.json b/composer.json index 11e931a..0e5c674 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "ext-pcntl": "*", "ext-pdo": "*", "ext-pdo_sqlite": "*", - "flus/minz": "^1.0" + "flus/minz": "^2.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 99025dd..d2c48a0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,25 +4,26 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "247f85356439a50125044e9e8e55cfd0", + "content-hash": "6e8c465d22c462a6ccdea7bbf380601e", "packages": [ { "name": "flus/minz", - "version": "1.1.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/flusio/Minz.git", - "reference": "7f0f50da7b4dd3f74b33709a4a9ab29041a93935" + "reference": "3eb6db53dccab8612477b5873f87069503d87af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/flusio/Minz/zipball/7f0f50da7b4dd3f74b33709a4a9ab29041a93935", - "reference": "7f0f50da7b4dd3f74b33709a4a9ab29041a93935", + "url": "https://api.github.com/repos/flusio/Minz/zipball/3eb6db53dccab8612477b5873f87069503d87af6", + "reference": "3eb6db53dccab8612477b5873f87069503d87af6", "shasum": "" }, "require": { "php": ">=8.2", - "phpmailer/phpmailer": "^6.9" + "phpmailer/phpmailer": "^6.9", + "twig/twig": "^3.21" }, "require-dev": { "phpstan/phpstan": "^2.0", @@ -33,7 +34,7 @@ "type": "library", "autoload": { "files": [ - "src/Output/view_helpers.php" + "src/Template/simple_template_helpers.php" ], "psr-4": { "Minz\\": "src/" @@ -47,9 +48,9 @@ "homepage": "https://github.com/flusio/Minz", "support": { "issues": "https://github.com/flusio/Minz/issues", - "source": "https://github.com/flusio/Minz/tree/1.1.0" + "source": "https://github.com/flusio/Minz/tree/2.0.1" }, - "time": "2025-04-30T12:59:00+00:00" + "time": "2025-05-29T16:15:27+00:00" }, { "name": "phpmailer/phpmailer", @@ -131,6 +132,312 @@ } ], "time": "2025-04-24T15:19:31+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "twig/twig", + "version": "v3.21.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/285123877d4dd97dd7c11842ac5fb7e86e60d81d", + "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.21.1" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2025-05-03T07:21:55+00:00" } ], "packages-dev": [ diff --git a/src/Application.php b/src/Application.php index c5ae77b..42c34c1 100644 --- a/src/Application.php +++ b/src/Application.php @@ -42,7 +42,7 @@ private function initCli(Request $request): void { $router = Router::loadCli(); - $bin = $request->param('bin'); + $bin = $request->parameters->getString('bin', ''); $bin = $bin === 'cli' ? 'php cli' : $bin; $current_command = $request->path(); @@ -55,7 +55,7 @@ private function initCli(Request $request): void 'controller_namespace' => '\\Webubbub\\cli', ]); - \Minz\Output\View::declareDefaultVariables([ + \Minz\Template\Simple::addGlobals([ 'error' => null, 'bin' => $bin, 'current_command' => $current_command, diff --git a/src/controllers/Home.php b/src/controllers/Home.php index 42e23ed..8723d02 100644 --- a/src/controllers/Home.php +++ b/src/controllers/Home.php @@ -28,7 +28,7 @@ public function index(Request $request): Response */ public function dummySubscriber(Request $request): Response { - $challenge = $request->param('hub_challenge', ''); + $challenge = $request->parameters->getString('hub_challenge', ''); return Response::ok('home/dummySubscriber.txt', [ 'challenge' => $challenge, ]); diff --git a/src/controllers/Requests.php b/src/controllers/Requests.php index 9e61972..43ae335 100644 --- a/src/controllers/Requests.php +++ b/src/controllers/Requests.php @@ -32,7 +32,7 @@ public function handle(Request $request): Response // reasons, PHP replaces those dots by underscores. Meh! // See https://www.php.net/variables.external#language.variables.external.dot-in-names - $mode = $request->param('hub_mode', ''); + $mode = $request->parameters->getString('hub_mode', ''); if ($mode === 'subscribe') { return $this->subscribe($request); @@ -63,13 +63,13 @@ public function handle(Request $request): Response */ public function subscribe(Request $request): Response { - $callback = $request->param('hub_callback', ''); - $topic = $request->param('hub_topic', ''); - $lease_seconds = $request->paramInteger( + $callback = $request->parameters->getString('hub_callback', ''); + $topic = $request->parameters->getString('hub_topic', ''); + $lease_seconds = $request->parameters->getInteger( 'hub_lease_seconds', models\Subscription::DEFAULT_LEASE_SECONDS ); - $secret = $request->param('hub_secret'); + $secret = $request->parameters->getString('hub_secret'); if ($secret === '') { return Response::badRequest('requests/error.txt', [ @@ -91,10 +91,9 @@ public function subscribe(Request $request): Response $secret ); - $errors = $subscription->validate(); - if ($errors) { + if (!$subscription->validate()) { return Response::badRequest('requests/error.txt', [ - 'errors' => $errors, + 'errors' => $subscription->errors(), ]); } @@ -103,10 +102,9 @@ public function subscribe(Request $request): Response // Subscription renewal $subscription->renew($lease_seconds, $secret); - $errors = $subscription->validate(); - if ($errors) { + if (!$subscription->validate()) { return Response::badRequest('requests/error.txt', [ - 'errors' => $errors, + 'errors' => $subscription->errors(), ]); } @@ -129,8 +127,8 @@ public function subscribe(Request $request): Response */ public function unsubscribe(Request $request): Response { - $callback = $request->param('hub_callback', ''); - $topic = $request->param('hub_topic', ''); + $callback = $request->parameters->getString('hub_callback', ''); + $topic = $request->parameters->getString('hub_topic', ''); $subscription = models\Subscription::findBy([ 'callback' => $callback, @@ -169,10 +167,10 @@ public function unsubscribe(Request $request): Response */ public function publish(Request $request): Response { - $url = $request->param('hub_url', ''); + $url = $request->parameters->getString('hub_url', ''); if ($url === '') { - $url = $request->param('hub_topic', ''); + $url = $request->parameters->getString('hub_topic', ''); } $content = models\Content::findBy([ @@ -187,16 +185,9 @@ public function publish(Request $request): Response $content = new models\Content($url); - if (!$content->isAllowed()) { + if (!$content->validate()) { return Response::badRequest('requests/error.txt', [ - 'errors' => ["url \"{$url}\" is not authorized"], - ]); - } - - $errors = $content->validate(); - if ($errors) { - return Response::badRequest('requests/error.txt', [ - 'errors' => $errors, + 'errors' => $content->errors(), ]); } diff --git a/src/models/Content.php b/src/models/Content.php index 64ec1c5..8fc54b9 100644 --- a/src/models/Content.php +++ b/src/models/Content.php @@ -89,9 +89,13 @@ public function deliver(): void /** * Return wheter a content is allowed on the hub or not. */ - public function isAllowed(): bool + #[Validable\Check] + public function checkIsAllowed(): void { - return utils\AllowedOriginHelper::isOriginAllowed($this->url); + $is_valid = utils\AllowedOriginHelper::isOriginAllowed($this->url); + if (!$is_valid) { + $this->addError('url', 'url_not_allowed', "url \"{$this->url}\" is not authorized"); + } } /** diff --git a/tests/models/SubscriptionTest.php b/tests/models/SubscriptionTest.php index 2d6c12c..8b45a97 100644 --- a/tests/models/SubscriptionTest.php +++ b/tests/models/SubscriptionTest.php @@ -129,8 +129,10 @@ public function testRenewFailsIfInvalidSecret(): void $secret = str_repeat('a', 201); $subscription->renew(Subscription::DEFAULT_LEASE_SECONDS, $secret); - $errors = $subscription->validate(); + $is_valid = $subscription->validate(); + $this->assertFalse($is_valid); + $errors = $subscription->errors(); $this->assertArrayHasKey('pending_secret', $errors); }