From c9c1fdf6d11f5ffe5399183400b2b82d8602be66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Fri, 10 Jul 2026 18:03:14 +0200 Subject: [PATCH 1/2] Fix indexer state updated value not being parsable as a datetime Indexer\Model\Indexer\State and Mview\View\State stored `updated` as a raw Unix timestamp via time(). Indexer::getLatestUpdated() feeds that value into new \DateTime(), which throws "Failed to parse time string" when the state is read from memory before being reloaded from the DB. Store the value pre-formatted as Y-m-d H:i:s, identical to what the DB adapter already persists, so in-memory reads stay parsable. Fixes #38411 --- app/code/Magento/Indexer/Model/Indexer/State.php | 2 +- app/code/Magento/Indexer/Model/Mview/View/State.php | 2 +- .../Indexer/Test/Unit/Model/Indexer/StateTest.php | 10 ++++++++++ .../Indexer/Test/Unit/Model/Mview/View/StateTest.php | 10 ++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Indexer/Model/Indexer/State.php b/app/code/Magento/Indexer/Model/Indexer/State.php index ef26cf6821d1..b591ef3f554f 100644 --- a/app/code/Magento/Indexer/Model/Indexer/State.php +++ b/app/code/Magento/Indexer/Model/Indexer/State.php @@ -180,7 +180,7 @@ public function setStatus($status) */ public function beforeSave() { - $this->setUpdated(time()); + $this->setUpdated((new \DateTimeImmutable())->format('Y-m-d H:i:s')); return parent::beforeSave(); } diff --git a/app/code/Magento/Indexer/Model/Mview/View/State.php b/app/code/Magento/Indexer/Model/Mview/View/State.php index 9726a9ac961f..6e3dcf903082 100644 --- a/app/code/Magento/Indexer/Model/Mview/View/State.php +++ b/app/code/Magento/Indexer/Model/Mview/View/State.php @@ -105,7 +105,7 @@ public function loadByView($viewId) */ public function beforeSave() { - $this->setUpdated(time()); + $this->setUpdated((new \DateTimeImmutable())->format('Y-m-d H:i:s')); return parent::beforeSave(); } diff --git a/app/code/Magento/Indexer/Test/Unit/Model/Indexer/StateTest.php b/app/code/Magento/Indexer/Test/Unit/Model/Indexer/StateTest.php index 34f7b6c12102..170ef672dc01 100644 --- a/app/code/Magento/Indexer/Test/Unit/Model/Indexer/StateTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Model/Indexer/StateTest.php @@ -92,6 +92,16 @@ public function testBeforeSave() $this->assertNotNull($this->model->getUpdated()); } + public function testBeforeSaveStoresParsableDateTime() + { + $this->model->beforeSave(); + $updated = $this->model->getUpdated(); + + $this->assertIsString($updated); + $this->assertMatchesRegularExpression('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $updated); + $this->assertInstanceOf(\DateTime::class, new \DateTime($updated)); + } + public function testSetStatus() { $setData = 'data'; diff --git a/app/code/Magento/Indexer/Test/Unit/Model/Mview/View/StateTest.php b/app/code/Magento/Indexer/Test/Unit/Model/Mview/View/StateTest.php index 150bdbb107c7..cbc6bc6f8922 100644 --- a/app/code/Magento/Indexer/Test/Unit/Model/Mview/View/StateTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Model/Mview/View/StateTest.php @@ -89,6 +89,16 @@ public function testBeforeSave() $this->assertNotNull($this->model->getUpdated()); } + public function testBeforeSaveStoresParsableDateTime() + { + $this->model->beforeSave(); + $updated = $this->model->getUpdated(); + + $this->assertIsString($updated); + $this->assertMatchesRegularExpression('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $updated); + $this->assertInstanceOf(\DateTime::class, new \DateTime($updated)); + } + public function testSetterAndGetterWithoutApplicationLock() { $this->configReaderMock->expects($this->any())->method('get')->willReturn(false); From cdc04edeb1264e8710528f1b378617aa5ccaf879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= Date: Sat, 11 Jul 2026 01:09:57 +0200 Subject: [PATCH 2/2] Fix static test findings in indexer state models --- app/code/Magento/Indexer/Model/Indexer/State.php | 11 +++++------ app/code/Magento/Indexer/Model/Mview/View/State.php | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Indexer/Model/Indexer/State.php b/app/code/Magento/Indexer/Model/Indexer/State.php index b591ef3f554f..0b8a1a5b0aad 100644 --- a/app/code/Magento/Indexer/Model/Indexer/State.php +++ b/app/code/Magento/Indexer/Model/Indexer/State.php @@ -86,7 +86,7 @@ public function __construct( */ public function getIndexerId() { - return parent::getIndexerId(); + return $this->getData('indexer_id'); } /** @@ -97,7 +97,7 @@ public function getIndexerId() */ public function setIndexerId($value) { - return parent::setIndexerId($value); + return $this->setData('indexer_id', $value); } /** @@ -108,8 +108,7 @@ public function setIndexerId($value) public function getStatus() { if ($this->isUseApplicationLock()) { - if ( - parent::getStatus() == StateInterface::STATUS_WORKING && + if (parent::getStatus() == StateInterface::STATUS_WORKING && !$this->lockManager->isLocked($this->lockPrefix . $this->getIndexerId()) ) { return StateInterface::STATUS_INVALID; @@ -126,7 +125,7 @@ public function getStatus() */ public function getUpdated() { - return parent::getUpdated(); + return $this->getData('updated'); } /** @@ -137,7 +136,7 @@ public function getUpdated() */ public function setUpdated($value) { - return parent::setUpdated($value); + return $this->setData('updated', $value); } /** diff --git a/app/code/Magento/Indexer/Model/Mview/View/State.php b/app/code/Magento/Indexer/Model/Mview/View/State.php index 6e3dcf903082..69841c68a074 100644 --- a/app/code/Magento/Indexer/Model/Mview/View/State.php +++ b/app/code/Magento/Indexer/Model/Mview/View/State.php @@ -150,8 +150,7 @@ public function getStatus() { $status = $this->getData('status'); if ($this->isUseApplicationLock()) { - if ( - $status == \Magento\Framework\Mview\View\StateInterface::STATUS_WORKING && + if ($status == \Magento\Framework\Mview\View\StateInterface::STATUS_WORKING && !$this->lockManager->isLocked($this->lockPrefix . $this->getViewId()) ) { return \Magento\Framework\Mview\View\StateInterface::STATUS_IDLE;