/**
  * 
  * Template function for debugging. Allows you to see at-a-glance, 
  * the fields, functions and child nodes held in the Object-Cache about 
  * the current object.
  * 
  * Usage:
  * 
  * <code>
  *  <% with $CachedData %>
  *  $Debug(98)
  *  <% end_with %>
  * <code>
  * 
  * @return string
  */
 public function Debug($id = null)
 {
     if (!Director::isDev() || !isset($_REQUEST['showcache'])) {
         return;
     }
     if ($id) {
         $mode = strtolower($_REQUEST['showcache']);
         $conf = SiteConfig::current_site_config();
         $cacheService = new CacheableNavigationService($mode, $conf);
         $objectCache = $cacheService->getObjectCache();
         $cachedSiteTree = $objectCache->get_site_map();
         if (isset($cachedSiteTree[$id])) {
             $object = $cachedSiteTree[$id];
         } else {
             return false;
         }
     } else {
         $object = $this;
     }
     $message = "<h2>Object-Cache fields & functions for: " . get_class($object) . "</h2>";
     $message .= "<ul>";
     $message .= "\t<li><strong>Cached specifics:</strong>";
     $message .= "\t\t<ul>";
     $message .= "\t\t\t<li>ID: " . $object->ID . "</li>";
     $message .= "\t\t\t<li>Title: " . $object->Title . "</li>";
     $message .= "\t\t\t<li>ClassName: " . $object->ClassName . "</li>";
     $message .= "\t\t\t<li>Child count: " . $object->getChildren()->count() . "</li>";
     $message .= "\t\t</ul>";
     $message .= "\t</li>";
     $message .= "</ul>";
     $message .= "<ul>";
     $message .= "\t<li><strong>Cached Fields:</strong>";
     $message .= "\t\t<ul>";
     foreach ($object->get_cacheable_fields() as $field) {
         $message .= "\t\t\t<li>" . $field . ': ' . $object->{$field} . "</li>";
     }
     $message .= "\t\t</ul>";
     $message .= "\t</li>";
     $message .= "\t<li><strong>Cached Functions:</strong>";
     $message .= "\t\t<ul>";
     foreach ($object->get_cacheable_functions() as $function) {
         $message .= "\t\t\t<li>" . $function . '</li>';
     }
     $message .= "\t\t</ul>";
     $message .= "\t</li>";
     $message .= "</ul>";
     $message .= "<h2>Child nodes of this object:</h2>";
     $message .= '<ol>';
     foreach ($object->getChildren() as $child) {
         $message .= "\t<li>" . $child->Title . ' (#' . $child->ID . ')</li>';
     }
     $message .= '</ol>';
     return $message;
 }
 /**
  * Ensure with and without filters, we get expected output
  */
 public function testGetChildren()
 {
     $config = $this->objFromFixture('SiteConfig', 'default');
     $parent = $this->objFromFixture('SiteTree', 'sitetreetest-page-1');
     $children = $parent->Children()->toArray();
     $models = array_merge(array($parent), $children);
     // Fake a rebuild task - Populate the object-cache with our fixture data
     foreach ($models as $model) {
         $service = new CacheableNavigationService('Live', $config, $model);
         $service->refreshCachedPage();
     }
     // Fetch the cache
     $objCache = $service->getObjectCache();
     $siteMap = $objCache->get_site_map();
     // Default: No custom filters passed - return everything
     $children = $siteMap[1]->getChildren();
     $this->assertEquals(2, $children->count());
     // Default: No custom filters passed - return everything
     $children = $siteMap[1]->getChildren(true, null);
     $this->assertEquals(2, $children->count());
     // Default: No custom filters passed - return everything
     $children = $siteMap[1]->getChildren(true, array());
     $this->assertEquals(2, $children->count());
     // Default: No custom filters passed - return everything
     $children = $siteMap[1]->getChildren(false, array());
     $this->assertEquals(2, $children->count());
     // Don't filter and still no filters passed
     $children = $siteMap[1]->getChildren(false, null);
     $this->assertEquals(2, $children->count());
     // Don't filter and filters passed
     $children = $siteMap[1]->getChildren(false, array('Title' => 'This is a child page 2'));
     $this->assertEquals(1, $children->count());
     // Do filter and filters passed
     $children = $siteMap[1]->getChildren(true, array('Title' => 'This is a child page 1'));
     $this->assertEquals(2, $children->count());
     // Do filter and filters passed
     $children = $siteMap[1]->getChildren(true, array('Title' => 'This is a child page 2'));
     $this->assertEquals(2, $children->count());
     // Do filter and filters passed
     $children = $siteMap[1]->getChildren(false, array('Title' => 'This is a child page 2'));
     $this->assertEquals(1, $children->count());
     // Do filter and "bad" filter passed
     $children = $siteMap[1]->getChildren(false, array('Title' => 'This is a child page null'));
     $this->assertEquals(0, $children->count());
     $children = $siteMap[1]->getChildren(true, array('Dummy' => null));
     $this->assertEquals(2, $children->count());
     $children = $siteMap[1]->getChildren(false, array('Dummy' => null));
     $this->assertEquals(2, $children->count());
 }
 /**
  * 
  * Get the total no. objects in the cache. Due to the way {@link CacheableNavigation} 
  * works, this is restricted to "SiteTree-ish" objects only at this point.
  * 
  * @param string $stage
  * @param string $className
  * @return int $total
  */
 private function getTotalCachedObjects($stage, $className = 'CacheableSiteTree')
 {
     $conf = SiteConfig::current_site_config();
     $service = new CacheableNavigationService($stage, $conf);
     $cache = $service->getObjectCache();
     $cachedIDs = $this->_cachedIDs;
     if ($cache && ($siteMap = $cache->get_site_map())) {
         // For reasons unknown, items appear in object-cache with NULL properties
         $cachedSiteTree = ArrayList::create($siteMap)->filterByCallback(function ($item) use(&$cachedIDs) {
             try {
                 if (!is_null($item->ParentID)) {
                     // push the item ID to the _cachedIDs array for comparison later
                     $cachedIDs[] = $item->ID;
                     return true;
                 }
                 return false;
             } catch (Exception $e) {
                 echo $e->getMessage();
             }
         });
         $this->_cachedIDs = $cachedIDs;
         return $cachedSiteTree->count();
     }
     return 0;
 }