diff --git a/.github/workflows/rector-cs.yml b/.github/workflows/rector-cs.yml index de7ea7f..192dc43 100644 --- a/.github/workflows/rector-cs.yml +++ b/.github/workflows/rector-cs.yml @@ -1,7 +1,7 @@ name: Rector + PHP CS Fixer on: - pull_request_target: + pull_request: paths: - 'config/**' - 'src/**' @@ -12,7 +12,7 @@ on: - '.php-cs-fixer.dist.php' permissions: - contents: read + contents: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -21,8 +21,5 @@ concurrency: jobs: rector: uses: yiisoft/actions/.github/workflows/rector-cs.yml@master - secrets: - token: ${{ secrets.YIISOFT_GITHUB_TOKEN }} with: - repository: ${{ github.event.pull_request.head.repo.full_name }} php: '8.0' diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd17d6..2da0eb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 3.1.1 under development - Enh #83: Explicitly import classes in "use" section (@mspirkov) +- Bug #84: Preserve modification time of rotated log files in `FileRotator` (@terabytesoftw) ## 3.1.0 December 13, 2025 diff --git a/src/FileRotator.php b/src/FileRotator.php index 3a2d393..83da6c8 100644 --- a/src/FileRotator.php +++ b/src/FileRotator.php @@ -13,6 +13,7 @@ use function fclose; use function feof; use function file_exists; +use function filemtime; use function filesize; use function flock; use function fread; @@ -20,6 +21,7 @@ use function is_file; use function sprintf; use function substr; +use function touch; use function unlink; use const LOCK_EX; @@ -129,6 +131,8 @@ public function shouldRotateFile(string $file): bool */ private function rotate(string $rotateFile, string $newFile): void { + $mTime = filemtime($rotateFile); + copy($rotateFile, $newFile); if ($this->compressRotatedFiles && !$this->isCompressed($newFile)) { @@ -139,6 +143,10 @@ private function rotate(string $rotateFile, string $newFile): void if ($this->fileMode !== null) { chmod($newFile, $this->fileMode); } + + if ($mTime !== false) { + touch($newFile, $mTime); + } } /** diff --git a/tests/FileRotatorTest.php b/tests/FileRotatorTest.php index 91b83d6..1e1bd28 100644 --- a/tests/FileRotatorTest.php +++ b/tests/FileRotatorTest.php @@ -14,10 +14,13 @@ use function clearstatcache; use function dirname; use function file_get_contents; +use function filemtime; use function filesize; use function mkdir; use function range; use function str_repeat; +use function time; +use function touch; final class FileRotatorTest extends TestCase { @@ -71,6 +74,34 @@ public function testRotate(bool $compress): void } } + /** + * @dataProvider rotateDataProvider + */ + public function testRotatePreservesModificationTime(bool $compress): void + { + $rotator = new FileRotator(1, 2, null, $compress); + $logFile = $this->getLogFilePath(); + $fileTarget = new FileTarget($logFile, $rotator); + $logger = new Logger([$fileTarget]); + $compressExtension = $compress ? '.gz' : ''; + + $logger->debug($this->generateKilobytesOfData(1)); + $logger->flush(true); + + $expectedTime = time() - 7200; + touch($logFile, $expectedTime); + clearstatcache(); + + $logger->debug('x'); + $logger->flush(true); + + clearstatcache(); + + $rotatedFile = "{$logFile}.1{$compressExtension}"; + $this->assertFileExists($rotatedFile); + $this->assertSame($expectedTime, filemtime($rotatedFile)); + } + /** * @dataProvider rotateDataProvider */