Skip to content

Commit

Permalink
Page Tree building: New method to use only one query
Browse files Browse the repository at this point in the history
  • Loading branch information
vlucas committed May 9, 2011
1 parent 815a2a7 commit 29bfd01
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
4 changes: 3 additions & 1 deletion app/Module/Page/Controller.php
Expand Up @@ -7,6 +7,8 @@
*/
class Controller extends Stackbox\Module\ControllerAbstract
{
protected $_path = __DIR__;

/**
* @method GET
*/
Expand Down Expand Up @@ -339,7 +341,7 @@ public function sitemapAction($request)
$pages = $mapper->pageTree();

// View template
return $this->view(__FUNCTION__)
return $this->template(__FUNCTION__)
->format($request->format)
->set(array('pages' => $pages));
}
Expand Down
5 changes: 5 additions & 0 deletions app/Module/Page/Entity.php
Expand Up @@ -11,6 +11,9 @@ class Entity extends Stackbox\EntityAbstract

// Table
protected static $_datasource = "pages";

// Hierarchy
public $children = array();

/**
* Fields
Expand All @@ -37,13 +40,15 @@ public static function fields() {
*/
public static function relations() {
return array(
/*
// Subpages / hierarchy
'children' => array(
'type' => 'HasMany',
'entity' => ':self',
'where' => array('site_id' => ':entity.site_id', 'parent_id' => ':entity.id'),
'order' => array('ordering' => 'ASC')
),
*/
// Modules in regions on page
'modules' => array(
'type' => 'HasMany',
Expand Down
47 changes: 35 additions & 12 deletions app/Module/Page/Mapper.php
Expand Up @@ -9,6 +9,9 @@ class Mapper extends Stackbox\Module\MapperAbstract
* @see Cx_Module_Mapper_Abstract
*/
protected $_auto_site_id_query = false;

// Page tree cache for fully sorted page tree nested set
protected static $_pageTree;


/**
Expand All @@ -32,19 +35,39 @@ public function getPageByUrl($url)
*/
public function pageTree($startPage = null)
{
if(null === $startPage) {
$rootPages = $this->all('Module\Page\Entity', array(
'site_id' => \Kernel()->config('app.site.id'),
'parent_id' => 0))->order(array('ordering' => 'ASC')
);
} else {
if($startPage instanceof \Module\Page\Entity) {
$rootPages = $startPage->children;
} else {
throw new Stackbox\Exception("Provided start page must be an instance of Module\Page\Entity");
}
// Get _ALL_ pages for current site - they will get sorted with PHP instead of the database
// Only real way to make Adjacency model efficient and avoid all the SQL horror of storing hierarchy in relational databases
$pages = $this->all('Module\Page\Entity')
->where(array('site_id' => \Kernel()->config('app.site.id')))
->order(array('parent_id' => 'ASC', 'ordering' => 'ASC'));

$index = array();
$tree = array();

// step 1: build index (note that I use &$row references!)
foreach($pages as $page) {
$index[$page->id] = $page;
if(!$page->parent_id) {
$tree[] = $page;
}
}

// step 2: link tree (references here as well!)
foreach ($pages as $page) {
$index[$page->parent_id]->children[] = $page;
}

//var_dump($tree);

return $rootPages;
// Return only a portion of the tree
/*
if($startPage instanceof \Module\Page\Entity) {
// Do stuff to return requested portion of tree
} else {
throw new \InvalidArgumentException("Provided start page must be an instance of Module\Page\Entity");
}
*/

return $tree;
}
}

0 comments on commit 29bfd01

Please sign in to comment.