Version: current

      1 <?php
      2 /**
      3  * Base class for filtering the subtree for certain node statuses.
      4  *
      5  * The simplest way of building a CMSSiteTreeFilter is to create a pagesToBeShown() method that
      6  * returns an Iterator of maps, each entry containing the 'ID' and 'ParentID' of the pages to be
      7  * included in the tree.  The reuslt of a DB::query() can be returned directly.
      8  *
      9  * If you wish to make a more complex tree, you can overload includeInTree($page) to return true/
     10  * false depending on whether the given page should be included.  Note that you will need to include
     11  * parent helper pages yourself.
     12  *
     13  * @package cms
     14  * @subpackage content
     15  */
     16 abstract class CMSSiteTreeFilter extends SS_Object {
     17
     18     protected $ids = null;
     19     protected $expanded = array();
     20
     21     static function showInList() {
     22         return true;
     23     }
     24
     25     function getTree() {
     26         if(method_exists($this, 'pagesIncluded')) {
     27             $this->populateIDs();
     28         }
     29
     30         $leftAndMain = new CMSMain();
     31         $tree = $leftAndMain->getSiteTreeFor('SiteTree', isset($_REQUEST['ID']) ? $_REQUEST['ID'] : 0, null, null, array($this, 'includeInTree'), count($this->ids));
     32
     33         // Trim off the outer tag
     34         $tree = preg_replace('!^[ \t\r\n]*<ul[^>]*>!','', $tree);
     35         $tree = preg_replace('!</ul[^>]*>[ \t\r\n]*$!','', $tree);
     36
     37         return $tree;
     38     }
     39
     40     /**
     41      * Populate $this->ids with the IDs of the pages returned by pagesIncluded(), also including
     42      * the necessary parent helper pages.
     43      */
     44     protected function populateIDs() {
     45         if($res = $this->pagesIncluded()) {
     46
     47             /* And keep a record of parents we don't need to get parents of themselves, as well as IDs to mark */
     48             foreach($res as $row) {
     49                 if ($row['ParentID']) $parents[$row['ParentID']] = true;
     50                 $this->ids[$row['ID']] = true;
     51             }
     52
     53
     54             while (!empty($parents)) {
     55                 $res = DB::query('SELECT "ParentID", "ID" FROM "SiteTree" WHERE "ID" in ('.implode(',',array_keys($parents)).')');
     56                 $parents = array();
     57
     58                 foreach($res as $row) {
     59                     if ($row['ParentID']) $parents[$row['ParentID']] = true;
     60                     $this->ids[$row['ID']] = true;
     61                     $this->expanded[$row['ID']] = true;
     62                 }
     63             }
     64         }
     65     }
     66
     67     /**
     68      * Returns true if the given page should be included in the tree.
     69      */
     70     public function includeInTree($page) {
     71         return isset($this->ids[$page->ID]) && $this->ids[$page->ID] ? true : false;
     72     }
     73
     74 }
     75
     76 /**
     77  * @package cms
     78  * @subpackage content
     79  */
     80 class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
     81     static function title() {
     82         return _t('CMSSiteTreeFilter.DELETEDPAGES', "All pages, including deleted");
     83     }
     84
     85     function getTree() {
     86         $leftAndMain = new CMSMain();
     87         $tree = $leftAndMain->getSiteTreeFor('SiteTree', isset($_REQUEST['ID']) ? $_REQUEST['ID'] : 0, "AllHistoricalChildren", "numHistoricalChildren");
     88
     89         // Trim off the outer tag
     90         $tree = preg_replace('!^[ \t\r\n]*<ul[^>]*>!','', $tree);
     91         $tree = preg_replace('!</ul[^>]*>[ \t\r\n]*$!','', $tree);
     92
     93         return $tree;
     94     }
     95 }
     96
     97 /**
     98  * @package cms
     99  * @subpackage content
    100  */
    101 class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter {
    102     static function title() {
    103         return _t('CMSSiteTreeFilter.CHANGEDPAGES', "Changed pages");
    104     }
    105
    106     function pagesIncluded() {
    107         return DB::query('SELECT "ParentID", "ID" FROM "SiteTree" WHERE "Status" LIKE \'Saved%\'');
    108     }
    109 }
    110
    111 /**
    112  * @package cms
    113  * @subpackage content
    114  */
    115 class CMSSiteTreeFilter_Search extends CMSSiteTreeFilter {
    116     public $data;
    117
    118
    119     function __construct() {
    120         $this->data = $_REQUEST;
    121     }
    122
    123     static function showInList() { return false; }
    124
    125     static function title() {
    126         return _t('CMSSiteTreeFilter.SEARCH', 'Search');
    127     }
    128
    129     /**
    130      * Retun an array of maps containing the keys, 'ID' and 'ParentID' for each page to be displayed
    131      * in the search.
    132      */
    133     function pagesIncluded() {
    134         $data = $this->data;
    135
    136         $this->ids = array();
    137         $this->expanded = array();
    138
    139         $where = array();
    140
    141         // Match against URLSegment, Title, MenuTitle & Content
    142         if (isset($data['SiteTreeSearchTerm'])) {
    143             $term = Convert::raw2sql($data['SiteTreeSearchTerm']);
    144             $where[] = "\"URLSegment\" LIKE '%$term%' OR \"Title\" LIKE '%$term%' OR \"MenuTitle\" LIKE '%$term%' OR \"Content\" LIKE '%$term%'";
    145         }
    146
    147         // Match against date
    148         if (isset($data['SiteTreeFilterDate'])) {
    149             $date = $data['SiteTreeFilterDate'];
    150             $date = ((int)substr($date,6,4)) . '-' . ((int)substr($date,3,2)) . '-' . ((int)substr($date,0,2));
    151             $where[] = "\"LastEdited\" > '$date'";
    152         }
    153
    154         // Match against exact ClassName
    155         if (isset($data['ClassName']) && $data['ClassName'] != 'All') {
    156             $klass = Convert::raw2sql($data['ClassName']);
    157             $where[] = "\"ClassName\" = '$klass'";
    158         }
    159
    160         // Partial string match against a variety of fields
    161         foreach (CMSMain::T_SiteTreeFilterOptions() as $key => $value) {
    162             if (!empty($data[$key])) {
    163                 $match = Convert::raw2sql($data[$key]);
    164                 $where[] = "\"$key\" LIKE '%$match%'";
    165             }
    166         }
    167
    168         $where = empty($where) ? '' : 'WHERE (' . implode(') AND (',$where) . ')';
    169
    170         $parents = array();
    171
    172         /* Do the actual search */
    173         $res = DB::query('SELECT "ParentID", "ID" FROM "SiteTree" '.$where);
    174         return $res;
    175     }
    176 }
    177

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -