diff --git a/README.md b/README.md index c4f7296..201b281 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,19 @@ $scheduler->php('script.php')->onlyOne(null, function ($lastExecutionTime) { }); ``` +### Before job execution + +In some cases you might want to run some code, if the job is due to run, before it's being executed. +For example you might want to add a log entry, ping a url or anything else. +To do so, you can call the `before` like the example below. + +```php +// $logger here is your own implementation +$scheduler->php('script.php')->before(function () use ($logger) { + $logger->info("script.php started at " . time()); +}); +``` + ### After job execution Sometime you might wish to do something after a job runs. The `then` methods provides you the flexibility to do anything you want after the job execution. The output of the job will be injected to this function. @@ -297,6 +310,21 @@ $scheduler->php('script.php')->then(function ($output) use ($logger) { }, true); ``` +#### Using "before" and "then" together + +```php +// $logger here is your own implementation +$scheduler->php('script.php') + ->before(function () use ($logger) { + $logger->info("script.php started at " . time()); + }) + ->then(function ($output) use ($logger) { + $logger->info("script.php completed at " . time(), [ + 'output' => $output, + ]); + }); +``` + ### Multiple scheduler runs In some cases you might need to run the scheduler multiple times in the same script. Although this is not a common case, the following methods will allow you to re-use the same instance of the scheduler. diff --git a/src/GO/Job.php b/src/GO/Job.php index 352f137..5646c0f 100644 --- a/src/GO/Job.php +++ b/src/GO/Job.php @@ -109,6 +109,13 @@ class Job */ private $emailConfig = []; + /** + * A function to execute before the job is executed. + * + * @var callable + */ + private $before; + /** * A function to execute after the job is executed. * @@ -365,6 +372,10 @@ public function run() // Write lock file if necessary $this->createLockFile(); + if (is_callable($this->before)) { + call_user_func($this->before); + } + if (is_callable($compiled)) { $this->output = $this->exec($compiled); } else { @@ -519,6 +530,20 @@ private function emailOutput() return true; } + /** + * Set function to be called before job execution + * Job object is injected as a parameter to callable function. + * + * @param callable $fn + * @return self + */ + public function before(callable $fn) + { + $this->before = $fn; + + return $this; + } + /** * Set a function to be called after job execution. * By default this will force the job to run in foreground diff --git a/tests/GO/JobTest.php b/tests/GO/JobTest.php index cb73720..7720e45 100644 --- a/tests/GO/JobTest.php +++ b/tests/GO/JobTest.php @@ -353,6 +353,24 @@ public function testShouldReturnOutputOfJobExecution() $this->assertEquals(['hi'], $job3->getOutput()); } + public function testShouldRunCallbackBeforeJobExecution() + { + $job = new Job(function () { + return 'Job for testing before function'; + }); + + $callbackWasExecuted = false; + $outputWasSet = false; + + $job->before(function () use ($job, &$callbackWasExecuted, &$outputWasSet) { + $callbackWasExecuted = true; + $outputWasSet = ! is_null($job->getOutput()); + })->run(); + + $this->assertTrue($callbackWasExecuted); + $this->assertFalse($outputWasSet); + } + public function testShouldRunCallbackAfterJobExecution() { $job = new Job(function () {