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); diff --git a/models/DataObject/ClassDefinition/Dao.php b/models/DataObject/ClassDefinition/Dao.php index 6402ff76c06..350818cf678 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'], null, 0, true); + } + 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); } /** @@ -300,6 +327,8 @@ public function delete() // clean slug table DataObject\Data\UrlSlug::handleClassDeleted($this->model->getId()); + // Update class name / id mapping in cache. + $this->getClassNameIdMap(true); } /**