Skip to content

Commit

Permalink
ENHANCEMENT Caching expensive CMSMain->SiteTreeHints() call on disk
Browse files Browse the repository at this point in the history
  • Loading branch information
chillu committed Apr 15, 2012
1 parent d9c4aa8 commit 2dc0e72
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 51 deletions.
103 changes: 54 additions & 49 deletions code/controllers/CMSMain.php
Expand Up @@ -244,67 +244,72 @@ public function Breadcrumbs($unlinked = false) {
* @return String Serialized JSON
*/
public function SiteTreeHints() {
$classes = ClassInfo::subclassesFor( $this->stat('tree_class') );

$def['Root'] = array();
$def['Root']['disallowedParents'] = array();
$json = '';

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"));
$classes = ClassInfo::subclassesFor( $this->stat('tree_class') );

// Find i18n - names and build allowed children array
foreach($possibleChildren as $child) {
$instance = singleton($child);
$cacheCanCreate = array();
foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate();

// 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();

foreach($classes as $class) {
$obj = singleton($class);
if($obj instanceof HiddenClass) continue;

$allowedChildren = $obj->allowedChildren();

if($instance instanceof HiddenClass) continue;
// 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();
$def[$class]['allowedChildren'][] = array("ssclass" => $child, "ssname" => $title);
}

$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;
$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;
}

// Are any classes allowed to be parents of root?
$def['Root']['disallowedParents'][] = $class;
}

return Convert::raw2xml(Convert::raw2json($def));
$json = Convert::raw2xml(Convert::raw2json($def));
$cache->save($json, $cacheKey);
}
return $json;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions code/model/SiteTree.php
Expand Up @@ -17,35 +17,40 @@ 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
*/
static $allowed_children = array("SiteTree");

/**
* The default child class for this page.
* Note: Value might be cached, see {@link $allowed_chilren}.
*
* @var string
*/
static $default_child = "Page";

/**
* The default parent class for this page.
* Note: Value might be cached, see {@link $allowed_chilren}.
*
* @var string
*/
static $default_parent = null;

/**
* 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
*/
Expand Down

0 comments on commit 2dc0e72

Please sign in to comment.