diff --git a/README.md b/README.md index 7443b31..cf86a40 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ $rotation ->truncate() // Optional, truncate the original log file in place after creating a copy, instead of moving the old log file. ->then(function ($filenameTarget, $filenameRotated) {}) // Optional, to get filename target and original filename ->catch(function (RotationFailed $exception) {}) // Optional, to catch a exception in rotating + ->finally(function ($message, $filenameTarget) {}) // Optional, this method will be called when the process has finished ->rotate('file.log'); ``` @@ -50,6 +51,7 @@ $rotation = new Rotation([ 'truncate' => false, 'then' => function ($filename) {}, 'catch' => function (RotationFailed $exception) {}, + 'finally' => function ($message, $filename) {}, ]); $rotation->rotate('file.log'); diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index 541d28c..c33de5f 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -7,10 +7,26 @@ trait ErrorHandler { + private $thenCallback = null; + private $catchCallable = null; + private $finallyCallback = null; + private ?string $_filename = null; + /** + * Function that will be executed when the rotation is successful. + * The first argument will be the name of the destination file and + * the second the name of the rotated file. + */ + public function then(callable $callable): self + { + $this->thenCallback = $callable; + + return $this; + } + /** * Call function if roteted catch any Exception. */ @@ -21,13 +37,36 @@ public function catch(callable $callable): self return $this; } + /** + * Function that will be executed when the process was finished. + */ + public function finally(callable $callable): self + { + $this->finallyCallback = $callable; + + return $this; + } + protected function setFilename(string $filename): void { $this->_filename = $filename; } + private function sucessfull(string $filenameSource, ?string $filenameRotated): void + { + $this->finished('sucessfull', $filenameSource); + + if (is_null($this->thenCallback) || is_null($filenameRotated)) { + return; + } + + call_user_func($this->thenCallback, $filenameRotated, $filenameSource); + } + protected function exception(Throwable $exception): self { + $this->finished($exception->getMessage(), $this->_filename); + if ($this->catchCallable) { call_user_func($this->catchCallable, $this->convertException($exception)); } else { @@ -37,6 +76,16 @@ protected function exception(Throwable $exception): self return $this; } + + protected function finished(string $message, ?string $filenameSource): void + { + if (is_null($this->finallyCallback)) { + return; + } + + call_user_func($this->finallyCallback, $message, $filenameSource); + } + private function convertException(Throwable $exception): RotationFailed { return new RotationFailed( diff --git a/src/Rotation.php b/src/Rotation.php index 7b6525b..df621dd 100644 --- a/src/Rotation.php +++ b/src/Rotation.php @@ -19,8 +19,6 @@ class Rotation private bool $_truncate = false; - private $thenCallback = null; - public function __construct(array $options = []) { $this->processor = new RotativeProcessor(); @@ -32,6 +30,7 @@ public function __construct(array $options = []) 'files', 'then', 'catch', + 'finally', ]); $this->options($options); @@ -87,18 +86,6 @@ public function minSize(int $bytes): self return $this; } - /** - * Function that will be executed when the rotation is successful. - * The first argument will be the name of the destination file and - * the second the name of the rotated file. - */ - public function then(callable $callable): self - { - $this->thenCallback = $callable; - - return $this; - } - /** * Rotate file. * @@ -167,21 +154,14 @@ private function runCompress(string $filename): ?string } } - private function sucessfull(string $filenameSource, ?string $filenameRotated): void - { - if (is_null($this->thenCallback) || is_null($filenameRotated)) { - return; - } - - call_user_func($this->thenCallback, $filenameRotated, $filenameSource); - } - /** * check if file need rotate. */ private function canRotate(string $filename): bool { if (!file_exists($filename)) { + $this->finished(sprintf('the file %s not exists.', $filename), $filename); + return false; } diff --git a/tests/ErrorHandlerTest.php b/tests/ErrorHandlerTest.php index 825e684..331ed77 100644 --- a/tests/ErrorHandlerTest.php +++ b/tests/ErrorHandlerTest.php @@ -7,6 +7,34 @@ class ErrorHandlerTest extends TestCase { + public function testCallThenIfRotateWasSucessfull() + { + file_put_contents(self::DIR_WORK.'file.log', microtime(true)); + + $rotation = new Rotation(); + + $thenCalled = false; + + $rotation->then(function () use (&$thenCalled) { + $thenCalled = true; + })->rotate(self::DIR_WORK.'file.log'); + + $this->assertTrue($thenCalled); + } + + public function testNotCallThenIfRotateNotWasSucessfull() + { + $rotation = new Rotation(); + + $thenCalled = false; + + $rotation->then(function () use (&$thenCalled) { + $thenCalled = true; + })->rotate(self::DIR_WORK.'file.log'); + + $this->assertFalse($thenCalled); + } + public function testThrowsException() { $this->expectException(RotationFailed::class); @@ -39,4 +67,50 @@ public function testCatchException() $this->assertFalse($result); } + + public function testCallFinallyIfRotateWasSucessfull() + { + file_put_contents(self::DIR_WORK.'file.log', microtime(true)); + + $rotation = new Rotation(); + + $finallyCalled = false; + + $rotation->finally(function () use (&$finallyCalled) { + $finallyCalled = true; + })->rotate(self::DIR_WORK.'file.log'); + + $this->assertTrue($finallyCalled); + } + + public function testCallFinallyIfFileDontExists() + { + $rotation = new Rotation(); + + $finallyCalled = false; + + $rotation->finally(function () use (&$finallyCalled) { + $finallyCalled = true; + })->rotate(self::DIR_WORK.'file.log'); + + $this->assertTrue($finallyCalled); + } + + public function testCallFinallyIfThrowException() + { + $this->expectException(RotationFailed::class); + + $rotation = new Rotation(); + + touch(self::DIR_WORK.'/file.log'); + chmod(self::DIR_WORK.'/file.log', 0444); + + $finallyCalled = false; + + $rotation->finally(function () use (&$finallyCalled) { + $finallyCalled = true; + })->rotate(self::DIR_WORK.'file.log'); + + $this->assertTrue($finallyCalled); + } } diff --git a/tests/OptionTest.php b/tests/OptionTest.php index b38435f..ed81ebd 100644 --- a/tests/OptionTest.php +++ b/tests/OptionTest.php @@ -15,6 +15,7 @@ public function testPassOptions() 'truncate' => false, 'then' => function ($filename) {}, 'catch' => function ($error) {}, + 'finally' => function ($message) {}, ]); $this->assertNotNull($rotation);