diff --git a/.circleci/config.yml b/.circleci/config.yml index 4653d8c..3632be3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,63 +1,66 @@ -# PHP CircleCI 2.0 configuration file -# See: https://circleci.com/docs/2.0/language-php/ -version: 2 +version: 2.1 -# Define a job to be invoked later in a workflow. -# See: https://circleci.com/docs/2.0/configuration-reference/#jobs -jobs: - build: - # Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub. - # See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor +executors: + php-executor: docker: - # Specify the version you desire here - - image: cimg/php:8.2.20-node - - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # Using the RAM variation mitigates I/O contention - # for database intensive operations. - # - image: circleci/mysql:5.7-ram - # - #- image: redis:2.8.19 + - image: cimg/php:<>-browsers + - image: redis:alpine + parameters: + php-version: + type: string + default: "8.0" + working_directory: ~/laravel-super-cache-invalidate - # Add steps to the job - # See: https://circleci.com/docs/2.0/configuration-reference/#steps +jobs: + test: + parameters: + php-version: + type: string + laravel-version: + type: string + executor: + name: php-executor + php-version: <> steps: - checkout + - run: + name: Install Redis Extension + command: | + yes 'no' | sudo pecl install -f redis || true + sudo docker-php-ext-enable redis.so + #- run: + # name: Update Composer + # command: sudo composer self-update + - run: + name: Install Dependencies + command: composer install --prefer-dist --no-interaction + - run: + name: Install Dependencies + command: | + sudo composer require "laravel/framework:^10.0" --no-update + sudo composer install --prefer-dist --no-interaction + - run: + name: Prepare bootstrap/cache directory + command: mkdir -p ./vendor/orchestra/testbench-core/laravel/bootstrap/cache && chmod -R 777 ./vendor/orchestra/testbench-core/laravel/bootstrap/cache - - run: sudo apt update -y && sudo apt-get install -y zip unzip # PHP CircleCI 2.0 Configuration File# PHP CircleCI 2.0 Configuration File sudo apt install zlib1g-dev libsqlite3-dev - - run: sudo docker-php-ext-install zip - #- run: sudo install-php-extensions redis - - # Download and cache dependencies - - restore_cache: - keys: - # "composer.lock" can be used if it is committed to the repo - - v1-dependencies-{{ checksum "composer.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - - run: composer install -n --prefer-dist --ignore-platform-req=ext-redis - - - save_cache: - key: v1-dependencies-{{ checksum "composer.json" }} - paths: - - ./vendor - #- restore_cache: - # keys: - # - node-v1-{{ checksum "package.json" }} - # - node-v1- - - run: yarn install - #- save_cache: - # key: node-v1-{{ checksum "package.json" }} - # paths: - # - node_modules - - # prepare the database - #- run: touch storage/testing.sqlite - #- run: php artisan migrate --env=testing --database=sqlite_testing --force + - run: + name: Run Tests + command: | + vendor/bin/phpunit - # run tests with phpunit or codecept - #- run: ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - - run: ./vendor/bin/phpunit +workflows: + version: 2 + test: + jobs: + - test: + name: PHP 8.2 + Laravel 10 + php-version: "8.2" + laravel-version: "10" + - test: + name: PHP 8.3 + Laravel 10 + php-version: "8.3" + laravel-version: "10" + - test: + name: PHP 8.4 + Laravel 10 + php-version: "8.4" + laravel-version: "10" diff --git a/.gitignore b/.gitignore index b18d6d8..0d7fe0c 100644 --- a/.gitignore +++ b/.gitignore @@ -468,3 +468,4 @@ resources/frontend/default/js/components/clientComponents/* #escludo la cartella personal_scripts presente in utility così ognuno può avere i suoi script personali utility/personal_scripts +/storage/logs/tests/.phpunit.cache/test-results diff --git a/README.md b/README.md index 98094a6..28d60b8 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ composer require padosoft/laravel-super-cache-invalidate Publish the configuration and migrations: ```bash -php artisan vendor:publish --provider="Padosoft\SuperCacheInvalidate\SuperCacheInvalidationServiceProvider" +php artisan vendor:publish --provider="Padosoft\SuperCacheInvalidate\SuperCacheInvalidateServiceProvider" ``` Run migrations: @@ -94,6 +94,7 @@ return [ 'lock_timeout' => 600, 'key_invalidation_callback' => null, 'tag_invalidation_callback' => null, + 'default_connection_name' => null, ]; ``` @@ -108,10 +109,10 @@ use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper; $helper = app(Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper::class); // Invalidate a tag -$helper->insertInvalidationEvent('tag', 'category:sport', 'Product updated in category sport'); +$helper->insertInvalidationEvent('tag', 'category:sport', 'cache', 'Product updated in category sport'); // Invalidate a key -$helper->insertInvalidationEvent('key', 'cache_key_xyz', 'Specific cache key invalidated'); +$helper->insertInvalidationEvent('key', 'cache_key_xyz', 'fullpage-cache', 'Specific cache key invalidated'); // Invalidate a key with associated tags // In this example, when the event for article_ID:7 is processed, @@ -121,10 +122,12 @@ $helper->insertInvalidationEvent('key', 'cache_key_xyz', 'Specific cache key inv $helper->insertInvalidationEvent( 'tag', 'article_ID:7', + 'fullpage-cache', 'Article 7 removed from sale', 0, + 0, [ - ['type' => 'tag', 'identifier' => 'plp:sport'] + ['type' => 'tag', 'identifier' => 'plp:sport', 'connection_name' => 'cache'] ] ); ``` @@ -134,7 +137,7 @@ $helper->insertInvalidationEvent( Schedule the processing command to run at desired intervals: ```bash -php artisan supercache:process-invalidation --shard=0 --priority=0 +php artisan supercache:process-invalidation --shard=0 --priority=0 --connection_name=cache ``` You can add it to your schedule method in App\Console\Kernel.php: diff --git a/composer.json b/composer.json index f593dfa..ee68a7d 100644 --- a/composer.json +++ b/composer.json @@ -19,13 +19,13 @@ } ], "require": { - "php" : "^8.0", - "illuminate/support": "^9.0|^10.0|^11.0" , + "php": "^8.0", + "illuminate/support": "^9.0|^10.0|^11.0", "laravel/framework": "^9.0|^10.0|^11.0", - "predis/predis": "^2.0", - "ext-redis": "*" + "predis/predis": "^2.0" }, "require-dev": { + "m6web/redis-mock": "^5.6", "phpunit/phpunit": "^9.5|^10.0|^11.0", "orchestra/testbench": "^7.0|^8.0|^9.0", "mockery/mockery": "^1.5", @@ -37,8 +37,7 @@ "phpmd/phpmd": "^2.15", "spatie/laravel-ignition": "^2.3", "spatie/laravel-ray": "^1.32", - "squizlabs/php_codesniffer": "^3.7", - "laradumps/laradumps": "3.0" + "squizlabs/php_codesniffer": "^3.7" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 5713405..3f40307 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": "719330be5ef09ca39aa3243474bf761d", + "content-hash": "e77b049017114c3e886cb24ee58f1a71", "packages": [ { "name": "brick/math", @@ -731,16 +731,16 @@ }, { "name": "laravel/framework", - "version": "v10.48.24", + "version": "v10.48.25", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "2add73f71b88fc45ee1d4f3421f22366247f6155" + "reference": "f132b23b13909cc22c615c01b0c5640541c3da0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/2add73f71b88fc45ee1d4f3421f22366247f6155", - "reference": "2add73f71b88fc45ee1d4f3421f22366247f6155", + "url": "https://api.github.com/repos/laravel/framework/zipball/f132b23b13909cc22c615c01b0c5640541c3da0c", + "reference": "f132b23b13909cc22c615c01b0c5640541c3da0c", "shasum": "" }, "require": { @@ -847,7 +847,7 @@ "nyholm/psr7": "^1.2", "orchestra/testbench-core": "^8.23.4", "pda/pheanstalk": "^4.0", - "phpstan/phpstan": "^1.4.7", + "phpstan/phpstan": "~1.11.11", "phpunit/phpunit": "^10.0.7", "predis/predis": "^2.0.2", "symfony/cache": "^6.2", @@ -934,7 +934,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-11-20T15:57:07+00:00" + "time": "2024-11-26T15:32:57+00:00" }, { "name": "laravel/prompts", @@ -2539,16 +2539,16 @@ }, { "name": "symfony/css-selector", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66" + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", - "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", "shasum": "" }, "require": { @@ -2584,7 +2584,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.1.6" + "source": "https://github.com/symfony/css-selector/tree/v7.2.0" }, "funding": [ { @@ -2600,20 +2600,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -2651,7 +2651,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -2667,7 +2667,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/error-handler", @@ -2746,16 +2746,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "87254c78dd50721cfd015b62277a8281c5589702" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702", - "reference": "87254c78dd50721cfd015b62277a8281c5589702", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { @@ -2806,7 +2806,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.1.6" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -2822,20 +2822,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -2882,7 +2882,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -2898,7 +2898,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/finder", @@ -2966,16 +2966,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.15", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9b3165eb2f04aeaa1a5a2cfef73e63fe3b22dff6" + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9b3165eb2f04aeaa1a5a2cfef73e63fe3b22dff6", - "reference": "9b3165eb2f04aeaa1a5a2cfef73e63fe3b22dff6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/431771b7a6f662f1575b3cfc8fd7617aa9864d57", + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57", "shasum": "" }, "require": { @@ -3023,7 +3023,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.15" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.16" }, "funding": [ { @@ -3039,20 +3039,20 @@ "type": "tidelift" } ], - "time": "2024-11-08T16:09:24+00:00" + "time": "2024-11-13T18:58:10+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.15", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "b002a5b3947653c5aee3adac2a024ea615fd3ff5" + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b002a5b3947653c5aee3adac2a024ea615fd3ff5", - "reference": "b002a5b3947653c5aee3adac2a024ea615fd3ff5", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", "shasum": "" }, "require": { @@ -3137,7 +3137,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/v6.4.15" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.16" }, "funding": [ { @@ -3153,7 +3153,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:57:37+00:00" + "time": "2024-11-27T12:49:36+00:00" }, { "name": "symfony/mailer", @@ -4019,16 +4019,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "640a74250d13f9c30d5ca045b6aaaabcc8215278" + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/640a74250d13f9c30d5ca045b6aaaabcc8215278", - "reference": "640a74250d13f9c30d5ca045b6aaaabcc8215278", + "url": "https://api.github.com/repos/symfony/routing/zipball/91e02e606b4b705c2f4fb42f7e7708b7923a3220", + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220", "shasum": "" }, "require": { @@ -4082,7 +4082,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.13" + "source": "https://github.com/symfony/routing/tree/v6.4.16" }, "funding": [ { @@ -4098,20 +4098,20 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:30:56+00:00" + "time": "2024-11-13T15:31:34+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -4165,7 +4165,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -4181,20 +4181,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { @@ -4252,7 +4252,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.8" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -4268,7 +4268,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:21+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/translation", @@ -4367,16 +4367,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -4425,7 +4425,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -4441,7 +4441,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/uid", @@ -5407,16 +5407,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.64.0", + "version": "v3.65.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "58dd9c931c785a79739310aef5178928305ffa67" + "reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", - "reference": "58dd9c931c785a79739310aef5178928305ffa67", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/79d4f3e77b250a7d8043d76c6af8f0695e8a469f", + "reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f", "shasum": "" }, "require": { @@ -5426,7 +5426,7 @@ "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", - "fidry/cpu-core-counter": "^1.0", + "fidry/cpu-core-counter": "^1.2", "php": "^7.4 || ^8.0", "react/child-process": "^0.6.5", "react/event-loop": "^1.0", @@ -5446,18 +5446,18 @@ "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "facile-it/paraunit": "^1.3 || ^2.3", - "infection/infection": "^0.29.5", - "justinrainbow/json-schema": "^5.2", + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", "keradus/cli-executor": "^2.1", - "mikey179/vfsstream": "^1.6.11", + "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", - "phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2", - "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", - "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + "phpunit/phpunit": "^9.6.21 || ^10.5.38 || ^11.4.3", + "symfony/var-dumper": "^5.4.47 || ^6.4.15 || ^7.1.8", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.1.6" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -5498,7 +5498,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.65.0" }, "funding": [ { @@ -5506,7 +5506,7 @@ "type": "github" } ], - "time": "2024-08-30T23:09:38+00:00" + "time": "2024-11-25T00:39:24+00:00" }, { "name": "guzzlehttp/psr7", @@ -5675,158 +5675,18 @@ }, "time": "2020-07-09T08:09:16+00:00" }, - { - "name": "laradumps/laradumps", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps.git", - "reference": "c70f5a7b7c5cd9f4d76002cf97d2d52e192d964f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps/zipball/c70f5a7b7c5cd9f4d76002cf97d2d52e192d964f", - "reference": "c70f5a7b7c5cd9f4d76002cf97d2d52e192d964f", - "shasum": "" - }, - "require": { - "illuminate/mail": "^10.0|^11.0", - "illuminate/support": "^10.0|^11.0", - "laradumps/laradumps-core": "^2.0", - "nunomaduro/termwind": "^1.15.1|^2.0.0", - "php": "^8.1" - }, - "require-dev": { - "larastan/larastan": "^2.7", - "laravel/framework": "^10.0|^11.0", - "laravel/pint": "^1.13.7", - "mockery/mockery": "^1.6", - "orchestra/testbench-core": "^8.0|^9.0", - "pestphp/pest": "^2.28.1", - "symfony/var-dumper": "^6.4.0|^7.0.3" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "LaraDumps\\LaraDumps\\LaraDumpsServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumps\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "A Dump Component for Laravel.", - "homepage": "https://github.com/laradumps/laradumps", - "support": { - "issues": "https://github.com/laradumps/laradumps/issues", - "source": "https://github.com/laradumps/laradumps/tree/v3.0.0" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2024-03-28T23:02:21+00:00" - }, - { - "name": "laradumps/laradumps-core", - "version": "v2.3.2", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps-core.git", - "reference": "de2a62929f339da160d58638b28ebf9f00ab2fdc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/de2a62929f339da160d58638b28ebf9f00ab2fdc", - "reference": "de2a62929f339da160d58638b28ebf9f00ab2fdc", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "nunomaduro/termwind": "^1.15|^2.0", - "php": "^8.1", - "ramsey/uuid": "^4.7.5", - "spatie/backtrace": "^1.5", - "symfony/console": "^5.4|^6.4|^7.0", - "symfony/finder": "^5.4|^6.4|^7.0", - "symfony/process": "^5.4|^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.4|^7.0", - "symfony/yaml": "^5.4|^6.4|^7.0" - }, - "require-dev": { - "illuminate/support": "^10.43", - "laravel/pint": "^1.13.7", - "pestphp/pest": "^2.28.1", - "phpstan/phpstan": "^1.10.50" - }, - "bin": [ - "bin/laradumps" - ], - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumpsCore\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "LaraDumps is a friendly app designed to boost your Laravel / PHP coding and debugging experience.", - "homepage": "https://github.com/laradumps/laradumps-core", - "support": { - "issues": "https://github.com/laradumps/laradumps-core/issues", - "source": "https://github.com/laradumps/laradumps-core/tree/v2.3.2" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2024-11-16T14:14:00+00:00" - }, { "name": "larastan/larastan", - "version": "v2.9.11", + "version": "v2.9.12", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "54eccd35d1732b9ee4392c25aec606a6a9c521e7" + "reference": "19012b39fbe4dede43dbe0c126d9681827a5e908" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/54eccd35d1732b9ee4392c25aec606a6a9c521e7", - "reference": "54eccd35d1732b9ee4392c25aec606a6a9c521e7", + "url": "https://api.github.com/repos/larastan/larastan/zipball/19012b39fbe4dede43dbe0c126d9681827a5e908", + "reference": "19012b39fbe4dede43dbe0c126d9681827a5e908", "shasum": "" }, "require": { @@ -5840,7 +5700,7 @@ "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.16", "php": "^8.0.2", "phpmyadmin/sql-parser": "^5.9.0", - "phpstan/phpstan": "^1.12.5" + "phpstan/phpstan": "^1.12.11" }, "require-dev": { "doctrine/coding-standard": "^12.0", @@ -5857,13 +5717,13 @@ }, "type": "phpstan-extension", "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - }, "phpstan": { "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-master": "2.0-dev" } }, "autoload": { @@ -5885,7 +5745,7 @@ "email": "enunomaduro@gmail.com" } ], - "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel", "keywords": [ "PHPStan", "code analyse", @@ -5898,40 +5758,28 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.9.11" + "source": "https://github.com/larastan/larastan/tree/v2.9.12" }, "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, { "url": "https://github.com/canvural", "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" } ], - "time": "2024-11-11T23:11:00+00:00" + "time": "2024-11-26T23:09:02+00:00" }, { "name": "laravel/pint", - "version": "v1.18.2", + "version": "v1.18.3", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "f55daaf7eb6c2f49ddf6702fb42e3091c64d8a64" + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/f55daaf7eb6c2f49ddf6702fb42e3091c64d8a64", - "reference": "f55daaf7eb6c2f49ddf6702fb42e3091c64d8a64", + "url": "https://api.github.com/repos/laravel/pint/zipball/cef51821608239040ab841ad6e1c6ae502ae3026", + "reference": "cef51821608239040ab841ad6e1c6ae502ae3026", "shasum": "" }, "require": { @@ -5942,13 +5790,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.64.0", - "illuminate/view": "^10.48.20", - "larastan/larastan": "^2.9.8", + "friendsofphp/php-cs-fixer": "^3.65.0", + "illuminate/view": "^10.48.24", + "larastan/larastan": "^2.9.11", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.35.1" + "nunomaduro/termwind": "^1.17.0", + "pestphp/pest": "^2.36.0" }, "bin": [ "builds/pint" @@ -5984,7 +5832,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-11-20T09:33:46+00:00" + "time": "2024-11-26T15:34:00+00:00" }, { "name": "laravel/tinker", @@ -6052,6 +5900,55 @@ }, "time": "2024-09-23T13:32:56+00:00" }, + { + "name": "m6web/redis-mock", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/BedrockStreaming/RedisMock.git", + "reference": "fdef627f640c63e95d804c11ac44d90d0baf2f99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/BedrockStreaming/RedisMock/zipball/fdef627f640c63e95d804c11ac44d90d0baf2f99", + "reference": "fdef627f640c63e95d804c11ac44d90d0baf2f99", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "atoum/atoum": "~3.4||~4.0", + "predis/predis": "~1.1" + }, + "type": "library", + "autoload": { + "psr-0": { + "M6Web\\Component\\RedisMock": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "M6Web", + "email": "opensource@m6web.fr", + "homepage": "http://tech.m6web.fr/" + } + ], + "description": "Library providing a PHP mock for Redis", + "keywords": [ + "mock", + "redis" + ], + "support": { + "issues": "https://github.com/BedrockStreaming/RedisMock/issues", + "source": "https://github.com/BedrockStreaming/RedisMock/tree/v5.6.0" + }, + "time": "2023-05-02T19:20:41+00:00" + }, { "name": "mockery/mockery", "version": "1.6.12", @@ -6351,34 +6248,34 @@ }, { "name": "orchestra/canvas", - "version": "v8.11.9", + "version": "v8.12.0", "source": { "type": "git", "url": "https://github.com/orchestral/canvas.git", - "reference": "9bed1ce6084af2ce166e9ea1cb160ff22dc94a6d" + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas/zipball/9bed1ce6084af2ce166e9ea1cb160ff22dc94a6d", - "reference": "9bed1ce6084af2ce166e9ea1cb160ff22dc94a6d", + "url": "https://api.github.com/repos/orchestral/canvas/zipball/76385dfcf96efae5f8533a4d522d14c3c946ac5a", + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "composer/semver": "^3.0", - "illuminate/console": "^10.48.4", - "illuminate/database": "^10.48.4", - "illuminate/filesystem": "^10.48.4", - "illuminate/support": "^10.48.4", + "illuminate/console": "^10.48.25", + "illuminate/database": "^10.48.25", + "illuminate/filesystem": "^10.48.25", + "illuminate/support": "^10.48.25", "orchestra/canvas-core": "^8.10.2", - "orchestra/testbench-core": "^8.19", + "orchestra/testbench-core": "^8.30", "php": "^8.1", - "symfony/polyfill-php83": "^1.28", + "symfony/polyfill-php83": "^1.31", "symfony/yaml": "^6.2" }, "require-dev": { - "laravel/framework": "^10.48.4", - "laravel/pint": "^1.6", + "laravel/framework": "^10.48.25", + "laravel/pint": "^1.17", "mockery/mockery": "^1.5.1", "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^10.5", @@ -6389,9 +6286,6 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-master": "9.0-dev" - }, "laravel": { "providers": [ "Orchestra\\Canvas\\LaravelServiceProvider" @@ -6420,9 +6314,9 @@ "description": "Code Generators for Laravel Applications and Packages", "support": { "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas/tree/v8.11.9" + "source": "https://github.com/orchestral/canvas/tree/v8.12.0" }, - "time": "2024-06-18T08:26:09+00:00" + "time": "2024-11-30T15:38:25+00:00" }, { "name": "orchestra/canvas-core", @@ -6498,25 +6392,25 @@ }, { "name": "orchestra/testbench", - "version": "v8.28.0", + "version": "v8.29.0", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "96beb6646dc2b766b92ba40379a56999a554904a" + "reference": "71b16faeb9b5eef1ea26414474cb5d845b5d91ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/96beb6646dc2b766b92ba40379a56999a554904a", - "reference": "96beb6646dc2b766b92ba40379a56999a554904a", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/71b16faeb9b5eef1ea26414474cb5d845b5d91ad", + "reference": "71b16faeb9b5eef1ea26414474cb5d845b5d91ad", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.23", + "laravel/framework": "^10.48.25", "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^8.29", - "orchestra/workbench": "^8.12", + "orchestra/testbench-core": "^8.30", + "orchestra/workbench": "^8.13", "php": "^8.1", "phpunit/phpunit": "^9.6 || ^10.1", "symfony/process": "^6.2", @@ -6547,22 +6441,22 @@ ], "support": { "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v8.28.0" + "source": "https://github.com/orchestral/testbench/tree/v8.29.0" }, - "time": "2024-11-18T23:55:06+00:00" + "time": "2024-12-01T11:05:50+00:00" }, { "name": "orchestra/testbench-core", - "version": "v8.29.0", + "version": "v8.30.0", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "55cf0234f9f96590bca4ece7081cc5c328e34e48" + "reference": "dd5d77d01bc1788cb328016eca6881fe07c2118d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/55cf0234f9f96590bca4ece7081cc5c328e34e48", - "reference": "55cf0234f9f96590bca4ece7081cc5c328e34e48", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/dd5d77d01bc1788cb328016eca6881fe07c2118d", + "reference": "dd5d77d01bc1788cb328016eca6881fe07c2118d", "shasum": "" }, "require": { @@ -6572,16 +6466,16 @@ }, "conflict": { "brianium/paratest": "<6.4.0 || >=7.0.0 <7.1.4 || >=8.0.0", - "laravel/framework": "<10.48.23 || >=11.0.0", + "laravel/framework": "<10.48.25 || >=11.0.0", "laravel/serializable-closure": "<1.3.0 || >=3.0.0", "nunomaduro/collision": "<6.4.0 || >=7.0.0 <7.4.0 || >=8.0.0", - "orchestra/testbench-dusk": "<8.21.0 || >=9.0.0", + "orchestra/testbench-dusk": "<8.32.0 || >=9.0.0", "orchestra/workbench": "<1.0.0", "phpunit/phpunit": "<9.6.0 || >=10.3.0 <10.3.3 || >=10.6.0" }, "require-dev": { "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.23", + "laravel/framework": "^10.48.25", "laravel/pint": "^1.17", "laravel/serializable-closure": "^1.3 || ^2.0", "mockery/mockery": "^1.5.1", @@ -6596,7 +6490,7 @@ "brianium/paratest": "Allow using parallel testing (^6.4 || ^7.1.4).", "ext-pcntl": "Required to use all features of the console signal trapping.", "fakerphp/faker": "Allow using Faker for testing (^1.21).", - "laravel/framework": "Required for testing (^10.48.23).", + "laravel/framework": "Required for testing (^10.48.25).", "mockery/mockery": "Allow using Mockery for testing (^1.5.1).", "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.4 || ^7.4).", "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^8.0).", @@ -6643,32 +6537,32 @@ "issues": "https://github.com/orchestral/testbench/issues", "source": "https://github.com/orchestral/testbench-core" }, - "time": "2024-11-18T12:42:00+00:00" + "time": "2024-12-01T09:20:16+00:00" }, { "name": "orchestra/workbench", - "version": "v8.12.0", + "version": "v8.13.0", "source": { "type": "git", "url": "https://github.com/orchestral/workbench.git", - "reference": "68a0042861ea4f9ace68d74a49e70aa5031244e7" + "reference": "88c8b743af8b46d7665b0195828ce3acb3c469bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/workbench/zipball/68a0042861ea4f9ace68d74a49e70aa5031244e7", - "reference": "68a0042861ea4f9ace68d74a49e70aa5031244e7", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/88c8b743af8b46d7665b0195828ce3acb3c469bd", + "reference": "88c8b743af8b46d7665b0195828ce3acb3c469bd", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.23", + "laravel/framework": "^10.48.25", "laravel/tinker": "^2.8.2", "nunomaduro/collision": "^6.4 || ^7.10", "orchestra/canvas": "^8.11.9", - "orchestra/testbench-core": "^8.29", + "orchestra/testbench-core": "^8.30", "php": "^8.1", - "symfony/polyfill-php83": "^1.28", + "symfony/polyfill-php83": "^1.31", "symfony/yaml": "^6.2" }, "require-dev": { @@ -6706,9 +6600,9 @@ ], "support": { "issues": "https://github.com/orchestral/workbench/issues", - "source": "https://github.com/orchestral/workbench/tree/v8.12.0" + "source": "https://github.com/orchestral/workbench/tree/v8.13.0" }, - "time": "2024-11-18T23:06:06+00:00" + "time": "2024-12-01T10:27:46+00:00" }, { "name": "pdepend/pdepend", @@ -7253,16 +7147,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.11", + "version": "1.12.12", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733" + "reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", - "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0", + "reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0", "shasum": "" }, "require": { @@ -7307,7 +7201,7 @@ "type": "github" } ], - "time": "2024-11-17T14:08:01+00:00" + "time": "2024-11-28T22:13:23+00:00" }, { "name": "phpunit/php-code-coverage", @@ -7841,16 +7735,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.4", + "version": "v0.12.5", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "2fd717afa05341b4f8152547f142cd2f130f6818" + "reference": "36a03ff27986682c22985e56aabaf840dd173cb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/2fd717afa05341b4f8152547f142cd2f130f6818", - "reference": "2fd717afa05341b4f8152547f142cd2f130f6818", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/36a03ff27986682c22985e56aabaf840dd173cb5", + "reference": "36a03ff27986682c22985e56aabaf840dd173cb5", "shasum": "" }, "require": { @@ -7877,12 +7771,12 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-main": "0.12.x-dev" - }, "bamarni-bin": { "bin-links": false, "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" } }, "autoload": { @@ -7914,9 +7808,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.4" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.5" }, - "time": "2024-06-10T01:18:23+00:00" + "time": "2024-11-29T06:14:30+00:00" }, { "name": "ralouphie/getallheaders", @@ -9469,27 +9363,27 @@ }, { "name": "spatie/backtrace", - "version": "1.6.3", + "version": "1.7.1", "source": { "type": "git", "url": "https://github.com/spatie/backtrace.git", - "reference": "7c18db2bc667ac84e5d7c18e33f16c38ff2d8838" + "reference": "0f2477c520e3729de58e061b8192f161c99f770b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/7c18db2bc667ac84e5d7c18e33f16c38ff2d8838", - "reference": "7c18db2bc667ac84e5d7c18e33f16c38ff2d8838", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/0f2477c520e3729de58e061b8192f161c99f770b", + "reference": "0f2477c520e3729de58e061b8192f161c99f770b", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^7.3 || ^8.0" }, "require-dev": { "ext-json": "*", - "laravel/serializable-closure": "^1.3", - "phpunit/phpunit": "^9.3", - "spatie/phpunit-snapshot-assertions": "^4.2", - "symfony/var-dumper": "^5.1" + "laravel/serializable-closure": "^1.3 || ^2.0", + "phpunit/phpunit": "^9.3 || ^11.4.3", + "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6", + "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0" }, "type": "library", "autoload": { @@ -9516,7 +9410,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/backtrace/tree/1.6.3" + "source": "https://github.com/spatie/backtrace/tree/1.7.1" }, "funding": [ { @@ -9528,7 +9422,7 @@ "type": "other" } ], - "time": "2024-11-18T14:58:58+00:00" + "time": "2024-12-02T13:28:15+00:00" }, { "name": "spatie/error-solutions", @@ -9606,16 +9500,16 @@ }, { "name": "spatie/flare-client-php", - "version": "1.8.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/spatie/flare-client-php.git", - "reference": "180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122" + "reference": "140a42b2c5d59ac4ecf8f5b493386a4f2eb28272" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122", - "reference": "180f8ca4c0d0d6fc51477bd8c53ce37ab5a96122", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/140a42b2c5d59ac4ecf8f5b493386a4f2eb28272", + "reference": "140a42b2c5d59ac4ecf8f5b493386a4f2eb28272", "shasum": "" }, "require": { @@ -9663,7 +9557,7 @@ ], "support": { "issues": "https://github.com/spatie/flare-client-php/issues", - "source": "https://github.com/spatie/flare-client-php/tree/1.8.0" + "source": "https://github.com/spatie/flare-client-php/tree/1.10.0" }, "funding": [ { @@ -9671,7 +9565,7 @@ "type": "github" } ], - "time": "2024-08-01T08:27:26+00:00" + "time": "2024-12-02T14:30:06+00:00" }, { "name": "spatie/ignition", @@ -9758,16 +9652,16 @@ }, { "name": "spatie/laravel-ignition", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "3c067b75bfb50574db8f7e2c3978c65eed71126c" + "reference": "62042df15314b829d0f26e02108f559018e2aad0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/3c067b75bfb50574db8f7e2c3978c65eed71126c", - "reference": "3c067b75bfb50574db8f7e2c3978c65eed71126c", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/62042df15314b829d0f26e02108f559018e2aad0", + "reference": "62042df15314b829d0f26e02108f559018e2aad0", "shasum": "" }, "require": { @@ -9798,12 +9692,12 @@ "type": "library", "extra": { "laravel": { - "providers": [ - "Spatie\\LaravelIgnition\\IgnitionServiceProvider" - ], "aliases": { "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" - } + }, + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ] } }, "autoload": { @@ -9845,7 +9739,7 @@ "type": "github" } ], - "time": "2024-06-12T15:01:18+00:00" + "time": "2024-12-02T08:43:31+00:00" }, { "name": "spatie/laravel-ray", @@ -9886,13 +9780,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - }, "laravel": { "providers": [ "Spatie\\LaravelRay\\RayServiceProvider" ] + }, + "branch-alias": { + "dev-main": "1.x-dev" } }, "autoload": { @@ -9986,35 +9880,35 @@ }, { "name": "spatie/ray", - "version": "1.41.2", + "version": "1.41.3", "source": { "type": "git", "url": "https://github.com/spatie/ray.git", - "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc" + "reference": "e2ecbc17a493dab635f3cf026858b46f0ccbb053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/ray/zipball/c44f8cfbf82c69909b505de61d8d3f2d324e93fc", - "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc", + "url": "https://api.github.com/repos/spatie/ray/zipball/e2ecbc17a493dab635f3cf026858b46f0ccbb053", + "reference": "e2ecbc17a493dab635f3cf026858b46f0ccbb053", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", - "php": "^7.3|^8.0", - "ramsey/uuid": "^3.0|^4.1", + "php": "^7.4 || ^8.0", + "ramsey/uuid": "^3.0 || ^4.1", "spatie/backtrace": "^1.1", - "spatie/macroable": "^1.0|^2.0", - "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", - "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" + "spatie/macroable": "^1.0 || ^2.0", + "symfony/stopwatch": "^4.2 || ^5.1 || ^6.0 || ^7.0", + "symfony/var-dumper": "^4.2 || ^5.1 || ^6.0 || ^7.0.3" }, "require-dev": { - "illuminate/support": "6.x|^8.18|^9.0", + "illuminate/support": "^7.20 || ^8.18 || ^9.0 || ^10.0 || ^11.0", "nesbot/carbon": "^2.63", "pestphp/pest": "^1.22", - "phpstan/phpstan": "^1.10", + "phpstan/phpstan": "^1.10.57 || ^2.0.2", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.19.2", + "rector/rector": "dev-main", "spatie/phpunit-snapshot-assertions": "^4.2", "spatie/test-time": "^1.2" }, @@ -10055,7 +9949,7 @@ ], "support": { "issues": "https://github.com/spatie/ray/issues", - "source": "https://github.com/spatie/ray/tree/1.41.2" + "source": "https://github.com/spatie/ray/tree/1.41.3" }, "funding": [ { @@ -10067,7 +9961,7 @@ "type": "other" } ], - "time": "2024-04-24T14:21:46+00:00" + "time": "2024-12-02T12:33:18+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -10151,16 +10045,16 @@ }, { "name": "symfony/config", - "version": "v7.1.7", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8" + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8", - "reference": "dc373a5cbd345354696f5dfd39c5c7a8ea23f4c8", + "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", "shasum": "" }, "require": { @@ -10206,7 +10100,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.1.7" + "source": "https://github.com/symfony/config/tree/v7.2.0" }, "funding": [ { @@ -10222,20 +10116,20 @@ "type": "tidelift" } ], - "time": "2024-11-04T11:34:07+00:00" + "time": "2024-11-04T11:36:24+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "e4d13f0f394f4d02a041ff76acd31c5a20a5f70b" + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e4d13f0f394f4d02a041ff76acd31c5a20a5f70b", - "reference": "e4d13f0f394f4d02a041ff76acd31c5a20a5f70b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", "shasum": "" }, "require": { @@ -10286,7 +10180,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.1.8" + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" }, "funding": [ { @@ -10302,20 +10196,20 @@ "type": "tidelift" } ], - "time": "2024-11-09T09:16:45+00:00" + "time": "2024-11-25T15:45:00+00:00" }, { "name": "symfony/filesystem", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { @@ -10352,7 +10246,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.6" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -10368,20 +10262,20 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:11:02+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "85e95eeede2d41cd146146e98c9c81d9214cae85" + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/85e95eeede2d41cd146146e98c9c81d9214cae85", - "reference": "85e95eeede2d41cd146146e98c9c81d9214cae85", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "shasum": "" }, "require": { @@ -10419,7 +10313,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.1.6" + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" }, "funding": [ { @@ -10435,7 +10329,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-20T11:17:29+00:00" }, { "name": "symfony/polyfill-iconv", @@ -10595,16 +10489,16 @@ }, { "name": "symfony/stopwatch", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "8b4a434e6e7faf6adedffb48783a5c75409a1a05" + "reference": "696f418b0d722a4225e1c3d95489d262971ca924" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/8b4a434e6e7faf6adedffb48783a5c75409a1a05", - "reference": "8b4a434e6e7faf6adedffb48783a5c75409a1a05", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924", "shasum": "" }, "require": { @@ -10637,7 +10531,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.1.6" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.0" }, "funding": [ { @@ -10653,20 +10547,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "90173ef89c40e7c8c616653241048705f84130ef" + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/90173ef89c40e7c8c616653241048705f84130ef", - "reference": "90173ef89c40e7c8c616653241048705f84130ef", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", "shasum": "" }, "require": { @@ -10713,7 +10607,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.1.6" + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" }, "funding": [ { @@ -10729,7 +10623,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-10-18T07:58:17+00:00" }, { "name": "symfony/yaml", @@ -11064,13 +10958,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.0", - "ext-redis": "*" + "php": "^8.0" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/config/super_cache_invalidate.php b/config/super_cache_invalidate.php index 7c58436..c0b6b18 100644 --- a/config/super_cache_invalidate.php +++ b/config/super_cache_invalidate.php @@ -69,5 +69,6 @@ */ 'key_invalidation_callback' => env('SUPERCACHE_INVALIDATE_KEY_INVALIDATION_CALLBACK', null), 'tag_invalidation_callback' => env('SUPERCACHE_INVALIDATE_TAG_INVALIDATION_CALLBACK', null), + 'default_connection_name' => env('SUPERCACHE_INVALIDATE_DEFAULT_CONNECTION_NAME', 'cache'), ]; diff --git a/database/migrations/2024_11_20_200800_create_cache_invalidation_events_table.php b/database/migrations/2024_11_20_200800_create_cache_invalidation_events_table.php index d62836e..2de5c3c 100644 --- a/database/migrations/2024_11_20_200800_create_cache_invalidation_events_table.php +++ b/database/migrations/2024_11_20_200800_create_cache_invalidation_events_table.php @@ -12,7 +12,7 @@ protected function generatePartitionSQL(): string { $startYear = 2024; - $endYear = 2050; + $endYear = 2030; $shards = config('super_cache_invalidate.total_shards', 10); $priorities = [0, 1]; // Adjust as needed @@ -22,7 +22,7 @@ protected function generatePartitionSQL(): string foreach ($priorities as $priority) { for ($shard = 0; $shard < $shards; $shard++) { $partitionName = "p_unprocessed_s{$shard}_p{$priority}"; - $partitionValue = ($shard * 100 + $priority) + 1; + $partitionValue = ($priority * $shards) + $shard + 1; $partitionStatements[] = "PARTITION {$partitionName} VALUES LESS THAN ({$partitionValue})"; } } @@ -32,9 +32,8 @@ protected function generatePartitionSQL(): string for ($week = 1; $week <= 53; $week++) { foreach ($priorities as $priority) { for ($shard = 0; $shard < $shards; $shard++) { - $partitionKey = $shard * 100000000 + $priority * 10000000 + ($year * 100 + $week); + $partitionKey = ($year * 10000) + ($week * 100) + ($priority * $shards) + $shard; $nextPartitionKey = $partitionKey + 1; - $partitionName = "p_s{$shard}_p{$priority}_{$year}w{$week}"; $partitionStatements[] = "PARTITION {$partitionName} VALUES LESS THAN ({$nextPartitionKey})"; } @@ -54,10 +53,16 @@ protected function generatePartitionSQL(): string */ public function up(): void { + if (Schema::hasTable('cache_invalidation_events')) { + return; + } + Schema::create('cache_invalidation_events', function (Blueprint $table) { - $table->bigIncrements('id'); + //$table->bigIncrements('id'); + $table->bigInteger('id')->unsigned(); // Definiamo l'ID come bigInteger senza autoincrement sennò la primarykey multipla non funziona $table->enum('type', ['key', 'tag'])->comment('Indicates whether the event is for a cache key or tag'); $table->string('identifier')->comment('The cache key or tag to invalidate'); + $table->string('connection_name')->comment('Redis Connection name'); $table->string('reason')->nullable()->comment('Reason for the invalidation (for logging purposes)'); $table->tinyInteger('priority')->default(0)->comment('Priority of the event'); $table->dateTime('event_time')->default(DB::raw('CURRENT_TIMESTAMP'))->comment('Timestamp when the event was created'); @@ -66,19 +71,23 @@ public function up(): void // Partition key as a generated stored column $table->integer('partition_key')->storedAs(' - CASE - WHEN `processed` = 0 THEN - `shard` * 100 + `priority` - ELSE - `shard` * 100000000 + `priority` * 10000000 + (YEAR(`event_time`) * 100 + WEEK(`event_time`, 3)) - END - ')->comment('Partition key for efficient querying and partitioning'); + CASE + WHEN `processed` = 0 THEN + (`priority` * `shard`) + `shard` + 1 + ELSE + (YEAR(`event_time`) * 10000) + (WEEK(`event_time`, 3) * 100) + (`priority` * `shard`) + `shard` + END + ')->comment('Partition key for efficient querying and partitioning'); // Indexes $table->index(['processed', 'shard', 'priority', 'partition_key', 'event_time'], 'idx_processed_shard_priority'); $table->index(['type', 'identifier'], 'idx_type_identifier'); + $table->primary(['id', 'partition_key']); }); + // Abilitare l'autoincrement manualmente + DB::statement('ALTER TABLE cache_invalidation_events MODIFY id BIGINT UNSIGNED AUTO_INCREMENT'); + // Generate partitions using the PHP script $partitionSQL = $this->generatePartitionSQL(); diff --git a/database/migrations/2024_11_20_200801_create_cache_invalidation_timestamps_table.php b/database/migrations/2024_11_20_200801_create_cache_invalidation_timestamps_table.php index 2722173..0b26ba3 100644 --- a/database/migrations/2024_11_20_200801_create_cache_invalidation_timestamps_table.php +++ b/database/migrations/2024_11_20_200801_create_cache_invalidation_timestamps_table.php @@ -11,15 +11,16 @@ */ public function up(): void { + if (Schema::hasTable('cache_invalidation_timestamps')) { + return; + } Schema::create('cache_invalidation_timestamps', function (Blueprint $table) { $table->enum('identifier_type', ['key', 'tag'])->comment('Indicates whether the identifier is a cache key or tag'); $table->string('identifier')->comment('The cache key or tag'); $table->dateTime('last_invalidated')->comment('Timestamp of the last invalidation'); - // Partition key as a generated stored column $table->integer('partition_key')->storedAs('YEAR(`last_invalidated`) * 100 + WEEK(`last_invalidated`, 3)')->comment('Partition key based on last_invalidated'); - - $table->primary(['identifier_type', 'identifier']); + $table->primary(['identifier_type', 'identifier', 'partition_key']); $table->index(['identifier_type', 'identifier'], 'idx_identifier_type_identifier'); $table->index('partition_key', 'idx_partition_key'); }); @@ -49,7 +50,7 @@ public function down(): void protected function generatePartitionSQL(): string { $startYear = 2024; - $endYear = 2050; + $endYear = 2030; $partitionStatements = []; diff --git a/database/migrations/2024_11_20_200802_create_cache_invalidation_event_associations_table.php b/database/migrations/2024_11_20_200802_create_cache_invalidation_event_associations_table.php index 6ad50b7..623f13b 100644 --- a/database/migrations/2024_11_20_200802_create_cache_invalidation_event_associations_table.php +++ b/database/migrations/2024_11_20_200802_create_cache_invalidation_event_associations_table.php @@ -11,25 +11,32 @@ */ public function up(): void { + if (Schema::hasTable('cache_invalidation_event_associations')) { + return; + } Schema::create('cache_invalidation_event_associations', function (Blueprint $table) { - $table->bigIncrements('id'); + //$table->bigIncrements('id'); + $table->bigInteger('id')->unsigned(); // Definiamo l'ID come bigInteger senza autoincrement sennò la primarykey multipla non funziona $table->unsignedBigInteger('event_id')->comment('Reference to cache_invalidation_events.id'); $table->enum('associated_type', ['key', 'tag'])->comment('Indicates if the associated identifier is a cache key or tag'); $table->string('associated_identifier')->comment('The associated cache key or tag'); + $table->string('connection_name')->comment('Redis Connection name'); $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->comment('Timestamp of association creation'); - // Partition key as a generated stored column $table->integer('partition_key')->storedAs('YEAR(`created_at`) * 100 + WEEK(`created_at`, 3)')->comment('Partition key based on created_at'); - // Indexes $table->index('event_id', 'idx_event_id'); $table->index(['associated_type', 'associated_identifier'], 'idx_associated_type_identifier'); $table->index('partition_key', 'idx_partition_key'); - + $table->primary(['id', 'partition_key']); // Foreign key constraint - $table->foreign('event_id')->references('id')->on('cache_invalidation_events')->onDelete('cascade'); + // Foreign keys are not yet supported in conjunction with partitioning + //$table->foreign('event_id')->references('id')->on('cache_invalidation_events')->onDelete('cascade'); }); + // Abilitare l'autoincrement manualmente + DB::statement('ALTER TABLE cache_invalidation_event_associations MODIFY id BIGINT UNSIGNED AUTO_INCREMENT'); + // Generate partitions $partitionSQL = $this->generatePartitionSQL(); @@ -55,7 +62,7 @@ public function down(): void protected function generatePartitionSQL(): string { $startYear = 2024; - $endYear = 2050; + $endYear = 2030; $partitionStatements = []; diff --git a/src/Console/ProcessCacheInvalidationEventsCommand.php b/src/Console/ProcessCacheInvalidationEventsCommand.php index 0d24279..cbf3e9f 100644 --- a/src/Console/ProcessCacheInvalidationEventsCommand.php +++ b/src/Console/ProcessCacheInvalidationEventsCommand.php @@ -19,7 +19,8 @@ class ProcessCacheInvalidationEventsCommand extends Command {--shard= : The shard number to process} {--priority= : The priority level} {--limit= : The maximum number of events to fetch per batch} - {--tag-batch-size= : The number of identifiers to process per invalidation batch}'; + {--tag-batch-size= : The number of identifiers to process per invalidation batch} + {--connection_name= : The Redis connection name}'; /** * The console command description. @@ -42,6 +43,22 @@ public function __construct(SuperCacheInvalidationHelper $helper) $this->helper = $helper; } + private function getStoreFromConnectionName(string $connection_name): ?string + { + // Cerca il nome dello store associato alla connessione Redis + foreach (config('cache.stores') as $storeName => $storeConfig) { + if ( + isset($storeConfig['driver'], $storeConfig['connection']) && + $storeConfig['driver'] === 'redis' && + $storeConfig['connection'] === $connection_name + ) { + return $storeName; + } + } + + return null; + } + /** * Process cache invalidation events. * @@ -52,17 +69,19 @@ public function __construct(SuperCacheInvalidationHelper $helper) * * @throws \Exception */ - protected function processEvents(int $shardId, int $priority, int $limit, int $tagBatchSize): void + protected function processEvents(int $shardId, int $priority, int $limit, int $tagBatchSize, string $connection_name): void { $processingStartTime = now(); $invalidationWindow = config('super_cache_invalidate.invalidation_window'); // Fetch a batch of unprocessed events $events = DB::table('cache_invalidation_events') - ->where('processed', 0) - ->where('shard', $shardId) - ->where('priority', $priority) + ->where('processed', '=', 0) + ->where('shard', '=', $shardId) + ->where('priority', '=', $priority) ->where('event_time', '<', $processingStartTime) + // Cerco tutte le chiavi/tag da invalidare per questo database redis + ->where('connection_name', '=', $connection_name) ->orderBy('event_time') ->limit($limit) ->get() @@ -86,6 +105,7 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t $eventIds = $events->pluck('id')->all(); //retrive associated identifiers related to fetched event id + // Per le chiavi/tag associati non filtro per connection_name, potrebbero esserci associazioni anche in altri database $associations = DB::table('cache_invalidation_event_associations') ->whereIn('event_id', $eventIds) ->get() @@ -94,18 +114,16 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t // Prepare list of all identifiers to fetch last invalidation times $allIdentifiers = []; - foreach ($eventsByIdentifier as $key => $eventsGroup) { $allIdentifiers[] = $key; foreach ($eventsGroup as $event) { - $eventAssociations = $associations->get($event->id, collect()); + $eventAssociations = $associations->where('event_id', '=', $event->id); foreach ($eventAssociations as $assoc) { $assocKey = $assoc->associated_type . ':' . $assoc->associated_identifier; $allIdentifiers[] = $assocKey; } } } - // Fetch last invalidation times in bulk $lastInvalidationTimes = $this->getLastInvalidationTimes(array_unique($allIdentifiers)); @@ -116,12 +134,13 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t // Get associated identifiers for the events $associatedIdentifiers = []; foreach ($eventsGroup as $event) { - $eventAssociations = $associations->get($event->id, collect()); + $eventAssociations = $associations->where('event_id', '=', $event->id); foreach ($eventAssociations as $assoc) { $assocKey = $assoc->associated_type . ':' . $assoc->associated_identifier; $associatedIdentifiers[$assocKey] = [ 'type' => $assoc->associated_type, 'identifier' => $assoc->associated_identifier, + 'connection_name' => $assoc->connection_name, ]; } } @@ -129,7 +148,6 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t // Build a list of all identifiers to check $identifiersToCheck = [$key]; $identifiersToCheck = array_merge($identifiersToCheck, array_keys($associatedIdentifiers)); - $lastInvalidationTimesSubset = array_intersect_key($lastInvalidationTimes, array_flip($identifiersToCheck)); $shouldInvalidate = $this->shouldInvalidateMultiple($identifiersToCheck, $lastInvalidationTimesSubset, $invalidationWindow); @@ -143,6 +161,7 @@ protected function processEvents(int $shardId, int $priority, int $limit, int $t 'type' => $type, 'identifier' => $identifier, 'event' => $latestEvent, + 'connection_name' => $connection_name, 'associated' => array_values($associatedIdentifiers), ]; @@ -292,6 +311,7 @@ protected function updateLastInvalidationTimes(array $identifiers): void */ protected function processBatch(array $batchIdentifiers, array $eventsToUpdate): void { + // Begin transaction for the batch DB::beginTransaction(); @@ -299,11 +319,15 @@ protected function processBatch(array $batchIdentifiers, array $eventsToUpdate): // Separate keys and tags $keys = []; $tags = []; + foreach ($batchIdentifiers as $item) { - if ($item['type'] === 'key') { - $keys[] = $item['identifier']; - } else { - $tags[] = $item['identifier']; + switch ($item['type']) { + case 'key': + $keys[] = $item['identifier'] . '§' . $item['connection_name']; + break; + case 'tag': + $tags[] = $item['identifier'] . '§' . $item['connection_name']; + break; } if (empty($item['associated'])) { @@ -312,12 +336,14 @@ protected function processBatch(array $batchIdentifiers, array $eventsToUpdate): // Include associated identifiers foreach ($item['associated'] as $assoc) { - if ($assoc['type'] === 'key') { - $keys[] = $assoc['identifier']; - continue; + switch ($assoc['type']) { + case 'key': + $keys[] = $assoc['identifier'] . '§' . $assoc['connection_name']; + break; + case 'tag': + $tags[] = $assoc['identifier'] . '§' . $assoc['connection_name']; + break; } - - $tags[] = $assoc['identifier']; } } @@ -359,15 +385,24 @@ protected function invalidateKeys(array $keys): void { $callback = config('super_cache_invalidate.key_invalidation_callback'); - if (is_callable($callback)) { - call_user_func($callback, $keys); - return; - } + // Anche in questo caso va fatto un loop perchè le chiavi potrebbero stare in database diversi + foreach ($keys as $keyAndConnectionName) { + [$key, $connection_name] = explode('§', $keyAndConnectionName); - //default invalidation method - foreach ($keys as $key) { - Cache::forget($key); + // Metodo del progetto + if (is_callable($callback)) { + $callback($key, $connection_name); + return; + } + + // oppure di default uso Laravel + $storeName = $this->getStoreFromConnectionName($connection_name); + + if ($storeName === null) { + return; + } + Cache::store($storeName)->forget($key); } } @@ -380,14 +415,30 @@ protected function invalidateTags(array $tags): void { $callback = config('super_cache_invalidate.tag_invalidation_callback'); - if (is_callable($callback)) { - call_user_func($callback, $tags); + $groupByConnection = []; + + // Anche in questo caso va fatto un loop perchè i tags potrebbero stare in database diversi, + // ma per ottimizzare possiamo raggruppare le operazioni per connessione + foreach ($tags as $tagAndConnectionName) { + // chiave e connessione + [$key, $connection] = explode('§', $tagAndConnectionName); + // Aggiungo la chiave alla connessione appropriata + $groupByConnection[$connection][] = $key; + } + if (is_callable($callback)) { + foreach ($groupByConnection as $connection_name => $arrTags) { + $callback($arrTags, $connection_name); + } return; } - - //default invalidation method - Cache::tags($tags)->flush(); + foreach ($groupByConnection as $connection_name => $arrTags) { + $storeName = $this->getStoreFromConnectionName($connection_name); + if ($storeName === null) { + return; + } + Cache::store($storeName)->tags($arrTags)->flush(); + } } /** @@ -402,27 +453,26 @@ public function handle(): void $tagBatchSize = $this->option('tag-batch-size') ?? config('super_cache_invalidate.tag_batch_size'); $tagBatchSize = (int)$tagBatchSize; $lockTimeout = (int) config('super_cache_invalidate.lock_timeout'); - + $connection_name = $this->option('connection_name') ?? config('super_cache_invalidate.default_connection_name'); + /* if ($shardId === 0 && $priority === 0) { $this->error('Shard and priority are required and must be non-zero integers.'); return; } - - $lockValue = $this->helper->acquireShardLock($shardId, $lockTimeout); + */ + $lockValue = $this->helper->acquireShardLock($shardId, $lockTimeout, $connection_name); if (!$lockValue) { - $this->info("Another process is handling shard $shardId."); - return; } try { - $this->processEvents($shardId, $priority, $limit, $tagBatchSize); + $this->processEvents($shardId, $priority, $limit, $tagBatchSize, $connection_name); } catch (\Exception $e) { $this->error('An error occourred in ' . __METHOD__ . ': ' . $e->getTraceAsString()); } finally { - $this->helper->releaseShardLock($shardId, $lockValue); + $this->helper->releaseShardLock($shardId, $lockValue, $connection_name); } } } diff --git a/src/Console/PruneCacheInvalidationDataCommand.php b/src/Console/PruneCacheInvalidationDataCommand.php index 827f650..63d039e 100644 --- a/src/Console/PruneCacheInvalidationDataCommand.php +++ b/src/Console/PruneCacheInvalidationDataCommand.php @@ -28,10 +28,10 @@ class PruneCacheInvalidationDataCommand extends Command * @param string $tableName The name of the table * @param int $retentionPartitionKey The partition key cutoff */ - protected function pruneTable(string $tableName, int $retentionPartitionKey): void + protected function pruneTable(string $tableName, int $retentionPartitionKey, ?int $minPartitionValueToExclude = 0): void { // Fetch partition names - $partitions = $this->getPartitionsFromDb($tableName, $retentionPartitionKey); + $partitions = $this->getPartitionsFromDb($tableName, $retentionPartitionKey, $minPartitionValueToExclude); if (empty($partitions)) { $this->info("No partitions to prune for table {$tableName}."); @@ -55,28 +55,38 @@ public function handle(): void { $months = (int) $this->option('months'); $retentionDate = now()->subMonths($months); - $retentionPartitionKey = $retentionDate->year * 100 + $retentionDate->week(); // Prune tables - $tables = [ - 'cache_invalidation_events', - 'cache_invalidation_timestamps', - 'cache_invalidation_event_associations', - ]; + $this->pruneTable('cache_invalidation_timestamps', ($retentionDate->year * 100 + $retentionDate->week) + 1); + $this->pruneTable('cache_invalidation_event_associations', ($retentionDate->year * 100 + $retentionDate->week) + 1); - foreach ($tables as $tableName) { - $this->pruneTable($tableName, $retentionPartitionKey); + $shards = config('super_cache_invalidate.total_shards', 10); + $priorities = [0, 1]; + + $minPartitionValueToExclude = 0; + foreach ($priorities as $priority) { + for ($shard = 0; $shard < $shards; $shard++) { + $minPartitionValueToExclude = ($priority * $shards) + $shard + 1; + } + } + $arrPartitionValues = []; + foreach ($priorities as $priority) { + for ($shard = 0; $shard < $shards; $shard++) { + $arrPartitionValues[] = (($retentionDate->year * 10000) + ($retentionDate->week * 100) + ($priority * $shards) + $shard) + 1; + } } + $maxPartitionValueToInclude = max($arrPartitionValues); + $this->pruneTable('cache_invalidation_events', $maxPartitionValueToInclude, $minPartitionValueToExclude); $this->info('Old cache invalidation data has been pruned.'); } /** * @param string $tableName - * @param int $retentionPartitionKey + * @param int $maxPartitionValueToInclude * @return array */ - protected function getPartitionsFromDb(string $tableName, int $retentionPartitionKey): array + protected function getPartitionsFromDb(string $tableName, int $maxPartitionValueToInclude, $minPartitionValueToExclude): array { $partitions = DB::select(' SELECT PARTITION_NAME, PARTITION_DESCRIPTION @@ -84,8 +94,8 @@ protected function getPartitionsFromDb(string $tableName, int $retentionPartitio WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND PARTITION_NAME IS NOT NULL - AND PARTITION_DESCRIPTION < ? - ', [$tableName, $retentionPartitionKey]); + AND PARTITION_DESCRIPTION < ? AND PARTITION_DESCRIPTION > ? + ', [$tableName, $maxPartitionValueToInclude, $minPartitionValueToExclude]); return $partitions; } } diff --git a/src/Events/SuperCacheInvalidationEvent.php b/src/Events/SuperCacheInvalidationEvent.php deleted file mode 100644 index 7dd3f9f..0000000 --- a/src/Events/SuperCacheInvalidationEvent.php +++ /dev/null @@ -1,47 +0,0 @@ -type = $type; - $this->identifier = $identifier; - $this->reason = $reason; - } -} diff --git a/src/Helpers/SuperCacheInvalidationHelper.php b/src/Helpers/SuperCacheInvalidationHelper.php index 290c76a..44524d0 100644 --- a/src/Helpers/SuperCacheInvalidationHelper.php +++ b/src/Helpers/SuperCacheInvalidationHelper.php @@ -2,7 +2,6 @@ namespace Padosoft\SuperCacheInvalidate\Helpers; -use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Redis; @@ -13,25 +12,28 @@ class SuperCacheInvalidationHelper * * @param string $type 'key' or 'tag' * @param string $identifier The cache key or tag to invalidate + * @param string|null $connection_name The Redis Connection name (optional, 'default') * @param string|null $reason Reason for invalidation (optional) - * @param int $priority Priority of the event - * @param array $associatedIdentifiers Optional array of associated tags or keys * @param int|null $totalShards Total number of shards (from config if null) + * @param int|null $priority Priority of the event + * @param array|null $associatedIdentifiers Optional array of associated tags or keys */ public function insertInvalidationEvent( string $type, string $identifier, + ?string $connection_name = null, ?string $reason = null, - int $priority = 0, - array $associatedIdentifiers = [], - ?int $totalShards = null + ?int $totalShards = 0, + ?int $priority = 0, + ?array $associatedIdentifiers = [], ): void { - $totalShards = $totalShards ?? config('super_cache_invalidate.total_shards', 10); - $shard = crc32($identifier) % $totalShards; + $shard = crc32($identifier) % ($totalShards > 0 ? $totalShards : config('super_cache_invalidate.total_shards', 10)); + $redisConnectionName = $connection_name ?? config('super_cache_invalidate.default_connection_name'); $data = [ 'type' => $type, 'identifier' => $identifier, + 'connection_name' => $redisConnectionName, 'reason' => $reason, 'priority' => $priority, 'event_time' => now(), @@ -50,6 +52,7 @@ public function insertInvalidationEvent( 'event_id' => $eventId, 'associated_type' => $associated['type'], // 'key' or 'tag' 'associated_identifier' => $associated['identifier'], + 'connection_name' => $associated['connection_name'], 'created_at' => now(), ]; } @@ -60,15 +63,26 @@ public function insertInvalidationEvent( /** * Acquire a lock for processing a shard. * - * @param int $shardId The shard number - * @param int $lockTimeout Lock timeout in seconds + * @param int $shardId The shard number + * @param int $lockTimeout Lock timeout in seconds + * @param string $connection_name The Redis Connection name * @return string|false The lock value if acquired, false otherwise */ - public function acquireShardLock(int $shardId, int $lockTimeout): bool|string + public function acquireShardLock(int $shardId, int $lockTimeout, string $connection_name): bool|string { $lockKey = "shard_lock:$shardId"; + // Il metodo has/exists occupa troppa memoria!!! + $retrieveValue = Redis::connection($connection_name)->get($lockKey); + if ($retrieveValue !== null) { + // Lock già attivo + return false; + } $lockValue = uniqid('', true); - $isLocked = Redis::set($lockKey, $lockValue, 'NX', 'EX', $lockTimeout); + $isLocked = Redis::connection($connection_name)->set($lockKey, $lockValue); + + if ($lockTimeout > 0) { + Redis::connection($connection_name)->expire($lockKey, $lockTimeout); + } return $isLocked ? $lockValue : false; } @@ -76,15 +90,16 @@ public function acquireShardLock(int $shardId, int $lockTimeout): bool|string /** * Release the lock for a shard. * - * @param int $shardId The shard number - * @param string $lockValue The lock value to validate ownership + * @param int $shardId The shard number + * @param string $lockValue The lock value to validate ownership + * @param string $connection_name The Redis Connection name */ - public function releaseShardLock(int $shardId, string $lockValue): void + public function releaseShardLock(int $shardId, string $lockValue, string $connection_name): void { $lockKey = "shard_lock:$shardId"; - $currentValue = Redis::get($lockKey); + $currentValue = Redis::connection($connection_name)->get($lockKey); if ($currentValue === $lockValue) { - Redis::del($lockKey); + Redis::connection($connection_name)->del($lockKey); } } } diff --git a/src/SuperCacheInvalidateServiceProvider.php b/src/SuperCacheInvalidateServiceProvider.php index 02c1ae3..e85481d 100644 --- a/src/SuperCacheInvalidateServiceProvider.php +++ b/src/SuperCacheInvalidateServiceProvider.php @@ -16,12 +16,16 @@ public function register(): void { // Merge package configuration $this->mergeConfigFrom( - __DIR__ . '/../../config/super_cache_invalidate.php', + __DIR__ . '/../config/super_cache_invalidate.php', 'super_cache_invalidate' ); // Register the helper as a singleton - $this->app->singleton('supercache.invalidation', function () { + $this->app->singleton(SuperCacheInvalidationHelper::class, function () { + return new SuperCacheInvalidationHelper(); + }); + + $this->app->singleton('super_cache_invalidate', function () { return new SuperCacheInvalidationHelper(); }); } @@ -33,12 +37,11 @@ public function boot(): void { // Publish configuration $this->publishes([ - __DIR__ . '/../../config/super_cache_invalidate.php' => config_path('super_cache_invalidate.php'), + __DIR__ . '/../config/super_cache_invalidate.php' => config_path('super_cache_invalidate.php'), ], 'config'); // Publish migrations - $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); - + $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); // Register commands if ($this->app->runningInConsole()) { $this->commands([ diff --git a/tests/Unit/ProcessCacheInvalidationEventsTest.php b/tests/Unit/ProcessCacheInvalidationEventsTest.php index b147201..facd546 100644 --- a/tests/Unit/ProcessCacheInvalidationEventsTest.php +++ b/tests/Unit/ProcessCacheInvalidationEventsTest.php @@ -2,22 +2,20 @@ namespace Padosoft\SuperCacheInvalidate\Test\Unit; -use PHPUnit\Framework\TestCase; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Cache; -use Padosoft\SuperCacheInvalidate\Console\ProcessCacheInvalidationEventsCommand; -use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper; use Carbon\Carbon; +use Mockery; +use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper; class ProcessCacheInvalidationEventsTest extends TestCase { - protected ProcessCacheInvalidationEventsCommand $command; + protected SuperCacheInvalidationHelper $helper; protected function setUp(): void { parent::setUp(); - $helper = new SuperCacheInvalidationHelper(); - $this->command = new ProcessCacheInvalidationEventsCommand($helper); + $this->helper = new SuperCacheInvalidationHelper(); } public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void @@ -26,9 +24,12 @@ public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void $events = collect([ (object)[ 'id' => 1, - 'type' => 'tag', + 'type' => 'key', 'identifier' => 'article_ID:7', - 'event_time' => Carbon::now()->subSeconds(10), + 'reason' => 'Article 7 removed', + 'connection_name' => 'default', + 'shard' => 1, + 'priority' => 1 ], ]); @@ -37,44 +38,90 @@ public function testProcessEventsWithAssociatedIdentifiersWithinWindow(): void 'event_id' => 1, 'associated_type' => 'tag', 'associated_identifier' => 'plp:sport', + 'connection_name' => 'default', ], ]); // Mock DB queries - DB::shouldReceive('table->where->where->where->where->orderBy->limit->get') + DB::shouldReceive('table->where->where->where->where->where->orderBy->limit->get') ->andReturn($events) ; - DB::shouldReceive('table->whereIn->get') + DB::shouldReceive('table->whereIn->get->groupBy') ->andReturn($associations) ; // Mock last invalidation times - DB::shouldReceive('select')->andReturn([ + DB::shouldReceive('select') + ->andReturn([ (object)[ - 'identifier_type' => 'tag', + 'identifier_type' => 'key', 'identifier' => 'article_ID:7', - 'last_invalidated' => Carbon::now()->subSeconds(40)->toDateTimeString(), + 'last_invalidated' => Carbon::now()->subSeconds(120)->toDateTimeString(), ], (object)[ 'identifier_type' => 'tag', 'identifier' => 'plp:sport', - 'last_invalidated' => Carbon::now()->subSeconds(20)->toDateTimeString(), + 'last_invalidated' => Carbon::now()->subSeconds(180)->toDateTimeString(), ], ]); + // Mock update or insert + DB::shouldReceive('table->updateOrInsert')->twice(); //1 per la chiave e 1 per il tag + + DB::shouldReceive('beginTransaction')->once(); + + // CHIAVE // Mock Cache - Cache::shouldReceive('tags->flush')->never(); + Cache::shouldReceive('store') + ->with('redis-store-1') // Nome dello store + ->once() + ->andReturn(Mockery::mock(\Illuminate\Contracts\Cache\Repository::class, function ($mock) { + // Mockiamo il comportamento del repository cache + $mock->shouldReceive('forget') + ->withArgs(function ($key) { + // controllo che la chiave sia proprio quella + $this->assertEquals('article_ID:7', $key); + return true; // Indica che l'argomento è accettabile + }) + ->once() + ->andReturn(true); + })); - // Mock update or insert - DB::shouldReceive('table->updateOrInsert')->never(); + // TAG + // Mock Cache + Cache::shouldReceive('store') + ->with('redis-store-1') // Nome dello store + ->once() + ->andReturn(Mockery::mock(\Illuminate\Contracts\Cache\Repository::class, function ($mock) { + // Mockiamo il comportamento del repository cache + $mock->shouldReceive('tags') + ->withArgs(function ($tags) { + // controllo che la chiave sia proprio quella + $this->assertEquals(['plp:sport'], $tags); + return true; // Indica che l'argomento è accettabile + }) + ->once() + ->andReturn(Mockery::mock(\Illuminate\Cache\TaggedCache::class, function ($taggedCacheMock) { + $taggedCacheMock->shouldReceive('flush') + ->once() + ->andReturn(true); + })); + })); // Mock event update DB::shouldReceive('table->whereIn->update')->once(); - // Run the command - $this->command->handle(); + DB::shouldReceive('commit')->once(); - // Assertions are handled by Mockery expectations + // Run the command + // Run the command + $this->artisan('supercache:process-invalidation', [ + '--shard' => 0, + '--priority' => 0, + '--limit' => 1, + '--tag-batch-size' => 1, + '--connection_name' => 'default', + ]); } } diff --git a/tests/Unit/PruneCacheInvalidationDataTest.php b/tests/Unit/PruneCacheInvalidationDataTest.php index 4db689d..00933e4 100644 --- a/tests/Unit/PruneCacheInvalidationDataTest.php +++ b/tests/Unit/PruneCacheInvalidationDataTest.php @@ -1,30 +1,26 @@ command = new PruneCacheInvalidationDataCommand(); } public function testPruneTables(): void { // Mock DB queries + $retentionDate = now()->subMonths(1); DB::shouldReceive('select') ->times(3) ->andReturn([ (object)[ - 'PARTITION_NAME' => 'p202401', - 'PARTITION_DESCRIPTION' => '202401', + 'PARTITION_NAME' => 'p_s0_p0_2024w1', + 'PARTITION_DESCRIPTION' => ($retentionDate->year * 10000) + ($retentionDate->week * 100) + 1, ], ]) ; @@ -32,7 +28,9 @@ public function testPruneTables(): void DB::shouldReceive('statement')->times(3); // Run the command - $this->command->handle(); + $this->artisan('supercache:prune-invalidation-data', [ + '--months' => 1, + ]); // Assertions are handled by Mockery expectations } diff --git a/tests/Unit/SuperCacheInvalidationHelperTest.php b/tests/Unit/SuperCacheInvalidationHelperTest.php index 6afadf9..6d9193a 100644 --- a/tests/Unit/SuperCacheInvalidationHelperTest.php +++ b/tests/Unit/SuperCacheInvalidationHelperTest.php @@ -2,7 +2,6 @@ namespace Padosoft\SuperCacheInvalidate\Test\Unit; -use PHPUnit\Framework\TestCase; use Illuminate\Support\Facades\DB; use Padosoft\SuperCacheInvalidate\Helpers\SuperCacheInvalidationHelper; @@ -21,9 +20,13 @@ public function testInsertInvalidationEvent(): void // Mock DB insert DB::shouldReceive('table->insertGetId')->once()->andReturn(1); - $this->helper->insertInvalidationEvent('tag', 'test_tag', 'Test reason', 0); - - // Assertions are handled by Mockery expectations + $this->helper->insertInvalidationEvent( + 'key', + 'test_tag', + 'default', + 'Article 7 removed', + 1, + 1); } public function testInsertInvalidationEventWithAssociations(): void @@ -33,15 +36,15 @@ public function testInsertInvalidationEventWithAssociations(): void DB::shouldReceive('table->insert')->once(); $this->helper->insertInvalidationEvent( - 'tag', + 'key', 'article_ID:7', + 'default', 'Article 7 removed', 0, + 0, [ - ['type' => 'tag', 'identifier' => 'plp:sport'], + ['type' => 'tag', 'identifier' => 'plp:sport', 'connection_name' => 'default'], ] ); - - // Assertions are handled by Mockery expectations } } diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php new file mode 100644 index 0000000..889ab51 --- /dev/null +++ b/tests/Unit/TestCase.php @@ -0,0 +1,90 @@ +removeCreatedPathDuringTest(__DIR__); + //$this->artisan('migrate:reset', ['--database' => 'testbench']); + parent::tearDown(); + + $this->restoreExceptionHandler(); + } + + protected function restoreExceptionHandler(): void + { + while (true) { + $previousHandler = set_exception_handler(static fn () => null); + + restore_exception_handler(); + + if ($previousHandler === null) { + break; + } + + restore_exception_handler(); + } + } + + /** + * @param \Illuminate\Foundation\Application $app + */ + protected function getPackageProviders($app): array + { + return [ + SuperCacheInvalidateServiceProvider::class, + ]; + } + + /** + * @param Application $app + */ + protected function getEnvironmentSetUp($app): void + { + // Configura il mock di Redis + $redisClient = new RedisMock(); // Crea una nuova istanza di RedisMock + $app->singleton('redis', function () use ($redisClient) { + return $redisClient; + }); + + $app['config']->set('database.redis', [ + 'default' => [ + 'host' => '127.0.0.1', + 'port' => 6379, + 'database' => 0, + ], + ]); + + /* + $app['config']->set('database.redis.default', [ + 'host' => '127.0.0.1', // Non usato ma richiesto per coerenza + 'password' => null, + 'port' => 6379, + 'database' => 0, + ]); + */ + + $app['config']->set('cache.stores', [ + 'array' => [ + 'driver' => 'array', + ], + 'redis-store-1' => [ + 'driver' => 'redis', + 'connection' => 'default', + ] + ]); + } +}