diff --git a/composer.json b/composer.json index c9d1609..5a5934f 100644 --- a/composer.json +++ b/composer.json @@ -66,6 +66,9 @@ "phpstan": "tools/phpstan analyse", "stan-baseline": "tools/phpstan --generate-baseline", "stan-setup": "phive install", + "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"^2.2\" && mv composer.backup composer.json", + "rector-check": "vendor/bin/rector process --dry-run", + "rector-fix": "vendor/bin/rector process", "test": "phpunit", "test-coverage": "phpunit --coverage-clover=clover.xml" } diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..330dc43 --- /dev/null +++ b/rector.php @@ -0,0 +1,35 @@ +withPhpVersion(PhpVersion::PHP_82) + ->withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->withSkip([ + DisallowedEmptyRuleFixerRector::class, + SimplifyIfElseToTernaryRector::class, + MakeInheritedMethodVisibilitySameAsParentRector::class, + RemoveNullTagValueNodeRector::class, + RemoveUselessReturnTagRector::class, + DocblockReturnArrayFromDirectArrayInstanceRector::class => [ + __DIR__ . '/src/Mailer/Transport/QueueTransport.php', + ], + ]) + ->withParallel() + ->withPreparedSets( + deadCode: true, + codeQuality: true, + codingStyle: true, + typeDeclarationDocblocks: true, + ); diff --git a/src/Command/PurgeFailedCommand.php b/src/Command/PurgeFailedCommand.php index f2c0d3a..c54cc8d 100644 --- a/src/Command/PurgeFailedCommand.php +++ b/src/Command/PurgeFailedCommand.php @@ -72,9 +72,9 @@ public function getOptionParser(): ConsoleOptionParser /** * @param \Cake\Console\Arguments $args Arguments * @param \Cake\Console\ConsoleIo $io ConsoleIo - * @return void + * @return int */ - public function execute(Arguments $args, ConsoleIo $io): void + public function execute(Arguments $args, ConsoleIo $io): int { /** @var \Cake\Queue\Model\Table\FailedJobsTable $failedJobsTable */ $failedJobsTable = $this->getTableLocator()->get('Cake/Queue.FailedJobs'); @@ -108,21 +108,23 @@ public function execute(Arguments $args, ConsoleIo $io): void if (!$deletingCount) { $io->out('0 jobs found.'); - return; + return self::CODE_SUCCESS; } if (!$args->getOption('force')) { - $confirmed = $io->askChoice("Delete {$deletingCount} jobs?", ['y', 'n'], 'n'); + $confirmed = $io->askChoice(sprintf('Delete %s jobs?', $deletingCount), ['y', 'n'], 'n'); if ($confirmed !== 'y') { - return; + return self::CODE_SUCCESS; } } - $io->out("Deleting {$deletingCount} jobs."); + $io->out(sprintf('Deleting %s jobs.', $deletingCount)); $failedJobsTable->deleteManyOrFail($jobsToDelete); - $io->success("{$deletingCount} jobs deleted."); + $io->success($deletingCount . ' jobs deleted.'); + + return self::CODE_SUCCESS; } } diff --git a/src/Command/RequeueCommand.php b/src/Command/RequeueCommand.php index b9efd02..ce00f7c 100644 --- a/src/Command/RequeueCommand.php +++ b/src/Command/RequeueCommand.php @@ -74,9 +74,9 @@ public function getOptionParser(): ConsoleOptionParser /** * @param \Cake\Console\Arguments $args Arguments * @param \Cake\Console\ConsoleIo $io ConsoleIo - * @return void + * @return int */ - public function execute(Arguments $args, ConsoleIo $io): void + public function execute(Arguments $args, ConsoleIo $io): int { /** @var \Cake\Queue\Model\Table\FailedJobsTable $failedJobsTable */ $failedJobsTable = $this->getTableLocator()->get('Cake/Queue.FailedJobs'); @@ -110,18 +110,18 @@ public function execute(Arguments $args, ConsoleIo $io): void if (!$requeueingCount) { $io->out('0 jobs found.'); - return; + return self::CODE_SUCCESS; } if (!$args->getOption('force')) { - $confirmed = $io->askChoice("Requeue {$requeueingCount} jobs?", ['y', 'n'], 'n'); + $confirmed = $io->askChoice(sprintf('Requeue %s jobs?', $requeueingCount), ['y', 'n'], 'n'); if ($confirmed !== 'y') { - return; + return self::CODE_SUCCESS; } } - $io->out("Requeueing {$requeueingCount} jobs."); + $io->out(sprintf('Requeueing %s jobs.', $requeueingCount)); $succeededCount = 0; $failedCount = 0; @@ -129,7 +129,7 @@ public function execute(Arguments $args, ConsoleIo $io): void /** @var array<\Cake\Queue\Model\Entity\FailedJob> $jobsToRequeue */ $jobsToRequeue = $jobsToRequeueQuery->all(); foreach ($jobsToRequeue as $failedJob) { - $io->verbose("Requeueing FailedJob with ID {$failedJob->id}."); + $io->verbose(sprintf('Requeueing FailedJob with ID %d.', $failedJob->id)); try { QueueManager::push( [$failedJob->class, $failedJob->method], @@ -145,19 +145,21 @@ public function execute(Arguments $args, ConsoleIo $io): void $succeededCount++; } catch (Exception $e) { - $io->err("Exception occurred while requeueing FailedJob with ID {$failedJob->id}"); + $io->err('Exception occurred while requeueing FailedJob with ID ' . $failedJob->id); $io->err((string)$e); $failedCount++; } } - if ($failedCount) { - $io->err("Failed to requeue {$failedCount} jobs."); + if ($failedCount !== 0) { + $io->err(sprintf('Failed to requeue %d jobs.', $failedCount)); } - if ($succeededCount) { - $io->success("{$succeededCount} jobs requeued."); + if ($succeededCount !== 0) { + $io->success($succeededCount . ' jobs requeued.'); } + + return self::CODE_SUCCESS; } } diff --git a/src/Command/WorkerCommand.php b/src/Command/WorkerCommand.php index e755b34..44605d1 100644 --- a/src/Command/WorkerCommand.php +++ b/src/Command/WorkerCommand.php @@ -43,17 +43,12 @@ */ class WorkerCommand extends Command { - /** - * @var \Cake\Core\ContainerInterface|null - */ - protected ?ContainerInterface $container = null; - /** * @param \Cake\Core\ContainerInterface|null $container DI container instance */ - public function __construct(?ContainerInterface $container = null) - { - $this->container = $container; + public function __construct( + protected readonly ?ContainerInterface $container = null, + ) { } /** @@ -138,12 +133,12 @@ protected function getQueueExtension(Arguments $args, LoggerInterface $logger): $limitAttempsExtension, ]; - if (!is_null($args->getOption('max-jobs'))) { + if ($args->getOption('max-jobs') !== null) { $maxJobs = (int)$args->getOption('max-jobs'); $extensions[] = new LimitConsumedMessagesExtension($maxJobs); } - if (!is_null($args->getOption('max-runtime'))) { + if ($args->getOption('max-runtime') !== null) { $endTime = new DateTime(sprintf('+%d seconds', (int)$args->getOption('max-runtime'))); $extensions[] = new LimitConsumptionTimeExtension($endTime); } @@ -187,12 +182,12 @@ protected function getProcessor(Arguments $args, ConsoleIo $io, LoggerInterface $processorClass = $config['processor'] ?? Processor::class; if (!class_exists($processorClass)) { - $io->error(sprintf(sprintf('Processor class %s not found', $processorClass))); + $io->error(sprintf('Processor class %s not found', $processorClass)); $this->abort(); } if (!is_subclass_of($processorClass, InteropProcessor::class)) { - $io->error(sprintf(sprintf('Processor class %s must implement Interop\Queue\Processor', $processorClass))); + $io->error(sprintf('Processor class %s must implement Interop\Queue\Processor', $processorClass)); $this->abort(); } @@ -231,10 +226,11 @@ public function execute(Arguments $args, ConsoleIo $io): int $processor->getEventManager()->on($listener); } } + $client = QueueManager::engine($config); $queue = $args->getOption('queue') ? (string)$args->getOption('queue') - : Configure::read("Queue.{$config}.queue", 'default'); + : Configure::read(sprintf('Queue.%s.queue', $config), 'default'); $processorName = $args->getOption('processor') ? (string)$args->getOption('processor') : 'default'; $client->bindTopic($queue, $processor, $processorName); diff --git a/src/Consumption/LimitAttemptsExtension.php b/src/Consumption/LimitAttemptsExtension.php index c3a0af6..0a87881 100644 --- a/src/Consumption/LimitAttemptsExtension.php +++ b/src/Consumption/LimitAttemptsExtension.php @@ -25,20 +25,12 @@ class LimitAttemptsExtension implements MessageResultExtensionInterface public const ATTEMPTS_PROPERTY = 'attempts'; /** - * The maximum number of times a job may be attempted. $maxAttempts defined on a - * Job will override this value. - * - * @var int|null - */ - protected ?int $maxAttempts = null; - - /** - * @param int|null $maxAttempts The maximum number of times a job may be attempted. + * @param int|null $maxAttempts The maximum number of times a job may be attempted. $maxAttempts defined on a Job will override this value. * @return void */ - public function __construct(?int $maxAttempts = null) - { - $this->maxAttempts = $maxAttempts; + public function __construct( + protected readonly ?int $maxAttempts = null, + ) { } /** diff --git a/src/Consumption/LimitConsumedMessagesExtension.php b/src/Consumption/LimitConsumedMessagesExtension.php index e202fbe..c5c7bd8 100644 --- a/src/Consumption/LimitConsumedMessagesExtension.php +++ b/src/Consumption/LimitConsumedMessagesExtension.php @@ -18,22 +18,15 @@ */ class LimitConsumedMessagesExtension implements PreConsumeExtensionInterface, PostConsumeExtensionInterface { - /** - * @var int - */ - protected int $messageLimit; - - /** - * @var int - */ protected int $messageConsumed = 0; /** * @param int $messageLimit The number of messages to process before exiting. + * @return void */ - public function __construct(int $messageLimit) - { - $this->messageLimit = $messageLimit; + public function __construct( + protected readonly int $messageLimit, + ) { } /** diff --git a/src/Consumption/RemoveUniqueJobIdFromCacheExtension.php b/src/Consumption/RemoveUniqueJobIdFromCacheExtension.php index 74ff3ad..8ad1fc6 100644 --- a/src/Consumption/RemoveUniqueJobIdFromCacheExtension.php +++ b/src/Consumption/RemoveUniqueJobIdFromCacheExtension.php @@ -11,20 +11,13 @@ class RemoveUniqueJobIdFromCacheExtension implements MessageResultExtensionInterface { - /** - * Cache engine name. - * - * @var string - */ - protected string $cache; - /** * @param string $cache Cache engine name. * @return void */ - public function __construct(string $cache) - { - $this->cache = $cache; + public function __construct( + protected readonly string $cache, + ) { } /** diff --git a/src/Job/MailerJob.php b/src/Job/MailerJob.php index 66db133..3d6d71e 100644 --- a/src/Job/MailerJob.php +++ b/src/Job/MailerJob.php @@ -41,13 +41,13 @@ public function execute(Message $message): ?string try { $mailer = $this->getMailer($mailerName, $mailerConfig); - } catch (MissingMailerException $e) { + } catch (MissingMailerException $missingMailerException) { return Processor::REJECT; } try { $mailer->send($action, $args, $headers); - } catch (BadMethodCallException $e) { + } catch (BadMethodCallException $badMethodCallException) { return Processor::REJECT; } diff --git a/src/Job/Message.php b/src/Job/Message.php index 7da6218..f1b504c 100644 --- a/src/Job/Message.php +++ b/src/Job/Message.php @@ -22,35 +22,33 @@ use Interop\Queue\Context; use Interop\Queue\Message as QueueMessage; use JsonSerializable; -use ReturnTypeWillChange; use RuntimeException; class Message implements JsonSerializable { - protected Context $context; - - protected QueueMessage $originalMessage; - + /** + * @var array + */ protected array $parsedBody; protected ?Closure $callable = null; - protected ?ContainerInterface $container = null; - /** * @param \Interop\Queue\Message $originalMessage Queue message. * @param \Interop\Queue\Context $context Context. * @param \Cake\Core\ContainerInterface|null $container DI container instance */ - public function __construct(QueueMessage $originalMessage, Context $context, ?ContainerInterface $container = null) - { - $this->context = $context; - $this->originalMessage = $originalMessage; + public function __construct( + protected readonly QueueMessage $originalMessage, + protected readonly Context $context, + protected readonly ?ContainerInterface $container = null, + ) { $this->parsedBody = json_decode($originalMessage->getBody(), true); - $this->container = $container; } /** + * Get the queue context. + * * @return \Interop\Queue\Context */ public function getContext(): Context @@ -59,6 +57,8 @@ public function getContext(): Context } /** + * Get the original queue message. + * * @return \Interop\Queue\Message */ public function getOriginalMessage(): QueueMessage @@ -67,7 +67,9 @@ public function getOriginalMessage(): QueueMessage } /** - * @return array + * Get the parsed message body. + * + * @return array */ public function getParsedBody(): array { @@ -84,7 +86,7 @@ public function getParsedBody(): array */ public function getCallable(): Closure { - if ($this->callable) { + if ($this->callable instanceof Closure) { return $this->callable; } @@ -128,6 +130,7 @@ public function getTarget(): array */ public function getArgument(mixed $key = null, mixed $default = null): mixed { + // support old jobs that still use args key if (array_key_exists('data', $this->parsedBody)) { $data = $this->parsedBody['data']; } else { @@ -157,6 +160,8 @@ public function getMaxAttempts(): ?int } /** + * Convert the message to a string representation. + * * @return string */ public function __toString(): string @@ -165,9 +170,10 @@ public function __toString(): string } /** - * @return array + * Serialize the message to JSON. + * + * @return array */ - #[ReturnTypeWillChange] public function jsonSerialize(): array { return $this->parsedBody; diff --git a/src/Job/SendMailJob.php b/src/Job/SendMailJob.php index 3ba9325..efb7ea7 100644 --- a/src/Job/SendMailJob.php +++ b/src/Job/SendMailJob.php @@ -46,10 +46,11 @@ public function execute(Message $message): ?string if (!is_array($data)) { throw new InvalidArgumentException('Email Message cannot be decoded.'); } + $emailMessage->createFromArray($data); $result = $transport->send($emailMessage); - } catch (Exception $e) { - Log::error(sprintf('An error has occurred processing message: %s', $e->getMessage())); + } catch (Exception $exception) { + Log::error(sprintf('An error has occurred processing message: %s', $exception->getMessage())); } if (!$result) { @@ -64,8 +65,8 @@ public function execute(Message $message): ?string * * @param string $transportClassName Transport class name * @param array $config Transport config - * @return \Cake\Mailer\AbstractTransport * @throws \InvalidArgumentException if empty transport class name, class does not exist or send method is not defined for class + * @return \Cake\Mailer\AbstractTransport */ protected function getTransport(string $transportClassName, array $config): AbstractTransport { diff --git a/src/Listener/FailedJobsListener.php b/src/Listener/FailedJobsListener.php index f60d15e..c983fb4 100644 --- a/src/Listener/FailedJobsListener.php +++ b/src/Listener/FailedJobsListener.php @@ -76,14 +76,14 @@ public function storeFailedJob(object $event): void try { $failedJobsTable->saveOrFail($failedJob); /** @phpstan-ignore-next-line */ - } catch (PersistenceFailedException $e) { + } catch (PersistenceFailedException $persistenceFailedException) { $logger = $event->getData('logger'); if (!$logger) { throw new RuntimeException( sprintf('`logger` was not defined on %s event.', $event->getName()), 0, - $e, + $persistenceFailedException, ); } @@ -91,11 +91,11 @@ public function storeFailedJob(object $event): void throw new RuntimeException( sprintf('`logger` is not an instance of `LoggerInterface` on %s event.', $event->getName()), 0, - $e, + $persistenceFailedException, ); } - $logger->error((string)$e); + $logger->error((string)$persistenceFailedException); } } } diff --git a/src/Mailer/QueueTrait.php b/src/Mailer/QueueTrait.php index b9a4a5d..fe94110 100644 --- a/src/Mailer/QueueTrait.php +++ b/src/Mailer/QueueTrait.php @@ -31,9 +31,9 @@ trait QueueTrait * @param string $action The name of the mailer action to trigger. * @param array $args Arguments to pass to the triggered mailer action. * @param array $headers Headers to set. - * @param array $options an array of options for publishing the job - * @return void + * @param array $options an array of options for publishing the job * @throws \Cake\Mailer\Exception\MissingActionException + * @return void */ public function push(string $action, array $args = [], array $headers = [], array $options = []): void { diff --git a/src/Mailer/Transport/QueueTransport.php b/src/Mailer/Transport/QueueTransport.php index c798d53..da45783 100644 --- a/src/Mailer/Transport/QueueTransport.php +++ b/src/Mailer/Transport/QueueTransport.php @@ -63,8 +63,8 @@ public function send(Message $message): array /** * Add job to queue * - * @param array $data Data to be sent to job - * @param array $options Job options + * @param array $data Data to be sent to job + * @param array $options Job options * @return void */ protected function enqueueJob(array $data, array $options): void @@ -80,7 +80,7 @@ protected function enqueueJob(array $data, array $options): void * Prepare data for job * * @param \Cake\Mailer\Message $message Email message - * @return array + * @return array */ protected function prepareData(Message $message): array { diff --git a/src/Model/Entity/FailedJob.php b/src/Model/Entity/FailedJob.php index a0e0c7a..62f1fc4 100644 --- a/src/Model/Entity/FailedJob.php +++ b/src/Model/Entity/FailedJob.php @@ -45,8 +45,8 @@ class FailedJob extends Entity ]; /** - * @return array * @see \Cake\Queue\Model\Entity\FailedJob::$decoded_data + * @return array */ protected function _getDecodedData(): array { diff --git a/src/Plugin.php b/src/Plugin.php index d607ef0..92cb0de 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -16,6 +16,7 @@ */ namespace Cake\Queue; +use Bake\Command\SimpleBakeCommand; use Cake\Console\CommandCollection; use Cake\Core\BasePlugin; use Cake\Core\Configure; @@ -72,7 +73,7 @@ public function bootstrap(PluginApplicationInterface $app): void */ public function console(CommandCollection $commands): CommandCollection { - if (class_exists('Bake\Command\SimpleBakeCommand')) { + if (class_exists(SimpleBakeCommand::class)) { $commands->add('bake job', JobCommand::class); } diff --git a/src/Queue/Processor.php b/src/Queue/Processor.php index b90601d..bff6628 100644 --- a/src/Queue/Processor.php +++ b/src/Queue/Processor.php @@ -37,25 +37,13 @@ class Processor implements InteropProcessor use EventDispatcherTrait; /** - * @var \Psr\Log\LoggerInterface - */ - protected LoggerInterface $logger; - - /** - * @var \Cake\Core\ContainerInterface|null - */ - protected ?ContainerInterface $container = null; - - /** - * Processor constructor - * - * @param \Psr\Log\LoggerInterface|null $logger Logger instance. + * @param \Psr\Log\LoggerInterface $logger Logger instance. * @param \Cake\Core\ContainerInterface|null $container DI container instance */ - public function __construct(?LoggerInterface $logger = null, ?ContainerInterface $container = null) - { - $this->logger = $logger ?: new NullLogger(); - $this->container = $container; + public function __construct( + protected readonly LoggerInterface $logger = new NullLogger(), + protected readonly ?ContainerInterface $container = null, + ) { } /** @@ -84,13 +72,13 @@ public function process(QueueMessage $message, Context $context): string|object try { $response = $this->processMessage($jobMessage); - } catch (Throwable $e) { - $message->setProperty('jobException', $e); + } catch (Throwable $throwable) { + $message->setProperty('jobException', $throwable); - $this->logger->debug(sprintf('Message encountered exception: %s', $e->getMessage())); + $this->logger->debug(sprintf('Message encountered exception: %s', $throwable->getMessage())); $this->dispatchEvent('Processor.message.exception', [ 'message' => $jobMessage, - 'exception' => $e, + 'exception' => $throwable, 'duration' => (int)((microtime(true) * 1000) - $startTime), ]); diff --git a/src/QueueManager.php b/src/QueueManager.php index 32cd914..976fd6c 100644 --- a/src/QueueManager.php +++ b/src/QueueManager.php @@ -24,20 +24,21 @@ use Enqueue\SimpleClient\SimpleClient; use InvalidArgumentException; use LogicException; +use Psr\Log\LoggerInterface; class QueueManager { /** * Configuration sets. * - * @var array + * @var array> */ protected static array $_config = []; /** * Queue clients * - * @var array + * @var array */ protected static array $_clients = []; @@ -72,8 +73,8 @@ class QueueManager * QueueManager::setConfig($arrayOfConfig); * ``` * - * @param array|string $key The name of the configuration, or an array of multiple configs. - * @param array $config An array of name => configuration data for adapter. + * @param array>|string $key The name of the configuration, or an array of multiple configs. + * @param array|null $config An array of name => configuration data for adapter. * @throws \BadMethodCallException When trying to modify an existing config. * @throws \LogicException When trying to store an invalid structured config array. * @return void @@ -84,6 +85,7 @@ public static function setConfig(string|array $key, ?array $config = null): void if (!is_array($key)) { throw new LogicException('If config is null, key must be an array.'); } + foreach ($key as $name => $settings) { static::setConfig($name, $settings); } @@ -126,9 +128,9 @@ public static function setConfig(string|array $key, ?array $config = null): void 'duration' => '+24 hours', ]; - $cacheConfig = array_merge($cacheDefaults, $config['uniqueCache']); + $cacheConfig = [...$cacheDefaults, ...$config['uniqueCache']]; - $config['uniqueCacheKey'] = "Cake/Queue.queueUnique.{$key}"; + $config['uniqueCacheKey'] = 'Cake/Queue.queueUnique.' . $key; Cache::setConfig($config['uniqueCacheKey'], $cacheConfig); } @@ -140,9 +142,9 @@ public static function setConfig(string|array $key, ?array $config = null): void * Reads existing configuration. * * @param string $key The name of the configuration. - * @return mixed Configuration data at the named key or null if the key does not exist. + * @return array|null Configuration data at the named key or null if the key does not exist. */ - public static function getConfig(string $key): mixed + public static function getConfig(string $key): ?array { return static::$_config[$key] ?? null; } @@ -150,7 +152,7 @@ public static function getConfig(string $key): mixed /** * Get the configured queue keys. * - * @return array List of configured queue configuration keys. + * @return array List of configured queue configuration keys. */ public static function configured(): array { @@ -190,7 +192,7 @@ public static function engine(string $name): SimpleClient static::$_clients[$name] = new SimpleClient($config['url'], $logger); static::$_clients[$name]->setupBroker(); - if (!is_null($config['receiveTimeout'])) { + if ($config['receiveTimeout'] !== null) { static::$_clients[$name]->getQueueConsumer()->setReceiveTimeout($config['receiveTimeout']); } @@ -200,11 +202,11 @@ public static function engine(string $name): SimpleClient /** * Push a single job onto the queue. * - * @param array|string $className The classname of a job that implements the + * @param array|string $className The classname of a job that implements the * \Cake\Queue\Job\JobInterface. The class will be constructed by * \Cake\Queue\Processor and have the execute method invoked. - * @param array $data An array of data that will be passed to the job. - * @param array $options An array of options for publishing the job: + * @param array $data An array of data that will be passed to the job. + * @param array $options An array of options for publishing the job: * - `config` - A queue config name. Defaults to 'default'. * - `delay` - Time (in integer seconds) to delay message, after which it * will be processed. Not all message brokers accept this. Default `null`. @@ -219,7 +221,6 @@ public static function engine(string $name): SimpleClient * - `\Enqueue\Client\MessagePriority::VERY_HIGH` * - `queue` - The name of a queue to use, from queue `config` array or * string 'default' if empty. - * @return void */ public static function push(string|array $className, array $data = [], array $options = []): void { @@ -227,7 +228,7 @@ public static function push(string|array $className, array $data = [], array $op $class = App::className($class, 'Job', 'Job'); if (is_null($class)) { - throw new InvalidArgumentException("`$class` class does not exist."); + throw new InvalidArgumentException(sprintf('`%s` class does not exist.', $class)); } $name = $options['config'] ?? 'default'; @@ -241,16 +242,19 @@ public static function push(string|array $className, array $data = [], array $op if (!empty($class::$shouldBeUnique)) { if (empty($config['uniqueCache'])) { throw new InvalidArgumentException( - "$class::\$shouldBeUnique is set to `true` but `uniqueCache` configuration is missing.", + $class . '::$shouldBeUnique is set to `true` but `uniqueCache` configuration is missing.', ); } $uniqueId = static::getUniqueId($class, $method, $data); if (Cache::read($uniqueId, $config['uniqueCacheKey'])) { - if ($logger) { + if ($logger instanceof LoggerInterface) { $logger->debug( - "An identical instance of $class already exists on the queue. This push will be ignored.", + sprintf( + 'An identical instance of %s already exists on the queue. This push will be ignored.', + $class, + ), ); } @@ -294,16 +298,15 @@ public static function push(string|array $className, array $data = [], array $op } /** - * @param string $class Class name + * @param class-string $class Class name * @param string $method Method name - * @param array $data Message data - * @return string + * @param array $data Message data */ public static function getUniqueId(string $class, string $method, array $data): string { sort($data); - $hashInput = implode([ + $hashInput = implode('', [ $class, $method, json_encode($data), diff --git a/tests/TestCase/Command/PurgeFailedCommandTest.php b/tests/TestCase/Command/PurgeFailedCommandTest.php index cf5cd6f..40af581 100644 --- a/tests/TestCase/Command/PurgeFailedCommandTest.php +++ b/tests/TestCase/Command/PurgeFailedCommandTest.php @@ -29,6 +29,9 @@ class PurgeFailedCommandTest extends TestCase { use ConsoleIntegrationTestTrait; + /** + * @var string[] + */ protected array $fixtures = [ 'plugin.Cake/Queue.FailedJobs', ]; @@ -73,7 +76,7 @@ public function testFailedJobsAreDeletedById() public function testFailedJobsAreDeletedByClass() { $class = LogToDebugJob::class; - $this->exec("queue purge_failed --class {$class} -f"); + $this->exec(sprintf('queue purge_failed --class %s -f', $class)); $this->assertOutputContains('Deleting 2 jobs.'); $this->assertOutputContains('2 jobs deleted.'); diff --git a/tests/TestCase/Command/RequeueCommandTest.php b/tests/TestCase/Command/RequeueCommandTest.php index 480b9e9..5887b51 100644 --- a/tests/TestCase/Command/RequeueCommandTest.php +++ b/tests/TestCase/Command/RequeueCommandTest.php @@ -34,6 +34,9 @@ class RequeueCommandTest extends TestCase use ConsoleIntegrationTestTrait; use QueueTestTrait; + /** + * @var string[] + */ protected array $fixtures = [ 'plugin.Cake/Queue.FailedJobs', ]; @@ -133,7 +136,7 @@ public function testJobsAreRequeuedByClass() $this->cleanupConsoleTrait(); $class = LogToDebugJob::class; - $this->exec("queue requeue --class {$class} --queue default -f"); + $this->exec(sprintf('queue requeue --class %s --queue default -f', $class)); $this->assertOutputContains('Requeueing 1 jobs.'); $this->assertOutputContains('1 jobs requeued.'); diff --git a/tests/TestCase/Command/WorkerCommandTest.php b/tests/TestCase/Command/WorkerCommandTest.php index 297fca6..f77552d 100644 --- a/tests/TestCase/Command/WorkerCommandTest.php +++ b/tests/TestCase/Command/WorkerCommandTest.php @@ -143,7 +143,7 @@ public function testQueueProcessesWithLogger() /** * Data provider for testQueueProcessesJob method * - * @return array + * @return array|string[]>> */ public static function dataProviderCallableTypes(): array { diff --git a/tests/TestCase/Job/MailerJobTest.php b/tests/TestCase/Job/MailerJobTest.php index 9a617b9..81dd8c8 100644 --- a/tests/TestCase/Job/MailerJobTest.php +++ b/tests/TestCase/Job/MailerJobTest.php @@ -32,12 +32,16 @@ class MailerJobTest extends TestCase * @var \Cake\Mailer\Mailer|\PHPUnit\Framework\MockObject\MockObject */ protected $mailer; + /** * @var \Cake\Queue\Job\MailerJob|\PHPUnit\Framework\MockObject\MockObject */ protected $job; + protected $mailerConfig; + protected $headers; + protected $args; /** @@ -139,8 +143,6 @@ public function testExecuteBadMethodCallException() /** * Create a simple message for testing. - * - * @return \Cake\Queue\Job\Message */ protected function createMessage(): Message { @@ -157,8 +159,7 @@ protected function createMessage(): Message $connectionFactory = new NullConnectionFactory(); $context = $connectionFactory->createContext(); $originalMessage = new NullMessage(json_encode($messageBody)); - $message = new Message($originalMessage, $context); - return $message; + return new Message($originalMessage, $context); } } diff --git a/tests/TestCase/Job/MessageTest.php b/tests/TestCase/Job/MessageTest.php index e828814..9d09471 100644 --- a/tests/TestCase/Job/MessageTest.php +++ b/tests/TestCase/Job/MessageTest.php @@ -23,6 +23,7 @@ use Enqueue\Null\NullMessage; use Error; use RuntimeException; +use TestApp\WelcomeMailer; class MessageTest extends TestCase { @@ -33,10 +34,10 @@ class MessageTest extends TestCase */ public function testConstructorAndGetters() { - $callable = ['TestApp\WelcomeMailer', 'welcome']; + $callable = [WelcomeMailer::class, 'welcome']; $time = 'sample data ' . time(); $id = 7; - $data = compact('id', 'time'); + $data = ['id' => $id, 'time' => $time]; $parsedBody = [ 'class' => $callable, 'data' => $data, @@ -71,7 +72,7 @@ public function testConstructorAndGetters() */ public function testLegacyArguments() { - $callable = ['TestApp\WelcomeMailer', 'welcome']; + $callable = [WelcomeMailer::class, 'welcome']; $args = [ 'first' => 1, 'second' => 'two', @@ -123,7 +124,7 @@ public function testGetCallableInvalidClass() public function testGetCallableInvalidType() { $parsedBody = [ - 'class' => ['TestApp\WelcomeMailer', 'trash', 'oops'], + 'class' => [WelcomeMailer::class, 'trash', 'oops'], 'args' => [], ]; $messageBody = json_encode($parsedBody); diff --git a/tests/TestCase/Job/SendMailJobTest.php b/tests/TestCase/Job/SendMailJobTest.php index 337c096..d60a219 100644 --- a/tests/TestCase/Job/SendMailJobTest.php +++ b/tests/TestCase/Job/SendMailJobTest.php @@ -109,6 +109,7 @@ public function testExecuteWithAttachments() { $emailMessage = clone $this->message; $emailMessage->addAttachments(['test.txt' => ROOT . 'files' . DS . 'test.txt']); + $message = $this->createMessage(DebugTransport::class, [], $emailMessage); $actual = $this->job->execute($message); $this->assertSame(Processor::ACK, $actual); @@ -147,8 +148,6 @@ public function testExecuteNoAbstractTransport() /** * Create a simple message for testing. - * - * @return \Cake\Queue\Job\Message */ protected function createMessage($transport, $config, $emailMessage): QueueJobMessage { diff --git a/tests/TestCase/Listener/FailedJobsListenerTest.php b/tests/TestCase/Listener/FailedJobsListenerTest.php index ab181a0..d5a56e9 100644 --- a/tests/TestCase/Listener/FailedJobsListenerTest.php +++ b/tests/TestCase/Listener/FailedJobsListenerTest.php @@ -39,6 +39,9 @@ class FailedJobsListenerTest extends TestCase { use QueueTestTrait; + /** + * @var string[] + */ protected array $fixtures = [ 'plugin.Cake/Queue.FailedJobs', ]; diff --git a/tests/TestCase/Queue/ProcessorTest.php b/tests/TestCase/Queue/ProcessorTest.php index c2eccf9..ff57b0b 100644 --- a/tests/TestCase/Queue/ProcessorTest.php +++ b/tests/TestCase/Queue/ProcessorTest.php @@ -29,6 +29,7 @@ use Interop\Queue\Processor as InteropProcessor; use PHPUnit\Framework\Attributes\DataProvider; use TestApp\TestProcessor; +use TestApp\WelcomeMailer; class ProcessorTest extends TestCase { @@ -39,7 +40,7 @@ class ProcessorTest extends TestCase /** * Data provider for testProcess method * - * @return array + * @return array */ public static function dataProviderTestProcess(): array { @@ -187,7 +188,7 @@ public function testProcessJobObject() ]); $messageBody = [ - 'class' => ['TestApp\WelcomeMailer', 'welcome'], + 'class' => [WelcomeMailer::class, 'welcome'], 'args' => [], ]; $connectionFactory = new NullConnectionFactory(); diff --git a/tests/TestCase/QueueTestTrait.php b/tests/TestCase/QueueTestTrait.php index c056223..f24f205 100644 --- a/tests/TestCase/QueueTestTrait.php +++ b/tests/TestCase/QueueTestTrait.php @@ -49,7 +49,7 @@ public function cleanupQueueManagerConfigs(): void $queueConfig = QueueManager::getConfig($config); if ($queueConfig && isset($queueConfig['uniqueCacheKey'])) { $cacheKey = $queueConfig['uniqueCacheKey']; - if (Cache::configured($cacheKey)) { + if (Cache::configured()) { Cache::drop($cacheKey); } } @@ -71,7 +71,7 @@ protected function assertDebugLogContains($expected): void { $found = $this->debugLogCount($expected); - $this->assertGreaterThanOrEqual(1, $found, "Did not find `{$expected}` in logs."); + $this->assertGreaterThanOrEqual(1, $found, sprintf('Did not find `%s` in logs.', $expected)); } /** @@ -85,7 +85,7 @@ protected function assertDebugLogContainsExactly($expected, $times): void { $found = $this->debugLogCount($expected); - $this->assertSame($times, $found, "Did not find `{$expected}` exactly {$times} times in logs."); + $this->assertSame($times, $found, sprintf('Did not find `%s` exactly %d times in logs.', $expected, $times)); } /** @@ -94,7 +94,7 @@ protected function assertDebugLogContainsExactly($expected, $times): void * @param string $search The message to search for * @return int The number of times the message was found */ - protected function debugLogCount($search) + protected function debugLogCount($search): int { $log = Log::engine('debug'); $found = 0; diff --git a/tests/TestCase/Task/JobTaskTest.php b/tests/TestCase/Task/JobTaskTest.php index a49324f..ec4f8f7 100644 --- a/tests/TestCase/Task/JobTaskTest.php +++ b/tests/TestCase/Task/JobTaskTest.php @@ -42,8 +42,6 @@ class JobTaskTest extends TestCase /** * setup method - * - * @return void */ public function setUp(): void { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 5c6d7c9..e2f7ee2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -30,13 +30,14 @@ return $root; } } while ($root !== $lastRoot); + throw new Exception('Cannot find the root of the application, unable to run tests'); }; $root = $findRoot(__FILE__); unset($findRoot); chdir($root); -require_once 'vendor/autoload.php'; +require_once $root . '/vendor/autoload.php'; define('CORE_PATH', $root . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp' . DS); define('ROOT', $root . DS . 'tests' . DS . 'test_app' . DS); @@ -58,6 +59,7 @@ if (Configure::version() <= '5.1.0') { $cache_key = '_cake_core_'; } + Cache::setConfig([ $cache_key => [ 'engine' => 'File', diff --git a/tests/test_app/src/Queue/TestCustomProcessor.php b/tests/test_app/src/Queue/TestCustomProcessor.php index 56f72eb..14afd6e 100644 --- a/tests/test_app/src/Queue/TestCustomProcessor.php +++ b/tests/test_app/src/Queue/TestCustomProcessor.php @@ -26,14 +26,8 @@ class TestCustomProcessor implements InteropProcessor { use EventDispatcherTrait; - /** - * @var \Psr\Log\LoggerInterface - */ protected LoggerInterface $logger; - /** - * @var \Cake\Core\ContainerInterface|null - */ protected ?ContainerInterface $container = null; /** @@ -73,13 +67,13 @@ public function process(QueueMessage $message, Context $context): string|object try { $response = $this->processMessage($jobMessage); - } catch (Throwable $e) { - $message->setProperty('jobException', $e); + } catch (Throwable $throwable) { + $message->setProperty('jobException', $throwable); - $this->logger->debug(sprintf('Message encountered exception: %s', $e->getMessage())); + $this->logger->debug(sprintf('Message encountered exception: %s', $throwable->getMessage())); $this->dispatchEvent('Processor.message.exception', [ 'message' => $jobMessage, - 'exception' => $e, + 'exception' => $throwable, ]); return Result::requeue('Exception occurred while processing message'); diff --git a/tests/test_app/src/TestProcessor.php b/tests/test_app/src/TestProcessor.php index d2cc69a..39a9cbf 100644 --- a/tests/test_app/src/TestProcessor.php +++ b/tests/test_app/src/TestProcessor.php @@ -15,8 +15,8 @@ class TestProcessor * Job to be used in test testProcessMessageCallableIsString * * @param Message $message The message to process - * @return null * @throws Exception + * @return null */ public static function processAndThrowException(Message $message) { diff --git a/tests/test_app/src/WelcomeMailerListener.php b/tests/test_app/src/WelcomeMailerListener.php index 2258bd8..243c2b5 100644 --- a/tests/test_app/src/WelcomeMailerListener.php +++ b/tests/test_app/src/WelcomeMailerListener.php @@ -26,7 +26,7 @@ class WelcomeMailerListener implements EventListenerInterface { /** - * @return array + * @return array{} */ public function implementedEvents(): array {