Skip to content

Commit 3b2d6f5

Browse files
authored
Merge pull request #20 from LordSimal/1.next
merge 1.next => 1.x
2 parents f377808 + 85d5904 commit 3b2d6f5

File tree

9 files changed

+282
-33
lines changed

9 files changed

+282
-33
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
branches:
66
- 'main'
77
- '1.x'
8+
- '1.next'
89
pull_request:
910
branches:
1011
- '*'

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
"type": "cakephp-plugin",
55
"require": {
66
"php": "^8.1",
7-
"cakephp/cakephp": "^5.0.0",
7+
"cakephp/cakephp": "^5.0",
88
"dragonmantank/cron-expression": "^3.3"
99
},
1010
"require-dev": {
1111
"cakephp/cakephp-codesniffer": "^5.0",
12-
"phpunit/phpunit": "^10.1"
12+
"mockery/mockery": "^1.6",
13+
"phpunit/phpunit": "^10.5.5 || ^11.1.3"
1314
},
1415
"license": "MIT",
1516
"autoload": {

phpstan-baseline.neon

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
parameters:
2+
ignoreErrors:
3+
-
4+
message: '#^Call to an undefined method CakeScheduler\\Scheduler\\Scheduler\|Mockery\\LegacyMockInterface\:\:getEventManager\(\)\.$#'
5+
identifier: method.notFound
6+
count: 2
7+
path: tests/TestCase/Command/ScheduleRunCommandTest.php
8+
9+
-
10+
message: '#^Call to an undefined method CakeScheduler\\Scheduler\\Scheduler\|Mockery\\LegacyMockInterface\:\:shouldReceive\(\)\.$#'
11+
identifier: method.notFound
12+
count: 8
13+
path: tests/TestCase/Command/ScheduleRunCommandTest.php
14+
15+
-
16+
message: '#^Call to an undefined method Mockery\\ExpectationInterface\|Mockery\\HigherOrderMessage\:\:andReturn\(\)\.$#'
17+
identifier: method.notFound
18+
count: 8
19+
path: tests/TestCase/Command/ScheduleRunCommandTest.php

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
includes:
2+
- phpstan-baseline.neon
3+
14
parameters:
25
paths:
36
- src

src/Command/ScheduleRunCommand.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
use Cake\Command\Command;
77
use Cake\Console\Arguments;
88
use Cake\Console\ConsoleIo;
9+
use CakeScheduler\Error\SchedulerStoppedException;
910
use CakeScheduler\Scheduler\Event;
1011
use CakeScheduler\Scheduler\Scheduler;
12+
use Throwable;
1113

1214
class ScheduleRunCommand extends Command
1315
{
@@ -34,7 +36,13 @@ public function execute(Arguments $args, ConsoleIo $io): int
3436
}
3537

3638
$events->each(function (Event $event) use ($io): void {
37-
$this->runEvent($event, $io);
39+
$returnCode = $this->runEvent($event, $io);
40+
41+
if ($returnCode === Scheduler::SHOULD_STOP_EXECUTION) {
42+
$io->error('Error while executing command: ' . get_class($event->getCommand()));
43+
44+
throw new SchedulerStoppedException('Scheduler was stopped by event listener');
45+
}
3846
});
3947

4048
return self::CODE_SUCCESS;
@@ -48,8 +56,17 @@ public function execute(Arguments $args, ConsoleIo $io): int
4856
protected function runEvent(Event $event, ConsoleIo $io): ?int
4957
{
5058
$this->scheduler->dispatchEvent('CakeScheduler.beforeExecute', ['event' => $event]);
51-
$result = $event->run($io);
52-
$this->scheduler->dispatchEvent('CakeScheduler.afterExecute', ['event' => $event, 'result' => $result]);
59+
try {
60+
$result = $event->run($io);
61+
$this->scheduler->dispatchEvent('CakeScheduler.afterExecute', ['event' => $event, 'result' => $result]);
62+
} catch (Throwable $exception) {
63+
$io->error($exception->getMessage());
64+
$event = $this->scheduler->dispatchEvent('CakeScheduler.errorExecute', [
65+
'event' => $event,
66+
'exception' => $exception,
67+
]);
68+
$result = $event->getResult();
69+
}
5370

5471
return $result;
5572
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace CakeScheduler\Error;
5+
6+
use RuntimeException;
7+
8+
class SchedulerStoppedException extends RuntimeException
9+
{
10+
}

src/Scheduler/Scheduler.php

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55

66
use Cake\Collection\Collection;
77
use Cake\Collection\CollectionInterface;
8+
use Cake\Command\Command;
9+
use Cake\Console\Arguments;
810
use Cake\Console\CommandInterface;
11+
use Cake\Console\ConsoleIo;
912
use Cake\Core\Container;
1013
use Cake\Core\ContainerInterface;
1114
use Cake\Event\EventDispatcherInterface;
@@ -33,6 +36,11 @@ class Scheduler implements EventDispatcherInterface
3336
*/
3437
protected CollectionInterface $events;
3538

39+
/**
40+
* The event code if execution should be stopped
41+
*/
42+
public const SHOULD_STOP_EXECUTION = 1;
43+
3644
/**
3745
* @param \Cake\Core\Container|null $container The DI container instance from the app
3846
*/
@@ -43,12 +51,16 @@ public function __construct(?Container $container = null)
4351
}
4452

4553
/**
46-
* @param string $command The FQCN of the command to be executed
54+
* @param callable|string $command The FQCN of the command to be executed or a callable function
4755
* @param array $args Args which should be passed on to the command
4856
* @return \CakeScheduler\Scheduler\Event
4957
*/
50-
public function execute(string $command, array $args = []): Event
58+
public function execute(string|callable $command, array $args = []): Event
5159
{
60+
if (is_callable($command)) {
61+
return $this->addCallable($command, $args);
62+
}
63+
5264
try {
5365
if ($this->container !== null) {
5466
$commandObj = $this->container->get($command);
@@ -81,6 +93,42 @@ protected function addCommand(CommandInterface $command, array $args = []): Even
8193
return $event;
8294
}
8395

96+
/**
97+
* @param callable $callable
98+
* @param array $args
99+
* @return \CakeScheduler\Scheduler\Event
100+
*/
101+
protected function addCallable(callable $callable, array $args = []): Event
102+
{
103+
$command = new class ($callable, $args) extends Command {
104+
/**
105+
* @param callable $callable
106+
* @param array $args
107+
*/
108+
public function __construct(
109+
protected $callable,
110+
protected array $args = []
111+
) {
112+
}
113+
114+
/**
115+
* @param \Cake\Console\Arguments $args
116+
* @param \Cake\Console\ConsoleIo $io
117+
* @return int|null
118+
*/
119+
public function execute(Arguments $args, ConsoleIo $io): ?int
120+
{
121+
array_push($this->args, $io);
122+
123+
return call_user_func_array($this->callable, $this->args);
124+
}
125+
};
126+
$event = new Event($command, $args);
127+
$this->events = $this->events->appendItem($event);
128+
129+
return $event;
130+
}
131+
84132
/**
85133
* @return \Cake\Collection\CollectionInterface
86134
*/

0 commit comments

Comments
 (0)