To participate you must create an account on apostrophenow.org. If you have already done so, click Login.

Changeset 1065

Show
Ignore:
Timestamp:
04/26/10 17:08:58 (22 months ago)
Author:
tboutell
Message:

New default behavior of navigation components is appropriate for use on large sites with many pages. On small sites it may be slightly slower, in which case you can set app_a_many_pages to false to get the old "fetch the entire page tree and reuse it in each navigation component as needed" behavior back. This worked quite well up to about 1,000 pages but became a serious problem on an 8,000-page site.

aPage::getAncestorsInfo now has an optional 'includeSelf' parameter which defaults to false for backwards compatibility.

aPage::getInfo provides a page info array about the current page. Useful when merging information from the Info methods with information about pages you already have as objects.

aPage::getAccordionInfo now has an optional final parameter, 'root', which specifies the slug of the root page of the accordion tree. The page on which getAccordionInfo is called should be a descendant of that page (or the root page itself).

Location:
plugins/apostrophePlugin/trunk/lib
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • plugins/apostrophePlugin/trunk/lib/model/doctrine/PluginaPage.class.php

    r970 r1065  
    570570  protected $ancestorsInfo; 
    571571   
    572   public function getAncestorsInfo() 
     572  public function getAncestorsInfo($includeSelf = false) 
    573573  { 
    574574    if (!isset($this->ancestorsInfo)) 
     
    577577      // Since our presence on an admin page implies we know about it, it's OK to include 
    578578      // admin pages in the breadcrumb. It's not OK in other navigation 
    579       $this->ancestorsInfo = $this->getPagesInfo(false, '( p.lft < ' . $this->lft . ' AND p.rgt > ' . $this->rgt . ' )', true); 
     579      $less = '<'; 
     580      $greater = '>'; 
     581      if ($includeSelf) 
     582      { 
     583        $less = '<='; 
     584        $greater = '>='; 
     585      } 
     586      $this->ancestorsInfo = $this->getPagesInfo(false, "( p.lft $less " . $this->lft . " AND p.rgt $greater " . $this->rgt . ' )', true); 
    580587    } 
    581588    return $this->ancestorsInfo; 
     
    602609      { 
    603610        // It's the home page. Return a stub: the home page is its only peer 
    604         $this->peerInfo = array(array('id' => $this->id, 'title' => $this->getTitle(), 'slug' => $this->slug, 'view_is_secure' => $this->view_is_secure, 'archived' => $this->archived, 'level' => $this->level, 'lft' => $this->lft, 'rgt' => $this->rgt)); 
     611        $this->peerInfo = array($this->getInfo()); 
    605612      } 
    606613      else 
     
    615622  } 
    616623 
     624  // Sometimes it is useful to have an info structure describing a page object 
     625  // (the aNavigation classes exploit this) 
     626   
     627  public function getInfo() 
     628  { 
     629    return array('id' => $this->id, 'title' => $this->getTitle(), 'slug' => $this->slug, 'view_is_secure' => $this->view_is_secure, 'archived' => $this->archived, 'level' => $this->level, 'lft' => $this->lft, 'rgt' => $this->rgt); 
     630  } 
     631   
    617632  protected $childrenInfo; 
    618633   
     
    709724  //   Two 
    710725   
     726  // You can now specify the root slug, which defaults to the home page. 
     727   
    711728  // Note that children of Two, 1a, and 1c are NOT returned. Only the siblings of 
    712729  // the current page's ancestors, the current page and its siblings, and the immediate 
    713730  // children of the current page are returned. For a full tree use getTreeInfo(). 
    714731   
    715   public function getAccordionInfo($livingOnly = true, $depth = null) 
     732  public function getAccordionInfo($livingOnly = true, $depth = null, $root = '/') 
    716733  { 
    717734    // As far as I can tell there is no super-elegant, single-query way to do this 
     
    724741    // an accordion contro. in the first place 
    725742    $ancestors = $this->getAncestorsInfo(); 
     743     
     744    // Dump ancestors we don't care about 
     745    for ($i = 0; ($i < count($ancestors)); $i++) 
     746    { 
     747      if ($ancestors[$i]['slug'] === $root) 
     748      { 
     749        $ancestors = array_slice($ancestors, $i); 
     750        break; 
     751      } 
     752    } 
     753    if ($i === count($ancestors)) 
     754    { 
     755      throw new sfException("Root slug $root never found among ancestors in getAccordionInfo"); 
     756    } 
    726757    $result = array(); 
    727758    // Ancestor levels 
  • plugins/apostrophePlugin/trunk/lib/navigation/aNavigation.class.php

    r826 r1065  
    1313  public static function simulateNewRequest() 
    1414  { 
     15    if (sfConfig::get('app_a_many_pages', false)) 
     16    { 
     17       
     18    } 
    1519    self::$tree = null; 
    1620    self::$hash = null; 
  • plugins/apostrophePlugin/trunk/lib/navigation/aNavigationAccordion.class.php

    r837 r1065  
    44{ 
    55  protected $cssClass = 'a-nav-item';  
    6   public function buildNavigation() 
     6  public function initializeTree() 
    77  { 
    8     $this->rootInfo = parent::$hash[$this->root]; 
    9     $this->activeInfo = parent::$hash[$this->active]; 
    10     if(isset($this->rootInfo['children'])) 
     8    if (sfConfig::get('app_a_many_pages', true)) 
    119    { 
    12       $this->nav = $this->rootInfo['children']; 
     10      // The use of the static sitewide page tree  
     11      // requires too much memory on sites with more 
     12      // than about 500-1000 pages. On smaller sites 
     13      // it turns out to be a performance win to get 
     14      // all of the page information for the site and 
     15      // cache it for subsequent navigation elements on 
     16      // the same page, which the base class does for us 
    1317    } 
    1418    else 
    1519    { 
    16       $this->nav = $this->rootInfo['parent']['children']; 
     20      parent::initializeTree(); 
    1721    } 
     22  } 
     23  public function buildNavigation() 
     24  { 
     25    if (sfConfig::get('app_a_many_pages', true)) 
     26    { 
     27      $activePage = aPageTable::retrieveBySlug($this->active); 
     28      $this->activeInfo = $activePage->getInfo(); 
     29      $this->rootInfo = $activePage->getAccordionInfo(false, null, $this->root); 
     30      // This rootInfo is already an array of kids 
     31      $this->nav = $this->rootInfo; 
     32    } 
     33    else 
     34    { 
     35      $this->rootInfo = parent::$hash[$this->root]; 
     36      $this->activeInfo = parent::$hash[$this->active]; 
     37      // This rootInfo is an individual page info 
     38      $this->nav = $this->rootInfo['children']; 
     39    } 
     40    // We no longer try to special case the situation where the root page has no children, 
     41    // because the active page should always be a descendant of the root page, and it 
     42    // complicated the implementation 
    1843    $this->traverse($this->nav); 
    1944  } 
     
    2651      $this->applyCSS($tree, $node); 
    2752       
    28       if(!self::isAncestor($node, $this->activeInfo) && !($node['id'] == $this->activeInfo['id'])) 
     53      // This is redundant if we used getAccordionInfo, and it won't work because we 
     54      // never set activeInfo or the 'parent' pointers 
     55      if (!sfConfig::get('app_a_many_pages', true)) 
    2956      { 
    30         unset($node['children']); 
     57        if(!self::isAncestor($node, $this->activeInfo) && !($node['id'] == $this->activeInfo['id'])) 
     58        { 
     59          unset($node['children']); 
     60        } 
    3161      } 
    3262       
  • plugins/apostrophePlugin/trunk/lib/navigation/aNavigationBreadcrumb.class.php

    r806 r1065  
    44{ 
    55  protected $cssClass = 'a-nav-item';  
     6  public function initializeTree() 
     7  { 
     8    if (sfConfig::get('app_a_many_pages', true)) 
     9    { 
     10      // The use of the static sitewide page tree  
     11      // requires too much memory on sites with more 
     12      // than about 500-1000 pages. On smaller sites 
     13      // it turns out to be a performance win to get 
     14      // all of the page information for the site and 
     15      // cache it for subsequent navigation elements on 
     16      // the same page, which the base class does for us 
     17    } 
     18    else 
     19    { 
     20      parent::initializeTree(); 
     21    } 
     22  } 
     23   
    624  public function buildNavigation() 
    725  { 
     26    if (sfConfig::get('app_a_many_pages', true)) 
     27    { 
     28      $activePage = aPageTable::retrieveBySlug($this->active); 
     29      // true = include the page itself 
     30      $this->nav = $activePage->getAncestorsInfo(true); 
     31      $i = count($this->nav); 
     32      $info = &$this->nav[$i - 1]; 
     33      if (!isset($info['class'])) 
     34      { 
     35        $info['class'] = ''; 
     36      } 
     37      $info['class'] .= ' a-current-page'; 
     38      return; 
     39    } 
    840    $this->rootInfo = parent::$hash[$this->root]; 
    941    $this->activeInfo = parent::$hash[$this->active]; 
  • plugins/apostrophePlugin/trunk/lib/navigation/aNavigationTabs.class.php

    r826 r1065  
    44{ 
    55  protected $cssClass = 'a-nav-item';  
    6   public function buildNavigation() 
     6  public function initializeTree() 
    77  { 
    8     $this->rootInfo = parent::$hash[$this->root]; 
    9     $this->activeInfo = parent::$hash[$this->active]; 
    10     $this->depth = $this->options['depth']; 
    11      
    12     if(isset($this->rootInfo['children'])) 
     8    if (sfConfig::get('app_a_many_pages', true)) 
    139    { 
    14       $this->nav = $this->rootInfo['children']; 
     10      // The use of the static sitewide page tree  
     11      // requires too much memory on sites with more 
     12      // than about 500-1000 pages. On smaller sites 
     13      // it turns out to be a performance win to get 
     14      // all of the page information for the site and 
     15      // cache it for subsequent navigation elements on 
     16      // the same page, which the base class does for us 
    1517    } 
    1618    else 
    1719    { 
    18       $this->nav = $this->rootInfo['parent']['children']; 
     20      parent::initializeTree(); 
    1921    } 
     22  } 
     23   
     24  public function buildNavigation() 
     25  { 
     26    if (sfConfig::get('app_a_many_pages', true)) 
     27    { 
     28      $activePage = aPageTable::retrieveBySlug($this->active); 
     29      $this->activeInfo = $activePage->getInfo(); 
     30       
     31      $rootPage = aPageTable::retrieveBySlug($this->root); 
     32      $this->rootInfo = $rootPage->getTreeInfo(false, $this->options['depth']); 
     33      // If no kids... 
     34      if (!count($this->rootInfo)) 
     35      { 
     36        // Try the parent 
     37        $rootPage = $rootPage->getParent(); 
     38        if (!$rootPage) 
     39        { 
     40          // Parent does not exist - this is the home page and there are no subpages 
     41          // (unlikely in practice due to admin pages) 
     42          $this->rootInfo = array(); 
     43        } 
     44        else 
     45        { 
     46          // Parent does exist, use its kids 
     47          $this->rootInfo = $rootPage->getTreeInfo(false, $this->options['depth']); 
     48        } 
     49      } 
     50      $this->nav = $this->rootInfo; 
     51    } 
     52    else 
     53    { 
     54      $this->rootInfo = parent::$hash[$this->root]; 
     55      $this->activeInfo = parent::$hash[$this->active]; 
     56      if(isset($this->rootInfo['children'])) 
     57      { 
     58        $this->nav = $this->rootInfo['children']; 
     59      } 
     60      else 
     61      { 
     62        if (!isset($this->rootInfo['parent'])) 
     63        { 
     64          // A site root with no children 
     65          $this->nav = array(); 
     66        } 
     67        else 
     68        { 
     69          $this->nav = $this->rootInfo['parent']['children']; 
     70        } 
     71      } 
     72    } 
     73    $this->depth = $this->options['depth']; 
     74     
    2075    $this->traverse($this->nav); 
    2176  }