From 5971486248fafbd9fd4a21b249b96ed1bdcbce42 Mon Sep 17 00:00:00 2001 From: Stefan Scheu Date: Tue, 13 Jun 2023 15:51:20 +0200 Subject: [PATCH 1/4] fix: creat new patch on 10.6 base --- models/DataObject/ClassDefinition/Dao.php | 39 ++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/models/DataObject/ClassDefinition/Dao.php b/models/DataObject/ClassDefinition/Dao.php index 6402ff76c06..e3dcb7940be 100644 --- a/models/DataObject/ClassDefinition/Dao.php +++ b/models/DataObject/ClassDefinition/Dao.php @@ -15,6 +15,8 @@ namespace Pimcore\Model\DataObject\ClassDefinition; +use Pimcore\Cache; +use Pimcore\Db\Helper; use Pimcore\Logger; use Pimcore\Model; use Pimcore\Model\DataObject; @@ -39,6 +41,26 @@ class Dao extends Model\Dao\AbstractDao */ protected $tableDefinitions = null; + /** + * Helper to minimize db queries used when looking up classes id / name. + * + * Mapping is actively updated as soon as a class is saved. + * + * @param bool $skipCache + * @return array + * @see self::save() + * + */ + protected function getClassNameIdMap(bool $skipCache = false): array + { + static $mapping; + if ($skipCache || (!isset($mapping) && !is_array(($mapping = Cache::load(md5(__METHOD__)))))) { + $mapping = Helper::fetchPairs($this->db, 'SELECT id, name FROM classes'); + Cache::save($mapping, md5(__METHOD__), ['ClassDefinitionDao']); + } + return $mapping; + } + /** * @param string $id * @@ -48,9 +70,8 @@ public function getNameById($id) { try { if (!empty($id)) { - if ($name = $this->db->fetchOne('SELECT name FROM classes WHERE id = ?', [$id])) { - return $name; - } + $mapping = $this->getClassNameIdMap(); + return $mapping[$id] ?? null; } } catch (\Exception $e) { } @@ -71,7 +92,11 @@ public function getIdByName($name) try { if (!empty($name)) { - $id = $this->db->fetchOne('SELECT id FROM classes WHERE name = ?', [$name]); + $mapping = $this->getClassNameIdMap(); + if (($v = array_search($name, $mapping, true)) !== false) { + $id = $v; + } + } } catch (\Exception $e) { } @@ -97,6 +122,8 @@ public function save($isUpdate = true) } $this->update(); + // Update class name / id mapping in cache. + $this->getClassNameIdMap(true); } /** @@ -242,6 +269,8 @@ public function update() public function create() { $this->db->insert('classes', ['name' => $this->model->getName(), 'id' => $this->model->getId()]); + // Update class name / id mapping in cache. + $this->getClassNameIdMap(true); } /** @@ -300,6 +329,8 @@ public function delete() // clean slug table DataObject\Data\UrlSlug::handleClassDeleted($this->model->getId()); + // Update class name / id mapping in cache. + $this->getClassNameIdMap(true); } /** From 7a3036a3fb7868b44f21ab438794060572f57485 Mon Sep 17 00:00:00 2001 From: Stefan Scheu Date: Tue, 13 Jun 2023 16:14:10 +0200 Subject: [PATCH 2/4] chore: removed unused method call --- models/DataObject/ClassDefinition/Dao.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/models/DataObject/ClassDefinition/Dao.php b/models/DataObject/ClassDefinition/Dao.php index e3dcb7940be..b4a04ee94b1 100644 --- a/models/DataObject/ClassDefinition/Dao.php +++ b/models/DataObject/ClassDefinition/Dao.php @@ -269,8 +269,6 @@ public function update() public function create() { $this->db->insert('classes', ['name' => $this->model->getName(), 'id' => $this->model->getId()]); - // Update class name / id mapping in cache. - $this->getClassNameIdMap(true); } /** From 34eba5a297e01a1593bad7697787c9aad23130c3 Mon Sep 17 00:00:00 2001 From: Stefan Scheu Date: Tue, 13 Jun 2023 16:19:31 +0200 Subject: [PATCH 3/4] fix: write cache immediately to prevent issues during creation of new classes --- models/DataObject/ClassDefinition/Dao.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/DataObject/ClassDefinition/Dao.php b/models/DataObject/ClassDefinition/Dao.php index b4a04ee94b1..350818cf678 100644 --- a/models/DataObject/ClassDefinition/Dao.php +++ b/models/DataObject/ClassDefinition/Dao.php @@ -56,7 +56,7 @@ protected function getClassNameIdMap(bool $skipCache = false): array static $mapping; if ($skipCache || (!isset($mapping) && !is_array(($mapping = Cache::load(md5(__METHOD__)))))) { $mapping = Helper::fetchPairs($this->db, 'SELECT id, name FROM classes'); - Cache::save($mapping, md5(__METHOD__), ['ClassDefinitionDao']); + Cache::save($mapping, md5(__METHOD__), ['ClassDefinitionDao'], null, 0, true); } return $mapping; } From f9ec009862578e98f9145b8d8b4ad7f138afe38c Mon Sep 17 00:00:00 2001 From: Stefan Scheu Date: Tue, 13 Jun 2023 17:07:31 +0200 Subject: [PATCH 4/4] fix: clear cache tags before checking if class definition exists --- models/DataObject/ClassDefinition.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/models/DataObject/ClassDefinition.php b/models/DataObject/ClassDefinition.php index 118310bbe0c..b17887c7cd8 100644 --- a/models/DataObject/ClassDefinition.php +++ b/models/DataObject/ClassDefinition.php @@ -407,6 +407,8 @@ public static function cleanupForExport(&$data) */ private function exists() { + // cache for class definitions needs to be cleared here to avoid wrong exists but still using the cache + Cache::clearTags(['ClassDefinitionDao']); $name = $this->getDao()->getNameById($this->getId()); return is_string($name);