From 07936f582d66ddd9a89bc8f823c088cdf61b4df0 Mon Sep 17 00:00:00 2001 From: Dimitrios Pantazis Date: Fri, 11 Jul 2025 15:13:03 +0300 Subject: [PATCH 1/2] From pigeon to shepherd --- .cursor/rules/context.mdc | 4 +- .cursor/rules/php-docblocks.mdc | 2 +- .cursor/rules/what-is-pigeon.mdc | 6 -- .cursor/rules/what-is-shepherd.mdc | 6 ++ .gitattributes | 2 +- .github/CONTRIBUTING.md | 8 +- .github/workflows/tests-php.yml | 2 +- .github/workflows/update_as.yml | 14 +-- CHANGELOG.md | 2 +- CLAUDE.md | 58 ++++++------ README.md | 8 +- composer.json | 6 +- docs/advanced-usage.md | 62 ++++++------- docs/api-reference.md | 84 +++++++++--------- docs/configuration.md | 60 ++++++------- docs/getting-started.md | 56 ++++++------ docs/tasks.md | 20 ++--- docs/tasks/email.md | 26 +++--- docs/tasks/http-request.md | 38 ++++---- phpcs.xml | 4 +- pigeon.php => shepherd.php | 8 +- src/Abstracts/Model_Abstract.php | 12 +-- src/Abstracts/Provider_Abstract.php | 6 +- src/Abstracts/Table_Abstract.php | 12 +-- src/Abstracts/Task_Abstract.php | 16 ++-- src/Abstracts/Task_Model_Abstract.php | 26 +++--- src/Action_Scheduler_Methods.php | 10 +-- src/Config.php | 16 ++-- src/Contracts/Log_Model.php | 10 +-- src/Contracts/Logger.php | 12 +-- src/Contracts/Model.php | 12 +-- src/Contracts/Task.php | 10 +-- src/Contracts/Task_Model.php | 10 +-- .../PigeonTaskAlreadyExistsException.php | 25 ------ src/Exceptions/PigeonTaskException.php | 25 ------ .../PigeonTaskFailWithoutRetryException.php | 25 ------ .../ShepherdTaskAlreadyExistsException.php | 25 ++++++ src/Exceptions/ShepherdTaskException.php | 25 ++++++ .../ShepherdTaskFailWithoutRetryException.php | 25 ++++++ src/Log.php | 32 +++---- src/Loggers/ActionScheduler_DB_Logger.php | 16 ++-- src/Loggers/DB_Logger.php | 16 ++-- src/Loggers/Null_Logger.php | 14 +-- src/Provider.php | 18 ++-- src/Regulator.php | 74 ++++++++-------- src/Tables/AS_Logs.php | 14 +-- src/Tables/Provider.php | 16 ++-- src/Tables/Task_Logs.php | 16 ++-- src/Tables/Tasks.php | 16 ++-- src/Tables/Utility/Safe_Dynamic_Prefix.php | 8 +- src/Tasks/Email.php | 32 +++---- src/Tasks/HTTP_Request.php | 50 +++++------ src/Traits/Custom_Table_Query_Methods.php | 10 +-- src/Traits/Loggable.php | 14 +-- src/functions.php | 28 +++--- tests/_support/Helper/Container.php | 10 +-- ...nSnapshot.php => ShepherdJsonSnapshot.php} | 6 +- .../Helper/Tasks/Always_Fail_Task.php | 4 +- .../_support/Helper/Tasks/Do_Action_Task.php | 6 +- .../Helper/Tasks/Do_Prefixed_Action_Task.php | 6 +- .../Helper/Tasks/Internal_Counting_Task.php | 6 +- .../Helper/Tasks/Retryable_Do_Action_Task.php | 6 +- .../Helper/Traits/With_AS_Assertions.php | 24 ++--- .../Helper/Traits/With_Clock_Mock.php | 2 +- .../Helper/Traits/With_Log_Snapshot.php | 8 +- tests/_support/Helper/Traits/With_Uopz.php | 2 +- tests/_support/Helper/test-functions.php | 42 ++++----- tests/integration.suite.dist.yml | 2 +- tests/integration/Regulator_Test.php | 88 +++++++++---------- tests/integration/Tasks/Email_Test.php | 76 ++++++++-------- tests/integration/Tasks/HTTP_Request_Test.php | 88 +++++++++---------- tests/integration/_bootstrap.php | 2 +- tests/wpunit.suite.dist.yml | 2 +- .../Abstracts/Provider_Abstract_Test.php | 6 +- .../wpunit/Abstracts/Table_Abstract_Test.php | 14 +-- tests/wpunit/Abstracts/Task_Test.php | 8 +- .../wpunit/Action_Scheduler_Methods_Test.php | 12 +-- tests/wpunit/Config_Test.php | 12 +-- tests/wpunit/Contracts/Task_Test.php | 4 +- tests/wpunit/Log_Test.php | 6 +- .../ActionScheduler_DB_Logger_Test.php | 12 +-- tests/wpunit/Loggers/DB_Logger_Test.php | 12 +-- tests/wpunit/Loggers/Null_Logger_Test.php | 4 +- tests/wpunit/Provider_Test.php | 4 +- tests/wpunit/Regulator_Test.php | 4 +- tests/wpunit/Tables/Task_Logs_Test.php | 4 +- tests/wpunit/Tables/Tasks_Test.php | 14 +-- .../Utility/Safe_Dynamic_Prefix_Test.php | 10 +-- tests/wpunit/Tasks/Email_Test.php | 10 +-- tests/wpunit/Tasks/HTTP_Request_Test.php | 22 ++--- .../Custom_Table_Query_Methods_Test.php | 12 +-- tests/wpunit/Traits/Loggable_Test.php | 6 +- tests/wpunit/_bootstrap.php | 2 +- 93 files changed, 855 insertions(+), 855 deletions(-) delete mode 100644 .cursor/rules/what-is-pigeon.mdc create mode 100644 .cursor/rules/what-is-shepherd.mdc rename pigeon.php => shepherd.php (79%) delete mode 100644 src/Exceptions/PigeonTaskAlreadyExistsException.php delete mode 100644 src/Exceptions/PigeonTaskException.php delete mode 100644 src/Exceptions/PigeonTaskFailWithoutRetryException.php create mode 100644 src/Exceptions/ShepherdTaskAlreadyExistsException.php create mode 100644 src/Exceptions/ShepherdTaskException.php create mode 100644 src/Exceptions/ShepherdTaskFailWithoutRetryException.php rename tests/_support/Helper/{PigeonJsonSnapshot.php => ShepherdJsonSnapshot.php} (95%) diff --git a/.cursor/rules/context.mdc b/.cursor/rules/context.mdc index b87a55c..0574fa1 100644 --- a/.cursor/rules/context.mdc +++ b/.cursor/rules/context.mdc @@ -7,12 +7,12 @@ alwaysApply: false - **Existing Patterns**: Follow the existing code structure, naming conventions, and architectural patterns found in the codebase. Consistency is key. - **Bail Early**: Use early returns in functions and methods to improve readability and reduce cognitive load. --- -description: Rules for implementing Pigeon tasks and features in PHP. +description: Rules for implementing Shepherd tasks and features in PHP. globs: - "src/**/*.php" --- ### Tasks -- All tasks **must** extend `StellarWP\Pigeon\Abstracts\Task_Abstract`. +- All tasks **must** extend `StellarWP\Shepherd\Abstracts\Task_Abstract`. - Task arguments must be passed to `parent::__construct()` to ensure they are correctly stored. - The core logic of a task resides in the `process()` method. - To trigger a retry, a task **must** overwrite the `get_max_retries` method. diff --git a/.cursor/rules/php-docblocks.mdc b/.cursor/rules/php-docblocks.mdc index e076df2..8e1313b 100644 --- a/.cursor/rules/php-docblocks.mdc +++ b/.cursor/rules/php-docblocks.mdc @@ -38,5 +38,5 @@ For properties they should be like: * * @since TBD * - * @package StellarWP\Pigeon + * @package StellarWP\Shepherd */ diff --git a/.cursor/rules/what-is-pigeon.mdc b/.cursor/rules/what-is-pigeon.mdc deleted file mode 100644 index aacae59..0000000 --- a/.cursor/rules/what-is-pigeon.mdc +++ /dev/null @@ -1,6 +0,0 @@ ---- -description: -globs: -alwaysApply: true ---- -Pigeon is a background offloading API. It's a wrapper of WooCommerce's Action Scheduler and on top of AS adds more functionality. diff --git a/.cursor/rules/what-is-shepherd.mdc b/.cursor/rules/what-is-shepherd.mdc new file mode 100644 index 0000000..3e67554 --- /dev/null +++ b/.cursor/rules/what-is-shepherd.mdc @@ -0,0 +1,6 @@ +--- +description: +globs: +alwaysApply: true +--- +Shpeherd is a background offloading API. It's a wrapper of WooCommerce's Action Scheduler and on top of AS adds more functionality. diff --git a/.gitattributes b/.gitattributes index ed71190..04be76b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,4 +8,4 @@ codeception.* export-ignore phpcs.xml export-ignore phpstan.neon.dist export-ignore docs export-ignore -pigeon.php export-ignore +shepherd.php export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 30b700a..f9c375b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to Pigeon +# Contributing to Shepherd -Thank you for contributing to Pigeon! This guide outlines the standards and processes for commits and pull requests. +Thank you for contributing to Shepherd! This guide outlines the standards and processes for commits and pull requests. ## Table of Contents @@ -250,8 +250,8 @@ Related to #789 * @param Task $task The task to schedule. * @param int $delay Delay in seconds before execution. Default 0. * - * @throws PigeonTaskException If task scheduling fails. - * @throws PigeonTaskAlreadyExistsException If duplicate task exists. + * @throws ShepherdTaskException If task scheduling fails. + * @throws ShepherdTaskAlreadyExistsException If duplicate task exists. * * @return void */ diff --git a/.github/workflows/tests-php.yml b/.github/workflows/tests-php.yml index 1a7a9af..ebc1e4e 100644 --- a/.github/workflows/tests-php.yml +++ b/.github/workflows/tests-php.yml @@ -72,7 +72,7 @@ jobs: ${SLIC_BIN} config - name: Start the Chrome container run: ${SLIC_BIN} up chrome - - name: Set up StellarWP Pigeon + - name: Set up StellarWP Shepherd run: | ${SLIC_BIN} use shepherd ${SLIC_BIN} composer install diff --git a/.github/workflows/update_as.yml b/.github/workflows/update_as.yml index 687b49d..9e460af 100644 --- a/.github/workflows/update_as.yml +++ b/.github/workflows/update_as.yml @@ -71,12 +71,12 @@ jobs: - name: Install WooCommerce run: ${SLIC_BIN} site-cli plugin install woocommerce - - name: Get Pigeon's AS Version from composer.json + - name: Get Shepherd's AS Version from composer.json run: | cd ${GITHUB_WORKSPACE}/ - PIGEON_AS_VERSION=$(grep -E '"woocommerce/action-scheduler": "[0-9]+\.[0-9]+\.[0-9]+"' composer.json | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') - echo "Pigeon's AS Version: $PIGEON_AS_VERSION" - echo "PIGEON_AS_VERSION=$PIGEON_AS_VERSION" >> $GITHUB_ENV + SHEPHERD_AS_VERSION=$(grep -E '"woocommerce/action-scheduler": "[0-9]+\.[0-9]+\.[0-9]+"' composer.json | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') + echo "Shepherd's AS Version: $SHEPHERD_AS_VERSION" + echo "SHEPHERD_AS_VERSION=$SHEPHERD_AS_VERSION" >> $GITHUB_ENV - name: Get WooCommerce's AS Version php eval run: | @@ -89,10 +89,10 @@ jobs: echo "WooCommerce's AS Version: $WC_AS_VERSION" echo "WC_AS_VERSION=$WC_AS_VERSION" >> $GITHUB_ENV - - name: Compare Pigeon's and WooCommerce's AS Versions + - name: Compare Shepherd's and WooCommerce's AS Versions run: | - if [ "$PIGEON_AS_VERSION" != "$WC_AS_VERSION" ]; then - echo "Pigeon's AS Version: $PIGEON_AS_VERSION" + if [ "$SHEPHERD_AS_VERSION" != "$WC_AS_VERSION" ]; then + echo "Shepherd's AS Version: $SHEPHERD_AS_VERSION" echo "WooCommerce's AS Version: $WC_AS_VERSION" exit 1 fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f28e94..54bb723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,4 +10,4 @@ All notable changes to this project will be documented in this file. This projec * Docs - Documentation * Tests - Automated tests -[1.0.0]: https://github.com/stellarwp/pigeon/releases/tag/1.0.0 +[1.0.0]: https://github.com/stellarwp/shepherd/releases/tag/1.0.0 diff --git a/CLAUDE.md b/CLAUDE.md index 05c2b25..977a6ff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,8 +1,8 @@ -# StellarWP Pigeon - AI Assistant Context +# StellarWP Shepherd - AI Assistant Context ## Project Overview -Pigeon is a lightweight background processing library for WordPress built on top of Action Scheduler. It provides a clean, fluent API for defining and dispatching asynchronous tasks with built-in support for retries, debouncing, and logging. +Shepherd is a lightweight background processing library for WordPress built on top of Action Scheduler. It provides a clean, fluent API for defining and dispatching asynchronous tasks with built-in support for retries, debouncing, and logging. ## Key Features @@ -26,8 +26,8 @@ Pigeon is a lightweight background processing library for WordPress built on top ### Database Schema -- `pigeon_{prefix}_tasks`: Stores task data and retry information -- `pigeon_{prefix}_task_logs`: Tracks task lifecycle events +- `shepherd_{prefix}_tasks`: Stores task data and retry information +- `shepherd_{prefix}_task_logs`: Tracks task lifecycle events ### Task Lifecycle States @@ -44,18 +44,18 @@ Pigeon is a lightweight background processing library for WordPress built on top ### Installation ```bash -composer require stellarwp/pigeon +composer require stellarwp/shepherd ``` ### Registration -Pigeon requires a DI container implementing `StellarWP\ContainerContract\ContainerInterface`. Register it on the `plugins_loaded` action at the LATEST: +Shepherd requires a DI container implementing `StellarWP\ContainerContract\ContainerInterface`. Register it on the `plugins_loaded` action at the LATEST: ```php -\StellarWP\Pigeon\Config::set_hook_prefix( 'my_app' ); // Needs to be set before the container is registered. +\StellarWP\Shepherd\Config::set_hook_prefix( 'my_app' ); // Needs to be set before the container is registered. $container = get_my_apps_container(); // Your container instance -$container->singleton( \StellarWP\Pigeon\Provider::class ); -$container->get( \StellarWP\Pigeon\Provider::class )->register(); +$container->singleton( \StellarWP\Shepherd\Provider::class ); +$container->get( \StellarWP\Shepherd\Provider::class )->register(); ``` ## Creating Tasks @@ -76,7 +76,7 @@ class My_Task extends Task_Abstract { // Task logic here if ( ! $result ) { - throw new PigeonTaskException( 'Task failed' ); + throw new ShepherdTaskException( 'Task failed' ); } } @@ -100,14 +100,14 @@ class My_Task extends Task_Abstract { ```php // Dispatch a task immediately -pigeon()->dispatch(new My_Task($arg1, $arg2)); +shepherd()->dispatch(new My_Task($arg1, $arg2)); // Dispatch with delay (in seconds) -pigeon()->dispatch(new My_Task($arg1, $arg2), 300); // 5 minutes +shepherd()->dispatch(new My_Task($arg1, $arg2), 300); // 5 minutes // Retrieve task logs -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Provider; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Provider; $logger = Provider::get_container()->get( Logger::class ); $logs = $logger->retrieve_logs( $task_id ); @@ -120,7 +120,7 @@ $logs = $logger->retrieve_logs( $task_id ); Sends emails asynchronously with automatic retries (up to 5 attempts): ```php -use StellarWP\Pigeon\Tasks\Email; +use StellarWP\Shepherd\Tasks\Email; $email_task = new Email( 'recipient@example.com', @@ -130,14 +130,14 @@ $email_task = new Email( ['/path/to/attachment.pdf'] ); -pigeon()->dispatch($email_task); +shepherd()->dispatch($email_task); ``` ## Logging System ### Default Logger Change (TBD) -Pigeon now uses `ActionScheduler_DB_Logger` as the default logger instead of `DB_Logger`. This change: +Shepherd now uses `ActionScheduler_DB_Logger` as the default logger instead of `DB_Logger`. This change: - **Reduces database overhead** by reusing Action Scheduler's existing `actionscheduler_logs` table - **Maintains compatibility** with the existing Logger interface @@ -146,14 +146,14 @@ Pigeon now uses `ActionScheduler_DB_Logger` as the default logger instead of `DB ### Logger Options ```php -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Loggers\ActionScheduler_DB_Logger; -use StellarWP\Pigeon\Loggers\DB_Logger; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Loggers\ActionScheduler_DB_Logger; +use StellarWP\Shepherd\Loggers\DB_Logger; // Default: Use Action Scheduler's logs table Config::set_logger( new ActionScheduler_DB_Logger() ); -// Alternative: Use Pigeon's dedicated logs table +// Alternative: Use Shepherd's dedicated logs table Config::set_logger( new DB_Logger() ); ``` @@ -162,17 +162,17 @@ Config::set_logger( new DB_Logger() ); When using `ActionScheduler_DB_Logger`, logs are stored in a special format within the `message` column: ``` -pigeon_{hook_prefix}||{task_id}||{type}||{level}||{json_entry} +shepherd_{hook_prefix}||{task_id}||{type}||{level}||{json_entry} ``` -This format allows Pigeon to store its metadata while maintaining compatibility with Action Scheduler's table structure. +This format allows Shepherd to store its metadata while maintaining compatibility with Action Scheduler's table structure. ## Development Commands ### Testing ```bash -# You need to have slic installed and configured to use pigeon. +# You need to have slic installed and configured to use shepherd. # Then you can run each suite like: slic run wpunit @@ -202,7 +202,7 @@ composer install --ignore-platform-req=ext-uopz ## Important Files and Locations -- **Main entry point**: `pigeon.php` +- **Main entry point**: `shepherd.php` - **Core logic**: `src/Regulator.php` - **Task base class**: `src/Abstracts/Task_Abstract.php` - **Database schemas**: `src/Tables/` @@ -222,7 +222,7 @@ composer install --ignore-platform-req=ext-uopz - Follows WordPress coding standards and more Specifically StellarWP's coding standards. - Uses PHPStan for static analysis (level defined in `phpstan.neon.dist`) - PHP 7.4+ compatibility required -- PSR-4 autoloading under `StellarWP\Pigeon` namespace +- PSR-4 autoloading under `StellarWP\Shepherd` namespace ## Dependencies @@ -239,7 +239,7 @@ composer install --ignore-platform-req=ext-uopz 1. Create a new class extending `Task_Abstract` in `src/Tasks/` 2. Implement required methods (`process()`, `get_task_prefix()`) 3. Optionally override retry configuration methods -4. If implemented withing Pigeon, add tests in `tests/unit/Tasks/` +4. If implemented withing Shepherd, add tests in `tests/unit/Tasks/` ### Modifying Database Schema @@ -265,14 +265,14 @@ composer install --ignore-platform-req=ext-uopz You can implement a custom logger by implementing the `Logger` interface: ```php -use StellarWP\Pigeon\Contracts\Logger; +use StellarWP\Shepherd\Contracts\Logger; class My_Custom_Logger implements Logger { // Implement required methods } // Set before Provider::register() -\StellarWP\Pigeon\Config::set_logger( new My_Custom_Logger() ); +\StellarWP\Shepherd\Config::set_logger( new My_Custom_Logger() ); ``` ## Task Behavior Details diff --git a/README.md b/README.md index 9bff3d5..7f25c9e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Pigeon +# Shepherd -Pigeon is a lightweight and powerful background processing library for WordPress, built on top of Action Scheduler. It provides a simple, fluent API for defining and dispatching asynchronous tasks, with built-in support for retries, debouncing, and logging. +Shepherd is a lightweight and powerful background processing library for WordPress, built on top of Action Scheduler. It provides a simple, fluent API for defining and dispatching asynchronous tasks, with built-in support for retries, debouncing, and logging. ## Features @@ -13,7 +13,7 @@ Pigeon is a lightweight and powerful background processing library for WordPress ## Getting Started -For a guide on how to install Pigeon and get started with creating and dispatching your first task, please see our [Getting Started guide](./docs/getting-started.md). +For a guide on how to install Shepherd and get started with creating and dispatching your first task, please see our [Getting Started guide](./docs/getting-started.md). ## Advanced Usage @@ -21,7 +21,7 @@ For more detailed information on advanced features like task retries, debouncing ## Built-in Tasks -Pigeon comes with a set of pre-packaged tasks to handle common background operations. For more information, please see our [Tasks guide](./docs/tasks.md). +Shepherd comes with a set of pre-packaged tasks to handle common background operations. For more information, please see our [Tasks guide](./docs/tasks.md). ## Contributing diff --git a/composer.json b/composer.json index d22c8a1..2c586fb 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "stellarwp/pigeon", + "name": "stellarwp/shepherd", "description": "A library for offloading tasks to background processes.", "type": "library", "license": "GPL-2.0", @@ -13,7 +13,7 @@ }, "autoload": { "psr-4": { - "StellarWP\\Pigeon\\": "src/" + "StellarWP\\Shepherd\\": "src/" }, "files": [ "src/functions.php" @@ -21,7 +21,7 @@ }, "autoload-dev": { "psr-4": { - "StellarWP\\Pigeon\\Tests\\": "tests/_support/Helper/" + "StellarWP\\Shepherd\\Tests\\": "tests/_support/Helper/" } }, "authors": [ diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 1e6a6a1..4918dc9 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -1,10 +1,10 @@ # Advanced Usage -This guide covers the advanced features of Pigeon for more complex use cases. +This guide covers the advanced features of Shepherd for more complex use cases. ## Automatic Retries -Pigeon can automatically retry failed tasks. A task is considered failed when it throws any exception during the `process()` method. +Shepherd can automatically retry failed tasks. A task is considered failed when it throws any exception during the `process()` method. ### Configuring Retries @@ -17,7 +17,7 @@ Override the `get_max_retries()` method on your task class. The default is `0` ( namespace My\App\Tasks; -use StellarWP\Pigeon\Abstracts\Task_Abstract; +use StellarWP\Shepherd\Abstracts\Task_Abstract; class My_Retryable_Task extends Task_Abstract { public function get_max_retries(): int { @@ -40,7 +40,7 @@ class My_Retryable_Task extends Task_Abstract { ### Retry Delays -By default, Pigeon uses exponential backoff for retries. You can customize this by overriding `get_retry_delay()`: +By default, Shepherd uses exponential backoff for retries. You can customize this by overriding `get_retry_delay()`: ```php public function get_retry_delay(): int { @@ -76,7 +76,7 @@ Organize related tasks into groups by overriding the `get_group()` method: ```php public function get_group(): string { - return 'my_custom_group'; // Default: 'pigeon_{prefix}_queue_default' + return 'my_custom_group'; // Default: 'shepherd_{prefix}_queue_default' } ``` @@ -88,9 +88,9 @@ Groups help with: ## Unique Tasks -Pigeon prevents duplicate tasks from being scheduled. A task is considered a duplicate if it has the same class and arguments as an existing scheduled task. +Shepherd prevents duplicate tasks from being scheduled. A task is considered a duplicate if it has the same class and arguments as an existing scheduled task. -When you try to dispatch a duplicate task, Pigeon will: +When you try to dispatch a duplicate task, Shepherd will: - Check if an identical task already exists (same class + arguments) - If it exists, silently ignore the dispatch request. You can listen to an action to be notified when this happens. See [API Reference](api-reference.md) for more information. @@ -100,27 +100,27 @@ This behavior prevents accidental task duplication and is enabled by default for ## Logging -Pigeon includes comprehensive logging that tracks the complete lifecycle of each task. +Shepherd includes comprehensive logging that tracks the complete lifecycle of each task. ### Built-in Logging By default, logs are stored in Action Scheduler's `actionscheduler_logs` table using the `ActionScheduler_DB_Logger`. This reduces database overhead by reusing existing infrastructure. The following events are automatically logged: -- `created`: Task scheduled (triggers `pigeon_{prefix}_task_created` action) -- `started`: Task execution begins (triggers `pigeon_{prefix}_task_started` action) -- `finished`: Task completed successfully (triggers `pigeon_{prefix}_task_finished` action) -- `failed`: Task failed (all retries exhausted, triggers `pigeon_{prefix}_task_failed` action) -- `rescheduled`: Task rescheduled (triggers `pigeon_{prefix}_task_rescheduled` action) +- `created`: Task scheduled (triggers `shepherd_{prefix}_task_created` action) +- `started`: Task execution begins (triggers `shepherd_{prefix}_task_started` action) +- `finished`: Task completed successfully (triggers `shepherd_{prefix}_task_finished` action) +- `failed`: Task failed (all retries exhausted, triggers `shepherd_{prefix}_task_failed` action) +- `rescheduled`: Task rescheduled (triggers `shepherd_{prefix}_task_rescheduled` action) - `retrying`: Retry attempt starting - `cancelled`: Task cancelled -Note: Tasks that fail without retry (e.g., HTTP 4xx errors) trigger `pigeon_{prefix}_task_failed_without_retry` instead of being rescheduled. +Note: Tasks that fail without retry (e.g., HTTP 4xx errors) trigger `shepherd_{prefix}_task_failed_without_retry` instead of being rescheduled. ### Retrieving Logs ```php -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Provider; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Provider; // Get the logger instance $logger = Provider::get_container()->get( Logger::class ); @@ -142,7 +142,7 @@ $logs = $logger->retrieve_logs( $task_id ); You can implement a custom logger by implementing the `Logger` interface: ```php -use StellarWP\Pigeon\Contracts\Logger; +use StellarWP\Shepherd\Contracts\Logger; use Psr\Log\AbstractLogger; class My_Custom_Logger extends AbstractLogger implements Logger { @@ -157,24 +157,24 @@ class My_Custom_Logger extends AbstractLogger implements Logger { } } -// Set your custom logger before registering Pigeon +// Set your custom logger before registering Shepherd Config::set_logger( new My_Custom_Logger() ); ``` ### Switching Between Loggers -Pigeon provides multiple logger implementations: +Shepherd provides multiple logger implementations: ```php -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Loggers\ActionScheduler_DB_Logger; -use StellarWP\Pigeon\Loggers\DB_Logger; -use StellarWP\Pigeon\Loggers\Null_Logger; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Loggers\ActionScheduler_DB_Logger; +use StellarWP\Shepherd\Loggers\DB_Logger; +use StellarWP\Shepherd\Loggers\Null_Logger; // Use Action Scheduler's logs table (default) Config::set_logger( new ActionScheduler_DB_Logger() ); -// Use Pigeon's dedicated logs table +// Use Shepherd's dedicated logs table Config::set_logger( new DB_Logger() ); // Disable logging entirely @@ -238,38 +238,38 @@ The task tables include indexes on: ### WordPress Hooks -Pigeon fires several WordPress actions during task lifecycle: +Shepherd fires several WordPress actions during task lifecycle: ```php $prefix = Config::get_hook_prefix(); // Task starts processing (fired by Regulator) -add_action( "pigeon_{$prefix}_task_started", function( $task, $action_id ) { +add_action( "shepherd_{$prefix}_task_started", function( $task, $action_id ) { // Log, monitor, or prepare for task execution }, 10, 2 ); // Task finished processing successfully (fired by Regulator) -add_action( "pigeon_{$prefix}_task_finished", function( $task, $action_id ) { +add_action( "shepherd_{$prefix}_task_finished", function( $task, $action_id ) { // Cleanup, notify, or trigger dependent tasks }, 10, 2 ); // Task failed with retries exhausted (fired by Regulator) -add_action( "pigeon_{$prefix}_task_failed", function( $task, $exception ) { +add_action( "shepherd_{$prefix}_task_failed", function( $task, $exception ) { // Handle permanent task failure }, 10, 2 ); // Task failed without retry (fired by Regulator) -add_action( "pigeon_{$prefix}_task_failed_without_retry", function( $task, $exception ) { +add_action( "shepherd_{$prefix}_task_failed_without_retry", function( $task, $exception ) { // Handle non-retryable failures (e.g., 4xx errors) }, 10, 2 ); // Email sent (fired by Email task) -add_action( "pigeon_{$prefix}_email_processed", function( $task ) { +add_action( "shepherd_{$prefix}_email_processed", function( $task ) { // Do something after the email is processed }, 10, 1 ); // HTTP request completed (fired by HTTP_Request task) -add_action( "pigeon_{$prefix}_http_request_processed", function( $task, $response ) { +add_action( "shepherd_{$prefix}_http_request_processed", function( $task, $response ) { // Handle successful HTTP response }, 10, 2 ); ``` diff --git a/docs/api-reference.md b/docs/api-reference.md index 808970f..a331514 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -1,6 +1,6 @@ # API Reference -This document provides a comprehensive reference for all public classes, interfaces, and methods in the Pigeon library. +This document provides a comprehensive reference for all public classes, interfaces, and methods in the Shepherd library. ## Table of Contents @@ -25,11 +25,11 @@ Schedules a task for execution. - **Parameters:** - `$task` - The task instance to schedule - `$delay` - Delay in seconds before execution (default: 0) -- **Throws:** and **Catches:** `PigeonTaskAlreadyExistsException` if duplicate task exists +- **Throws:** and **Catches:** `ShepherdTaskAlreadyExistsException` if duplicate task exists - **Throws:** and **Catches:** `RuntimeException` if task fails to be scheduled or inserted into the database. - You can listen for those errors above, by listening to the following actions: - - `pigeon_{prefix}_task_scheduling_failed` - - `pigeon_{prefix}_task_already_exists` + - `shepherd_{prefix}_task_scheduling_failed` + - `shepherd_{prefix}_task_already_exists` ##### `get_last_scheduled_task_id(): ?int` @@ -47,7 +47,7 @@ Clears the runtime cache of task data. ### `Config` -Static configuration management for Pigeon. +Static configuration management for Shepherd. #### Methods @@ -71,7 +71,7 @@ Returns the hook prefix trimmed to a safe length to ensure table names don't exc Returns the maximum safe length for a hook prefix based on: - WordPress table prefix length -- The longest Pigeon table name +- The longest Shepherd table name ##### `set_logger( ?Logger $logger ): void` @@ -98,13 +98,13 @@ Service provider for dependency injection and initialization. #### Constants -- `VERSION` - Pigeon's current version +- `VERSION` - Shepherd's current version #### Methods ##### `register(): void` -Initializes Pigeon and registers all components. +Initializes Shepherd and registers all components. ##### `set_container( ContainerInterface $container ): void` @@ -116,7 +116,7 @@ Returns the container instance. ##### `is_registered(): bool` -Checks if Pigeon has been registered. +Checks if Shepherd has been registered. --- @@ -138,15 +138,15 @@ public function __construct( #### Configuration -- **Task Prefix:** `pigeon_email_` +- **Task Prefix:** `shepherd_email_` - **Max Retries:** 4 - **Retry Delay:** 30 seconds (exponential backoff: 30s then 60s then 120s then 240s and so on) -- **Group:** `pigeon_{prefix}_queue_default` +- **Group:** `shepherd_{prefix}_queue_default` - **Priority:** 10 #### WordPress Hooks -- `pigeon_{prefix}_email_processed` - Fired after a successful call to `wp_mail()` +- `shepherd_{prefix}_email_processed` - Fired after a successful call to `wp_mail()` --- @@ -166,12 +166,12 @@ public function __construct( #### Configuration -- **Task Prefix:** `pigeon_http_` +- **Task Prefix:** `shepherd_http_` - **Max Retries:** 10 - **Retry Delay:** Exponential backoff - **Default Timeout:** 3 seconds - **Default Args:** Compression enabled, 5 redirects, reject unsafe URLs -- **Group:** `pigeon_{prefix}_queue_default` +- **Group:** `shepherd_{prefix}_queue_default` - **Priority:** 10 #### Supported Methods @@ -189,20 +189,20 @@ public function get_auth_headers(): array #### Error Handling -- **WP_Error responses**: Fail immediately without retry (throws `PigeonTaskFailWithoutRetryException`) -- **4xx HTTP errors**: Fail immediately without retry (throws `PigeonTaskFailWithoutRetryException`) -- **5xx HTTP errors**: Retry with exponential backoff (throws `PigeonTaskException`) -- **Other non-2xx**: Retry with exponential backoff (throws `PigeonTaskException`) +- **WP_Error responses**: Fail immediately without retry (throws `ShepherdTaskFailWithoutRetryException`) +- **4xx HTTP errors**: Fail immediately without retry (throws `ShepherdTaskFailWithoutRetryException`) +- **5xx HTTP errors**: Retry with exponential backoff (throws `ShepherdTaskException`) +- **Other non-2xx**: Retry with exponential backoff (throws `ShepherdTaskException`) #### WordPress Hooks -- `pigeon_{prefix}_http_request_processed` - Fired after successful HTTP request -- `pigeon_{prefix}_task_failed_without_retry` - Fired when task fails without retry (4xx errors, WP_Error) +- `shepherd_{prefix}_http_request_processed` - Fired after successful HTTP request +- `shepherd_{prefix}_task_failed_without_retry` - Fired when task fails without retry (4xx errors, WP_Error) #### Special Features - **Authentication Headers**: Override `get_auth_headers()` to add auth without storing credentials in database -- **Task ID Header**: Automatically adds `X-Pigeon-Task-ID` header with task ID +- **Task ID Header**: Automatically adds `X-Shepherd-Task-ID` header with task ID - **Security Defaults**: URL validation, compression, and redirect limits enabled by default --- @@ -293,7 +293,7 @@ Abstract method - return a unique prefix (max 15 characters). ##### `get_group(): string` -Returns the task group (default: `pigeon_{prefix}_queue_default`). +Returns the task group (default: `shepherd_{prefix}_queue_default`). ##### `get_priority(): int` @@ -315,19 +315,19 @@ Protected method for custom argument validation. ## Exceptions -### `PigeonTaskException` +### `ShepherdTaskException` General exception for task-related errors. ```php -throw new PigeonTaskException( 'Task processing failed' ); +throw new ShepherdTaskException( 'Task processing failed' ); ``` -### `PigeonTaskAlreadyExistsException` +### `ShepherdTaskAlreadyExistsException` Thrown and caught when attempting to schedule a duplicate task. -### `PigeonTaskFailWithoutRetryException` +### `ShepherdTaskFailWithoutRetryException` Thrown when a task encounters an error that should not be retried (e.g., 4xx HTTP errors, WP_Error responses). @@ -335,16 +335,16 @@ Thrown when a task encounters an error that should not be retried (e.g., 4xx HTT ## Helper Functions -### `pigeon(): Regulator` +### `shepherd(): Regulator` Global helper function to access the Regulator instance. ```php // Dispatch a task -pigeon()->dispatch( new My_Task() ); +shepherd()->dispatch( new My_Task() ); // Get last task ID -$task_id = pigeon()->get_last_scheduled_task_id(); +$task_id = shepherd()->get_last_scheduled_task_id(); ``` --- @@ -355,7 +355,7 @@ $task_id = pigeon()->get_last_scheduled_task_id(); Default logger that stores logs in the database. -- Table: `pigeon_{prefix}_task_logs` +- Table: `shepherd_{prefix}_task_logs` - Implements PSR-3 log levels - Stores logs as JSON @@ -373,7 +373,7 @@ Config::set_logger( new Null_Logger() ); ### Tasks Table -Table name: `pigeon_{prefix}_tasks` +Table name: `shepherd_{prefix}_tasks` | Column | Type | Description | |--------|------|-------------| @@ -386,7 +386,7 @@ Table name: `pigeon_{prefix}_tasks` ### Task Logs Table -Table name: `pigeon_{prefix}_task_logs` +Table name: `shepherd_{prefix}_task_logs` | Column | Type | Description | |--------|------|-------------| @@ -403,30 +403,30 @@ Table name: `pigeon_{prefix}_task_logs` ### Actions -- `pigeon_{prefix}_task_scheduling_failed` - Fired when a task fails to be scheduled +- `shepherd_{prefix}_task_scheduling_failed` - Fired when a task fails to be scheduled - Parameters: `$task`, `$exception` -- `pigeon_{prefix}_task_already_scheduled` - Fired when a task already exists +- `shepherd_{prefix}_task_already_scheduled` - Fired when a task already exists - Parameters: `$task` -- `pigeon_{prefix}_task_started` - Fired when a task starts being processed +- `shepherd_{prefix}_task_started` - Fired when a task starts being processed - Parameters: `$task`, `$action_id` (int) -- `pigeon_{prefix}_task_finished` - Fired when a task finishes processing successfully +- `shepherd_{prefix}_task_finished` - Fired when a task finishes processing successfully - Parameters: `$task`, `$action_id` (int) -- `pigeon_{prefix}_task_failed` - Fired when a task fails +- `shepherd_{prefix}_task_failed` - Fired when a task fails - Parameters: `$task`, `$exception` -- `pigeon_{prefix}_task_failed_without_retry` - Fired when a task fails without retry - - Parameters: `$task`, `$exception` (PigeonTaskFailWithoutRetryException) +- `shepherd_{prefix}_task_failed_without_retry` - Fired when a task fails without retry + - Parameters: `$task`, `$exception` (ShepherdTaskFailWithoutRetryException) -- `pigeon_{prefix}_email_processed` - Fired after a successful call to `wp_mail()` +- `shepherd_{prefix}_email_processed` - Fired after a successful call to `wp_mail()` - Parameters: `$task` (Email instance) -- `pigeon_{prefix}_http_request_processed` - Fired after successful HTTP request +- `shepherd_{prefix}_http_request_processed` - Fired after successful HTTP request - Parameters: `$task` (HTTP_Request instance), `$response` (wp_remote_request response array) ### Filters -Currently, Pigeon does not provide any filters. +Currently, Shepherd does not provide any filters. diff --git a/docs/configuration.md b/docs/configuration.md index 8b08aed..3220351 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,15 +1,15 @@ # Configuration Guide -This guide covers all configuration options available in Pigeon. +This guide covers all configuration options available in Shepherd. ## Required Configuration ### Hook Prefix -The hook prefix is **required** and must be set before registering Pigeon: +The hook prefix is **required** and must be set before registering Shepherd: ```php -use StellarWP\Pigeon\Config; +use StellarWP\Shepherd\Config; // Set a unique prefix for your application Config::set_hook_prefix( 'my_app' ); @@ -28,10 +28,10 @@ The hook prefix is used to: **Automatic Length Protection:** -Pigeon automatically ensures table names don't exceed MySQL's 64-character limit. If your hook prefix is too long, it will be automatically trimmed to a safe length based on: +Shepherd automatically ensures table names don't exceed MySQL's 64-character limit. If your hook prefix is too long, it will be automatically trimmed to a safe length based on: - Your WordPress table prefix length -- The longest Pigeon table name +- The longest Shepherd table name You can check the maximum safe length using: @@ -43,24 +43,24 @@ $max_length = Config::get_max_hook_prefix_length(); ### Custom Logger -By default, Pigeon uses `ActionScheduler_DB_Logger` to store logs in Action Scheduler's existing logs table. This reduces database overhead by reusing Action Scheduler's infrastructure. +By default, Shepherd uses `ActionScheduler_DB_Logger` to store logs in Action Scheduler's existing logs table. This reduces database overhead by reusing Action Scheduler's infrastructure. Available loggers: - **`ActionScheduler_DB_Logger`** (default): Stores logs in Action Scheduler's `actionscheduler_logs` table -- **`DB_Logger`**: Stores logs in Pigeon's dedicated `task_logs` table +- **`DB_Logger`**: Stores logs in Shepherd's dedicated `task_logs` table - **`Null_Logger`**: Disables logging entirely ```php -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Loggers\ActionScheduler_DB_Logger; -use StellarWP\Pigeon\Loggers\DB_Logger; -use StellarWP\Pigeon\Loggers\Null_Logger; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Loggers\ActionScheduler_DB_Logger; +use StellarWP\Shepherd\Loggers\DB_Logger; +use StellarWP\Shepherd\Loggers\Null_Logger; // Use Action Scheduler's logs table (default) Config::set_logger( new ActionScheduler_DB_Logger() ); -// Use Pigeon's dedicated logs table +// Use Shepherd's dedicated logs table Config::set_logger( new DB_Logger() ); // Disable logging @@ -74,40 +74,40 @@ Config::set_logger( new My_Custom_Logger() ); ## Container Configuration -Pigeon requires a dependency injection container that implements `StellarWP\ContainerContract\ContainerInterface`. +Shepherd requires a dependency injection container that implements `StellarWP\ContainerContract\ContainerInterface`. ### Basic Setup ```php -use StellarWP\Pigeon\Provider; -use StellarWP\Pigeon\Config; +use StellarWP\Shepherd\Provider; +use StellarWP\Shepherd\Config; // Get your container instance $container = get_my_container(); -// Register Pigeon as a singleton +// Register Shepherd as a singleton $container->singleton( Provider::class ); Config::set_container( $container ); Config::set_hook_prefix( 'my_app' ); // Needs to be set before the provider is initialized. -// Initialize Pigeon +// Initialize Shepherd $container->get( Provider::class )->register(); ``` ## Database Configuration -Pigeon automatically creates database tables during registration: +Shepherd automatically creates database tables during registration: -1. **Tasks Table**: `{prefix}_pigeon_{hook_prefix}_tasks` -2. **Logs Table** (optional): `{prefix}_pigeon_{hook_prefix}_task_logs` +1. **Tasks Table**: `{prefix}_shepherd_{hook_prefix}_tasks` +2. **Logs Table** (optional): `{prefix}_shepherd_{hook_prefix}_task_logs` Where: - `{prefix}` is your WordPress table prefix (e.g., `wp_`) - `{hook_prefix}` is your configured hook prefix (automatically trimmed if needed) -**Note:** If your hook prefix is too long, Pigeon will automatically trim it to ensure table names don't exceed MySQL's 64-character limit. The trimming is calculated based on the longest table name. +**Note:** If your hook prefix is too long, Shepherd will automatically trim it to ensure table names don't exceed MySQL's 64-character limit. The trimming is calculated based on the longest table name. ### Table Creation @@ -117,11 +117,11 @@ The logs table is only created if you're using the `DB_Logger`. When using the d ## Action Scheduler Configuration -Pigeon uses Action Scheduler for task scheduling. You can configure Action Scheduler settings separately: +Shepherd uses Action Scheduler for task scheduling. You can configure Action Scheduler settings separately: ### Custom Action Scheduler Tables -Action Scheduler uses its own tables. If you need custom table names, configure Action Scheduler before loading Pigeon. +Action Scheduler uses its own tables. If you need custom table names, configure Action Scheduler before loading Shepherd. ### Concurrent Execution @@ -129,7 +129,7 @@ By default, Action Scheduler processes one task at a time. To increase concurren ## Complete Configuration Example -Here's a complete example of configuring Pigeon: +Here's a complete example of configuring Shepherd: ```php singleton( Provider::class ); $container->get( Provider::class )->register(); @@ -157,10 +157,10 @@ $container->get( Provider::class )->register(); ## Configuration Best Practices -1. **Set Configuration Early**: Configure Pigeon before any code tries to use it +1. **Set Configuration Early**: Configure Shepherd before any code tries to use it 2. **Use Consistent Prefixes**: Keep your hook prefix consistent across your application 3. **Container Singleton**: Always register Provider as a singleton -4. **Check Registration**: If you are not sure whether Pigeon is registered, you can check it using `Provider::is_registered()` before accessing Pigeon +4. **Check Registration**: If you are not sure whether Shepherd is registered, you can check it using `Provider::is_registered()` before accessing Shepherd ```php if ( ! Provider::is_registered() ) { diff --git a/docs/getting-started.md b/docs/getting-started.md index c42d968..3bf0a27 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,18 +1,18 @@ -# Getting Started with Pigeon +# Getting Started with Shepherd -This guide will walk you through the basics of installing and using Pigeon to run your first background task. +This guide will walk you through the basics of installing and using Shepherd to run your first background task. ## Installation -Pigeon is a Composer package that provides a robust background task processing system for WordPress applications. To install it, you'll need to have Composer in your project. If you don't have it already, you can follow the instructions on the [Composer website](https://getcomposer.org/). +Shepherd is a Composer package that provides a robust background task processing system for WordPress applications. To install it, you'll need to have Composer in your project. If you don't have it already, you can follow the instructions on the [Composer website](https://getcomposer.org/). -Once you have Composer set up, you can add Pigeon to your project by running the following command in your project's root directory: +Once you have Composer set up, you can add Shepherd to your project by running the following command in your project's root directory: ```bash -composer require stellarwp/pigeon +composer require stellarwp/shepherd ``` -After installing Pigeon, you need to make sure you're including the Composer autoloader in your plugin or theme. This is typically done by adding the following line to your main plugin file or `functions.php`: +After installing Shepherd, you need to make sure you're including the Composer autoloader in your plugin or theme. This is typically done by adding the following line to your main plugin file or `functions.php`: ```php require_once __DIR__ . '/vendor/autoload.php'; @@ -20,11 +20,11 @@ require_once __DIR__ . '/vendor/autoload.php'; ## Configuration and Registration -Pigeon requires a DI container that implements `StellarWP\ContainerContract\ContainerInterface`. You need to configure and register Pigeon before using it. This is typically done in your plugin's main file: +Shepherd requires a DI container that implements `StellarWP\ContainerContract\ContainerInterface`. You need to configure and register Shepherd before using it. This is typically done in your plugin's main file: ```php -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Provider; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Provider; // Example function to get your container instance function get_my_container(): \StellarWP\ContainerContract\ContainerInterface { @@ -32,7 +32,7 @@ function get_my_container(): \StellarWP\ContainerContract\ContainerInterface { return $container; } -// Register Pigeon (at the latest on plugins_loaded) +// Register Shepherd (at the latest on plugins_loaded) add_action( 'plugins_loaded', function() { // IMPORTANT: Set the hook prefix first (required) Config::set_hook_prefix( 'my_app' ); // Use a unique prefix for your application @@ -40,20 +40,20 @@ add_action( 'plugins_loaded', function() { // Get your container instance $container = get_my_container(); - // Register Pigeon as a singleton + // Register Shepherd as a singleton $container->singleton( Provider::class ); - // Set the container for Pigeon. + // Set the container for Shepherd. Config::set_container( $container ); - // Initialize Pigeon + // Initialize Shepherd $container->get( Provider::class )->register(); } ); ``` ### Configuration Options -Before registering Pigeon, you can configure it using the `Config` class: +Before registering Shepherd, you can configure it using the `Config` class: ```php // Set a custom logger (optional - defaults to DB_Logger) @@ -65,7 +65,7 @@ $prefix = Config::get_hook_prefix(); ## Creating Your First Task -Tasks in Pigeon are classes that extend the `StellarWP\Pigeon\Abstracts\Task_Abstract` class. At a minimum, you need to implement the `process()` method and `get_task_prefix()` method. +Tasks in Shepherd are classes that extend the `StellarWP\Shepherd\Abstracts\Task_Abstract` class. At a minimum, you need to implement the `process()` method and `get_task_prefix()` method. Let's create a simple task that logs a message: @@ -74,7 +74,7 @@ Let's create a simple task that logs a message: namespace My\App\Tasks; -use StellarWP\Pigeon\Abstracts\Task_Abstract; +use StellarWP\Shepherd\Abstracts\Task_Abstract; class Log_Message_Task extends Task_Abstract { /** @@ -97,7 +97,7 @@ class Log_Message_Task extends Task_Abstract { $code = $this->get_args()[1]; // Your task logic here - error_log( 'Pigeon Task: ' . $message . ' with code ' . $code ); + error_log( 'Shepherd Task: ' . $message . ' with code ' . $code ); // If something goes wrong, throw an exception if ( $code >= 400 ) { @@ -124,31 +124,31 @@ class Log_Message_Task extends Task_Abstract { ## Dispatching Your Task -Once you've created your task, you can dispatch it using the `pigeon()` helper function: +Once you've created your task, you can dispatch it using the `shepherd()` helper function: ```php use My\App\Tasks\Log_Message_Task; -use function StellarWP\Pigeon\pigeon; +use function StellarWP\Shepherd\shepherd; // Create a task instance $my_task = new Log_Message_Task( 'Hello, World!', 200 ); // Dispatch immediately -pigeon()->dispatch( $my_task ); +shepherd()->dispatch( $my_task ); // Or dispatch with a delay (in seconds) -pigeon()->dispatch( $my_task, 5 * MINUTE_IN_SECONDS ); // Execute after 5 minutes +shepherd()->dispatch( $my_task, 5 * MINUTE_IN_SECONDS ); // Execute after 5 minutes ``` ### What Happens Next? -1. Pigeon schedules your task with Action Scheduler +1. Shepherd schedules your task with Action Scheduler 2. WordPress cron (or another Action Scheduler's runner, like CLI) picks up the task 3. Your task's `process()` method is executed 4. The task lifecycle is logged in the database 5. If the task fails, it may be retried based on your configuration -Check your `debug.log` file, and you should see the message "Pigeon Task: Hello, World! with code 200". +Check your `debug.log` file, and you should see the message "Shepherd Task: Hello, World! with code 200". ## Verifying Task Execution @@ -156,11 +156,11 @@ You can check if your task was scheduled successfully: ```php // Get the last scheduled task ID -$task_id = pigeon()->get_last_scheduled_task_id(); +$task_id = shepherd()->get_last_scheduled_task_id(); // Retrieve task logs -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Provider; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Provider; $logger = Provider::get_container()->get( Logger::class ); $logs = $logger->retrieve_logs( $task_id ); @@ -169,7 +169,7 @@ $logs = $logger->retrieve_logs( $task_id ); ## Next Steps - Learn about [Advanced Usage](./advanced-usage.md) including retries, debouncing, and custom configuration -- Explore the [Built-in Tasks](./tasks.md) that come with Pigeon +- Explore the [Built-in Tasks](./tasks.md) that come with Shepherd - Read the [API Reference](./api-reference.md) for detailed information about all classes and methods ## Troubleshooting @@ -179,4 +179,4 @@ If your tasks aren't running: 1. **Check Action Scheduler**: Visit Tools → Scheduled Actions in WordPress admin 2. **Verify WP-Cron**: Ensure WordPress cron is running or set up a real cron job 3. **Check Logs**: Look for errors in your WordPress debug log -4. **Database Tables**: Ensure Pigeon's tables were created during registration +4. **Database Tables**: Ensure Shepherd's tables were created during registration diff --git a/docs/tasks.md b/docs/tasks.md index ce516b9..8a242ab 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -1,6 +1,6 @@ # Built-in Tasks -Pigeon comes with pre-packaged tasks to handle common background operations. Each task is designed to be reliable, well-tested, and includes automatic retry logic. +Shepherd comes with pre-packaged tasks to handle common background operations. Each task is designed to be reliable, well-tested, and includes automatic retry logic. ## Available Tasks @@ -18,7 +18,7 @@ Sends emails asynchronously using WordPress's `wp_mail()` function. **Quick Example:** ```php -use StellarWP\Pigeon\Tasks\Email; +use StellarWP\Shepherd\Tasks\Email; $email = new Email( 'user@example.com', @@ -27,7 +27,7 @@ $email = new Email( ['Content-Type: text/html; charset=UTF-8'] ); -pigeon()->dispatch( $email ); +shepherd()->dispatch( $email ); ``` ### [HTTP Request Task](./tasks/http-request.md) @@ -46,11 +46,11 @@ Makes HTTP requests asynchronously using WordPress's `wp_remote_request()` funct **Quick Example:** ```php -use StellarWP\Pigeon\Tasks\HTTP_Request; +use StellarWP\Shepherd\Tasks\HTTP_Request; // Simple GET request (uses default 3s timeout) $request = new HTTP_Request( 'https://api.example.com/status' ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); // POST request with JSON data and custom timeout $webhook = new HTTP_Request( @@ -62,7 +62,7 @@ $webhook = new HTTP_Request( ], 'POST' ); -pigeon()->dispatch( $webhook ); +shepherd()->dispatch( $webhook ); // Custom authentication (extend the class) class Authenticated_HTTP_Request extends HTTP_Request { @@ -83,7 +83,7 @@ To create custom tasks, extend the `Task_Abstract` class: namespace My\App\Tasks; -use StellarWP\Pigeon\Abstracts\Task_Abstract; +use StellarWP\Shepherd\Abstracts\Task_Abstract; class My_Custom_Task extends Task_Abstract { public function __construct( string $data ) { @@ -156,7 +156,7 @@ class Process_Everything extends Task_Abstract { } ``` -Instead of doing everything in one task, you can create multiple tasks that are more focused and easier to test. On each task's `process()` method, you can fire an `action` than next tasks can listen to, or directly schedule the next task to be processed via `pigeon()->dispatch()`. +Instead of doing everything in one task, you can create multiple tasks that are more focused and easier to test. On each task's `process()` method, you can fire an `action` than next tasks can listen to, or directly schedule the next task to be processed via `shepherd()->dispatch()`. ### 4. Proper Argument Validation @@ -183,7 +183,7 @@ protected function validate_args(): void { ## Contributing Tasks -If you've created a useful task that could benefit others, consider contributing it to the Pigeon library: +If you've created a useful task that could benefit others, consider contributing it to the Shepherd library: 1. Ensure your task follows WordPress coding standards 2. Include comprehensive PHPDoc comments @@ -200,4 +200,4 @@ Planned tasks for future releases: - **Cache Warming Task**: Pre-populate caches - **Bulk Operations Task**: Handle large data sets in chunks -Have ideas for built-in tasks? [Open an issue](https://github.com/stellarwp/pigeon/issues) to discuss your suggestions. +Have ideas for built-in tasks? [Open an issue](https://github.com/stellarwp/shepherd/issues) to discuss your suggestions. diff --git a/docs/tasks/email.md b/docs/tasks/email.md index 10c80a0..b8b4a85 100644 --- a/docs/tasks/email.md +++ b/docs/tasks/email.md @@ -24,19 +24,19 @@ public function __construct( ## Configuration -- **Task Prefix**: `pigeon_email_` +- **Task Prefix**: `shepherd_email_` - **Max Retries**: 4 additional attempts (5 total attempts) - **Retry Delay**: 30 seconds between attempts - **Priority**: 10 (default) -- **Group**: `pigeon_{prefix}_queue_default` +- **Group**: `shepherd_{prefix}_queue_default` ## Usage Examples ### Basic Email ```php -use StellarWP\Pigeon\Tasks\Email; -use function StellarWP\Pigeon\pigeon; +use StellarWP\Shepherd\Tasks\Email; +use function StellarWP\Shepherd\shepherd; // Simple text email $email = new Email( @@ -45,7 +45,7 @@ $email = new Email( 'Thank you for signing up!' ); -pigeon()->dispatch( $email ); +shepherd()->dispatch( $email ); ``` ### HTML Email with Headers @@ -62,7 +62,7 @@ $email = new Email( ] ); -pigeon()->dispatch( $email ); +shepherd()->dispatch( $email ); ``` ### Email with Attachments @@ -79,7 +79,7 @@ $email = new Email( ] ); -pigeon()->dispatch( $email ); +shepherd()->dispatch( $email ); ``` ### Delayed Email @@ -92,7 +92,7 @@ $email = new Email( 'This is a friendly reminder about your appointment.' ); -pigeon()->dispatch( $email, HOUR_IN_SECONDS ); +shepherd()->dispatch( $email, HOUR_IN_SECONDS ); ``` ## Error Handling @@ -122,7 +122,7 @@ The Email task automatically handles failures and retries. Common scenarios: The Email task fires a WordPress action after successfully sending: ```php -add_action( 'pigeon_{prefix}_email_processed', function( $task ) { +add_action( 'shepherd_{prefix}_email_processed', function( $task ) { // Track successful email sending error_log( "Email sent to: {$task->get_args()[0]} with subject: {$task->get_args()[1]}" ); }, 10, 1 ); @@ -157,11 +157,11 @@ Email tasks are automatically logged with these events: ### Retrieving Logs ```php -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Provider; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Provider; // Get task ID after dispatching -$task_id = pigeon()->get_last_scheduled_task_id(); +$task_id = shepherd()->get_last_scheduled_task_id(); // Retrieve logs $logger = Provider::get_container()->get( Logger::class ); @@ -212,7 +212,7 @@ You can extend the `Email` task to create your own tasks. 1. Check WordPress email configuration 2. Verify SMTP settings if using SMTP plugin 3. Check email logs in Action Scheduler -4. Review Pigeon task logs +4. Review Shepherd task logs ### Attachments Not Working diff --git a/docs/tasks/http-request.md b/docs/tasks/http-request.md index ecbe001..e0a114f 100644 --- a/docs/tasks/http-request.md +++ b/docs/tasks/http-request.md @@ -30,12 +30,12 @@ public function __construct( ## Configuration -- **Task Prefix**: `pigeon_http_` +- **Task Prefix**: `shepherd_http_` - **Max Retries**: 10 additional attempts (11 total attempts) - **Retry Delay**: Exponential backoff using base class defaults - **Default Timeout**: 3 seconds - **Priority**: 10 (default) -- **Group**: `pigeon_{prefix}_queue_default` +- **Group**: `shepherd_{prefix}_queue_default` ## Default Request Arguments @@ -60,26 +60,26 @@ The HTTP_Request task uses intelligent error handling: - **WP_Error responses**: Network failures, DNS issues, etc. - **4xx HTTP errors**: Client errors (400, 401, 403, 404, etc.) -These throw `PigeonTaskFailWithoutRetryException` and do not retry. +These throw `ShepherdTaskFailWithoutRetryException` and do not retry. ### Retryable Failures - **5xx HTTP errors**: Server errors (500, 502, 503, etc.) - **Other non-2xx responses**: Redirects that exceed limits, etc. -These throw `PigeonTaskException` and retry up to 10 times with exponential backoff. +These throw `ShepherdTaskException` and retry up to 10 times with exponential backoff. ## Usage Examples ### Basic GET Request ```php -use StellarWP\Pigeon\Tasks\HTTP_Request; -use function StellarWP\Pigeon\pigeon; +use StellarWP\Shepherd\Tasks\HTTP_Request; +use function StellarWP\Shepherd\shepherd; // Simple GET request with 3-second timeout $request = new HTTP_Request( 'https://api.example.com/status' ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); ``` ### POST Request with JSON Body @@ -102,7 +102,7 @@ $webhook = new HTTP_Request( ], 'POST' ); -pigeon()->dispatch( $webhook ); +shepherd()->dispatch( $webhook ); ``` ### Custom Authentication @@ -124,14 +124,14 @@ $request = new Authenticated_API_Request( 'https://api.example.com/protected', ['timeout' => 30] ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); ``` ## Special Features ### Task ID Header -Every request automatically includes an `X-Pigeon-Task-ID` header containing the task's database ID. This helps with debugging and request tracking. +Every request automatically includes an `X-Shepherd-Task-ID` header containing the task's database ID. This helps with debugging and request tracking. ### Security Defaults @@ -153,7 +153,7 @@ When a request completes successfully (2xx response), this action fires: * @param HTTP_Request $task The task instance * @param array $response Full wp_remote_request response */ -do_action( 'pigeon_{prefix}_http_request_processed', $task, $response ); +do_action( 'shepherd_{prefix}_http_request_processed', $task, $response ); ``` ### Failure Hook @@ -165,9 +165,9 @@ When a request fails without retry (4xx errors, WP_Error): * Fires when HTTP request fails without retry. * * @param HTTP_Request $task The task instance - * @param PigeonTaskFailWithoutRetryException $exception The exception + * @param ShepherdTaskFailWithoutRetryException $exception The exception */ -do_action( 'pigeon_{prefix}_task_failed_without_retry', $task, $exception ); +do_action( 'shepherd_{prefix}_task_failed_without_retry', $task, $exception ); ``` ## Error Examples @@ -176,10 +176,10 @@ do_action( 'pigeon_{prefix}_task_failed_without_retry', $task, $exception ); ```php $request = new HTTP_Request( 'https://api.example.com/nonexistent' ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); // If API returns 404, task fails immediately: -// PigeonTaskFailWithoutRetryException: +// ShepherdTaskFailWithoutRetryException: // HTTP GET request to https://api.example.com/nonexistent returned error 404: `Not Found` ``` @@ -187,10 +187,10 @@ pigeon()->dispatch( $request ); ```php $request = new HTTP_Request( 'https://unstable-api.example.com/data' ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); // If API returns 500, task retries up to 10 times: -// PigeonTaskException: +// ShepherdTaskException: // HTTP GET request to https://unstable-api.example.com/data returned error 500: `Internal Server Error` ``` @@ -198,10 +198,10 @@ pigeon()->dispatch( $request ); ```php $request = new HTTP_Request( 'https://nonexistent-domain.invalid' ); -pigeon()->dispatch( $request ); +shepherd()->dispatch( $request ); // DNS failure results in immediate failure: -// PigeonTaskFailWithoutRetryException: +// ShepherdTaskFailWithoutRetryException: // HTTP GET request to https://nonexistent-domain.invalid failed with code: `http_request_failed` and message: `Could not resolve host` ``` diff --git a/phpcs.xml b/phpcs.xml index d323a63..05d74cc 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,5 +1,5 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/pigeon.php b/shepherd.php similarity index 79% rename from pigeon.php rename to shepherd.php index 7ea0e2e..ab95cfe 100644 --- a/pigeon.php +++ b/shepherd.php @@ -1,19 +1,19 @@ get_group(); @@ -179,7 +179,7 @@ protected function dispatch_callback( Task $task, int $delay ): void { DB::beginTransaction(); if ( Action_Scheduler_Methods::has_scheduled_action( $this->process_task_hook, [ $args_hash ], $group ) ) { - throw new PigeonTaskAlreadyExistsException( 'The task is already scheduled.' ); + throw new ShepherdTaskAlreadyExistsException( 'The task is already scheduled.' ); } $previous_action_id = $task->get_action_id(); @@ -214,7 +214,7 @@ protected function dispatch_callback( Task $task, int $delay ): void { * * @param Task $task The task that should be retried. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_rescheduled', $task ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_rescheduled', $task ); $this->log_rescheduled( $task->get_id(), @@ -233,7 +233,7 @@ protected function dispatch_callback( Task $task, int $delay ): void { * * @param Task $task The task that should be retried. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_created', $task ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_created', $task ); $this->log_created( $task->get_id(), $log_data ); } @@ -249,8 +249,8 @@ protected function dispatch_callback( Task $task, int $delay ): void { * @param Task $task The task that failed to be scheduled or inserted into the database. * @param RuntimeException $e The exception that was thrown. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_scheduling_failed', $task, $e ); - } catch ( PigeonTaskAlreadyExistsException $e ) { + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_scheduling_failed', $task, $e ); + } catch ( ShepherdTaskAlreadyExistsException $e ) { DB::rollback(); /** * Fires when a task is already scheduled. @@ -259,7 +259,7 @@ protected function dispatch_callback( Task $task, int $delay ): void { * * @param Task $task The task that is already scheduled. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_already_scheduled', $task ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_already_scheduled', $task ); } } @@ -301,9 +301,9 @@ public function bust_runtime_cached_tasks(): void { * * @param string $args_hash The arguments hash. * - * @throws RuntimeException If no action ID is found, no Pigeon task is found with the action ID, or the task arguments hash does not match the expected hash. - * @throws PigeonTaskException If the task fails to be processed. - * @throws PigeonTaskFailWithoutRetryException If the task fails to be processed without retry. + * @throws RuntimeException If no action ID is found, no Shepherd task is found with the action ID, or the task arguments hash does not match the expected hash. + * @throws ShepherdTaskException If the task fails to be processed. + * @throws ShepherdTaskFailWithoutRetryException If the task fails to be processed without retry. * @throws Exception If the task fails to be processed. * @throws Throwable If the task fails to be processed. */ @@ -314,7 +314,7 @@ public function process_task( string $args_hash ): void { $task = Tasks_Table::get_by_args_hash( $args_hash ); if ( ! $task ) { - throw new RuntimeException( 'No Pigeon task found with args hash ' . $args_hash . '.' ); + throw new RuntimeException( 'No Shepherd task found with args hash ' . $args_hash . '.' ); } $task = array_shift( $task ); @@ -323,7 +323,7 @@ public function process_task( string $args_hash ): void { $task ??= Tasks_Table::get_by_action_id( $this->current_action_id ); if ( ! $task ) { - throw new RuntimeException( 'No Pigeon task found with action ID ' . $this->current_action_id . '.' ); + throw new RuntimeException( 'No Shepherd task found with action ID ' . $this->current_action_id . '.' ); } $log_data = [ @@ -339,7 +339,7 @@ public function process_task( string $args_hash ): void { * @param Task $task The task that is being processed. * @param int $action_id The action ID that is being processed. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_started', $task, $this->current_action_id ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_started', $task, $this->current_action_id ); try { try { @@ -352,19 +352,19 @@ public function process_task( string $args_hash ): void { $task->process(); $this->log_finished( $task->get_id(), $log_data ); - } catch ( PigeonTaskException $e ) { + } catch ( ShepherdTaskException $e ) { throw $e; } - } catch ( PigeonTaskFailWithoutRetryException $e ) { + } catch ( ShepherdTaskFailWithoutRetryException $e ) { /** * Fires when a task fails to be processed without retry. * * @since TBD * * @param Task $task The task that failed to be processed without retry. - * @param PigeonTaskFailWithoutRetryException $e The exception that was thrown. + * @param ShepherdTaskFailWithoutRetryException $e The exception that was thrown. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_failed_without_retry', $task, $e ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_failed_without_retry', $task, $e ); /** * Fires when a task fails to be processed without retry. @@ -372,9 +372,9 @@ public function process_task( string $args_hash ): void { * @since TBD * * @param Task $task The task that failed to be processed without retry. - * @param PigeonTaskFailWithoutRetryException $e The exception that was thrown. + * @param ShepherdTaskFailWithoutRetryException $e The exception that was thrown. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_failed_without_retry', $task, $e ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_failed_without_retry', $task, $e ); $this->log_failed( $task->get_id(), array_merge( $log_data, [ 'exception' => $e->getMessage() ] ) ); @@ -388,10 +388,10 @@ public function process_task( string $args_hash ): void { * @param Task $task The task that failed to be processed. * @param Exception $e The exception that was thrown. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_failed', $task, $e ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_failed', $task, $e ); if ( $this->should_retry( $task ) ) { - throw new PigeonTaskException( __( 'The task failed, but will be retried.', 'stellarwp-pigeon' ) ); + throw new ShepherdTaskException( __( 'The task failed, but will be retried.', 'stellarwp-shepherd' ) ); } $this->log_failed( $task->get_id(), array_merge( $log_data, [ 'exception' => $e->getMessage() ] ) ); @@ -405,10 +405,10 @@ public function process_task( string $args_hash ): void { * @param Task $task The task that failed to be processed. * @param Throwable $e The exception that was thrown. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_failed', $task, $e ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_failed', $task, $e ); if ( $this->should_retry( $task ) ) { - throw new PigeonTaskException( __( 'The task failed, but will be retried.', 'stellarwp-pigeon' ) ); + throw new ShepherdTaskException( __( 'The task failed, but will be retried.', 'stellarwp-shepherd' ) ); } $this->log_failed( $task->get_id(), array_merge( $log_data, [ 'exception' => $e->getMessage() ] ) ); @@ -423,7 +423,7 @@ public function process_task( string $args_hash ): void { * @param Task $task The task that is finished processing. * @param int $action_id The action ID that is finished processing. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_task_finished', $task, $this->current_action_id ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_task_finished', $task, $this->current_action_id ); } /** diff --git a/src/Tables/AS_Logs.php b/src/Tables/AS_Logs.php index 7ae5e22..b280604 100644 --- a/src/Tables/AS_Logs.php +++ b/src/Tables/AS_Logs.php @@ -4,14 +4,14 @@ * * @since TBD * - * @package StellarWP\Pigeon\Tables; + * @package StellarWP\Shepherd\Tables; */ -namespace StellarWP\Pigeon\Tables; +namespace StellarWP\Shepherd\Tables; -use StellarWP\Pigeon\Abstracts\Table_Abstract as Table; -use StellarWP\Pigeon\Log; -use StellarWP\Pigeon\Config; +use StellarWP\Shepherd\Abstracts\Table_Abstract as Table; +use StellarWP\Shepherd\Log; +use StellarWP\Shepherd\Config; use StellarWP\DB\DB; use DateTime; @@ -22,7 +22,7 @@ * * @since TBD * - * @package StellarWP\Pigeon\Tables; + * @package StellarWP\Shepherd\Tables; */ class AS_Logs extends Table { /** @@ -98,7 +98,7 @@ public static function get_columns(): array { public static function get_by_task_id( int $task_id ): array { $results = []; - foreach ( self::fetch_all_where( DB::prepare( 'WHERE message LIKE %s', 'pigeon_' . Config::get_hook_prefix() . '||' . $task_id . '||%' ), 50, ARRAY_A, 'log_date_gmt ASC' ) as $log_array ) { + foreach ( self::fetch_all_where( DB::prepare( 'WHERE message LIKE %s', 'shepherd_' . Config::get_hook_prefix() . '||' . $task_id . '||%' ), 50, ARRAY_A, 'log_date_gmt ASC' ) as $log_array ) { $results[] = self::get_model_from_array( $log_array ); } diff --git a/src/Tables/Provider.php b/src/Tables/Provider.php index 2600ff9..1206683 100644 --- a/src/Tables/Provider.php +++ b/src/Tables/Provider.php @@ -1,27 +1,27 @@ get_args() ); if ( ! $result ) { - throw new PigeonTaskException( __( 'Failed to send email.', 'stellarwp-pigeon' ) ); + throw new ShepherdTaskException( __( 'Failed to send email.', 'stellarwp-shepherd' ) ); } /** @@ -65,7 +65,7 @@ public function process(): void { * * @param Email $task The email task that was processed. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_email_processed', $this ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_email_processed', $this ); } /** @@ -78,19 +78,19 @@ public function process(): void { protected function validate_args(): void { $args = $this->get_args(); if ( count( $args ) < 3 ) { - throw new InvalidArgumentException( __( 'Email task requires at least 3 arguments.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'Email task requires at least 3 arguments.', 'stellarwp-shepherd' ) ); } if ( ! is_email( $args[0] ) ) { - throw new InvalidArgumentException( __( 'Email address is invalid.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'Email address is invalid.', 'stellarwp-shepherd' ) ); } if ( ! is_string( $args[1] ) ) { - throw new InvalidArgumentException( __( 'Email subject must be a string.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'Email subject must be a string.', 'stellarwp-shepherd' ) ); } if ( ! is_string( $args[2] ) ) { - throw new InvalidArgumentException( __( 'Email body must be a string.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'Email body must be a string.', 'stellarwp-shepherd' ) ); } } @@ -102,7 +102,7 @@ protected function validate_args(): void { * @return string The email task's hook prefix. */ public function get_task_prefix(): string { - return 'pigeon_email_'; + return 'shepherd_email_'; } /** diff --git a/src/Tasks/HTTP_Request.php b/src/Tasks/HTTP_Request.php index e1a397c..4f4035d 100644 --- a/src/Tasks/HTTP_Request.php +++ b/src/Tasks/HTTP_Request.php @@ -1,34 +1,34 @@ get_url(); @@ -94,7 +94,7 @@ public function process(): void { $request_args['headers'] = array_merge( $request_args['headers'], $this->get_auth_headers() ); - $request_args['headers']['X-Pigeon-Task-ID'] = $this->get_id(); + $request_args['headers']['X-Shepherd-Task-ID'] = $this->get_id(); // Make the HTTP request. $response = wp_remote_request( $url, $request_args ); @@ -112,12 +112,12 @@ public function process(): void { */ $should_retry = apply_filters( 'shepherd_' . Config::get_hook_prefix() . '_http_request_should_retry_on_wp_error', false, $response, $this ); - $expection_class = $should_retry ? PigeonTaskException::class : PigeonTaskFailWithoutRetryException::class; + $expection_class = $should_retry ? ShepherdTaskException::class : ShepherdTaskFailWithoutRetryException::class; throw new $expection_class( sprintf( /* translators: %1$s: HTTP method, %2$s: URL, %3$s: Error message */ - __( 'HTTP %1$s request to %2$s failed with code: `%3$s` and message: `%4$s`', 'stellarwp-pigeon' ), + __( 'HTTP %1$s request to %2$s failed with code: `%3$s` and message: `%4$s`', 'stellarwp-shepherd' ), $method, $url, $response->get_error_code(), @@ -138,10 +138,10 @@ public function process(): void { */ $should_retry = apply_filters( 'shepherd_' . Config::get_hook_prefix() . '_http_request_should_retry_on_invalid_response', false, $response, $this ); - $expection_class = $should_retry ? PigeonTaskException::class : PigeonTaskFailWithoutRetryException::class; + $expection_class = $should_retry ? ShepherdTaskException::class : ShepherdTaskFailWithoutRetryException::class; throw new $expection_class( - __( 'HTTP request returned an invalid response.', 'stellarwp-pigeon' ) + __( 'HTTP request returned an invalid response.', 'stellarwp-shepherd' ) ); } @@ -162,12 +162,12 @@ public function process(): void { */ $should_retry = apply_filters( 'shepherd_' . Config::get_hook_prefix() . '_http_request_should_retry_on_http_error_status_codes', false, $response, $this ); - $expection_class = $should_retry ? PigeonTaskException::class : PigeonTaskFailWithoutRetryException::class; + $expection_class = $should_retry ? ShepherdTaskException::class : ShepherdTaskFailWithoutRetryException::class; throw new $expection_class( sprintf( /* translators: %1$s: HTTP method, %2$s: URL, %3$d: Response code, %4$s: Response message */ - __( 'HTTP %1$s request to %2$s returned error %3$d: `%4$s`', 'stellarwp-pigeon' ), + __( 'HTTP %1$s request to %2$s returned error %3$d: `%4$s`', 'stellarwp-shepherd' ), $method, $url, $response_code, @@ -188,12 +188,12 @@ public function process(): void { */ $should_retry = apply_filters( 'shepherd_' . Config::get_hook_prefix() . '_http_request_should_retry_on_non_2xx_response_codes', true, $response, $this ); - $expection_class = $should_retry ? PigeonTaskException::class : PigeonTaskFailWithoutRetryException::class; + $expection_class = $should_retry ? ShepherdTaskException::class : ShepherdTaskFailWithoutRetryException::class; throw new $expection_class( sprintf( /* translators: %1$s: HTTP method, %2$s: URL, %3$d: Response code, %4$s: Response message */ - __( 'HTTP %1$s request to %2$s returned error %3$d: `%4$s`', 'stellarwp-pigeon' ), + __( 'HTTP %1$s request to %2$s returned error %3$d: `%4$s`', 'stellarwp-shepherd' ), $method, $url, $response_code, @@ -210,7 +210,7 @@ public function process(): void { * @param HTTP_Request $task The HTTP request task that was processed. * @param array $response The wp_remote_request response array. */ - do_action( 'pigeon_' . Config::get_hook_prefix() . '_http_request_processed', $this, $response ); + do_action( 'shepherd_' . Config::get_hook_prefix() . '_http_request_processed', $this, $response ); } // phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.Missing @@ -226,12 +226,12 @@ protected function validate_args(): void { $args = $this->get_args(); if ( empty( $args[0] ) ) { - throw new InvalidArgumentException( __( 'URL is required.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'URL is required.', 'stellarwp-shepherd' ) ); } // Validate request arguments. if ( isset( $args[1] ) && ! is_array( $args[1] ) ) { - throw new InvalidArgumentException( __( 'Request arguments must be an array.', 'stellarwp-pigeon' ) ); + throw new InvalidArgumentException( __( 'Request arguments must be an array.', 'stellarwp-shepherd' ) ); } // Validate HTTP method. @@ -239,7 +239,7 @@ protected function validate_args(): void { throw new InvalidArgumentException( sprintf( /* translators: %s: Valid HTTP methods */ - __( 'HTTP method must be one of: %s', 'stellarwp-pigeon' ), + __( 'HTTP method must be one of: %s', 'stellarwp-shepherd' ), implode( ', ', self::VALID_METHODS ) ) ); @@ -254,7 +254,7 @@ protected function validate_args(): void { * @return string The HTTP request task's hook prefix. */ public function get_task_prefix(): string { - return 'pigeon_http_'; + return 'shepherd_http_'; } /** diff --git a/src/Traits/Custom_Table_Query_Methods.php b/src/Traits/Custom_Table_Query_Methods.php index 24fbfa0..44bf7c8 100644 --- a/src/Traits/Custom_Table_Query_Methods.php +++ b/src/Traits/Custom_Table_Query_Methods.php @@ -4,24 +4,24 @@ * * @since TBD * - * @package StellarWP\Pigeon\Traits; + * @package StellarWP\Shepherd\Traits; */ -namespace StellarWP\Pigeon\Traits; +namespace StellarWP\Shepherd\Traits; use Generator; use StellarWP\DB\DB; use InvalidArgumentException; use DateTimeInterface; -use StellarWP\Pigeon\Abstracts\Table_Abstract as Table; -use StellarWP\Pigeon\Contracts\Model; +use StellarWP\Shepherd\Abstracts\Table_Abstract as Table; +use StellarWP\Shepherd\Contracts\Model; /** * Trait Custom_Table_Query_Methods. * * @since TBD * - * @package StellarWP\Pigeon\Traits; + * @package StellarWP\Shepherd\Traits; */ trait Custom_Table_Query_Methods { /** diff --git a/src/Traits/Loggable.php b/src/Traits/Loggable.php index 1cea577..1f49990 100644 --- a/src/Traits/Loggable.php +++ b/src/Traits/Loggable.php @@ -1,26 +1,26 @@ get( Regulator::class ); + $shepherd = Config::get_container()->get( Regulator::class ); - return $pigeon; + return $shepherd; } diff --git a/tests/_support/Helper/Container.php b/tests/_support/Helper/Container.php index a427087..391ce89 100644 --- a/tests/_support/Helper/Container.php +++ b/tests/_support/Helper/Container.php @@ -1,25 +1,25 @@ get_args()['0'] . '_pigeon_test_do_action_task'; + return $this->get_args()['0'] . '_shepherd_test_do_action_task'; } public function process(): void { diff --git a/tests/_support/Helper/Tasks/Internal_Counting_Task.php b/tests/_support/Helper/Tasks/Internal_Counting_Task.php index 59f0cf1..25ecc51 100644 --- a/tests/_support/Helper/Tasks/Internal_Counting_Task.php +++ b/tests/_support/Helper/Tasks/Internal_Counting_Task.php @@ -1,9 +1,9 @@ get( Task_Model_Abstract::TABLE_INTERFACE )->empty_table(); DB::query( DB::prepare( "DELETE FROM %i", DB::prefix( 'actionscheduler_actions' ) ) ); - remove_all_actions( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_started' ); + remove_all_actions( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_started' ); } protected function get_task_from_id( int $task_id ): Task { @@ -44,7 +44,7 @@ protected function assertTaskHasActionPending( int $task_id ): void { $task = $this->get_task_from_id( $task_id ); $action = $this->get_action_from_task( $task ); - $this->assertEquals( pigeon()->get_hook(), $action->get_hook() ); + $this->assertEquals( shepherd()->get_hook(), $action->get_hook() ); $this->assertFalse( $action->is_finished() ); } @@ -53,7 +53,7 @@ protected function assertTaskHasActionFinished( int $task_id ): void { $task = $this->get_task_from_id( $task_id ); $action = $this->get_action_from_task( $task ); - $this->assertEquals( pigeon()->get_hook(), $action->get_hook() ); + $this->assertEquals( shepherd()->get_hook(), $action->get_hook() ); $this->assertTrue( $action->is_finished() ); } @@ -120,11 +120,11 @@ protected function assertTaskExecutesFails( int $task_id ): void { } protected function add_listener( int $action_id, int $task_id ): void { - add_action( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_started', function( Task $task, int $aid ) use ( $action_id, $task_id ) { + add_action( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_started', function( Task $task, int $aid ) use ( $action_id, $task_id ) { Assert::assertSame( $action_id, $aid ); Assert::assertSame( $action_id, $task->get_action_id() ); Assert::assertSame( $task_id, $task->get_id() ); - remove_all_actions( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_started' ); + remove_all_actions( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_started' ); }, 10, 2 ); } diff --git a/tests/_support/Helper/Traits/With_Clock_Mock.php b/tests/_support/Helper/Traits/With_Clock_Mock.php index 6f6a6df..c2b057a 100644 --- a/tests/_support/Helper/Traits/With_Clock_Mock.php +++ b/tests/_support/Helper/Traits/With_Clock_Mock.php @@ -3,7 +3,7 @@ * Wraps the Clock Mock library for easier use in testing. */ -namespace StellarWP\Pigeon\Tests\Traits; +namespace StellarWP\Shepherd\Tests\Traits; use SlopeIt\ClockMock\ClockMock; use DateTimeInterface; diff --git a/tests/_support/Helper/Traits/With_Log_Snapshot.php b/tests/_support/Helper/Traits/With_Log_Snapshot.php index 2062106..733ba92 100644 --- a/tests/_support/Helper/Traits/With_Log_Snapshot.php +++ b/tests/_support/Helper/Traits/With_Log_Snapshot.php @@ -1,10 +1,10 @@ setDataVisitor($dataVisitor); } diff --git a/tests/_support/Helper/Traits/With_Uopz.php b/tests/_support/Helper/Traits/With_Uopz.php index ed26bec..50643ed 100644 --- a/tests/_support/Helper/Traits/With_Uopz.php +++ b/tests/_support/Helper/Traits/With_Uopz.php @@ -1,6 +1,6 @@ get( Tables\Utility\Safe_Dynamic_Prefix::class ); $tables = []; @@ -49,7 +49,7 @@ function tests_pigeon_drop_tables() { * * @return void */ -function tests_pigeon_raise_auto_increment(): void { +function tests_shepherd_raise_auto_increment(): void { DB::query( DB::prepare( 'ALTER TABLE %i AUTO_INCREMENT = 86740', DB::prefix( 'actionscheduler_actions' ) ) ); DB::query( DB::prepare( 'ALTER TABLE %i AUTO_INCREMENT = 94540', DB::prefix( 'actionscheduler_logs' ) ) ); @@ -70,10 +70,10 @@ function tests_pigeon_raise_auto_increment(): void { * * @return void */ -function tests_pigeon_reset_config(): void { +function tests_shepherd_reset_config(): void { Config::reset(); - Config::set_hook_prefix( tests_pigeon_get_hook_prefix() ); - Config::set_container( tests_pigeon_get_container() ); + Config::set_hook_prefix( tests_shepherd_get_hook_prefix() ); + Config::set_container( tests_shepherd_get_container() ); Config::set_max_table_name_length( 25 ); } @@ -82,7 +82,7 @@ function tests_pigeon_reset_config(): void { * * @return string */ -function tests_pigeon_get_hook_prefix(): string { +function tests_shepherd_get_hook_prefix(): string { return 'foobar'; } @@ -91,7 +91,7 @@ function tests_pigeon_get_hook_prefix(): string { * * @return ContainerInterface */ -function tests_pigeon_get_container(): ContainerInterface { +function tests_shepherd_get_container(): ContainerInterface { static $container = null; if ( null === $container ) { @@ -107,7 +107,7 @@ function tests_pigeon_get_container(): ContainerInterface { * * @return DateTimeInterface */ -function tests_pigeon_get_dt(): DateTimeInterface { +function tests_shepherd_get_dt(): DateTimeInterface { return new DateTime( '2025-06-13 17:25:00', new DateTimeZone( 'UTC' ) ); } @@ -116,24 +116,24 @@ function tests_pigeon_get_dt(): DateTimeInterface { * * @return void */ -function tests_pigeon_common_bootstrap(): void { - tests_pigeon_reset_config(); - tests_pigeon_drop_tables(); +function tests_shepherd_common_bootstrap(): void { + tests_shepherd_reset_config(); + tests_shepherd_drop_tables(); $container = Config::get_container(); - // Bootstrap Pigeon. + // Bootstrap Shepherd. $container->singleton( Provider::class ); $container->get( Provider::class )->register(); // For tests we forcefully register the task logs table for it to exist. Register::table( Task_Logs::class ); - tests_pigeon_raise_auto_increment(); + tests_shepherd_raise_auto_increment(); // Drop the tables after the tests are done. tests_add_filter( 'shutdown', - 'tests_pigeon_drop_tables' + 'tests_shepherd_drop_tables' ); } \ No newline at end of file diff --git a/tests/integration.suite.dist.yml b/tests/integration.suite.dist.yml index ea204e3..6efc23b 100644 --- a/tests/integration.suite.dist.yml +++ b/tests/integration.suite.dist.yml @@ -14,6 +14,6 @@ modules: tablePrefix: "%WP_TABLE_PREFIX%" domain: "%WP_DOMAIN%" adminEmail: admin@%WP_DOMAIN% - title: 'Pigeon Integration Tests' + title: 'Shepherd Integration Tests' configFile: tests/config.php theme: kadence diff --git a/tests/integration/Regulator_Test.php b/tests/integration/Regulator_Test.php index d550407..5688506 100644 --- a/tests/integration/Regulator_Test.php +++ b/tests/integration/Regulator_Test.php @@ -2,24 +2,24 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Loggers\DB_Logger; -use StellarWP\Pigeon\Provider; -use StellarWP\Pigeon\Tests\Tasks\Do_Action_Task; -use StellarWP\Pigeon\Tests\Tasks\Always_Fail_Task; -use StellarWP\Pigeon\Tests\Tasks\Do_Prefixed_Action_Task; -use StellarWP\Pigeon\Tests\Tasks\Retryable_Do_Action_Task; -use StellarWP\Pigeon\Tests\Tasks\Internal_Counting_Task; -use StellarWP\Pigeon\Tests\Traits\With_AS_Assertions; -use StellarWP\Pigeon\Tests\Traits\With_Clock_Mock; -use StellarWP\Pigeon\Tests\Traits\With_Log_Snapshot; -use StellarWP\Pigeon\Tests\Traits\With_Uopz; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Loggers\DB_Logger; +use StellarWP\Shepherd\Provider; +use StellarWP\Shepherd\Tests\Tasks\Do_Action_Task; +use StellarWP\Shepherd\Tests\Tasks\Always_Fail_Task; +use StellarWP\Shepherd\Tests\Tasks\Do_Prefixed_Action_Task; +use StellarWP\Shepherd\Tests\Tasks\Retryable_Do_Action_Task; +use StellarWP\Shepherd\Tests\Tasks\Internal_Counting_Task; +use StellarWP\Shepherd\Tests\Traits\With_AS_Assertions; +use StellarWP\Shepherd\Tests\Traits\With_Clock_Mock; +use StellarWP\Shepherd\Tests\Traits\With_Log_Snapshot; +use StellarWP\Shepherd\Tests\Traits\With_Uopz; use Exception; -use function StellarWP\Pigeon\pigeon; +use function StellarWP\Shepherd\shepherd; class Regulator_Test extends WPTestCase { use With_AS_Assertions; @@ -32,14 +32,14 @@ class Regulator_Test extends WPTestCase { * @after */ public function reset(): void { - pigeon()->bust_runtime_cached_tasks(); + shepherd()->bust_runtime_cached_tasks(); } /** * @before */ public function freeze(): void { - $this->freeze_time( tests_pigeon_get_dt() ); + $this->freeze_time( tests_shepherd_get_dt() ); } private function get_logger(): Logger { @@ -50,13 +50,13 @@ private function get_logger(): Logger { * @test */ public function it_should_schedule_and_process_task_without_args(): void { - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Do_Action_Task(); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -87,16 +87,16 @@ public function it_should_schedule_and_process_task_without_args(): void { * @test */ public function it_should_schedule_same_task_only_once(): void { - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Internal_Counting_Task(); - $this->assertSame( 0, did_action( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled' ) ); - $pigeon->dispatch( $dummy_task ); - $this->assertSame( 0, did_action( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled' ) ); + $this->assertSame( 0, did_action( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled' ) ); + $shepherd->dispatch( $dummy_task ); + $this->assertSame( 0, did_action( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled' ) ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -104,13 +104,13 @@ public function it_should_schedule_same_task_only_once(): void { $this->assertTaskIsScheduledForExecutionAt( $last_scheduled_task_id, time() ); - $pigeon->dispatch( $dummy_task ); - $this->assertSame( 1, did_action( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled' ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $shepherd->dispatch( $dummy_task ); + $this->assertSame( 1, did_action( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled' ) ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); - $pigeon->dispatch( new Internal_Counting_Task() ); - $this->assertSame( 2, did_action( 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled' ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $shepherd->dispatch( new Internal_Counting_Task() ); + $this->assertSame( 2, did_action( 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled' ) ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); $this->assertSame( 0, did_action( $dummy_task->get_task_name() ) ); @@ -135,14 +135,14 @@ public function it_should_schedule_same_task_only_once(): void { * @test */ public function it_should_schedule_and_process_task_with_args(): void { - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Do_Prefixed_Action_Task( 'dimi' ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -173,13 +173,13 @@ public function it_should_schedule_and_process_task_with_args(): void { * @test */ public function it_should_retry_task_and_mark_as_failed(): void { - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Always_Fail_Task( 'arg1', 'arg2', 55, 44 ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -211,13 +211,13 @@ public function it_should_retry_task_and_mark_as_failed(): void { * @test */ public function it_should_retry_task_and_succeed(): void { - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Retryable_Do_Action_Task(); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); diff --git a/tests/integration/Tasks/Email_Test.php b/tests/integration/Tasks/Email_Test.php index cb2b9a0..95a2245 100644 --- a/tests/integration/Tasks/Email_Test.php +++ b/tests/integration/Tasks/Email_Test.php @@ -1,17 +1,17 @@ freeze_time( tests_pigeon_get_dt() ); - pigeon()->bust_runtime_cached_tasks(); + $this->freeze_time( tests_shepherd_get_dt() ); + shepherd()->bust_runtime_cached_tasks(); } private function get_logger(): Logger { @@ -41,13 +41,13 @@ public function it_should_dispatch_and_process_email(): void { return true; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Email( 'test@test.com', 'subject', 'body', [ 'Reply-To: test@test.com' ], [ 'attachment.txt' ] ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -79,13 +79,13 @@ public function it_should_try_a_total_of_5_times(): void { return false; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Email( 'test@test.com', 'subject', 'body', [ 'Reply-To: dimi@test.com' ], [ 'attachment.jpg' ] ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -138,13 +138,13 @@ public function it_should_retry_and_succeed_email(): void { return false; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Email( 'test@test.com', 'subject', 'body' ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -187,27 +187,27 @@ public function it_should_not_schedule_same_task_twice(): void { return true; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $dummy_task = new Email( 'test@test.com', 'subject', 'body' ); - $hook_name = 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled'; + $hook_name = 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled'; $this->assertSame( 0, did_action( $hook_name ) ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); $this->assertSame( 0, did_action( $hook_name ) ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); - $pigeon->dispatch( $dummy_task ); + $shepherd->dispatch( $dummy_task ); $this->assertSame( 1, did_action( $hook_name ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); - $pigeon->dispatch( new Email( 'test@test.com', 'subject', 'body' ) ); + $shepherd->dispatch( new Email( 'test@test.com', 'subject', 'body' ) ); $this->assertSame( 2, did_action( $hook_name ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); $this->assertTaskExecutesWithoutErrors( $last_scheduled_task_id ); @@ -225,22 +225,22 @@ public function it_should_schedule_multiple_tasks_with_different_args(): void { return true; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $task1 = new Email( 'test1@test.com', 'subject1', 'body1' ); - $pigeon->dispatch( $task1 ); - $task1_id = $pigeon->get_last_scheduled_task_id(); + $shepherd->dispatch( $task1 ); + $task1_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $task1_id ); $task2 = new Email( 'test2@test.com', 'subject2', 'body2' ); - $pigeon->dispatch( $task2 ); - $task2_id = $pigeon->get_last_scheduled_task_id(); + $shepherd->dispatch( $task2 ); + $task2_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $task2_id ); $this->assertNotEquals( $task1_id, $task2_id ); - $hook_name = 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled'; + $hook_name = 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled'; $this->assertSame( 0, did_action( $hook_name ) ); $this->assertTaskExecutesWithoutErrors( $task1_id ); diff --git a/tests/integration/Tasks/HTTP_Request_Test.php b/tests/integration/Tasks/HTTP_Request_Test.php index 5790301..7c0c39d 100644 --- a/tests/integration/Tasks/HTTP_Request_Test.php +++ b/tests/integration/Tasks/HTTP_Request_Test.php @@ -1,18 +1,18 @@ freeze_time( tests_pigeon_get_dt() ); - pigeon()->bust_runtime_cached_tasks(); + $this->freeze_time( tests_shepherd_get_dt() ); + shepherd()->bust_runtime_cached_tasks(); } private function get_logger(): Logger { @@ -50,13 +50,13 @@ public function it_should_dispatch_and_process_http_get_request(): void { return $response; }, true ); - $pigeon = pigeon(); - $this->assertNull( $pigeon->get_last_scheduled_task_id() ); + $shepherd = shepherd(); + $this->assertNull( $shepherd->get_last_scheduled_task_id() ); $task = new HTTP_Request( 'https://example.com/api/test' ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); @@ -97,7 +97,7 @@ public function it_should_dispatch_and_process_http_post_request_with_body(): vo return $response; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $request_args = [ 'headers' => [ @@ -109,9 +109,9 @@ public function it_should_dispatch_and_process_http_post_request_with_body(): vo ]; $task = new HTTP_Request( 'https://api.example.com/items', $request_args, 'POST' ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertTaskExecutesWithoutErrors( $last_scheduled_task_id ); @@ -136,12 +136,12 @@ public function it_should_fail_immediately_on_wp_error(): void { return $error; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task = new HTTP_Request( 'https://flaky-api.example.com' ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertTaskHasActionPending( $last_scheduled_task_id ); $this->assertTaskIsScheduledForExecutionAt( $last_scheduled_task_id, time() ); @@ -179,12 +179,12 @@ public function it_should_retry_on_http_error_status(): void { return $error_response; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task = new HTTP_Request( 'https://unstable-api.example.com' ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); // First attempt fails and reschedules $this->assertTaskExecutesFailsAndReschedules( $last_scheduled_task_id ); @@ -238,12 +238,12 @@ public function it_should_fail_immediately_on_4xx_error(): void { return $error_response; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task = new HTTP_Request( 'https://missing-api.example.com' ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertTaskHasActionPending( $last_scheduled_task_id ); $this->assertTaskIsScheduledForExecutionAt( $last_scheduled_task_id, time() ); @@ -283,20 +283,20 @@ public function it_should_fire_action_on_successful_request(): void { $action_task = null; $action_response = null; - $hook_name = 'pigeon_' . tests_pigeon_get_hook_prefix() . '_http_request_processed'; + $hook_name = 'shepherd_' . tests_shepherd_get_hook_prefix() . '_http_request_processed'; add_action( $hook_name, function ( $task, $resp ) use ( &$action_fired, &$action_task, &$action_response ) { $action_fired = true; $action_task = $task; $action_response = $resp; }, 10, 2 ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task = new HTTP_Request( 'https://webhook.example.com/notify' ); $this->assertEquals( 0, $task->get_id() ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertEquals( $last_scheduled_task_id, $task->get_id() ); @@ -326,28 +326,28 @@ public function it_should_not_schedule_same_request_twice(): void { return $response; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task = new HTTP_Request( 'https://api.example.com/webhook', [ 'body' => '{"event": "test"}' ], 'POST' ); - $hook_name = 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled'; + $hook_name = 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled'; $this->assertSame( 0, did_action( $hook_name ) ); - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); $this->assertSame( 0, did_action( $hook_name ) ); - $last_scheduled_task_id = $pigeon->get_last_scheduled_task_id(); + $last_scheduled_task_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $last_scheduled_task_id ); // Try to dispatch same task again - $pigeon->dispatch( $task ); + $shepherd->dispatch( $task ); $this->assertSame( 1, did_action( $hook_name ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); // Try with identical task instance - $pigeon->dispatch( new HTTP_Request( 'https://api.example.com/webhook', [ 'body' => '{"event": "test"}' ], 'POST' ) ); + $shepherd->dispatch( new HTTP_Request( 'https://api.example.com/webhook', [ 'body' => '{"event": "test"}' ], 'POST' ) ); $this->assertSame( 2, did_action( $hook_name ) ); - $this->assertEquals( $pigeon->get_last_scheduled_task_id(), $last_scheduled_task_id ); + $this->assertEquals( $shepherd->get_last_scheduled_task_id(), $last_scheduled_task_id ); $this->assertTaskExecutesWithoutErrors( $last_scheduled_task_id ); @@ -375,21 +375,21 @@ public function it_should_schedule_different_requests_separately(): void { return $response; }, true ); - $pigeon = pigeon(); + $shepherd = shepherd(); $task1 = new HTTP_Request( 'https://api1.example.com/endpoint' ); - $pigeon->dispatch( $task1 ); - $task1_id = $pigeon->get_last_scheduled_task_id(); + $shepherd->dispatch( $task1 ); + $task1_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $task1_id ); $task2 = new HTTP_Request( 'https://api2.example.com/endpoint' ); - $pigeon->dispatch( $task2 ); - $task2_id = $pigeon->get_last_scheduled_task_id(); + $shepherd->dispatch( $task2 ); + $task2_id = $shepherd->get_last_scheduled_task_id(); $this->assertIsInt( $task2_id ); $this->assertNotEquals( $task1_id, $task2_id ); - $hook_name = 'pigeon_' . tests_pigeon_get_hook_prefix() . '_task_already_scheduled'; + $hook_name = 'shepherd_' . tests_shepherd_get_hook_prefix() . '_task_already_scheduled'; $this->assertSame( 0, did_action( $hook_name ) ); $this->assertTaskExecutesWithoutErrors( $task1_id ); diff --git a/tests/integration/_bootstrap.php b/tests/integration/_bootstrap.php index e029146..0d45df0 100644 --- a/tests/integration/_bootstrap.php +++ b/tests/integration/_bootstrap.php @@ -1,3 +1,3 @@ assertFalse( $provider->isDeferred() ); } @@ -26,7 +26,7 @@ public function it_should_not_be_deferred_by_default() { * @test */ public function it_should_return_empty_array_for_provides_by_default() { - $provider = new Dummy_Provider( tests_pigeon_get_container() ); + $provider = new Dummy_Provider( tests_shepherd_get_container() ); $this->assertEquals( [], $provider->provides() ); } } diff --git a/tests/wpunit/Abstracts/Table_Abstract_Test.php b/tests/wpunit/Abstracts/Table_Abstract_Test.php index 8ddf510..b633439 100644 --- a/tests/wpunit/Abstracts/Table_Abstract_Test.php +++ b/tests/wpunit/Abstracts/Table_Abstract_Test.php @@ -2,17 +2,17 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Abstracts; +namespace StellarWP\Shepherd\Abstracts; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Contracts\Model; -use StellarWP\Pigeon\Tables\Utility\Safe_Dynamic_Prefix; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Contracts\Model; +use StellarWP\Shepherd\Tables\Utility\Safe_Dynamic_Prefix; use StellarWP\DB\DB; class Dummy_Table extends Table_Abstract { protected static $base_table_name = 'pi_%s_dummy_table'; - protected static $schema_slug = 'pigeon-%s-dummy-table'; + protected static $schema_slug = 'shepherd-%s-dummy-table'; protected static $uid_column = 'id'; public static function get_columns(): array { @@ -38,7 +38,7 @@ public function set_config_prefix(): void { * @after */ public function reset_config(): void { - Config::set_hook_prefix( tests_pigeon_get_hook_prefix() ); + Config::set_hook_prefix( tests_shepherd_get_hook_prefix() ); } /** @@ -46,7 +46,7 @@ public function reset_config(): void { */ public function it_should_get_correct_table_name_and_slug() { $this->assertEquals( 'wp_pi_test_dummy_table', Dummy_Table::table_name() ); - $this->assertEquals( 'pigeon-test-dummy-table', Dummy_Table::get_schema_slug() ); + $this->assertEquals( 'shepherd-test-dummy-table', Dummy_Table::get_schema_slug() ); } /** diff --git a/tests/wpunit/Abstracts/Task_Test.php b/tests/wpunit/Abstracts/Task_Test.php index 3b5aec1..ee1b530 100644 --- a/tests/wpunit/Abstracts/Task_Test.php +++ b/tests/wpunit/Abstracts/Task_Test.php @@ -2,10 +2,10 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Abstracts; +namespace StellarWP\Shepherd\Abstracts; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Task; +use StellarWP\Shepherd\Contracts\Task; class Task_Test extends WPTestCase { protected function get_task( ...$args ): Task { @@ -27,10 +27,10 @@ public function it_should_be_compatible_after_updates(): void { $this->assertInstanceOf( Task::class, $task ); $this->assertInstanceOf( Task_Abstract::class, $task ); - $prefix = tests_pigeon_get_hook_prefix(); + $prefix = tests_shepherd_get_hook_prefix(); $this->assertSame( [ 'test1', 3, 'test2' ], $task->get_args() ); - $this->assertSame( "pigeon_{$prefix}_queue_default", $task->get_group() ); + $this->assertSame( "shepherd_{$prefix}_queue_default", $task->get_group() ); $this->assertSame( 10, $task->get_priority() ); $this->assertIsInt( $task->get_id() ); diff --git a/tests/wpunit/Action_Scheduler_Methods_Test.php b/tests/wpunit/Action_Scheduler_Methods_Test.php index 036f8fa..122ed8a 100644 --- a/tests/wpunit/Action_Scheduler_Methods_Test.php +++ b/tests/wpunit/Action_Scheduler_Methods_Test.php @@ -2,7 +2,7 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; @@ -12,7 +12,7 @@ class Action_Scheduler_Methods_Test extends WPTestCase { * @after */ public function unschedule_test_actions(): void { - as_unschedule_all_actions( 'pigeon_test_hook' ); + as_unschedule_all_actions( 'shepherd_test_hook' ); } /** @@ -20,9 +20,9 @@ public function unschedule_test_actions(): void { */ public function it_should_schedule_a_single_action() { $time = time() + 100; - $hook = 'pigeon_test_hook'; + $hook = 'shepherd_test_hook'; $args = [ 'test' => 'arg' ]; - $group = 'pigeon_test_group'; + $group = 'shepherd_test_group'; $action_id = Action_Scheduler_Methods::schedule_single_action( $time, $hook, $args, $group, true, 10 ); @@ -35,9 +35,9 @@ public function it_should_schedule_a_single_action() { */ public function it_should_check_if_action_is_scheduled() { $time = time() + 200; - $hook = 'pigeon_test_hook'; + $hook = 'shepherd_test_hook'; $args = [ 'test' => 'arg2' ]; - $group = 'pigeon_test_group'; + $group = 'shepherd_test_group'; $this->assertFalse( Action_Scheduler_Methods::has_scheduled_action( $hook, $args, $group ) ); diff --git a/tests/wpunit/Config_Test.php b/tests/wpunit/Config_Test.php index 9711260..c658537 100644 --- a/tests/wpunit/Config_Test.php +++ b/tests/wpunit/Config_Test.php @@ -2,20 +2,20 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; use RuntimeException; use StellarWP\ContainerContract\ContainerInterface; -use StellarWP\Pigeon\Loggers\ActionScheduler_DB_Logger; -use StellarWP\Pigeon\Loggers\Null_Logger; +use StellarWP\Shepherd\Loggers\ActionScheduler_DB_Logger; +use StellarWP\Shepherd\Loggers\Null_Logger; class Config_Test extends WPTestCase { /** * @test */ public function it_should_get_the_container(): void { - $container = tests_pigeon_get_container(); + $container = tests_shepherd_get_container(); $this->assertInstanceOf( ContainerInterface::class, $container ); $this->assertInstanceOf( ContainerInterface::class, Config::get_container() ); @@ -67,13 +67,13 @@ public function it_should_set_and_get_logger(): void { */ public function it_should_set_and_get_logger_when_null(): void { Config::reset(); - Config::set_container( tests_pigeon_get_container() ); + Config::set_container( tests_shepherd_get_container() ); } /** * @after */ public function reset(): void { - tests_pigeon_reset_config(); + tests_shepherd_reset_config(); } } diff --git a/tests/wpunit/Contracts/Task_Test.php b/tests/wpunit/Contracts/Task_Test.php index 88e8fa5..136a4ef 100644 --- a/tests/wpunit/Contracts/Task_Test.php +++ b/tests/wpunit/Contracts/Task_Test.php @@ -2,10 +2,10 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Contracts; +namespace StellarWP\Shepherd\Contracts; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Abstracts\Table_Abstract; +use StellarWP\Shepherd\Abstracts\Table_Abstract; class Task_Test extends WPTestCase { diff --git a/tests/wpunit/Log_Test.php b/tests/wpunit/Log_Test.php index 13484a3..374c7e1 100644 --- a/tests/wpunit/Log_Test.php +++ b/tests/wpunit/Log_Test.php @@ -2,13 +2,13 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; use Psr\Log\LogLevel; use InvalidArgumentException; -use StellarWP\Pigeon\Contracts\Log_Model; -use StellarWP\Pigeon\Tables\AS_Logs; +use StellarWP\Shepherd\Contracts\Log_Model; +use StellarWP\Shepherd\Tables\AS_Logs; class Log_Test extends WPTestCase { private function get_log_instance(): Log { diff --git a/tests/wpunit/Loggers/ActionScheduler_DB_Logger_Test.php b/tests/wpunit/Loggers/ActionScheduler_DB_Logger_Test.php index 226071b..bb32639 100644 --- a/tests/wpunit/Loggers/ActionScheduler_DB_Logger_Test.php +++ b/tests/wpunit/Loggers/ActionScheduler_DB_Logger_Test.php @@ -2,12 +2,12 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Loggers; +namespace StellarWP\Shepherd\Loggers; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Log; -use StellarWP\Pigeon\Config; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Log; +use StellarWP\Shepherd\Config; use Psr\Log\InvalidArgumentException; use StellarWP\DB\DB; @@ -16,7 +16,7 @@ class ActionScheduler_DB_Logger_Test extends WPTestCase { * @before */ public function set_action_scheduler_db_logger_as_default(): void { - tests_pigeon_get_container()->singleton( Logger::class, ActionScheduler_DB_Logger::class ); + tests_shepherd_get_container()->singleton( Logger::class, ActionScheduler_DB_Logger::class ); } /** @@ -129,7 +129,7 @@ public function it_should_save_logs_in_action_scheduler_format(): void { // Verify the log was saved in the correct format $prefix = Config::get_hook_prefix(); - $expected_message_prefix = 'pigeon_' . $prefix . '||' . $task_id . '||started||warning||'; + $expected_message_prefix = 'shepherd_' . $prefix . '||' . $task_id . '||started||warning||'; $result = DB::get_row( DB::prepare( diff --git a/tests/wpunit/Loggers/DB_Logger_Test.php b/tests/wpunit/Loggers/DB_Logger_Test.php index 40af06e..5093b95 100644 --- a/tests/wpunit/Loggers/DB_Logger_Test.php +++ b/tests/wpunit/Loggers/DB_Logger_Test.php @@ -2,26 +2,26 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Loggers; +namespace StellarWP\Shepherd\Loggers; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Logger; -use StellarWP\Pigeon\Log; -use StellarWP\Pigeon\Config; +use StellarWP\Shepherd\Contracts\Logger; +use StellarWP\Shepherd\Log; +use StellarWP\Shepherd\Config; class DB_Logger_Test extends WPTestCase { /** * @before */ public function set_db_logger_as_default(): void { - tests_pigeon_get_container()->singleton( Logger::class, DB_Logger::class ); + tests_shepherd_get_container()->singleton( Logger::class, DB_Logger::class ); } /** * @after */ public function set_action_scheduler_db_logger_as_default(): void { - tests_pigeon_get_container()->singleton( Logger::class, ActionScheduler_DB_Logger::class ); + tests_shepherd_get_container()->singleton( Logger::class, ActionScheduler_DB_Logger::class ); } /** diff --git a/tests/wpunit/Loggers/Null_Logger_Test.php b/tests/wpunit/Loggers/Null_Logger_Test.php index 271710a..7d7cf29 100644 --- a/tests/wpunit/Loggers/Null_Logger_Test.php +++ b/tests/wpunit/Loggers/Null_Logger_Test.php @@ -2,10 +2,10 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Loggers; +namespace StellarWP\Shepherd\Loggers; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Logger; +use StellarWP\Shepherd\Contracts\Logger; class Null_Logger_Test extends WPTestCase { /** diff --git a/tests/wpunit/Provider_Test.php b/tests/wpunit/Provider_Test.php index a7ee03d..e40cf35 100644 --- a/tests/wpunit/Provider_Test.php +++ b/tests/wpunit/Provider_Test.php @@ -2,7 +2,7 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; @@ -18,6 +18,6 @@ public function it_should_assert_that_the_provider_is_not_registered(): void { * @test */ public function it_should_evaluate_hook_prefix(): void { - $this->assertEquals( tests_pigeon_get_hook_prefix(), Config::get_hook_prefix() ); + $this->assertEquals( tests_shepherd_get_hook_prefix(), Config::get_hook_prefix() ); } } diff --git a/tests/wpunit/Regulator_Test.php b/tests/wpunit/Regulator_Test.php index ae90056..10d42fe 100644 --- a/tests/wpunit/Regulator_Test.php +++ b/tests/wpunit/Regulator_Test.php @@ -2,7 +2,7 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon; +namespace StellarWP\Shepherd; use lucatume\WPBrowser\TestCase\WPTestCase; @@ -12,6 +12,6 @@ class Regulator_Test extends WPTestCase { */ public function it_should_have_as_hook_registered(): void { $regulator = Config::get_container()->get( Regulator::class ); - $this->assertSame( 10, has_action( 'pigeon_' . Config::get_hook_prefix() . '_process_task', [ $regulator, 'process_task' ] ) ); + $this->assertSame( 10, has_action( 'shepherd_' . Config::get_hook_prefix() . '_process_task', [ $regulator, 'process_task' ] ) ); } } diff --git a/tests/wpunit/Tables/Task_Logs_Test.php b/tests/wpunit/Tables/Task_Logs_Test.php index 82bb38d..e3c4a63 100644 --- a/tests/wpunit/Tables/Task_Logs_Test.php +++ b/tests/wpunit/Tables/Task_Logs_Test.php @@ -2,10 +2,10 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Tables; +namespace StellarWP\Shepherd\Tables; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Log; +use StellarWP\Shepherd\Log; use StellarWP\DB\DB; class Task_Logs_Test extends WPTestCase { diff --git a/tests/wpunit/Tables/Tasks_Test.php b/tests/wpunit/Tables/Tasks_Test.php index 641f585..7792404 100644 --- a/tests/wpunit/Tables/Tasks_Test.php +++ b/tests/wpunit/Tables/Tasks_Test.php @@ -2,14 +2,14 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Tables; +namespace StellarWP\Shepherd\Tables; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Contracts\Task; -use StellarWP\Pigeon\Abstracts\Task_Abstract; +use StellarWP\Shepherd\Contracts\Task; +use StellarWP\Shepherd\Abstracts\Task_Abstract; use StellarWP\DB\DB; -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Tables\Utility\Safe_Dynamic_Prefix; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Tables\Utility\Safe_Dynamic_Prefix; use InvalidArgumentException; class Dummy_Task extends Task_Abstract implements Task { @@ -130,7 +130,7 @@ public function it_should_handle_very_long_hook_prefix_without_exceeding_mysql_l $container = Config::get_container(); $safe_dynamic_prefix = $container->get( Safe_Dynamic_Prefix::class ); $safe_prefix = $safe_dynamic_prefix->get(); - $expected = DB::prefix( 'pigeon_' . $safe_prefix . '_tasks' ); + $expected = DB::prefix( 'shepherd_' . $safe_prefix . '_tasks' ); $this->assertEquals( $expected, $table_name ); } @@ -138,6 +138,6 @@ public function it_should_handle_very_long_hook_prefix_without_exceeding_mysql_l * @after */ public function reset() { - Config::set_hook_prefix( tests_pigeon_get_hook_prefix() ); + Config::set_hook_prefix( tests_shepherd_get_hook_prefix() ); } } diff --git a/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php b/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php index a99878f..86d2734 100644 --- a/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php +++ b/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php @@ -2,12 +2,12 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Tables\Utility; +namespace StellarWP\Shepherd\Tables\Utility; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Tables; -use StellarWP\Pigeon\Tables\Utility\Safe_Dynamic_Prefix; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Tables; +use StellarWP\Shepherd\Tables\Utility\Safe_Dynamic_Prefix; class Safe_Dynamic_Prefix_Test extends WPTestCase { /** @@ -42,6 +42,6 @@ public function it_should_trim_long_hook_prefix_to_safe_length(): void { * @after */ public function reset(): void { - Config::set_hook_prefix( tests_pigeon_get_hook_prefix() ); + Config::set_hook_prefix( tests_shepherd_get_hook_prefix() ); } } diff --git a/tests/wpunit/Tasks/Email_Test.php b/tests/wpunit/Tasks/Email_Test.php index 25181d3..c3b904e 100644 --- a/tests/wpunit/Tasks/Email_Test.php +++ b/tests/wpunit/Tasks/Email_Test.php @@ -2,13 +2,13 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Tasks; +namespace StellarWP\Shepherd\Tasks; use lucatume\WPBrowser\TestCase\WPTestCase; use InvalidArgumentException; -use StellarWP\Pigeon\Exceptions\PigeonTaskException; +use StellarWP\Shepherd\Exceptions\ShepherdTaskException; use TypeError; -use StellarWP\Pigeon\Tests\Traits\With_Uopz; +use StellarWP\Shepherd\Tests\Traits\With_Uopz; class Email_Test extends WPTestCase { use With_Uopz; @@ -60,12 +60,12 @@ public function it_should_process_and_call_wp_mail() { /** * @test */ - public function it_should_throw_pigeon_exception_if_wp_mail_fails() { + public function it_should_throw_shepherd_exception_if_wp_mail_fails() { $email = new Email( 'test@test.com', 'Subject', 'Body' ); $this->set_fn_return( 'wp_mail', false ); - $this->expectException( PigeonTaskException::class ); + $this->expectException( ShepherdTaskException::class ); $email->process(); } } diff --git a/tests/wpunit/Tasks/HTTP_Request_Test.php b/tests/wpunit/Tasks/HTTP_Request_Test.php index c724cf4..4242e4d 100644 --- a/tests/wpunit/Tasks/HTTP_Request_Test.php +++ b/tests/wpunit/Tasks/HTTP_Request_Test.php @@ -2,14 +2,14 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Tasks; +namespace StellarWP\Shepherd\Tasks; use lucatume\WPBrowser\TestCase\WPTestCase; use InvalidArgumentException; -use StellarWP\Pigeon\Exceptions\PigeonTaskException; -use StellarWP\Pigeon\Exceptions\PigeonTaskFailWithoutRetryException; +use StellarWP\Shepherd\Exceptions\ShepherdTaskException; +use StellarWP\Shepherd\Exceptions\ShepherdTaskFailWithoutRetryException; use TypeError; -use StellarWP\Pigeon\Tests\Traits\With_Uopz; +use StellarWP\Shepherd\Tests\Traits\With_Uopz; use WP_Error; class HTTP_Request_Test extends WPTestCase { @@ -156,7 +156,7 @@ public function it_should_throw_exception_for_wp_error() { $this->set_fn_return( 'wp_remote_request', $error ); - $this->expectException( PigeonTaskFailWithoutRetryException::class ); + $this->expectException( ShepherdTaskFailWithoutRetryException::class ); $this->expectExceptionMessage( 'HTTP GET request to https://example.com failed with code: `http_request_failed` and message: `Connection timeout`' ); $request->process(); @@ -178,7 +178,7 @@ public function it_should_throw_exception_for_http_error_status() { $this->set_fn_return( 'wp_remote_request', $response ); - $this->expectException( PigeonTaskFailWithoutRetryException::class ); + $this->expectException( ShepherdTaskFailWithoutRetryException::class ); $this->expectExceptionMessage( 'HTTP GET request to https://example.com returned error 404: `Not Found`' ); $request->process(); @@ -200,7 +200,7 @@ public function it_should_throw_retryable_exception_for_5xx_error() { $this->set_fn_return( 'wp_remote_request', $response ); - $this->expectException( PigeonTaskException::class ); + $this->expectException( ShepherdTaskException::class ); $this->expectExceptionMessage( 'HTTP GET request to https://example.com returned error 500: `Internal Server Error`' ); $request->process(); @@ -221,7 +221,7 @@ public function it_should_have_auth_headers_method() { public function it_should_have_correct_task_prefix() { $request = new HTTP_Request( 'https://example.com' ); - $this->assertEquals( 'pigeon_http_', $request->get_task_prefix() ); + $this->assertEquals( 'shepherd_http_', $request->get_task_prefix() ); } /** @@ -249,13 +249,13 @@ public function it_should_fire_action_on_successful_request() { $this->set_fn_return( 'wp_remote_request', $response ); - $prefix = tests_pigeon_get_hook_prefix(); + $prefix = tests_shepherd_get_hook_prefix(); - $this->assertSame( 0, did_action( 'pigeon_' . $prefix . '_http_request_processed' ) ); + $this->assertSame( 0, did_action( 'shepherd_' . $prefix . '_http_request_processed' ) ); $request->process(); - $this->assertSame( 1, did_action( 'pigeon_' . $prefix . '_http_request_processed' ) ); + $this->assertSame( 1, did_action( 'shepherd_' . $prefix . '_http_request_processed' ) ); } /** diff --git a/tests/wpunit/Traits/Custom_Table_Query_Methods_Test.php b/tests/wpunit/Traits/Custom_Table_Query_Methods_Test.php index aced801..6f1b3fd 100644 --- a/tests/wpunit/Traits/Custom_Table_Query_Methods_Test.php +++ b/tests/wpunit/Traits/Custom_Table_Query_Methods_Test.php @@ -2,23 +2,23 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Traits; +namespace StellarWP\Shepherd\Traits; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Abstracts\Table_Abstract; +use StellarWP\Shepherd\Abstracts\Table_Abstract; use StellarWP\Schema\Register; -use StellarWP\Pigeon\Contracts\Model; +use StellarWP\Shepherd\Contracts\Model; class Dummy_Query_Table extends Table_Abstract { use Custom_Table_Query_Methods; - protected static $base_table_name = 'pigeon_query_table_%s'; - protected static $schema_slug = 'pigeon-query-table-%s'; + protected static $base_table_name = 'shepherd_query_table_%s'; + protected static $schema_slug = 'shepherd-query-table-%s'; protected static $uid_column = 'id'; const SCHEMA_VERSION = '0.0.1-dev'; - protected static $group = 'stellarwp_pigeon'; + protected static $group = 'stellarwp_shepherd'; public static function get_columns(): array { return [ diff --git a/tests/wpunit/Traits/Loggable_Test.php b/tests/wpunit/Traits/Loggable_Test.php index 1104724..dce8cca 100644 --- a/tests/wpunit/Traits/Loggable_Test.php +++ b/tests/wpunit/Traits/Loggable_Test.php @@ -2,11 +2,11 @@ declare( strict_types=1 ); -namespace StellarWP\Pigeon\Traits; +namespace StellarWP\Shepherd\Traits; use lucatume\WPBrowser\TestCase\WPTestCase; -use StellarWP\Pigeon\Config; -use StellarWP\Pigeon\Contracts\Logger; +use StellarWP\Shepherd\Config; +use StellarWP\Shepherd\Contracts\Logger; use Psr\Log\LogLevel; class Dummy_Loggable { diff --git a/tests/wpunit/_bootstrap.php b/tests/wpunit/_bootstrap.php index e029146..0d45df0 100644 --- a/tests/wpunit/_bootstrap.php +++ b/tests/wpunit/_bootstrap.php @@ -1,3 +1,3 @@ Date: Fri, 11 Jul 2025 15:25:00 +0300 Subject: [PATCH 2/2] fix wpunit --- tests/wpunit/Abstracts/Table_Abstract_Test.php | 8 ++++---- tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/wpunit/Abstracts/Table_Abstract_Test.php b/tests/wpunit/Abstracts/Table_Abstract_Test.php index b633439..03d11f8 100644 --- a/tests/wpunit/Abstracts/Table_Abstract_Test.php +++ b/tests/wpunit/Abstracts/Table_Abstract_Test.php @@ -45,7 +45,7 @@ public function reset_config(): void { * @test */ public function it_should_get_correct_table_name_and_slug() { - $this->assertEquals( 'wp_pi_test_dummy_table', Dummy_Table::table_name() ); + $this->assertEquals( 'wp_pi_tes_dummy_table', Dummy_Table::table_name() ); $this->assertEquals( 'shepherd-test-dummy-table', Dummy_Table::get_schema_slug() ); } @@ -56,7 +56,7 @@ public function it_should_generate_correct_table_definition() { $table = new Dummy_Table(); $definition = $table->get_definition(); - $this->assertStringContainsString( 'CREATE TABLE `wp_pi_test_dummy_table`', $definition ); + $this->assertStringContainsString( 'CREATE TABLE `wp_pi_tes_dummy_table`', $definition ); $this->assertStringContainsString( '`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT', $definition ); $this->assertStringContainsString( '`name` varchar(255) NOT NULL', $definition ); $this->assertStringContainsString( 'PRIMARY KEY (`id`)', $definition ); @@ -99,12 +99,12 @@ public function it_should_trim_long_hook_prefix_to_prevent_exceeding_mysql_table */ public function it_should_not_trim_short_hook_prefix() { // Set a short hook prefix that won't exceed the limit - $short_prefix = 'short'; + $short_prefix = 'sho'; Config::set_hook_prefix( $short_prefix ); $table_name = Dummy_Table::table_name(); // The table name should contain the full hook prefix - $this->assertEquals( 'wp_pi_short_dummy_table', $table_name ); + $this->assertEquals( 'wp_pi_sho_dummy_table', $table_name ); } } diff --git a/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php b/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php index 86d2734..9779c48 100644 --- a/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php +++ b/tests/wpunit/Tables/Utility/Safe_Dynamic_Prefix_Test.php @@ -14,17 +14,17 @@ class Safe_Dynamic_Prefix_Test extends WPTestCase { * @test */ public function it_should_calculate_max_hook_prefix_length(): void { - $this->assertEquals( 5, Config::get_container()->get( Safe_Dynamic_Prefix::class )->get_max_length() ); + $this->assertEquals( 3, Config::get_container()->get( Safe_Dynamic_Prefix::class )->get_max_length() ); } /** * @test */ public function it_should_return_safe_hook_prefix_for_short_prefix(): void { - Config::set_hook_prefix( 'short' ); + Config::set_hook_prefix( 'sho' ); // Short prefix should be returned as-is - $this->assertEquals( 'short', Config::get_container()->get( Safe_Dynamic_Prefix::class )->get() ); + $this->assertEquals( 'sho', Config::get_container()->get( Safe_Dynamic_Prefix::class )->get() ); } /** @@ -35,7 +35,7 @@ public function it_should_trim_long_hook_prefix_to_safe_length(): void { Config::set_hook_prefix( $very_long_prefix ); // Safe prefix should be trimmed to max length - $this->assertEquals( 'aaaaa', Config::get_container()->get( Safe_Dynamic_Prefix::class )->get() ); + $this->assertEquals( 'aaa', Config::get_container()->get( Safe_Dynamic_Prefix::class )->get() ); } /**