diff --git a/code/controllers/CMSMain.php b/code/controllers/CMSMain.php index 6fb37ab9..4e2f953f 100644 --- a/code/controllers/CMSMain.php +++ b/code/controllers/CMSMain.php @@ -244,67 +244,72 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr * @return String Serialized JSON */ public function SiteTreeHints() { + $json = ''; + $classes = ClassInfo::subclassesFor( $this->stat('tree_class') ); - $def['Root'] = array(); - $def['Root']['disallowedParents'] = array(); + $cacheCanCreate = array(); + foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate(); - foreach($classes as $class) { - $obj = singleton($class); - - if($obj instanceof HiddenClass) continue; - - $allowedChildren = $obj->allowedChildren(); - - // SiteTree::allowedChildren() returns null rather than an empty array if SiteTree::allowed_chldren == 'none' - if($allowedChildren == null) $allowedChildren = array(); - - // Exclude SiteTree from possible Children - $possibleChildren = array_diff($allowedChildren, array("SiteTree")); + // Generate basic cache key. Too complex to encompass all variations + $cache = SS_Cache::factory('CMSMain_SiteTreeHints'); + $cacheKey = md5(implode('_', array(Member::currentUserID(), implode(',', $cacheCanCreate), implode(',', $classes)))); + if($this->request->getVar('flush')) $cache->clean(Zend_Cache::CLEANING_MODE_ALL); + $json = $cache->load($cacheKey); + if(!$json) { + $def['Root'] = array(); + $def['Root']['disallowedParents'] = array(); - // Find i18n - names and build allowed children array - foreach($possibleChildren as $child) { - $instance = singleton($child); + foreach($classes as $class) { + $obj = singleton($class); + if($obj instanceof HiddenClass) continue; - if($instance instanceof HiddenClass) continue; + $allowedChildren = $obj->allowedChildren(); + + // SiteTree::allowedChildren() returns null rather than an empty array if SiteTree::allowed_chldren == 'none' + if($allowedChildren == null) $allowedChildren = array(); + + // Exclude SiteTree from possible Children + $possibleChildren = array_diff($allowedChildren, array("SiteTree")); - if(!$instance->canCreate()) continue; + // Find i18n - names and build allowed children array + foreach($possibleChildren as $child) { + $instance = singleton($child); + + if($instance instanceof HiddenClass) continue; - // skip this type if it is restricted - if($instance->stat('need_permission') && !$this->can(singleton($class)->stat('need_permission'))) continue; + if(!$cacheCanCreate[$child]) continue; - $title = $instance->i18n_singular_name(); + // skip this type if it is restricted + if($instance->stat('need_permission') && !$this->can(singleton($class)->stat('need_permission'))) continue; - $def[$class]['allowedChildren'][] = array("ssclass" => $child, "ssname" => $title); - } + $title = $instance->i18n_singular_name(); - $allowedChildren = array_keys(array_diff($classes, $allowedChildren)); - if($allowedChildren) $def[$class]['disallowedChildren'] = $allowedChildren; - - $defaultChild = $obj->defaultChild(); - - if($defaultChild != 'Page' && $defaultChild != null) - $def[$class]['defaultChild'] = $defaultChild; - - $defaultParent = $obj->defaultParent(); - - $parent = SiteTree::get_by_link($defaultParent); - - $id = $parent ? $parent->id : null; - - if ($defaultParent != 1 && $defaultParent != null) $def[$class]['defaultParent'] = $defaultParent; - - if(isset($def[$class]['disallowedChildren'])) { - foreach($def[$class]['disallowedChildren'] as $disallowedChild) { - $def[$disallowedChild]['disallowedParents'][] = $class; + $def[$class]['allowedChildren'][] = array("ssclass" => $child, "ssname" => $title); } - } - - // Are any classes allowed to be parents of root? - $def['Root']['disallowedParents'][] = $class; - } - return Convert::raw2xml(Convert::raw2json($def)); + $allowedChildren = array_keys(array_diff($classes, $allowedChildren)); + if($allowedChildren) $def[$class]['disallowedChildren'] = $allowedChildren; + $defaultChild = $obj->defaultChild(); + if($defaultChild != 'Page' && $defaultChild != null) $def[$class]['defaultChild'] = $defaultChild; + $defaultParent = $obj->defaultParent(); + $parent = SiteTree::get_by_link($defaultParent); + $id = $parent ? $parent->id : null; + if ($defaultParent != 1 && $defaultParent != null) $def[$class]['defaultParent'] = $defaultParent; + if(isset($def[$class]['disallowedChildren'])) { + foreach($def[$class]['disallowedChildren'] as $disallowedChild) { + $def[$disallowedChild]['disallowedParents'][] = $class; + } + } + + // Are any classes allowed to be parents of root? + $def['Root']['disallowedParents'][] = $class; + } + + $json = Convert::raw2xml(Convert::raw2json($def)); + $cache->save($json, $cacheKey); + } + return $json; } /** diff --git a/code/model/SiteTree.php b/code/model/SiteTree.php index f9b0d4a0..7c98aedb 100644 --- a/code/model/SiteTree.php +++ b/code/model/SiteTree.php @@ -17,6 +17,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid * class is allowed - no subclasses. Otherwise, the class and all its * subclasses are allowed. * To control allowed children on root level (no parent), use {@link $can_be_root}. + * + * Note that this setting is cached when used in the CMS, use the "flush" query parameter to clear it. * * @var array */ @@ -24,6 +26,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid /** * The default child class for this page. + * Note: Value might be cached, see {@link $allowed_chilren}. * * @var string */ @@ -31,6 +34,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid /** * The default parent class for this page. + * Note: Value might be cached, see {@link $allowed_chilren}. * * @var string */ @@ -38,14 +42,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid /** * Controls whether a page can be in the root of the site tree. + * Note: Value might be cached, see {@link $allowed_chilren}. * * @var bool */ static $can_be_root = true; /** - * List of permission codes a user can have to allow a user to create a - * page of this type. + * List of permission codes a user can have to allow a user to create a page of this type. + * Note: Value might be cached, see {@link $allowed_chilren}. * * @var array */