diff --git a/src/Model/ModelData.php b/src/Model/ModelData.php index 04d5a1fc027..f038b9e146d 100644 --- a/src/Model/ModelData.php +++ b/src/Model/ModelData.php @@ -74,11 +74,38 @@ class ModelData private array $objCache = []; + private $_cache_statusFlags = null; + public function __construct() { // no-op } + /** + * Flags provides the user with additional data about the current page status. + * + * Mostly this is used for versioning, but can be used for other purposes (e.g. localisation). + * Each page can have more than one status flag. + * + * Returns an associative array of a unique key to a (localized) title for the flag. + * The unique key can be reused as a CSS class. + * + * Example (simple): + * "deletedonlive" => "Deleted" + * + * Example (with optional title attribute): + * "deletedonlive" => ['text' => "Deleted", 'title' => 'This page has been deleted'] + */ + public function getStatusFlags(bool $cached = true): array + { + if (!$this->_cache_statusFlags || !$cached) { + $flags = []; + $this->extend('updateStatusFlags', $flags); + $this->_cache_statusFlags = $flags; + } + return $this->_cache_statusFlags; + } + // ----------------------------------------------------------------------------------------------------------------- // FIELD GETTERS & SETTERS ----------------------------------------------------------------------------------------- @@ -677,4 +704,18 @@ public function Debug(): ModelData|string { return ModelDataDebugger::create($this); } + + /** + * Clears record-specific cached data. + * + * @param boolean $persistent When true will also clear persistent data stored in the Cache system. + * When false will just clear session-local cached data + */ + public function flushCache(bool $persistent = true): static + { + $this->objCacheClear(); + $this->_cache_statusFlags = null; + $this->extend('onFlushCache'); + return $this; + } } diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index e0d2b755d61..b715359a873 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -3511,14 +3511,11 @@ public static function get_one($callerClass = null, $filter = "", $cache = true, } /** - * Flush the cached results for all relations (has_one, has_many, many_many) - * Also clears any cached aggregate data. + * @inheritDoc * - * @param boolean $persistent When true will also clear persistent data stored in the Cache system. - * When false will just clear session-local cached data - * @return static $this + * Also flush the cached results for all relations (has_one, has_many, many_many) */ - public function flushCache($persistent = true) + public function flushCache(bool $persistent = true): static { if (static::class == DataObject::class) { DataObject::$_cache_get_one = []; @@ -3532,11 +3529,9 @@ public function flushCache($persistent = true) } } - $this->extend('onFlushCache'); - $this->components = []; $this->eagerLoadedData = []; - return $this; + return parent::flushCache($persistent); } /** @@ -3563,7 +3558,7 @@ public static function flush_and_destroy_cache() */ public static function reset() { - DBEnum::flushCache(); + DBEnum::clearStaticCache(); ClassInfo::reset_db_cache(); static::getSchema()->reset(); DataObject::$_cache_get_one = []; diff --git a/src/ORM/FieldType/DBEnum.php b/src/ORM/FieldType/DBEnum.php index e71e6d17d9c..a666fc90034 100644 --- a/src/ORM/FieldType/DBEnum.php +++ b/src/ORM/FieldType/DBEnum.php @@ -38,7 +38,7 @@ class DBEnum extends DBString /** * Clear all cached enum values. */ - public static function flushCache(): void + public static function clearStaticCache(): void { DBEnum::$enum_cache = []; } @@ -176,7 +176,7 @@ public function getEnum(): array * If table or name are not set, or if it is not a valid field on the given table, * then only known enum values are returned. * - * Values cached in this method can be cleared via `DBEnum::flushCache();` + * Values cached in this method can be cleared via `DBEnum::clearStaticCache();` */ public function getEnumObsolete(): array { diff --git a/src/ORM/Hierarchy/Hierarchy.php b/src/ORM/Hierarchy/Hierarchy.php index 929476fc778..6792d02b655 100644 --- a/src/ORM/Hierarchy/Hierarchy.php +++ b/src/ORM/Hierarchy/Hierarchy.php @@ -567,6 +567,16 @@ public function getBreadcrumbs($separator = ' » ') return implode($separator ?? '', $crumbs); } + /** + * Get the title that will be used in TreeDropdownField and other tree structures. + */ + public function getTreeTitle(): string + { + $title = $this->getOwner()->MenuTitle ?? $this->getOwner()->Title; + $this->getOwner()->extend('updateTreeTitle', $title); + return $title; // @TODO see if we need to escape this (it was escaped in Group and is in File too) + } + /** * Flush all Hierarchy caches: * - Children (instance) diff --git a/src/Security/Group.php b/src/Security/Group.php index 6c10d32c073..3cc484dead4 100755 --- a/src/Security/Group.php +++ b/src/Security/Group.php @@ -494,16 +494,6 @@ public function stageChildren() ->sort('"Sort"'); } - /** - * @return string - */ - public function getTreeTitle() - { - $title = htmlspecialchars($this->Title ?? '', ENT_QUOTES); - $this->extend('updateTreeTitle', $title); - return $title; - } - /** * Overloaded to ensure the code is always descent. * diff --git a/tests/php/ORM/DBEnumTest.php b/tests/php/ORM/DBEnumTest.php index a44fbc57f51..1ae128b527f 100644 --- a/tests/php/ORM/DBEnumTest.php +++ b/tests/php/ORM/DBEnumTest.php @@ -95,7 +95,7 @@ public function testObsoleteValues() // Test values with a record $obj->Colour = 'Red'; $obj->write(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( ['Red', 'Blue', 'Green'], @@ -104,7 +104,7 @@ public function testObsoleteValues() // If the value is removed from the enum, obsolete content is still retained $colourField->setEnum(['Blue', 'Green', 'Purple']); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( ['Blue', 'Green', 'Purple', 'Red'], // Red on the end now, because it's obsolete @@ -135,7 +135,7 @@ public function testObsoleteValues() // If obsolete records are deleted, the extra values go away $obj->delete(); $obj2->delete(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( ['Blue', 'Green'], $colourField->getEnumObsolete() diff --git a/tests/php/ORM/DataObjectSchemaGenerationTest.php b/tests/php/ORM/DataObjectSchemaGenerationTest.php index e5c04ce185e..b89e9a8c4a4 100644 --- a/tests/php/ORM/DataObjectSchemaGenerationTest.php +++ b/tests/php/ORM/DataObjectSchemaGenerationTest.php @@ -197,7 +197,7 @@ public function testClassNameSpecGeneration() $schema = DataObject::getSchema(); // Test with blank entries - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $do1 = new TestObject(); $fields = $schema->databaseFields(TestObject::class, false); // May be overridden from DBClassName to DBClassNameVarchar by config @@ -215,7 +215,7 @@ public function testClassNameSpecGeneration() // Test with instance of subclass $item1 = new TestIndexObject(); $item1->write(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( [ TestObject::class, @@ -228,7 +228,7 @@ public function testClassNameSpecGeneration() // Test with instance of main class $item2 = new TestObject(); $item2->write(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( [ TestObject::class, @@ -243,7 +243,7 @@ public function testClassNameSpecGeneration() $item1->write(); $item2 = new TestObject(); $item2->write(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); $this->assertEquals( [ TestObject::class, diff --git a/tests/php/Security/SecurityTest.php b/tests/php/Security/SecurityTest.php index 9f73a925df3..2f4102c4186 100644 --- a/tests/php/Security/SecurityTest.php +++ b/tests/php/Security/SecurityTest.php @@ -681,7 +681,7 @@ public function testSuccessfulLoginAttempts() public function testDatabaseIsReadyWithInsufficientMemberColumns() { Security::clear_database_is_ready(); - DBEnum::flushCache(); + DBEnum::clearStaticCache(); // Assumption: The database has been built correctly by the test runner, // and has all columns present in the ORM