From de282030b878a254acbf24bae517ba3dc8aae7d0 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Sun, 31 Aug 2025 16:19:26 +0200 Subject: [PATCH 01/19] Update PHP version constraint to allow 8.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f67965d96..5c8937a87 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "license": "MIT", "type": "project", "require": { - "php": "8.3.*", + "php": "^8.3 || ^8.4", "algolia/scout-extended": "^3.1", "blade-ui-kit/blade-heroicons": "^2.3", "blade-ui-kit/blade-icons": "^1.6", From 9d090abd7354e9590e1dc5c08154d6dc4db89e03 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Sun, 31 Aug 2025 16:53:17 +0200 Subject: [PATCH 02/19] composer update --- composer.lock | 551 +++++++++++++++++++++++++++++--------------------- 1 file changed, 316 insertions(+), 235 deletions(-) diff --git a/composer.lock b/composer.lock index db9a83443..eb33b9826 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fd53a824d0eb289a65ca8e5ad86e829b", + "content-hash": "d831dd60822af33558c88503219583af", "packages": [ { "name": "abraham/twitteroauth", @@ -279,16 +279,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.343.13", + "version": "3.356.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "eb50d111a09ef39675358e74801260ac129ee346" + "reference": "3efa8c62c11fedb17b90f60b2d3a9f815b406e63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/eb50d111a09ef39675358e74801260ac129ee346", - "reference": "eb50d111a09ef39675358e74801260ac129ee346", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3efa8c62c11fedb17b90f60b2d3a9f815b406e63", + "reference": "3efa8c62c11fedb17b90f60b2d3a9f815b406e63", "shasum": "" }, "require": { @@ -370,9 +370,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.343.13" + "source": "https://github.com/aws/aws-sdk-php/tree/3.356.8" }, - "time": "2025-05-16T18:24:39+00:00" + "time": "2025-08-29T18:06:18+00:00" }, { "name": "blade-ui-kit/blade-heroicons", @@ -726,16 +726,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.5.6", + "version": "1.5.8", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "f65c239c970e7f072f067ab78646e9f0b2935175" + "reference": "719026bb30813accb68271fee7e39552a58e9f65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/f65c239c970e7f072f067ab78646e9f0b2935175", - "reference": "f65c239c970e7f072f067ab78646e9f0b2935175", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/719026bb30813accb68271fee7e39552a58e9f65", + "reference": "719026bb30813accb68271fee7e39552a58e9f65", "shasum": "" }, "require": { @@ -782,7 +782,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.6" + "source": "https://github.com/composer/ca-bundle/tree/1.5.8" }, "funding": [ { @@ -792,13 +792,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2025-03-06T14:30:56+00:00" + "time": "2025-08-20T18:49:47+00:00" }, { "name": "dflydev/dot-access-data", @@ -2826,16 +2822,16 @@ }, { "name": "laravel/scout", - "version": "v10.15.0", + "version": "v10.19.0", "source": { "type": "git", "url": "https://github.com/laravel/scout.git", - "reference": "102fe09ae1c045c6f9cf1b3a2234e1fadb2198f2" + "reference": "996b2a8b5ccc583e7df667c8aac924a46bc8bdd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/scout/zipball/102fe09ae1c045c6f9cf1b3a2234e1fadb2198f2", - "reference": "102fe09ae1c045c6f9cf1b3a2234e1fadb2198f2", + "url": "https://api.github.com/repos/laravel/scout/zipball/996b2a8b5ccc583e7df667c8aac924a46bc8bdd3", + "reference": "996b2a8b5ccc583e7df667c8aac924a46bc8bdd3", "shasum": "" }, "require": { @@ -2859,7 +2855,7 @@ "orchestra/testbench": "^7.31|^8.11|^9.0|^10.0", "php-http/guzzle7-adapter": "^1.0", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.3|^10.4", + "phpunit/phpunit": "^9.3|^10.4|^11.5", "typesense/typesense-php": "^4.9.3" }, "suggest": { @@ -2903,7 +2899,7 @@ "issues": "https://github.com/laravel/scout/issues", "source": "https://github.com/laravel/scout" }, - "time": "2025-05-13T13:34:05+00:00" + "time": "2025-08-26T14:24:24+00:00" }, { "name": "laravel/serializable-closure", @@ -3993,16 +3989,16 @@ }, { "name": "lorisleiva/cron-translator", - "version": "v0.4.5", + "version": "v0.4.6", "source": { "type": "git", "url": "https://github.com/lorisleiva/cron-translator.git", - "reference": "3c7d8e3984c845a33bc1ae3cdc36c0b38f4783e9" + "reference": "082e3cd493de13bd5816bfdda484d07bb2326768" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorisleiva/cron-translator/zipball/3c7d8e3984c845a33bc1ae3cdc36c0b38f4783e9", - "reference": "3c7d8e3984c845a33bc1ae3cdc36c0b38f4783e9", + "url": "https://api.github.com/repos/lorisleiva/cron-translator/zipball/082e3cd493de13bd5816bfdda484d07bb2326768", + "reference": "082e3cd493de13bd5816bfdda484d07bb2326768", "shasum": "" }, "require": { @@ -4037,7 +4033,7 @@ ], "support": { "issues": "https://github.com/lorisleiva/cron-translator/issues", - "source": "https://github.com/lorisleiva/cron-translator/tree/v0.4.5" + "source": "https://github.com/lorisleiva/cron-translator/tree/v0.4.6" }, "funding": [ { @@ -4045,7 +4041,7 @@ "type": "github" } ], - "time": "2024-02-02T10:51:56+00:00" + "time": "2025-06-23T10:51:20+00:00" }, { "name": "masterminds/html5", @@ -4699,16 +4695,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" }, "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/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "shasum": "" }, "require": { @@ -4727,7 +4723,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -4751,9 +4747,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.6.1" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-08-13T20:13:15+00:00" }, { "name": "nunomaduro/termwind", @@ -5807,16 +5803,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.8", + "version": "v0.12.10", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625" + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/85057ceedee50c49d4f6ecaff73ee96adb3b3625", - "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/6e80abe6f2257121f1eb9a4c55bf29d921025b22", + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22", "shasum": "" }, "require": { @@ -5866,12 +5862,11 @@ "authors": [ { "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "email": "justin@justinhileman.info" } ], "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", + "homepage": "https://psysh.org", "keywords": [ "REPL", "console", @@ -5880,9 +5875,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.8" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.10" }, - "time": "2025-03-16T03:05:19+00:00" + "time": "2025-08-04T12:39:37+00:00" }, { "name": "ralouphie/getallheaders", @@ -6133,16 +6128,16 @@ }, { "name": "sentry/sentry", - "version": "4.14.1", + "version": "4.15.1", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda" + "reference": "0d09baf3700869ec4b723c95eb466de56c3d74b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/a28c4a6f5fda2bf730789a638501d7a737a64eda", - "reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/0d09baf3700869ec4b723c95eb466de56c3d74b6", + "reference": "0d09baf3700869ec4b723c95eb466de56c3d74b6", "shasum": "" }, "require": { @@ -6206,7 +6201,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.14.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.15.1" }, "funding": [ { @@ -6218,7 +6213,7 @@ "type": "custom" } ], - "time": "2025-06-23T15:25:52+00:00" + "time": "2025-08-28T15:45:14+00:00" }, { "name": "sentry/sentry-laravel", @@ -6311,16 +6306,16 @@ }, { "name": "spatie/backtrace", - "version": "1.7.4", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/spatie/backtrace.git", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe" + "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110", + "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110", "shasum": "" }, "require": { @@ -6358,7 +6353,8 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/backtrace/tree/1.7.4" + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.8.1" }, "funding": [ { @@ -6370,7 +6366,7 @@ "type": "other" } ], - "time": "2025-05-08T15:41:09+00:00" + "time": "2025-08-26T08:22:30+00:00" }, { "name": "spatie/browsershot", @@ -7460,16 +7456,16 @@ }, { "name": "symfony/console", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1" + "reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1", - "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1", + "url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7", + "reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7", "shasum": "" }, "require": { @@ -7534,7 +7530,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.2" + "source": "https://github.com/symfony/console/tree/v7.3.3" }, "funding": [ { @@ -7554,7 +7550,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T17:13:41+00:00" + "time": "2025-08-25T06:35:40+00:00" }, { "name": "symfony/css-selector", @@ -7690,16 +7686,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v7.3.1", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "8b2ee2e06ab99fa5f067b6699296d4e35c156bb9" + "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8b2ee2e06ab99fa5f067b6699296d4e35c156bb9", - "reference": "8b2ee2e06ab99fa5f067b6699296d4e35c156bb9", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/efa076ea0eeff504383ff0dcf827ea5ce15690ba", + "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba", "shasum": "" }, "require": { @@ -7737,7 +7733,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.3.1" + "source": "https://github.com/symfony/dom-crawler/tree/v7.3.3" }, "funding": [ { @@ -7748,12 +7744,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-15T10:07:06+00:00" + "time": "2025-08-06T20:13:54+00:00" }, { "name": "symfony/error-handler", @@ -7838,16 +7838,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.3.0", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", - "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", "shasum": "" }, "require": { @@ -7898,7 +7898,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" }, "funding": [ { @@ -7909,12 +7909,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-22T09:11:45+00:00" + "time": "2025-08-13T11:49:31+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8062,16 +8066,16 @@ }, { "name": "symfony/http-client", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "1c064a0c67749923483216b081066642751cc2c7" + "reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/1c064a0c67749923483216b081066642751cc2c7", - "reference": "1c064a0c67749923483216b081066642751cc2c7", + "url": "https://api.github.com/repos/symfony/http-client/zipball/333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019", + "reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019", "shasum": "" }, "require": { @@ -8079,6 +8083,7 @@ "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -8137,7 +8142,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.3.2" + "source": "https://github.com/symfony/http-client/tree/v7.3.3" }, "funding": [ { @@ -8157,7 +8162,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:36:08+00:00" + "time": "2025-08-27T07:45:05+00:00" }, { "name": "symfony/http-client-contracts", @@ -8239,16 +8244,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6" + "reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6877c122b3a6cc3695849622720054f6e6fa5fa6", - "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/7475561ec27020196c49bb7c4f178d33d7d3dc00", + "reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00", "shasum": "" }, "require": { @@ -8298,7 +8303,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.2" + "source": "https://github.com/symfony/http-foundation/tree/v7.3.3" }, "funding": [ { @@ -8318,20 +8323,20 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-20T08:04:18+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c" + "reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6ecc895559ec0097e221ed2fd5eb44d5fede083c", - "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/72c304de37e1a1cec6d5d12b81187ebd4850a17b", + "reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b", "shasum": "" }, "require": { @@ -8416,7 +8421,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.3.2" + "source": "https://github.com/symfony/http-kernel/tree/v7.3.3" }, "funding": [ { @@ -8436,20 +8441,20 @@ "type": "tidelift" } ], - "time": "2025-07-31T10:45:04+00:00" + "time": "2025-08-29T08:23:45+00:00" }, { "name": "symfony/mailer", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b" + "reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/d43e84d9522345f96ad6283d5dfccc8c1cfc299b", - "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b", + "url": "https://api.github.com/repos/symfony/mailer/zipball/a32f3f45f1990db8c4341d5122a7d3a381c7e575", + "reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575", "shasum": "" }, "require": { @@ -8500,7 +8505,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.3.2" + "source": "https://github.com/symfony/mailer/tree/v7.3.3" }, "funding": [ { @@ -8520,7 +8525,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:36:08+00:00" + "time": "2025-08-13T11:49:31+00:00" }, { "name": "symfony/mailgun-mailer", @@ -8681,16 +8686,16 @@ }, { "name": "symfony/options-resolver", - "version": "v7.3.0", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca" + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca", - "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", "shasum": "" }, "require": { @@ -8728,7 +8733,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.3.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.3.3" }, "funding": [ { @@ -8739,12 +8744,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-04T13:12:05+00:00" + "time": "2025-08-05T10:16:07+00:00" }, { "name": "symfony/polyfill-ctype", @@ -9417,16 +9426,16 @@ }, { "name": "symfony/process", - "version": "v7.3.0", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" + "reference": "32241012d521e2e8a9d713adb0812bb773b907f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", - "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1", + "reference": "32241012d521e2e8a9d713adb0812bb773b907f1", "shasum": "" }, "require": { @@ -9458,7 +9467,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.3.0" + "source": "https://github.com/symfony/process/tree/v7.3.3" }, "funding": [ { @@ -9469,12 +9478,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-17T09:11:12+00:00" + "time": "2025-08-18T09:42:54+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -9729,16 +9742,16 @@ }, { "name": "symfony/string", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", - "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", + "url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", "shasum": "" }, "require": { @@ -9796,7 +9809,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.2" + "source": "https://github.com/symfony/string/tree/v7.3.3" }, "funding": [ { @@ -9816,20 +9829,20 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-25T06:35:40+00:00" }, { "name": "symfony/translation", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90" + "reference": "e0837b4cbcef63c754d89a4806575cada743a38d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/81b48f4daa96272efcce9c7a6c4b58e629df3c90", - "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90", + "url": "https://api.github.com/repos/symfony/translation/zipball/e0837b4cbcef63c754d89a4806575cada743a38d", + "reference": "e0837b4cbcef63c754d89a4806575cada743a38d", "shasum": "" }, "require": { @@ -9896,7 +9909,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.3.2" + "source": "https://github.com/symfony/translation/tree/v7.3.3" }, "funding": [ { @@ -9916,7 +9929,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T17:31:46+00:00" + "time": "2025-08-01T21:02:37+00:00" }, { "name": "symfony/translation-contracts", @@ -10072,16 +10085,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "53205bea27450dc5c65377518b3275e126d45e75" + "reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/53205bea27450dc5c65377518b3275e126d45e75", - "reference": "53205bea27450dc5c65377518b3275e126d45e75", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/34d8d4c4b9597347306d1ec8eb4e1319b1e6986f", + "reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f", "shasum": "" }, "require": { @@ -10135,7 +10148,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.3.2" + "source": "https://github.com/symfony/var-dumper/tree/v7.3.3" }, "funding": [ { @@ -10155,7 +10168,7 @@ "type": "tidelift" } ], - "time": "2025-07-29T20:02:46+00:00" + "time": "2025-08-13T11:49:31+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -10432,16 +10445,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.8.3", + "version": "v7.8.4", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "a585c346ddf1bec22e51e20b5387607905604a71" + "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/a585c346ddf1bec22e51e20b5387607905604a71", - "reference": "a585c346ddf1bec22e51e20b5387607905604a71", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/130a9bf0e269ee5f5b320108f794ad03e275cad4", + "reference": "130a9bf0e269ee5f5b320108f794ad03e275cad4", "shasum": "" }, "require": { @@ -10450,26 +10463,26 @@ "ext-reflection": "*", "ext-simplexml": "*", "fidry/cpu-core-counter": "^1.2.0", - "jean85/pretty-package-versions": "^2.1.0", + "jean85/pretty-package-versions": "^2.1.1", "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "phpunit/php-code-coverage": "^11.0.9 || ^12.0.4", - "phpunit/php-file-iterator": "^5.1.0 || ^6", - "phpunit/php-timer": "^7.0.1 || ^8", - "phpunit/phpunit": "^11.5.11 || ^12.0.6", - "sebastian/environment": "^7.2.0 || ^8", - "symfony/console": "^6.4.17 || ^7.2.1", - "symfony/process": "^6.4.19 || ^7.2.4" + "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.5.24", + "sebastian/environment": "^7.2.1", + "symfony/console": "^6.4.22 || ^7.3.0", + "symfony/process": "^6.4.20 || ^7.3.0" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", "ext-pcov": "*", "ext-posix": "*", - "phpstan/phpstan": "^2.1.6", - "phpstan/phpstan-deprecation-rules": "^2.0.1", - "phpstan/phpstan-phpunit": "^2.0.4", - "phpstan/phpstan-strict-rules": "^2.0.3", - "squizlabs/php_codesniffer": "^3.11.3", - "symfony/filesystem": "^6.4.13 || ^7.2.0" + "phpstan/phpstan": "^2.1.17", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.6", + "phpstan/phpstan-strict-rules": "^2.0.4", + "squizlabs/php_codesniffer": "^3.13.2", + "symfony/filesystem": "^6.4.13 || ^7.3.0" }, "bin": [ "bin/paratest", @@ -10509,7 +10522,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.8.3" + "source": "https://github.com/paratestphp/paratest/tree/v7.8.4" }, "funding": [ { @@ -10521,7 +10534,7 @@ "type": "paypal" } ], - "time": "2025-03-05T08:29:11+00:00" + "time": "2025-06-23T06:07:21+00:00" }, { "name": "doctrine/deprecations", @@ -10636,16 +10649,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "8520451a140d3f46ac33042715115e290cf5785f" + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", - "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { @@ -10655,10 +10668,10 @@ "fidry/makefile": "^0.2.0", "fidry/php-cs-fixer-config": "^1.1.2", "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^8.5.31 || ^9.5.26", "webmozarts/strict-phpunit": "^7.5" }, @@ -10685,7 +10698,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" }, "funding": [ { @@ -10693,20 +10706,20 @@ "type": "github" } ], - "time": "2024-08-06T10:04:20+00:00" + "time": "2025-08-14T07:29:31+00:00" }, { "name": "filp/whoops", - "version": "2.18.3", + "version": "2.18.4", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "59a123a3d459c5a23055802237cb317f609867e5" + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", - "reference": "59a123a3d459c5a23055802237cb317f609867e5", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", "shasum": "" }, "require": { @@ -10756,7 +10769,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.3" + "source": "https://github.com/filp/whoops/tree/2.18.4" }, "funding": [ { @@ -10764,7 +10777,7 @@ "type": "github" } ], - "time": "2025-06-16T00:02:10+00:00" + "time": "2025-08-08T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -10902,16 +10915,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.1", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", - "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -10950,7 +10963,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -10958,7 +10971,7 @@ "type": "tidelift" } ], - "time": "2025-04-29T12:36:36+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nunomaduro/collision", @@ -11061,38 +11074,38 @@ }, { "name": "pestphp/pest", - "version": "v3.8.2", + "version": "v3.8.4", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "c6244a8712968dbac88eb998e7ff3b5caa556b0d" + "reference": "72cf695554420e21858cda831d5db193db102574" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/c6244a8712968dbac88eb998e7ff3b5caa556b0d", - "reference": "c6244a8712968dbac88eb998e7ff3b5caa556b0d", + "url": "https://api.github.com/repos/pestphp/pest/zipball/72cf695554420e21858cda831d5db193db102574", + "reference": "72cf695554420e21858cda831d5db193db102574", "shasum": "" }, "require": { - "brianium/paratest": "^7.8.3", - "nunomaduro/collision": "^8.8.0", - "nunomaduro/termwind": "^2.3.0", + "brianium/paratest": "^7.8.4", + "nunomaduro/collision": "^8.8.2", + "nunomaduro/termwind": "^2.3.1", "pestphp/pest-plugin": "^3.0.0", - "pestphp/pest-plugin-arch": "^3.1.0", + "pestphp/pest-plugin-arch": "^3.1.1", "pestphp/pest-plugin-mutate": "^3.0.5", "php": "^8.2.0", - "phpunit/phpunit": "^11.5.15" + "phpunit/phpunit": "^11.5.33" }, "conflict": { "filp/whoops": "<2.16.0", - "phpunit/phpunit": ">11.5.15", + "phpunit/phpunit": ">11.5.33", "sebastian/exporter": "<6.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { "pestphp/pest-dev-tools": "^3.4.0", - "pestphp/pest-plugin-type-coverage": "^3.5.0", - "symfony/process": "^7.2.5" + "pestphp/pest-plugin-type-coverage": "^3.6.1", + "symfony/process": "^7.3.0" }, "bin": [ "bin/pest" @@ -11157,7 +11170,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v3.8.2" + "source": "https://github.com/pestphp/pest/tree/v3.8.4" }, "funding": [ { @@ -11169,7 +11182,7 @@ "type": "github" } ], - "time": "2025-04-17T10:53:02+00:00" + "time": "2025-08-20T19:12:42+00:00" }, { "name": "pestphp/pest-plugin", @@ -11752,16 +11765,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8" + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8", - "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", "shasum": "" }, "require": { @@ -11793,22 +11806,22 @@ "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/2.2.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" }, - "time": "2025-07-13T07:04:09+00:00" + "time": "2025-08-30T15:50:23+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "11.0.9", + "version": "11.0.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", - "reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", + "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", "shasum": "" }, "require": { @@ -11865,15 +11878,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.11" }, "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/phpunit/php-code-coverage", + "type": "tidelift" } ], - "time": "2025-02-25T13:26:39+00:00" + "time": "2025-08-27T14:37:49+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12122,16 +12147,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.15", + "version": "11.5.33", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c" + "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c", - "reference": "4b6a4ee654e5e0c5e1f17e2f83c0f4c91dee1f9c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", + "reference": "5965e9ff57546cb9137c0ff6aa78cb7442b05cf6", "shasum": "" }, "require": { @@ -12141,24 +12166,24 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.0", + "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.9", + "phpunit/php-code-coverage": "^11.0.10", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-invoker": "^5.0.1", "phpunit/php-text-template": "^4.0.1", "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.1", + "sebastian/comparator": "^6.3.2", "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", - "sebastian/type": "^5.1.2", + "sebastian/type": "^5.1.3", "sebastian/version": "^5.0.2", "staabm/side-effects-detector": "^1.0.5" }, @@ -12203,7 +12228,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.15" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.33" }, "funding": [ { @@ -12214,12 +12239,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2025-03-23T16:02:11+00:00" + "time": "2025-08-16T05:19:02+00:00" }, { "name": "sebastian/cli-parser", @@ -12393,16 +12426,16 @@ }, { "name": "sebastian/comparator", - "version": "6.3.1", + "version": "6.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959" + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959", - "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", + "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", "shasum": "" }, "require": { @@ -12461,15 +12494,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2025-03-07T06:57:01+00:00" + "time": "2025-08-10T08:07:46+00:00" }, { "name": "sebastian/complexity", @@ -12598,23 +12643,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": "*" @@ -12650,15 +12695,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", @@ -12974,23 +13031,23 @@ }, { "name": "sebastian/recursion-context", - "version": "6.0.2", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", - "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { @@ -13026,28 +13083,40 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2024-07-03T05:10:34+00:00" + "time": "2025-08-13T04:42:22+00:00" }, { "name": "sebastian/type", - "version": "5.1.2", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", - "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", "shasum": "" }, "require": { @@ -13083,15 +13152,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" }, "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/type", + "type": "tidelift" } ], - "time": "2025-03-18T13:35:50+00:00" + "time": "2025-08-09T06:55:48+00:00" }, { "name": "sebastian/version", @@ -13381,7 +13462,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "8.3.*" + "php": "^8.3 || ^8.4" }, "platform-dev": {}, "plugin-api-version": "2.6.0" From 773fe8a1e670bac7d099bd054500e6c43f1a35df Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Sun, 31 Aug 2025 17:24:13 +0200 Subject: [PATCH 03/19] Install and setup Filament v4 --- app/Models/User.php | 13 +- app/Providers/Filament/AdminPanelProvider.php | 62 + bootstrap/providers.php | 3 +- composer.json | 4 +- composer.lock | 1854 ++++++++++++++++- 5 files changed, 1862 insertions(+), 74 deletions(-) create mode 100644 app/Providers/Filament/AdminPanelProvider.php diff --git a/app/Models/User.php b/app/Models/User.php index ca946155e..bdadcdc65 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,7 +5,11 @@ use App\Concerns\HasTimestamps; use App\Concerns\PreparesSearch; use App\Enums\NotificationType; +use App\Policies\UserPolicy; use Carbon\Carbon; +use Filament\Facades\Filament; +use Filament\Models\Contracts\FilamentUser; +use Filament\Panel; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -17,7 +21,7 @@ use Laravel\Sanctum\HasApiTokens; use Laravel\Scout\Searchable; -final class User extends Authenticatable implements MustVerifyEmail +final class User extends Authenticatable implements MustVerifyEmail, FilamentUser { use HasApiTokens; use HasFactory; @@ -456,4 +460,11 @@ public function isNotificationAllowed(string $notification): bool return NotificationType::from($notificationType)->getClass() === $notification; }); } + + public function canAccessPanel(Panel $panel): bool + { + $guard = Filament::getAuthGuard(); + + return Auth::guard($guard)->user()->can(UserPolicy::ADMIN, User::class); + } } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php new file mode 100644 index 000000000..25d035bde --- /dev/null +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -0,0 +1,62 @@ +default() + ->id('admint') + ->path('admin-filament') + ->login() + ->colors([ + 'primary' => '#18bc9c', + ]) + ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') + ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') + ->pages([ + Dashboard::class, + ]) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') + ->widgets([ + AccountWidget::class, + FilamentInfoWidget::class, + ]) + ->middleware([ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + DisableBladeIconComponents::class, + DispatchServingFilamentEvent::class, + ]) + ->authMiddleware([ + Authenticate::class, + ]) + ->brandLogo(asset('images/laravelio-logo.svg')) + ->unsavedChangesAlerts() + ->spa(); + } +} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 7ad1b7b6b..e590a976d 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -1,6 +1,7 @@ =7.1", + "pragmarx/google2fa": ">=4.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "chillerlan/php-qrcode": "^1.0|^2.0|^3.0|^4.0", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "phpunit/phpunit": "~4|~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "For QR Code generation, requires imagick", + "chillerlan/php-qrcode": "For QR Code generation" + }, + "type": "library", + "extra": { + "component": "package", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FAQRCode\\": "src/", + "PragmaRX\\Google2FAQRCode\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "QR Code package for Google2FA", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa", + "qr code", + "qrcode" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues", + "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0" + }, + "time": "2021-08-15T12:53:48+00:00" + }, { "name": "predis/predis", "version": "v2.4.0", @@ -6065,66 +7355,222 @@ "license": [ "MIT" ], - "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.0" + }, + "time": "2025-06-25T14:20:11+00:00" + }, + { + "name": "riimu/kit-phpencoder", + "version": "v2.4.2", + "source": { + "type": "git", + "url": "https://github.com/Riimu/Kit-PHPEncoder.git", + "reference": "72ff7825de193b272e17b228394819dbfc638e72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Riimu/Kit-PHPEncoder/zipball/72ff7825de193b272e17b228394819dbfc638e72", + "reference": "72ff7825de193b272e17b228394819dbfc638e72", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Riimu\\Kit\\PHPEncoder\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Riikka Kalliomäki", + "email": "riikka.kalliomaki@gmail.com", + "homepage": "http://riimu.net" + } + ], + "description": "Highly customizable alternative to var_export for PHP code generation", + "homepage": "http://kit.riimu.net", + "keywords": [ + "code", + "encoder", + "export", + "generator", + "variable" + ], + "support": { + "issues": "https://github.com/Riimu/Kit-PHPEncoder/issues", + "source": "https://github.com/Riimu/Kit-PHPEncoder/tree/v2.4.2" + }, + "time": "2022-12-10T18:12:25+00:00" + }, + { + "name": "ryangjchandler/blade-capture-directive", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/ryangjchandler/blade-capture-directive.git", + "reference": "bbb1513dfd89eaec87a47fe0c449a7e3d4a1976d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ryangjchandler/blade-capture-directive/zipball/bbb1513dfd89eaec87a47fe0c449a7e3d4a1976d", + "reference": "bbb1513dfd89eaec87a47fe0c449a7e3d4a1976d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0|^11.0|^12.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.9.2" + }, + "require-dev": { + "nunomaduro/collision": "^7.0|^8.0", + "nunomaduro/larastan": "^2.0|^3.0", + "orchestra/testbench": "^8.0|^9.0|^10.0", + "pestphp/pest": "^2.0|^3.7", + "pestphp/pest-plugin-laravel": "^2.0|^3.1", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", + "phpstan/phpstan-phpunit": "^1.0|^2.0", + "phpunit/phpunit": "^10.0|^11.5.3", + "spatie/laravel-ray": "^1.26" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "BladeCaptureDirective": "RyanChandler\\BladeCaptureDirective\\Facades\\BladeCaptureDirective" + }, + "providers": [ + "RyanChandler\\BladeCaptureDirective\\BladeCaptureDirectiveServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "RyanChandler\\BladeCaptureDirective\\": "src", + "RyanChandler\\BladeCaptureDirective\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryan Chandler", + "email": "support@ryangjchandler.co.uk", + "role": "Developer" + } + ], + "description": "Create inline partials in your Blade templates with ease.", + "homepage": "https://github.com/ryangjchandler/blade-capture-directive", "keywords": [ - "guid", - "identifier", - "uuid" + "blade-capture-directive", + "laravel", + "ryangjchandler" ], "support": { - "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.0" + "issues": "https://github.com/ryangjchandler/blade-capture-directive/issues", + "source": "https://github.com/ryangjchandler/blade-capture-directive/tree/v1.1.0" }, - "time": "2025-06-25T14:20:11+00:00" + "funding": [ + { + "url": "https://github.com/ryangjchandler", + "type": "github" + } + ], + "time": "2025-02-25T09:09:36+00:00" }, { - "name": "riimu/kit-phpencoder", - "version": "v2.4.2", + "name": "scrivo/highlight.php", + "version": "v9.18.1.10", "source": { "type": "git", - "url": "https://github.com/Riimu/Kit-PHPEncoder.git", - "reference": "72ff7825de193b272e17b228394819dbfc638e72" + "url": "https://github.com/scrivo/highlight.php.git", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Riimu/Kit-PHPEncoder/zipball/72ff7825de193b272e17b228394819dbfc638e72", - "reference": "72ff7825de193b272e17b228394819dbfc638e72", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/850f4b44697a2552e892ffe71490ba2733c2fc6e", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e", "shasum": "" }, "require": { - "php": ">=5.6.0" + "ext-json": "*", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4|^5.4", + "symfony/var-dumper": "^2.8|^3.4|^5.4" + }, + "suggest": { + "ext-mbstring": "Allows highlighting code with unicode characters and supports language with unicode keywords" }, "type": "library", "autoload": { - "psr-4": { - "Riimu\\Kit\\PHPEncoder\\": "src/" + "files": [ + "HighlightUtilities/functions.php" + ], + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Riikka Kalliomäki", - "email": "riikka.kalliomaki@gmail.com", - "homepage": "http://riimu.net" + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" } ], - "description": "Highly customizable alternative to var_export for PHP code generation", - "homepage": "http://kit.riimu.net", + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", "keywords": [ "code", - "encoder", - "export", - "generator", - "variable" + "highlight", + "highlight.js", + "highlight.php", + "syntax" ], "support": { - "issues": "https://github.com/Riimu/Kit-PHPEncoder/issues", - "source": "https://github.com/Riimu/Kit-PHPEncoder/tree/v2.4.2" + "issues": "https://github.com/scrivo/highlight.php/issues", + "source": "https://github.com/scrivo/highlight.php" }, - "time": "2022-12-10T18:12:25+00:00" + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2022-12-17T21:53:22+00:00" }, { "name": "sentry/sentry", @@ -6730,6 +8176,65 @@ ], "time": "2025-02-21T14:31:39+00:00" }, + { + "name": "spatie/invade", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/invade.git", + "reference": "b920f6411d21df4e8610a138e2e87ae4957d7f63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/invade/zipball/b920f6411d21df4e8610a138e2e87ae4957d7f63", + "reference": "b920f6411d21df4e8610a138e2e87ae4957d7f63", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.20", + "phpstan/phpstan": "^1.4", + "spatie/ray": "^1.28" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Spatie\\Invade\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "A PHP function to work with private properties and methods", + "homepage": "https://github.com/spatie/invade", + "keywords": [ + "invade", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/invade/tree/2.1.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-05-17T09:06:10+00:00" + }, { "name": "spatie/laravel-feed", "version": "4.4.2", @@ -7319,6 +8824,71 @@ ], "time": "2025-07-01T07:07:44+00:00" }, + { + "name": "spatie/shiki-php", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/shiki-php.git", + "reference": "a2e78a9ff8a1290b25d550be8fbf8285c13175c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/shiki-php/zipball/a2e78a9ff8a1290b25d550be8fbf8285c13175c5", + "reference": "a2e78a9ff8a1290b25d550be8fbf8285c13175c5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "symfony/process": "^5.4|^6.4|^7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v3.0", + "pestphp/pest": "^1.8", + "phpunit/phpunit": "^9.5", + "spatie/pest-plugin-snapshots": "^1.1", + "spatie/ray": "^1.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ShikiPhp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rias Van der Veken", + "email": "rias@spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Highlight code using Shiki in PHP", + "homepage": "https://github.com/spatie/shiki-php", + "keywords": [ + "shiki", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/shiki-php/tree/2.3.2" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-02-21T14:16:57+00:00" + }, { "name": "spatie/temporary-directory", "version": "2.3.0", @@ -8064,6 +9634,79 @@ ], "time": "2025-07-15T13:41:35+00:00" }, + { + "name": "symfony/html-sanitizer", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/html-sanitizer.git", + "reference": "8740fc48979f649dee8b8fc51a2698e5c190bf12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/8740fc48979f649dee8b8fc51a2698e5c190bf12", + "reference": "8740fc48979f649dee8b8fc51a2698e5c190bf12", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "league/uri": "^6.5|^7.0", + "masterminds/html5": "^2.7.2", + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HtmlSanitizer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a document's DOM.", + "homepage": "https://symfony.com", + "keywords": [ + "Purifier", + "html", + "sanitizer" + ], + "support": { + "source": "https://github.com/symfony/html-sanitizer/tree/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-12T10:34:03+00:00" + }, { "name": "symfony/http-client", "version": "v7.3.3", @@ -10225,6 +11868,75 @@ }, "time": "2024-12-21T16:25:41+00:00" }, + { + "name": "ueberdosis/tiptap-php", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ueberdosis/tiptap-php.git", + "reference": "458194ad0f8b0cf616fecdf451a84f9a6c1f3056" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ueberdosis/tiptap-php/zipball/458194ad0f8b0cf616fecdf451a84f9a6c1f3056", + "reference": "458194ad0f8b0cf616fecdf451a84f9a6c1f3056", + "shasum": "" + }, + "require": { + "php": "^8.0", + "scrivo/highlight.php": "^9.18", + "spatie/shiki-php": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.5", + "pestphp/pest": "^1.21", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tiptap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Hans Pagel", + "email": "humans@tiptap.dev", + "role": "Developer" + } + ], + "description": "A PHP package to work with Tiptap output", + "homepage": "https://github.com/ueberdosis/tiptap-php", + "keywords": [ + "prosemirror", + "tiptap", + "ueberdosis" + ], + "support": { + "issues": "https://github.com/ueberdosis/tiptap-php/issues", + "source": "https://github.com/ueberdosis/tiptap-php/tree/2.0.0" + }, + "funding": [ + { + "url": "https://tiptap.dev/pricing", + "type": "custom" + }, + { + "url": "https://github.com/ueberdosis", + "type": "github" + }, + { + "url": "https://opencollective.com/tiptap", + "type": "open_collective" + } + ], + "time": "2025-06-26T14:11:46+00:00" + }, { "name": "vlucas/phpdotenv", "version": "v5.6.2", From 6e29252bf8b5a861601aa4090c1524215803e7a1 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Mon, 1 Sep 2025 18:23:39 +0200 Subject: [PATCH 04/19] Refactor canAccessPanel method to simplify authorization check --- app/Models/User.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Models/User.php b/app/Models/User.php index bdadcdc65..e56969faa 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -463,8 +463,6 @@ public function isNotificationAllowed(string $notification): bool public function canAccessPanel(Panel $panel): bool { - $guard = Filament::getAuthGuard(); - - return Auth::guard($guard)->user()->can(UserPolicy::ADMIN, User::class); + return $this->can(UserPolicy::ADMIN, User::class); } } From 25ca82374b9b232ebc2f1a6687fcf0d690631af9 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Mon, 1 Sep 2025 19:46:41 +0200 Subject: [PATCH 05/19] Add ReplyResource --- .../Resources/Replies/Pages/ListReplies.php | 18 ++++ .../Resources/Replies/ReplyResource.php | 49 +++++++++++ .../Resources/Replies/Tables/RepliesTable.php | 84 +++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 app/Filament/Resources/Replies/Pages/ListReplies.php create mode 100644 app/Filament/Resources/Replies/ReplyResource.php create mode 100644 app/Filament/Resources/Replies/Tables/RepliesTable.php diff --git a/app/Filament/Resources/Replies/Pages/ListReplies.php b/app/Filament/Resources/Replies/Pages/ListReplies.php new file mode 100644 index 000000000..26e03bac8 --- /dev/null +++ b/app/Filament/Resources/Replies/Pages/ListReplies.php @@ -0,0 +1,18 @@ + ListReplies::route('/'), + ]; + } + + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/Replies/Tables/RepliesTable.php b/app/Filament/Resources/Replies/Tables/RepliesTable.php new file mode 100644 index 000000000..73e2845f2 --- /dev/null +++ b/app/Filament/Resources/Replies/Tables/RepliesTable.php @@ -0,0 +1,84 @@ +defaultSort('updated_at', 'desc') + ->openRecordUrlInNewTab() + ->columns([ + ImageColumn::make('authorRelation.github_id') + ->label('Author') + ->circular() + ->defaultImageUrl(fn(?string $state): string => $state ? sprintf('https://avatars.githubusercontent.com/u/%s', $state) : asset('images/laravelio-icon-gray.svg')), + + TextColumn::make('authorRelation.name') + ->label('') + ->description(fn(Reply $record): ?string => $record->authorRelation->username), + + TextColumn::make('replyAbleRelation.subject') + ->label('Thread') + ->searchable(), + + TextColumn::make('body') + ->label('Content') + ->limit(250) + ->wrap() + ->searchable(), + + IconColumn::make('updated_by') + ->label('Updated') + ->boolean(), + + TextColumn::make('created_at') + ->label('Created on') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + + TextColumn::make('updated_at') + ->label('Last updated on') + ->dateTime() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + TrashedFilter::make(), + + TernaryFilter::make('updated_by') + ->label('Updated') + ->nullable() + ]) + ->recordActions([ + Action::make('view') + ->url(fn(Reply $record): string => route('thread', $record->replyAble()->slug()) . '#' . $record->id()) + ->openUrlInNewTab() + ->icon('heroicon-s-eye'), + + DeleteAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ForceDeleteBulkAction::make(), + RestoreBulkAction::make(), + ]), + ]); + } +} From e05ea9dd9e7a3fdc97ab8764bd2f06e250e134d0 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Mon, 1 Sep 2025 19:59:57 +0200 Subject: [PATCH 06/19] Add default value for Updated column --- app/Filament/Resources/Replies/Tables/RepliesTable.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Filament/Resources/Replies/Tables/RepliesTable.php b/app/Filament/Resources/Replies/Tables/RepliesTable.php index 73e2845f2..540daef00 100644 --- a/app/Filament/Resources/Replies/Tables/RepliesTable.php +++ b/app/Filament/Resources/Replies/Tables/RepliesTable.php @@ -45,7 +45,8 @@ public static function configure(Table $table): Table IconColumn::make('updated_by') ->label('Updated') - ->boolean(), + ->boolean() + ->default(false), TextColumn::make('created_at') ->label('Created on') From 9a9a124f75ca36e4b9173e2c90b91d65ae86a2ce Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Mon, 1 Sep 2025 21:30:50 +0200 Subject: [PATCH 07/19] Add UserResource --- .../Resources/Users/Pages/ListUsers.php | 19 ++ .../Resources/Users/Tables/UsersTable.php | 192 ++++++++++++++++++ app/Filament/Resources/Users/UserResource.php | 43 ++++ app/Jobs/BanUser.php | 6 +- app/Jobs/DeleteUserThreads.php | 6 +- app/Jobs/UnbanUser.php | 6 +- 6 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 app/Filament/Resources/Users/Pages/ListUsers.php create mode 100644 app/Filament/Resources/Users/Tables/UsersTable.php create mode 100644 app/Filament/Resources/Users/UserResource.php diff --git a/app/Filament/Resources/Users/Pages/ListUsers.php b/app/Filament/Resources/Users/Pages/ListUsers.php new file mode 100644 index 000000000..778848e6f --- /dev/null +++ b/app/Filament/Resources/Users/Pages/ListUsers.php @@ -0,0 +1,19 @@ +defaultSort('created_at', 'desc') + ->openRecordUrlInNewTab() + ->columns([ + ImageColumn::make('github_id') + ->label('Name') + ->circular() + ->width('0%') + ->defaultImageUrl(fn(?string $state): string => $state ? sprintf('https://avatars.githubusercontent.com/u/%s', $state) : asset('images/laravelio-icon-gray.svg')), + + TextColumn::make('username') + ->label('') + ->searchable() + ->formatStateUsing(fn(User $user): ?string => $user->name) + ->description(fn(User $user): ?string => $user->username), + + TextColumn::make('email') + ->searchable() + ->toggleable(isToggledHiddenByDefault: true), + + TextColumn::make('type') + ->label('Role') + ->badge() + ->formatStateUsing(fn(string $state): string => match ($state) { + '1' => 'User', + '2' => 'Moderator', + '3' => 'Admin', + }), + + IconColumn::make('banned_at') + ->label('Banned') + ->boolean() + ->default(false), + + TextColumn::make('created_at') + ->label('Joined on') + ->dateTime() + ->sortable() + ]) + ->filters([ + SelectFilter::make('type') + ->options([ + '1' => 'User', + '2' => 'Moderator', + '3' => 'Admin', + ]), + + TernaryFilter::make('banned_at') + ->label('Banned') + ->nullable() + ]) + ->recordActions([ + Action::make('view') + ->url(fn(User $user): string => route('profile', $user->username)) + ->openUrlInNewTab() + ->icon('heroicon-s-eye'), + + ActionGroup::make([ + Action::make('verify_author') + ->action(function (User $user) { + VerifyAuthor::dispatchSync($user); + + Notification::make() + ->title($user->name . ' is now a verified author.') + ->success() + ->send(); + }) + ->openUrlInNewTab() + ->color('primary') + ->icon('heroicon-s-check-circle') + ->requiresConfirmation() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::ADMIN, $user) && ! $user->isVerifiedAuthor()), + + Action::make('unverify_author') + ->action(function (User $user) { + UnVerifyAuthor::dispatchSync($user); + + Notification::make() + ->title($user->name . '\'s threads have been deleted.') + ->success() + ->send(); + }) + ->openUrlInNewTab() + ->color('danger') + ->icon('heroicon-s-x-circle') + ->requiresConfirmation() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::ADMIN, $user) && $user->isVerifiedAuthor()), + + Action::make('ban_author') + ->schema([ + TextInput::make('reason') + ->label('Reason') + ->required() + ->placeholder('Provide a reason for banning this user...'), + + Checkbox::make('delete_threads') + ->label('Delete all threads') + ->default(false), + ]) + ->action(function (User $user, array $data) { + BanUser::dispatchSync($user, $data['reason']); + + if ($data['delete_threads']) { + DeleteUserThreads::dispatchSync($user); + } + + Notification::make() + ->title( + $user->name . ' is now banned.' . ($data['delete_threads'] ? ' And all his threads are now deleted.' : '') + ) + ->success() + ->send(); + }) + ->modalDescription('Are you sure you\'d like to ban this user? This will prevent him from logging in, posting threads and replying to threads.') + ->openUrlInNewTab() + ->color('danger') + ->icon('heroicon-s-check-circle') + ->requiresConfirmation() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::BAN, $user) && ! $user->isBanned()), + + Action::make('unban_author') + ->action(function (User $user) { + + UnbanUser::dispatchSync($user); + + Notification::make() + ->title($user->name . ' is no longer a banned user.') + ->success() + ->send(); + }) + ->openUrlInNewTab() + ->color('primary') + ->icon('heroicon-s-x-circle') + ->requiresConfirmation() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::BAN, $user) && $user->isBanned()), + + Action::make('delete_threads') + ->action(function (User $user) { + DeleteUserThreads::dispatchSync($user); + + Notification::make() + ->title($user->name . '\'s threads have been deleted.') + ->success() + ->send(); + }) + ->openUrlInNewTab() + ->color('danger') + ->icon('heroicon-s-archive-box-x-mark') + ->requiresConfirmation() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::DELETE, $user)), + + DeleteAction::make() + ->visible(fn(User $user): bool => auth()->user()->can(UserPolicy::DELETE, $user)), + ]), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Users/UserResource.php b/app/Filament/Resources/Users/UserResource.php new file mode 100644 index 000000000..6dd5e6a7c --- /dev/null +++ b/app/Filament/Resources/Users/UserResource.php @@ -0,0 +1,43 @@ + ListUsers::route('/'), + ]; + } +} diff --git a/app/Jobs/BanUser.php b/app/Jobs/BanUser.php index 50f8288d1..b0fcb5a51 100644 --- a/app/Jobs/BanUser.php +++ b/app/Jobs/BanUser.php @@ -4,9 +4,13 @@ use App\Models\User; use Carbon\Carbon; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Queue\Queueable; -final class BanUser +final class BanUser implements ShouldQueue { + use Queueable; + public function __construct(private User $user, private $reason) {} public function handle(): void diff --git a/app/Jobs/DeleteUserThreads.php b/app/Jobs/DeleteUserThreads.php index 445b9dc4f..1fc6865eb 100644 --- a/app/Jobs/DeleteUserThreads.php +++ b/app/Jobs/DeleteUserThreads.php @@ -3,9 +3,13 @@ namespace App\Jobs; use App\Models\User; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Queue\Queueable; -final class DeleteUserThreads +final class DeleteUserThreads implements ShouldQueue { + use Queueable; + public function __construct(private User $user) {} public function handle(): void diff --git a/app/Jobs/UnbanUser.php b/app/Jobs/UnbanUser.php index 49b1bdfb7..2d8d0fd34 100644 --- a/app/Jobs/UnbanUser.php +++ b/app/Jobs/UnbanUser.php @@ -3,9 +3,13 @@ namespace App\Jobs; use App\Models\User; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Queue\Queueable; -final class UnbanUser +final class UnbanUser implements ShouldQueue { + use Queueable; + public function __construct(private User $user) {} public function handle(): void From 2445882e2f335d62af6c022f5f2cd2a5a943f5a3 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 16:21:30 +0200 Subject: [PATCH 08/19] Fix variable name in RepliesTable for consistency --- app/Filament/Resources/Replies/Tables/RepliesTable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Filament/Resources/Replies/Tables/RepliesTable.php b/app/Filament/Resources/Replies/Tables/RepliesTable.php index 540daef00..8f4736993 100644 --- a/app/Filament/Resources/Replies/Tables/RepliesTable.php +++ b/app/Filament/Resources/Replies/Tables/RepliesTable.php @@ -31,7 +31,7 @@ public static function configure(Table $table): Table TextColumn::make('authorRelation.name') ->label('') - ->description(fn(Reply $record): ?string => $record->authorRelation->username), + ->description(fn(Reply $reply): ?string => $reply->authorRelation->username), TextColumn::make('replyAbleRelation.subject') ->label('Thread') @@ -68,7 +68,7 @@ public static function configure(Table $table): Table ]) ->recordActions([ Action::make('view') - ->url(fn(Reply $record): string => route('thread', $record->replyAble()->slug()) . '#' . $record->id()) + ->url(fn(Reply $reply): string => route('thread', $reply->replyAble()->slug()) . '#' . $reply->id()) ->openUrlInNewTab() ->icon('heroicon-s-eye'), From 8e762c782063d639ae2d157410ca84646161415d Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 19:33:16 +0200 Subject: [PATCH 09/19] Add ArticleResource, --- .../Resources/Articles/ArticleResource.php | 39 +++++++++++++ .../Resources/Articles/Pages/ListArticles.php | 16 +++++ .../Articles/Tables/ArticlesTable.php | 58 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 app/Filament/Resources/Articles/ArticleResource.php create mode 100644 app/Filament/Resources/Articles/Pages/ListArticles.php create mode 100644 app/Filament/Resources/Articles/Tables/ArticlesTable.php diff --git a/app/Filament/Resources/Articles/ArticleResource.php b/app/Filament/Resources/Articles/ArticleResource.php new file mode 100644 index 000000000..de4b5174a --- /dev/null +++ b/app/Filament/Resources/Articles/ArticleResource.php @@ -0,0 +1,39 @@ + ListArticles::route('/') + ]; + } +} diff --git a/app/Filament/Resources/Articles/Pages/ListArticles.php b/app/Filament/Resources/Articles/Pages/ListArticles.php new file mode 100644 index 000000000..2b985ff8d --- /dev/null +++ b/app/Filament/Resources/Articles/Pages/ListArticles.php @@ -0,0 +1,16 @@ +defaultSort('submitted_at', 'desc') + ->openRecordUrlInNewTab() + ->columns([ + ImageColumn::make('authorRelation.github_id') + ->label('Author') + ->circular() + ->width('1%') + ->defaultImageUrl(fn(?string $state): string => $state ? sprintf('https://avatars.githubusercontent.com/u/%s', $state) : asset('images/laravelio-icon-gray.svg')), + + TextColumn::make('authorRelation.name') + ->label('') + ->description(fn(Article $article): ?string => $article->authorRelation->username), + + TextColumn::make('title') + ->searchable(['title', 'slug', 'body']), + + TextColumn::make('submitted_at') + ->label('Submitted on') + ->dateTime() + ->sortable(), + ]) + ->filters([ + Filter::make('awaiting_approvals') + ->query(fn(Builder $query): Builder => $query->awaitingApproval()) + ->default() + ]) + ->recordActions([ + Action::make('view') + ->url(fn(Article $article): string => route('articles.show', $article->slug())) + ->openUrlInNewTab() + ->icon('heroicon-s-eye'), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} From 88c111ba183e16c6a2c3e065db22c4439bd0c7eb Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 19:37:06 +0200 Subject: [PATCH 10/19] Add Horizon to user menu --- app/Providers/Filament/AdminPanelProvider.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 25d035bde..12efaa14f 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -2,6 +2,7 @@ namespace App\Providers\Filament; +use Filament\Actions\Action; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\DisableBladeIconComponents; @@ -55,6 +56,12 @@ public function panel(Panel $panel): Panel ->authMiddleware([ Authenticate::class, ]) + ->userMenuItems([ + Action::make('Horizon') + ->url(fn(): string => route('horizon.index')) + ->icon('heroicon-o-presentation-chart-bar') + ->openUrlInNewTab(), + ]) ->brandLogo(asset('images/laravelio-logo.svg')) ->unsavedChangesAlerts() ->spa(); From 5006f25146650e24ce4ddb72b77be45014cc1cd5 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 19:46:21 +0200 Subject: [PATCH 11/19] Remove default widgets and disable global search --- app/Providers/Filament/AdminPanelProvider.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 12efaa14f..6c9d10dcd 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -38,10 +38,7 @@ public function panel(Panel $panel): Panel Dashboard::class, ]) ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') - ->widgets([ - AccountWidget::class, - FilamentInfoWidget::class, - ]) + ->widgets([]) ->middleware([ EncryptCookies::class, AddQueuedCookiesToResponse::class, @@ -64,6 +61,7 @@ public function panel(Panel $panel): Panel ]) ->brandLogo(asset('images/laravelio-logo.svg')) ->unsavedChangesAlerts() + ->globalSearch(false) ->spa(); } } From 2e233ee2d357350e99fcb90f761be652ae389c3b Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 21:07:30 +0200 Subject: [PATCH 12/19] Add widgets to the dashboards --- .../Widgets/ArticlesStatsOverview.php | 66 ++++++++++++++++ app/Filament/Widgets/ArticlesTrendChart.php | 42 ++++++++++ app/Filament/Widgets/RepliesStatsOverview.php | 52 +++++++++++++ app/Filament/Widgets/RepliesTrendChart.php | 42 ++++++++++ app/Filament/Widgets/UsersStatsOverview.php | 53 +++++++++++++ app/Filament/Widgets/UsersTrendChart.php | 42 ++++++++++ app/Providers/Filament/AdminPanelProvider.php | 20 +++-- composer.json | 1 + composer.lock | 76 ++++++++++++++++++- 9 files changed, 388 insertions(+), 6 deletions(-) create mode 100644 app/Filament/Widgets/ArticlesStatsOverview.php create mode 100644 app/Filament/Widgets/ArticlesTrendChart.php create mode 100644 app/Filament/Widgets/RepliesStatsOverview.php create mode 100644 app/Filament/Widgets/RepliesTrendChart.php create mode 100644 app/Filament/Widgets/UsersStatsOverview.php create mode 100644 app/Filament/Widgets/UsersTrendChart.php diff --git a/app/Filament/Widgets/ArticlesStatsOverview.php b/app/Filament/Widgets/ArticlesStatsOverview.php new file mode 100644 index 000000000..50d340738 --- /dev/null +++ b/app/Filament/Widgets/ArticlesStatsOverview.php @@ -0,0 +1,66 @@ +remember( + "widgets:articles:total", + now()->addSeconds($cacheTtlSeconds), + fn() => Article::query()->count(), + ); + + $publishedTotal = cache()->remember( + "widgets:articles:published:total", + now()->addSeconds($cacheTtlSeconds), + fn() => Article::query()->published()->count(), + ); + + $publishedWindow = cache()->remember( + "widgets:articles:published:{$window}", + now()->addSeconds($cacheTtlSeconds), + fn() => Article::query() + ->published() + ->where('submitted_at', '>=', now()->subDays($window)) + ->count(), + ); + + $awaiting = cache()->remember( + "widgets:articles:awaiting", + now()->addSeconds(60), + fn() => Article::query()->awaitingApproval()->count(), + ); + + return [ + Stat::make('Articles', number_format($total)) + ->description('Total articles') + ->icon('heroicon-o-newspaper'), + + Stat::make('Published', number_format($publishedTotal)) + ->description('All-time approved') + ->color('success') + ->icon('heroicon-o-check-circle'), + + Stat::make("Published ({$window}d)", number_format($publishedWindow)) + ->description("Approved in last {$window} days") + ->color('info') + ->icon('heroicon-o-check-badge'), + + Stat::make('Awaiting Approval', number_format($awaiting)) + ->description('Submitted but not approved') + ->color('warning') + ->icon('heroicon-o-clock'), + ]; + } +} diff --git a/app/Filament/Widgets/ArticlesTrendChart.php b/app/Filament/Widgets/ArticlesTrendChart.php new file mode 100644 index 000000000..deb925453 --- /dev/null +++ b/app/Filament/Widgets/ArticlesTrendChart.php @@ -0,0 +1,42 @@ +between( + start: now()->startOfYear(), + end: now()->endOfYear(), + ) + ->perMonth() + ->count(); + + return [ + 'datasets' => [ + [ + 'label' => 'Submitted', + 'data' => $data->map(fn(TrendValue $value) => $value->aggregate), + 'tension' => 0.35, + ], + ], + 'labels' => $data->map(fn(TrendValue $value) => Carbon::parse($value->date)->format('M Y')), + ]; + } +} diff --git a/app/Filament/Widgets/RepliesStatsOverview.php b/app/Filament/Widgets/RepliesStatsOverview.php new file mode 100644 index 000000000..1b8b3cb7e --- /dev/null +++ b/app/Filament/Widgets/RepliesStatsOverview.php @@ -0,0 +1,52 @@ +remember( + 'widgets:replies:total', + now()->addSeconds($cacheTtlSeconds), + fn() => Reply::query()->count(), + ); + + $lastWindow = cache()->remember( + "widgets:replies:new:{$window}", + now()->addSeconds($cacheTtlSeconds), + fn() => Reply::query()->where('created_at', '>=', now()->subDays($window))->count(), + ); + + $solutions = cache()->remember( + 'widgets:replies:solutions', + now()->addSeconds($cacheTtlSeconds), + fn() => Reply::query()->isSolution()->count(), + ); + + return [ + Stat::make('Replies', number_format($total)) + ->description('Total replies') + ->icon('heroicon-o-chat-bubble-left-right'), + + Stat::make("New ({$window}d)", number_format($lastWindow)) + ->description("Replies in last {$window} days") + ->color('info') + ->icon('heroicon-o-chat-bubble-left-ellipsis'), + + Stat::make('Solutions', number_format($solutions)) + ->description('Marked as solution') + ->color('success') + ->icon('heroicon-o-sparkles'), + ]; + } +} diff --git a/app/Filament/Widgets/RepliesTrendChart.php b/app/Filament/Widgets/RepliesTrendChart.php new file mode 100644 index 000000000..0fa74870a --- /dev/null +++ b/app/Filament/Widgets/RepliesTrendChart.php @@ -0,0 +1,42 @@ +between( + start: now()->startOfYear(), + end: now()->endOfYear(), + ) + ->perMonth() + ->count(); + + return [ + 'datasets' => [ + [ + 'label' => 'Submitted', + 'data' => $data->map(fn(TrendValue $value) => $value->aggregate), + 'tension' => 0.35, + ], + ], + 'labels' => $data->map(fn(TrendValue $value) => Carbon::parse($value->date)->format('M Y')), + ]; + } +} diff --git a/app/Filament/Widgets/UsersStatsOverview.php b/app/Filament/Widgets/UsersStatsOverview.php new file mode 100644 index 000000000..4e60bc19c --- /dev/null +++ b/app/Filament/Widgets/UsersStatsOverview.php @@ -0,0 +1,53 @@ +remember( + 'widgets:users:total', + now()->addSeconds($cacheTtlSeconds), + fn() => User::query()->count(), + ); + + $lastWindow = cache()->remember( + "widgets:users:new:{$window}", + now()->addSeconds($cacheTtlSeconds), + fn() => User::query()->where('created_at', '>=', now()->subDays($window))->count(), + ); + + $verified = cache()->remember( + 'widgets:users:verified', + now()->addSeconds($cacheTtlSeconds), + fn() => User::query()->whereNotNull('author_verified_at')->count(), + ); + + return [ + Stat::make('Users', number_format($total)) + ->description('Total registered') + ->icon('heroicon-o-users'), + + Stat::make("New ({$window}d)", number_format($lastWindow)) + ->description("Joined in last {$window} days") + ->color('info') + ->icon('heroicon-o-user-plus'), + + Stat::make('Verified Authors', number_format($verified)) + ->description('Users verified as authors') + ->color('success') + ->icon('heroicon-o-check'), + ]; + } +} diff --git a/app/Filament/Widgets/UsersTrendChart.php b/app/Filament/Widgets/UsersTrendChart.php new file mode 100644 index 000000000..680edb9d9 --- /dev/null +++ b/app/Filament/Widgets/UsersTrendChart.php @@ -0,0 +1,42 @@ +between( + start: now()->startOfYear(), + end: now()->endOfYear(), + ) + ->perMonth() + ->count(); + + return [ + 'datasets' => [ + [ + 'label' => 'Submitted', + 'data' => $data->map(fn(TrendValue $value) => $value->aggregate), + 'tension' => 0.35, + ], + ], + 'labels' => $data->map(fn(TrendValue $value) => Carbon::parse($value->date)->format('M Y')), + ]; + } +} diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 6c9d10dcd..051541098 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -2,6 +2,12 @@ namespace App\Providers\Filament; +use App\Filament\Widgets\ArticlesStatsOverview; +use App\Filament\Widgets\ArticlesTrendChart; +use App\Filament\Widgets\RepliesStatsOverview; +use App\Filament\Widgets\RepliesTrendChart; +use App\Filament\Widgets\UsersStatsOverview; +use App\Filament\Widgets\UsersTrendChart; use Filament\Actions\Action; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\AuthenticateSession; @@ -10,9 +16,6 @@ use Filament\Pages\Dashboard; use Filament\Panel; use Filament\PanelProvider; -use Filament\Support\Colors\Color; -use Filament\Widgets\AccountWidget; -use Filament\Widgets\FilamentInfoWidget; use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; @@ -37,8 +40,15 @@ public function panel(Panel $panel): Panel ->pages([ Dashboard::class, ]) - ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') - ->widgets([]) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') + ->widgets([ + ArticlesStatsOverview::class, + UsersStatsOverview::class, + RepliesStatsOverview::class, + ArticlesTrendChart::class, + UsersTrendChart::class, + RepliesTrendChart::class, + ]) ->middleware([ EncryptCookies::class, AddQueuedCookiesToResponse::class, diff --git a/composer.json b/composer.json index 2ce90e608..d3d9f5172 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "codeat3/blade-simple-icons": "^7.1", "embed/embed": "^4.4", "filament/filament": "^4.0", + "flowframe/laravel-trend": "^0.4.0", "guzzlehttp/guzzle": "^7.2", "guzzlehttp/psr7": "^2.7", "innocenzi/bluesky-notification-channel": "^0.2.0", diff --git a/composer.lock b/composer.lock index 7170f9898..d3bc0563b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4299bc16c81dee1ecce70d3d54fd15f5", + "content-hash": "e78f320ff0b64523a34839c1dff8334c", "packages": [ { "name": "abraham/twitteroauth", @@ -2092,6 +2092,80 @@ }, "time": "2025-04-09T20:32:01+00:00" }, + { + "name": "flowframe/laravel-trend", + "version": "v0.4.0", + "source": { + "type": "git", + "url": "https://github.com/Flowframe/laravel-trend.git", + "reference": "5ace11d3075932652dc48963faa732c043aeb14d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Flowframe/laravel-trend/zipball/5ace11d3075932652dc48963faa732c043aeb14d", + "reference": "5ace11d3075932652dc48963faa732c043aeb14d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.37|^9|^10.0|^11.0|^12.0", + "php": "^8.2", + "spatie/laravel-package-tools": "^1.4.3" + }, + "require-dev": { + "nunomaduro/collision": "^5.3|^6.1|^8.0", + "orchestra/testbench": "^6.15|^7.0|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.18|^2.34|^3.7", + "pestphp/pest-plugin-laravel": "^1.1|^2.3|^3.1", + "spatie/laravel-ray": "^1.23", + "vimeo/psalm": "^4.8|^5.6|^6.5" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Trend": "Flowframe\\Trend\\TrendFacade" + }, + "providers": [ + "Flowframe\\Trend\\TrendServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Flowframe\\Trend\\": "src", + "Flowframe\\Trend\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Klopstra", + "email": "lars@flowframe.nl", + "role": "Developer" + } + ], + "description": "Easily generate model trends", + "homepage": "https://github.com/flowframe/laravel-trend", + "keywords": [ + "Flowframe", + "laravel", + "laravel-trend" + ], + "support": { + "issues": "https://github.com/Flowframe/laravel-trend/issues", + "source": "https://github.com/Flowframe/laravel-trend/tree/v0.4.0" + }, + "funding": [ + { + "url": "https://github.com/larsklopstra", + "type": "github" + } + ], + "time": "2025-02-25T11:13:23+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.3.0", From 44ada4d885e048bda5e4b22c649227dd3fdfa969 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 21:09:05 +0200 Subject: [PATCH 13/19] Enable top navigation --- app/Providers/Filament/AdminPanelProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 051541098..31003346e 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -72,6 +72,7 @@ public function panel(Panel $panel): Panel ->brandLogo(asset('images/laravelio-logo.svg')) ->unsavedChangesAlerts() ->globalSearch(false) + ->topNavigation() ->spa(); } } From b13ed56cf9de39494c79ce8a3cd50d416b9d6448 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Tue, 2 Sep 2025 21:36:17 +0200 Subject: [PATCH 14/19] Remove unnecessary bulk delete actions --- app/Filament/Resources/Articles/Tables/ArticlesTable.php | 4 +--- app/Filament/Resources/Users/Tables/UsersTable.php | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/Filament/Resources/Articles/Tables/ArticlesTable.php b/app/Filament/Resources/Articles/Tables/ArticlesTable.php index d7c795d57..a6817c114 100644 --- a/app/Filament/Resources/Articles/Tables/ArticlesTable.php +++ b/app/Filament/Resources/Articles/Tables/ArticlesTable.php @@ -50,9 +50,7 @@ public static function configure(Table $table): Table ->icon('heroicon-s-eye'), ]) ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), + // ]); } } diff --git a/app/Filament/Resources/Users/Tables/UsersTable.php b/app/Filament/Resources/Users/Tables/UsersTable.php index 76822aab4..658b86abc 100644 --- a/app/Filament/Resources/Users/Tables/UsersTable.php +++ b/app/Filament/Resources/Users/Tables/UsersTable.php @@ -184,9 +184,7 @@ public static function configure(Table $table): Table ]), ]) ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make(), - ]), + // ]); } } From 6071d21678c833f7bdaa101ea5aa1a763ef45380 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Wed, 3 Sep 2025 19:33:21 +0200 Subject: [PATCH 15/19] Remove unused old admin panel parts --- .../Controllers/Admin/RepliesController.php | 21 --- app/Providers/Filament/AdminPanelProvider.php | 4 +- resources/views/admin/articles.blade.php | 84 ----------- .../admin/partials/_navigation.blade.php | 48 ------ resources/views/admin/replies.blade.php | 93 ------------ resources/views/admin/users.blade.php | 138 ------------------ resources/views/layouts/_nav.blade.php | 2 +- routes/web.php | 10 -- 8 files changed, 3 insertions(+), 397 deletions(-) delete mode 100644 app/Http/Controllers/Admin/RepliesController.php delete mode 100644 resources/views/admin/articles.blade.php delete mode 100644 resources/views/admin/partials/_navigation.blade.php delete mode 100644 resources/views/admin/replies.blade.php delete mode 100644 resources/views/admin/users.blade.php diff --git a/app/Http/Controllers/Admin/RepliesController.php b/app/Http/Controllers/Admin/RepliesController.php deleted file mode 100644 index 50f431a96..000000000 --- a/app/Http/Controllers/Admin/RepliesController.php +++ /dev/null @@ -1,21 +0,0 @@ -appends(['admin_search' => $adminSearch]); - } else { - $replies = Reply::with('replyAbleRelation')->orderByDesc('updated_at')->paginate(); - } - - return view('admin.replies', compact('replies', 'adminSearch')); - } -} diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 31003346e..a262d5a78 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -29,8 +29,8 @@ public function panel(Panel $panel): Panel { return $panel ->default() - ->id('admint') - ->path('admin-filament') + ->id('admin') + ->path('admin') ->login() ->colors([ 'primary' => '#18bc9c', diff --git a/resources/views/admin/articles.blade.php b/resources/views/admin/articles.blade.php deleted file mode 100644 index 407b12438..000000000 --- a/resources/views/admin/articles.blade.php +++ /dev/null @@ -1,84 +0,0 @@ -@title('Articles') - -@extends('layouts.default') - -@section('content') -
- @include('admin.partials._navigation', [ - 'query' => route('admin'), - 'search' => $adminSearch, - 'placeholder' => 'Search for articles...', - ]) -
- -
-
- @if($articles->isNotEmpty()) -
-
-
- - - - Author - Title - Submitted on - View - - - - @foreach ($articles as $article) - - - - - - - {{ $article->title() }} - - - - {{ $article->submittedAt()->format('j M Y H:i:s') }} - - - - - - - - - @endforeach - -
-
-
-
- @else - - @endif -
- -
- {{ $articles->render() }} -
-
-@endsection diff --git a/resources/views/admin/partials/_navigation.blade.php b/resources/views/admin/partials/_navigation.blade.php deleted file mode 100644 index ba3d45618..000000000 --- a/resources/views/admin/partials/_navigation.blade.php +++ /dev/null @@ -1,48 +0,0 @@ -
-
-
-

- Admin -

- - -
- -
-
- - -
-
-
- -
- - -
-
-
-
-
-
diff --git a/resources/views/admin/replies.blade.php b/resources/views/admin/replies.blade.php deleted file mode 100644 index 32ff43308..000000000 --- a/resources/views/admin/replies.blade.php +++ /dev/null @@ -1,93 +0,0 @@ -@title('Replies') - -@extends('layouts.default') - -@section('content') -
- @include('admin.partials._navigation', [ - 'query' => route('admin.replies'), - 'search' => $adminSearch, - 'placeholder' => 'Search for replies...', - ]) -
- -
-
- @if($replies->isNotEmpty()) -
-
-
- - - - Author - Thread - Content - Updated - View - - - - @foreach ($replies as $reply) - - - - - - - {{ $reply->replyAble()->subject() }} - - - - {{ $reply->excerpt() }} - - - - @if ($reply->updatedBy()) - YES - @else - NO - @endif - - - - - - - - - @endforeach - -
-
-
-
- @else - - @endif -
- -
- {{ $replies->render() }} -
-
-@endsection diff --git a/resources/views/admin/users.blade.php b/resources/views/admin/users.blade.php deleted file mode 100644 index fa8a6c21c..000000000 --- a/resources/views/admin/users.blade.php +++ /dev/null @@ -1,138 +0,0 @@ -@title('Users') - -@extends('layouts.default') - -@section('content') -
- @include('admin.partials._navigation', [ - 'query' => route('admin.users'), - 'search' => $adminSearch, - 'placeholder' => 'Search for users...', - ]) -
- -
-
-
-
-
- - - - Name - Role - Joined On - Profile - - - - @foreach ($users as $user) - - - - - - - - @if ($user->isBanned()) - banned - @elseif ($user->isAdmin()) - admin - @elseif ($user->isModerator()) - moderator - @else - user - @endif - - - - - {{ $user->createdAt()->format('j M Y H:i:s') }} - - - - - - - - @can(App\Policies\UserPolicy::DELETE, $user) - - - -

Deleting this user will remove their account and any related content like threads & replies. This cannot be undone.

-
- - - - -

All the threads from this user will be deleted. This cannot be undone.

-
- @endcan - - {{-- Toggle Verified Author --}} - @can(App\Policies\UserPolicy::ADMIN, $user) - @if ($user->isVerifiedAuthor()) - - -

This will remove the verified author status from this user.

-
- @else - - -

This will mark this user as a verified author.

-
- @endif - @endcan -
- - @endforeach - -
-
-
-
-
- -
- {{ $users->render() }} -
-
-@endsection diff --git a/resources/views/layouts/_nav.blade.php b/resources/views/layouts/_nav.blade.php index ac272c243..b396eb49f 100644 --- a/resources/views/layouts/_nav.blade.php +++ b/resources/views/layouts/_nav.blade.php @@ -209,7 +209,7 @@ @can(App\Policies\UserPolicy::ADMIN, App\Models\User::class)
  • - + Admin diff --git a/routes/web.php b/routes/web.php index 3e01420bd..ef6950645 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,7 +1,6 @@ name('admin')->group(function () { - Route::get('/', [AdminArticlesController::class, 'index']); - Route::get('replies', [AdminRepliesController::class, 'index'])->name('.replies'); - // Users - Route::get('users', [UsersController::class, 'index'])->name('.users'); Route::put('users/{username}/ban', [UsersController::class, 'ban'])->name('.users.ban'); Route::put('users/{username}/unban', [UsersController::class, 'unban'])->name('.users.unban'); - Route::put('users/{username}/verify-author', [UsersController::class, 'verifyAuthor'])->name('.users.verify-author'); - Route::put('users/{username}/unverify-author', [UsersController::class, 'unverifyAuthor'])->name('.users.unverify-author'); - Route::delete('users/{username}', [UsersController::class, 'delete'])->name('.users.delete'); - - Route::delete('users/{username}/threads', [UsersController::class, 'deleteThreads'])->name('.users.threads.delete'); // Articles Route::put('articles/{article}/approve', [AdminArticlesController::class, 'approve'])->name('.articles.approve'); From ed5a2037b5c38319fe7db7fbd0d05f7d9b577e6e Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Wed, 3 Sep 2025 21:13:28 +0200 Subject: [PATCH 16/19] Update AdminTest.php --- composer.json | 1 + composer.lock | 68 ++++++++++++++++++++++++++++++++++++- tests/Feature/AdminTest.php | 25 +++++++------- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index d3d9f5172..5022535ee 100644 --- a/composer.json +++ b/composer.json @@ -47,6 +47,7 @@ "nunomaduro/collision": "^8.0", "pestphp/pest": "^3.0", "pestphp/pest-plugin-laravel": "^3.0", + "pestphp/pest-plugin-livewire": "^3.0", "spatie/pixelmatch-php": "^1.1" }, "autoload": { diff --git a/composer.lock b/composer.lock index d3bc0563b..3793c5cda 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e78f320ff0b64523a34839c1dff8334c", + "content-hash": "5e92b2b4f9f381a4649d6f72fee04112", "packages": [ { "name": "abraham/twitteroauth", @@ -13184,6 +13184,72 @@ ], "time": "2025-04-21T07:40:53+00:00" }, + { + "name": "pestphp/pest-plugin-livewire", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-livewire.git", + "reference": "e2f2edb0a7d414d6837d87908a0e148256d3bf89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-livewire/zipball/e2f2edb0a7d414d6837d87908a0e148256d3bf89", + "reference": "e2f2edb0a7d414d6837d87908a0e148256d3bf89", + "shasum": "" + }, + "require": { + "livewire/livewire": "^3.5.6", + "pestphp/pest": "^3.0.0", + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^9.4.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Livewire Plugin", + "keywords": [ + "framework", + "livewire", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-livewire/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-09T00:05:59+00:00" + }, { "name": "pestphp/pest-plugin-mutate", "version": "v3.0.5", diff --git a/tests/Feature/AdminTest.php b/tests/Feature/AdminTest.php index 116b1b08e..d2a57e97d 100644 --- a/tests/Feature/AdminTest.php +++ b/tests/Feature/AdminTest.php @@ -1,5 +1,6 @@ get('/admin') - ->assertRedirect('/login'); + ->assertRedirect('/admin/login'); }); test('normal users cannot visit the admin section', function () { @@ -119,12 +122,10 @@ $this->loginAsAdmin(); - $this->delete('/admin/users/'.$user->username()) - ->assertRedirect('/admin/users'); + livewire(ListUsers::class) + ->callAction(TestAction::make('delete')->table($user)); $this->assertDatabaseMissing('users', ['name' => 'Freek Murze']); - - // Make sure associated content is deleted. $this->assertDatabaseMissing('threads', ['author_id' => $user->id()]); $this->assertDatabaseMissing('replies', ['replyable_id' => $thread->id()]); $this->assertDatabaseMissing('replies', ['author_id' => $user->id()]); @@ -135,8 +136,8 @@ $this->loginAsAdmin(); - $this->delete('/admin/users/'.$user->username()) - ->assertForbidden(); + livewire(ListUsers::class) + ->assertActionHidden(TestAction::make('delete')->table($user)); }); test('moderators cannot delete users', function () { @@ -144,8 +145,8 @@ $this->loginAsModerator(); - $this->delete('/admin/users/'.$user->username()) - ->assertForbidden(); + livewire(ListUsers::class) + ->assertActionHidden(TestAction::make('delete')->table($user)); }); test('admins can list submitted articles', function () { @@ -155,7 +156,7 @@ $this->loginAsAdmin(); - $this->get('admin') + $this->get('admin/articles') ->assertSee($submittedArticle->title()) ->assertDontSee($draftArticle->title()) ->assertDontSee($liveArticle->title()); @@ -168,7 +169,7 @@ $this->loginAsModerator(); - $this->get('admin') + $this->get('admin/articles') ->assertSee($submittedArticle->title()) ->assertDontSee($draftArticle->title()) ->assertDontSee($liveArticle->title()); @@ -183,7 +184,7 @@ test('guests cannot list submitted articles', function () { $this->get('admin') - ->assertRedirect('/login'); + ->assertRedirect('/admin/login'); }); test('admins can view submitted articles', function () { From 266c5cbfc652df2b5bd47214f7f9aff1ba73e2a0 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Sat, 6 Sep 2025 11:12:05 +0200 Subject: [PATCH 17/19] Rename Notifications component to UserNotifications to avoid conflict with Filament --- .../{Notifications.php => UserNotifications.php} | 4 ++-- ...ns.blade.php => user-notifications.blade.php} | 0 resources/views/users/notifications.blade.php | 2 +- tests/Feature/NotificationsTest.php | 16 ++++++++-------- 4 files changed, 11 insertions(+), 11 deletions(-) rename app/Livewire/{Notifications.php => UserNotifications.php} (92%) rename resources/views/livewire/{notifications.blade.php => user-notifications.blade.php} (100%) diff --git a/app/Livewire/Notifications.php b/app/Livewire/UserNotifications.php similarity index 92% rename from app/Livewire/Notifications.php rename to app/Livewire/UserNotifications.php index e86e8235e..9badf6f48 100644 --- a/app/Livewire/Notifications.php +++ b/app/Livewire/UserNotifications.php @@ -10,7 +10,7 @@ use Livewire\Component; use Livewire\WithPagination; -final class Notifications extends Component +final class UserNotifications extends Component { use AuthorizesRequests; use WithPagination; @@ -22,7 +22,7 @@ public function render(): View $notifications = Auth::user()->unreadNotifications()->paginate(10); $lastPage = count($notifications) == 0 ? $notifications->lastPage() : null; - return view('livewire.notifications', [ + return view('livewire.user-notifications', [ 'notifications' => Auth::user()->unreadNotifications()->paginate(10, ['*'], 'page', $lastPage), ]); } diff --git a/resources/views/livewire/notifications.blade.php b/resources/views/livewire/user-notifications.blade.php similarity index 100% rename from resources/views/livewire/notifications.blade.php rename to resources/views/livewire/user-notifications.blade.php diff --git a/resources/views/users/notifications.blade.php b/resources/views/users/notifications.blade.php index 5d2851275..3a2eb9a30 100644 --- a/resources/views/users/notifications.blade.php +++ b/resources/views/users/notifications.blade.php @@ -4,6 +4,6 @@ @section('content')
    - +
    @endsection diff --git a/tests/Feature/NotificationsTest.php b/tests/Feature/NotificationsTest.php index 917830ee6..792e9f219 100644 --- a/tests/Feature/NotificationsTest.php +++ b/tests/Feature/NotificationsTest.php @@ -1,6 +1,6 @@ loginAs($userOne); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->assertSee(new HtmlString( "A new reply was added to \"{$thread->subject()}\".", )); @@ -65,7 +65,7 @@ $this->loginAs($userOne); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->assertSee(new HtmlString( "A new reply was added to \"{$thread->subject()}\".", )) @@ -77,7 +77,7 @@ }); test('a_non_logged_in_user_cannot_access_notifications', function () { - Livewire::test(Notifications::class)->assertForbidden(); + Livewire::test(UserNotifications::class)->assertForbidden(); }); test('a_user_cannot_mark_other_users_notifications_as_read', function () { @@ -108,7 +108,7 @@ $this->loginAs($userTwo); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->call('markAsRead', $notification->id) ->assertForbidden(); }); @@ -143,7 +143,7 @@ $this->loginAs($userOne); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->assertSee('10'); }); @@ -167,13 +167,13 @@ $this->loginAs($userOne); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->assertSee('Clear All') ->assertViewHas('notificationCount', 1); post('/notifications/mark-as-read'); - Livewire::test(Notifications::class) + Livewire::test(UserNotifications::class) ->assertDontSee('Clear All') ->assertViewHas('notificationCount', 0); }); From 1e4945ca8ae67efee510fc91bf4aba24eb668eb0 Mon Sep 17 00:00:00 2001 From: theHocineSaad Date: Sat, 6 Sep 2025 11:42:49 +0200 Subject: [PATCH 18/19] composer update --- composer.lock | 279 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 186 insertions(+), 93 deletions(-) diff --git a/composer.lock b/composer.lock index 243136793..bdaef62c2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94003e630bf49820e3575d9b30c040c4", + "content-hash": "755b5e304f196a4a12f86795cebd0316", "packages": [ { "name": "abraham/twitteroauth", @@ -345,16 +345,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.356.8", + "version": "3.356.12", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3efa8c62c11fedb17b90f60b2d3a9f815b406e63" + "reference": "0068088fed44e2bed3a2e82f2c7a0bb9e356b3c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3efa8c62c11fedb17b90f60b2d3a9f815b406e63", - "reference": "3efa8c62c11fedb17b90f60b2d3a9f815b406e63", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0068088fed44e2bed3a2e82f2c7a0bb9e356b3c3", + "reference": "0068088fed44e2bed3a2e82f2c7a0bb9e356b3c3", "shasum": "" }, "require": { @@ -436,9 +436,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.356.8" + "source": "https://github.com/aws/aws-sdk-php/tree/3.356.12" }, - "time": "2025-08-29T18:06:18+00:00" + "time": "2025-09-05T18:10:41+00:00" }, { "name": "blade-ui-kit/blade-heroicons", @@ -592,25 +592,25 @@ }, { "name": "brick/math", - "version": "0.13.1", + "version": "0.14.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04" + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04", - "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04", + "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", + "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "6.8.8" + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" }, "type": "library", "autoload": { @@ -640,7 +640,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.13.1" + "source": "https://github.com/brick/math/tree/0.14.0" }, "funding": [ { @@ -648,7 +648,7 @@ "type": "github" } ], - "time": "2025-03-29T13:50:30+00:00" + "time": "2025-08-29T12:40:03+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -1591,16 +1591,16 @@ }, { "name": "filament/actions", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "d0eb10c93138ab09440bec8b00516c51dedb192f" + "reference": "839ce7099627bea6f44fb71d4302e2696795fede" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/d0eb10c93138ab09440bec8b00516c51dedb192f", - "reference": "d0eb10c93138ab09440bec8b00516c51dedb192f", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/839ce7099627bea6f44fb71d4302e2696795fede", + "reference": "839ce7099627bea6f44fb71d4302e2696795fede", "shasum": "" }, "require": { @@ -1636,20 +1636,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:50:43+00:00" + "time": "2025-09-04T14:12:54+00:00" }, { "name": "filament/filament", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "8c334868cef83c33c998ced5a800128be65065fd" + "reference": "5cc9f39f8f2112776d66cd0daeab8430f77921ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/8c334868cef83c33c998ced5a800128be65065fd", - "reference": "8c334868cef83c33c998ced5a800128be65065fd", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/5cc9f39f8f2112776d66cd0daeab8430f77921ce", + "reference": "5cc9f39f8f2112776d66cd0daeab8430f77921ce", "shasum": "" }, "require": { @@ -1693,20 +1693,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:38+00:00" + "time": "2025-09-04T14:12:49+00:00" }, { "name": "filament/forms", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "1b5baca0ed3d9c1814cf71ebced22e35e29e4b1e" + "reference": "8aea1f3a16bceefd226554953013c457aa430c40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/1b5baca0ed3d9c1814cf71ebced22e35e29e4b1e", - "reference": "1b5baca0ed3d9c1814cf71ebced22e35e29e4b1e", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/8aea1f3a16bceefd226554953013c457aa430c40", + "reference": "8aea1f3a16bceefd226554953013c457aa430c40", "shasum": "" }, "require": { @@ -1743,20 +1743,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:23+00:00" + "time": "2025-09-04T14:12:46+00:00" }, { "name": "filament/infolists", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "e24ee4af06b0f3621e1d5dc8cffa63d93f85316e" + "reference": "ecf47afbcc80732671b7c9170e7d9807a9f5a22b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/e24ee4af06b0f3621e1d5dc8cffa63d93f85316e", - "reference": "e24ee4af06b0f3621e1d5dc8cffa63d93f85316e", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/ecf47afbcc80732671b7c9170e7d9807a9f5a22b", + "reference": "ecf47afbcc80732671b7c9170e7d9807a9f5a22b", "shasum": "" }, "require": { @@ -1788,20 +1788,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:22+00:00" + "time": "2025-09-04T14:12:51+00:00" }, { "name": "filament/notifications", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", - "reference": "7f66df600982cacb8570bd3e8559a706a8151057" + "reference": "378b819305ca262eb8f0677774105dfccce49ac1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/notifications/zipball/7f66df600982cacb8570bd3e8559a706a8151057", - "reference": "7f66df600982cacb8570bd3e8559a706a8151057", + "url": "https://api.github.com/repos/filamentphp/notifications/zipball/378b819305ca262eb8f0677774105dfccce49ac1", + "reference": "378b819305ca262eb8f0677774105dfccce49ac1", "shasum": "" }, "require": { @@ -1835,20 +1835,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-15T11:44:04+00:00" + "time": "2025-09-04T14:12:43+00:00" }, { "name": "filament/schemas", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/schemas.git", - "reference": "2390d31073ab1cc485ae6aac17d8134310e641a4" + "reference": "328a2b34e812a56b33cf6e4184e1f177094b4a47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/schemas/zipball/2390d31073ab1cc485ae6aac17d8134310e641a4", - "reference": "2390d31073ab1cc485ae6aac17d8134310e641a4", + "url": "https://api.github.com/repos/filamentphp/schemas/zipball/328a2b34e812a56b33cf6e4184e1f177094b4a47", + "reference": "328a2b34e812a56b33cf6e4184e1f177094b4a47", "shasum": "" }, "require": { @@ -1880,20 +1880,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:19+00:00" + "time": "2025-09-04T14:12:50+00:00" }, { "name": "filament/support", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "68a0bb85f2b0ba88fd7d0856603cdf4d11574c2f" + "reference": "48684756dd3609abebb5c659cf90113a26e9e219" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/68a0bb85f2b0ba88fd7d0856603cdf4d11574c2f", - "reference": "68a0bb85f2b0ba88fd7d0856603cdf4d11574c2f", + "url": "https://api.github.com/repos/filamentphp/support/zipball/48684756dd3609abebb5c659cf90113a26e9e219", + "reference": "48684756dd3609abebb5c659cf90113a26e9e219", "shasum": "" }, "require": { @@ -1938,20 +1938,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:45+00:00" + "time": "2025-09-04T14:12:45+00:00" }, { "name": "filament/tables", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "ca4f15058e4cd756cffe67ea03c0eda3031d6a17" + "reference": "0c8e7f4f2bacfe1bea6dcfeb5c3d6cc0d173844f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/ca4f15058e4cd756cffe67ea03c0eda3031d6a17", - "reference": "ca4f15058e4cd756cffe67ea03c0eda3031d6a17", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/0c8e7f4f2bacfe1bea6dcfeb5c3d6cc0d173844f", + "reference": "0c8e7f4f2bacfe1bea6dcfeb5c3d6cc0d173844f", "shasum": "" }, "require": { @@ -1983,20 +1983,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:42+00:00" + "time": "2025-09-04T14:12:44+00:00" }, { "name": "filament/widgets", - "version": "v4.0.4", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", - "reference": "e693e6a2bf4c9ae9c52af6b16428a53b1feb038f" + "reference": "f761a52df367f8bde47d9d2518c3c0b646155345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/widgets/zipball/e693e6a2bf4c9ae9c52af6b16428a53b1feb038f", - "reference": "e693e6a2bf4c9ae9c52af6b16428a53b1feb038f", + "url": "https://api.github.com/repos/filamentphp/widgets/zipball/f761a52df367f8bde47d9d2518c3c0b646155345", + "reference": "f761a52df367f8bde47d9d2518c3c0b646155345", "shasum": "" }, "require": { @@ -2027,7 +2027,7 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-08-27T09:51:50+00:00" + "time": "2025-09-04T14:12:52+00:00" }, { "name": "firebase/php-jwt", @@ -3440,16 +3440,16 @@ }, { "name": "laravel/horizon", - "version": "v5.33.4", + "version": "v5.33.5", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "678362049ce5b9ce96673ac0282bbfda3279eca9" + "reference": "ef1c74b8134432eddabbd512e6e61a2e84a13d7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/678362049ce5b9ce96673ac0282bbfda3279eca9", - "reference": "678362049ce5b9ce96673ac0282bbfda3279eca9", + "url": "https://api.github.com/repos/laravel/horizon/zipball/ef1c74b8134432eddabbd512e6e61a2e84a13d7a", + "reference": "ef1c74b8134432eddabbd512e6e61a2e84a13d7a", "shasum": "" }, "require": { @@ -3514,9 +3514,9 @@ ], "support": { "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.33.4" + "source": "https://github.com/laravel/horizon/tree/v5.33.5" }, - "time": "2025-08-25T13:31:24+00:00" + "time": "2025-08-31T23:36:14+00:00" }, { "name": "laravel/nightwatch", @@ -4927,16 +4927,16 @@ }, { "name": "livewire/flux", - "version": "v2.2.6", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/livewire/flux.git", - "reference": "a0e8f33a5cd54ead4d8e27721961425ccbae2e33" + "reference": "d76c702806f48b75427226a81ffdbfb1d2b1b47d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/flux/zipball/a0e8f33a5cd54ead4d8e27721961425ccbae2e33", - "reference": "a0e8f33a5cd54ead4d8e27721961425ccbae2e33", + "url": "https://api.github.com/repos/livewire/flux/zipball/d76c702806f48b75427226a81ffdbfb1d2b1b47d", + "reference": "d76c702806f48b75427226a81ffdbfb1d2b1b47d", "shasum": "" }, "require": { @@ -4987,9 +4987,9 @@ ], "support": { "issues": "https://github.com/livewire/flux/issues", - "source": "https://github.com/livewire/flux/tree/v2.2.6" + "source": "https://github.com/livewire/flux/tree/v2.3.1" }, - "time": "2025-08-27T02:05:01+00:00" + "time": "2025-09-05T03:49:53+00:00" }, { "name": "livewire/livewire", @@ -6068,6 +6068,99 @@ ], "time": "2024-09-09T07:06:30+00:00" }, + { + "name": "openspout/openspout", + "version": "v4.32.0", + "source": { + "type": "git", + "url": "https://github.com/openspout/openspout.git", + "reference": "41f045c1f632e1474e15d4c7bc3abcb4a153563d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/openspout/openspout/zipball/41f045c1f632e1474e15d4c7bc3abcb4a153563d", + "reference": "41f045c1f632e1474e15d4c7bc3abcb4a153563d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-filter": "*", + "ext-libxml": "*", + "ext-xmlreader": "*", + "ext-zip": "*", + "php": "~8.3.0 || ~8.4.0 || ~8.5.0" + }, + "require-dev": { + "ext-zlib": "*", + "friendsofphp/php-cs-fixer": "^3.86.0", + "infection/infection": "^0.31.2", + "phpbench/phpbench": "^1.4.1", + "phpstan/phpstan": "^2.1.22", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.6", + "phpunit/phpunit": "^12.3.7" + }, + "suggest": { + "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)", + "ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "OpenSpout\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Adrien Loison", + "email": "adrien@box.com" + } + ], + "description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way", + "homepage": "https://github.com/openspout/openspout", + "keywords": [ + "OOXML", + "csv", + "excel", + "memory", + "odf", + "ods", + "office", + "open", + "php", + "read", + "scale", + "spreadsheet", + "stream", + "write", + "xlsx" + ], + "support": { + "issues": "https://github.com/openspout/openspout/issues", + "source": "https://github.com/openspout/openspout/tree/v4.32.0" + }, + "funding": [ + { + "url": "https://paypal.me/filippotessarotto", + "type": "custom" + }, + { + "url": "https://github.com/Slamdunk", + "type": "github" + } + ], + "time": "2025-09-03T16:03:54+00:00" + }, { "name": "oscarotero/html-parser", "version": "v0.1.8", @@ -7217,20 +7310,20 @@ }, { "name": "ramsey/uuid", - "version": "4.9.0", + "version": "4.9.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0" + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0", - "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -7289,9 +7382,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.0" + "source": "https://github.com/ramsey/uuid/tree/4.9.1" }, - "time": "2025-06-25T14:20:11+00:00" + "time": "2025-09-04T20:59:21+00:00" }, { "name": "riimu/kit-phpencoder", @@ -7500,16 +7593,16 @@ }, { "name": "sentry/sentry", - "version": "4.15.1", + "version": "4.15.2", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "0d09baf3700869ec4b723c95eb466de56c3d74b6" + "reference": "61a2d918e8424b6de4a2e265c15133a00c17db51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/0d09baf3700869ec4b723c95eb466de56c3d74b6", - "reference": "0d09baf3700869ec4b723c95eb466de56c3d74b6", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/61a2d918e8424b6de4a2e265c15133a00c17db51", + "reference": "61a2d918e8424b6de4a2e265c15133a00c17db51", "shasum": "" }, "require": { @@ -7573,7 +7666,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.15.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.15.2" }, "funding": [ { @@ -7585,27 +7678,27 @@ "type": "custom" } ], - "time": "2025-08-28T15:45:14+00:00" + "time": "2025-09-03T07:23:48+00:00" }, { "name": "sentry/sentry-laravel", - "version": "4.15.1", + "version": "4.15.3", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-laravel.git", - "reference": "7e0675e8e06d1ec5cb623792892920000a3aedb5" + "reference": "c3f71a83e8b3a1451e811199d145e864519cecc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/7e0675e8e06d1ec5cb623792892920000a3aedb5", - "reference": "7e0675e8e06d1ec5cb623792892920000a3aedb5", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/c3f71a83e8b3a1451e811199d145e864519cecc1", + "reference": "c3f71a83e8b3a1451e811199d145e864519cecc1", "shasum": "" }, "require": { "illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 | ^12.0", "nyholm/psr7": "^1.0", "php": "^7.2 | ^8.0", - "sentry/sentry": "^4.14.1", + "sentry/sentry": "^4.15.2", "symfony/psr-http-message-bridge": "^1.0 | ^2.0 | ^6.0 | ^7.0" }, "require-dev": { @@ -7662,7 +7755,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-laravel/issues", - "source": "https://github.com/getsentry/sentry-laravel/tree/4.15.1" + "source": "https://github.com/getsentry/sentry-laravel/tree/4.15.3" }, "funding": [ { @@ -7674,7 +7767,7 @@ "type": "custom" } ], - "time": "2025-06-24T12:39:03+00:00" + "time": "2025-09-04T14:37:41+00:00" }, { "name": "spatie/backtrace", From b3786c159472773d3d49a0c66d1445a1e12a4ea2 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 19 Sep 2025 16:47:38 +0200 Subject: [PATCH 19/19] wip --- .../Resources/Users/Pages/ListUsers.php | 1 - .../Resources/Users/Tables/UsersTable.php | 2 - app/Filament/Resources/Users/UserResource.php | 4 -- .../Controllers/Admin/ArticlesController.php | 15 ----- .../Controllers/Admin/UsersController.php | 60 ------------------- routes/web.php | 6 +- 6 files changed, 3 insertions(+), 85 deletions(-) diff --git a/app/Filament/Resources/Users/Pages/ListUsers.php b/app/Filament/Resources/Users/Pages/ListUsers.php index 778848e6f..9de7f5b08 100644 --- a/app/Filament/Resources/Users/Pages/ListUsers.php +++ b/app/Filament/Resources/Users/Pages/ListUsers.php @@ -3,7 +3,6 @@ namespace App\Filament\Resources\Users\Pages; use App\Filament\Resources\Users\UserResource; -use Filament\Actions\CreateAction; use Filament\Resources\Pages\ListRecords; class ListUsers extends ListRecords diff --git a/app/Filament/Resources/Users/Tables/UsersTable.php b/app/Filament/Resources/Users/Tables/UsersTable.php index 658b86abc..4787a2f57 100644 --- a/app/Filament/Resources/Users/Tables/UsersTable.php +++ b/app/Filament/Resources/Users/Tables/UsersTable.php @@ -11,9 +11,7 @@ use App\Policies\UserPolicy; use Filament\Actions\Action; use Filament\Actions\ActionGroup; -use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteAction; -use Filament\Actions\DeleteBulkAction; use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\TextInput; use Filament\Notifications\Notification; diff --git a/app/Filament/Resources/Users/UserResource.php b/app/Filament/Resources/Users/UserResource.php index 6dd5e6a7c..34f784bfa 100644 --- a/app/Filament/Resources/Users/UserResource.php +++ b/app/Filament/Resources/Users/UserResource.php @@ -2,15 +2,11 @@ namespace App\Filament\Resources\Users; -use App\Filament\Resources\Users\Pages\CreateUser; -use App\Filament\Resources\Users\Pages\EditUser; use App\Filament\Resources\Users\Pages\ListUsers; -use App\Filament\Resources\Users\Schemas\UserForm; use App\Filament\Resources\Users\Tables\UsersTable; use App\Models\User; use BackedEnum; use Filament\Resources\Resource; -use Filament\Schemas\Schema; use Filament\Support\Icons\Heroicon; use Filament\Tables\Table; diff --git a/app/Http/Controllers/Admin/ArticlesController.php b/app/Http/Controllers/Admin/ArticlesController.php index a8433dc1f..8d928645e 100644 --- a/app/Http/Controllers/Admin/ArticlesController.php +++ b/app/Http/Controllers/Admin/ArticlesController.php @@ -9,10 +9,8 @@ use App\Jobs\DisapproveArticle; use App\Models\Article; use App\Policies\ArticlePolicy; -use App\Queries\SearchArticles; use Illuminate\Auth\Middleware\Authenticate; use Illuminate\Http\RedirectResponse; -use Illuminate\View\View; class ArticlesController extends Controller { @@ -21,19 +19,6 @@ public function __construct() $this->middleware([Authenticate::class, VerifyAdmins::class]); } - public function index(): View - { - if ($adminSearch = request('admin_search')) { - $articles = SearchArticles::get($adminSearch)->appends(['admin_search' => $adminSearch]); - } else { - $articles = Article::awaitingApproval() - ->orderByDesc('submitted_at') - ->paginate(); - } - - return view('admin.articles', compact('articles', 'adminSearch')); - } - public function approve(Article $article): RedirectResponse { $this->authorize(ArticlePolicy::APPROVE, $article); diff --git a/app/Http/Controllers/Admin/UsersController.php b/app/Http/Controllers/Admin/UsersController.php index f274e2393..e03c2ecf5 100644 --- a/app/Http/Controllers/Admin/UsersController.php +++ b/app/Http/Controllers/Admin/UsersController.php @@ -6,17 +6,12 @@ use App\Http\Middleware\VerifyAdmins; use App\Http\Requests\BanRequest; use App\Jobs\BanUser; -use App\Jobs\DeleteUser; use App\Jobs\DeleteUserThreads; use App\Jobs\UnbanUser; -use App\Jobs\UnVerifyAuthor; -use App\Jobs\VerifyAuthor; use App\Models\User; use App\Policies\UserPolicy; -use App\Queries\SearchUsers; use Illuminate\Auth\Middleware\Authenticate; use Illuminate\Http\RedirectResponse; -use Illuminate\View\View; class UsersController extends Controller { @@ -25,17 +20,6 @@ public function __construct() $this->middleware([Authenticate::class, VerifyAdmins::class]); } - public function index(): View - { - if ($adminSearch = request('admin_search')) { - $users = SearchUsers::get($adminSearch)->appends(['admin_search' => $adminSearch]); - } else { - $users = User::latest()->paginate(20); - } - - return view('admin.users', compact('users', 'adminSearch')); - } - public function ban(BanRequest $request, User $user): RedirectResponse { $this->authorize(UserPolicy::BAN, $user); @@ -61,48 +45,4 @@ public function unban(User $user): RedirectResponse return redirect()->route('profile', $user->username()); } - - public function verifyAuthor(User $user) - { - $this->authorize(UserPolicy::ADMIN, $user); - - $this->dispatchSync(new VerifyAuthor($user)); - - $this->success($user->name().' was verified!'); - - return redirect()->route('admin.users'); - } - - public function unverifyAuthor(User $user) - { - $this->authorize(UserPolicy::ADMIN, $user); - - $this->dispatchSync(new UnverifyAuthor($user)); - - $this->success($user->name().' was unverified!'); - - return redirect()->route('admin.users'); - } - - public function delete(User $user): RedirectResponse - { - $this->authorize(UserPolicy::DELETE, $user); - - $this->dispatchSync(new DeleteUser($user)); - - $this->success($user->name().' was deleted and all of their content was removed!'); - - return redirect()->route('admin.users'); - } - - public function deleteThreads(User $user): RedirectResponse - { - $this->authorize(UserPolicy::DELETE, $user); - - $this->dispatchSync(new DeleteUserThreads($user)); - - $this->success($user->name().' threads were deleted!'); - - return redirect()->route('admin.users'); - } } diff --git a/routes/web.php b/routes/web.php index ef6950645..f8b42d2c4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,7 +1,7 @@ name('admin')->group(function () { // Users - Route::put('users/{username}/ban', [UsersController::class, 'ban'])->name('.users.ban'); - Route::put('users/{username}/unban', [UsersController::class, 'unban'])->name('.users.unban'); + Route::put('users/{username}/ban', [AdminUsersController::class, 'ban'])->name('.users.ban'); + Route::put('users/{username}/unban', [AdminUsersController::class, 'unban'])->name('.users.unban'); // Articles Route::put('articles/{article}/approve', [AdminArticlesController::class, 'approve'])->name('.articles.approve');