silverstripe-cms/code/CMSSiteTreeFilter.php
jean c3b28e34cd BUGFIX Use the default string 'Any' instead of 'All' for class name criteria in search form on CMSMain
At the moment, the only way to get results from the search form is to click "Clear" before adding any criteria, or the search form returns zero results. This is due to the difference between CMSMain#SiteTreeFilterPageTypeField which uses 'Any' as the default value for any classname, while CMSSiteTreeFilter#pagesIncluded expects 'All'. Regression introduced in 9e5af18b5c
2014-02-10 10:01:15 +13:00

177 lines
4.9 KiB
PHP

<?php
/**
* Base class for filtering the subtree for certain node statuses.
*
* The simplest way of building a CMSSiteTreeFilter is to create a pagesToBeShown() method that
* returns an Iterator of maps, each entry containing the 'ID' and 'ParentID' of the pages to be
* included in the tree. The reuslt of a DB::query() can be returned directly.
*
* If you wish to make a more complex tree, you can overload includeInTree($page) to return true/
* false depending on whether the given page should be included. Note that you will need to include
* parent helper pages yourself.
*
* @package cms
* @subpackage content
*/
abstract class CMSSiteTreeFilter extends Object {
protected $ids = null;
protected $expanded = array();
static function showInList() {
return true;
}
function getTree() {
if(method_exists($this, 'pagesIncluded')) {
$this->populateIDs();
}
$leftAndMain = new CMSMain();
$tree = $leftAndMain->getSiteTreeFor('SiteTree', isset($_REQUEST['ID']) ? $_REQUEST['ID'] : 0, null, null, array($this, 'includeInTree'), count($this->ids));
// Trim off the outer tag
$tree = ereg_replace('^[ \t\r\n]*<ul[^>]*>','', $tree);
$tree = ereg_replace('</ul[^>]*>[ \t\r\n]*$','', $tree);
return $tree;
}
/**
* Populate $this->ids with the IDs of the pages returned by pagesIncluded(), also including
* the necessary parent helper pages.
*/
protected function populateIDs() {
if($res = $this->pagesIncluded()) {
/* And keep a record of parents we don't need to get parents of themselves, as well as IDs to mark */
foreach($res as $row) {
if ($row['ParentID']) $parents[$row['ParentID']] = true;
$this->ids[$row['ID']] = true;
}
while (!empty($parents)) {
$res = DB::query('SELECT "ParentID", "ID" FROM "SiteTree" WHERE "ID" in ('.implode(',',array_keys($parents)).')');
$parents = array();
foreach($res as $row) {
if ($row['ParentID']) $parents[$row['ParentID']] = true;
$this->ids[$row['ID']] = true;
$this->expanded[$row['ID']] = true;
}
}
}
}
/**
* Returns true if the given page should be included in the tree.
*/
public function includeInTree($page) {
return isset($this->ids[$page->ID]) && $this->ids[$page->ID] ? true : false;
}
}
/**
* @package cms
* @subpackage content
*/
class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
static function title() {
return _t('CMSSiteTreeFilter.DELETEDPAGES', "All pages, including deleted");
}
function getTree() {
$leftAndMain = new CMSMain();
$tree = $leftAndMain->getSiteTreeFor('SiteTree', isset($_REQUEST['ID']) ? $_REQUEST['ID'] : 0, "AllHistoricalChildren", "numHistoricalChildren");
// Trim off the outer tag
$tree = ereg_replace('^[ \t\r\n]*<ul[^>]*>','', $tree);
$tree = ereg_replace('</ul[^>]*>[ \t\r\n]*$','', $tree);
return $tree;
}
}
/**
* @package cms
* @subpackage content
*/
class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter {
static function title() {
return _t('CMSSiteTreeFilter.CHANGEDPAGES', "Changed pages");
}
function pagesIncluded() {
return DB::query('SELECT "ParentID", "ID" FROM "SiteTree" WHERE "Status" LIKE \'Saved%\'');
}
}
/**
* @package cms
* @subpackage content
*/
class CMSSiteTreeFilter_Search extends CMSSiteTreeFilter {
public $data;
function __construct() {
$this->data = $_REQUEST;
}
static function showInList() { return false; }
static function title() {
return _t('CMSSiteTreeFilter.SEARCH', 'Search');
}
/**
* Retun an array of maps containing the keys, 'ID' and 'ParentID' for each page to be displayed
* in the search.
*/
function pagesIncluded() {
$data = $this->data;
$this->ids = array();
$this->expanded = array();
$where = array();
// Match against URLSegment, Title, MenuTitle & Content
if (isset($data['SiteTreeSearchTerm'])) {
$term = Convert::raw2sql($data['SiteTreeSearchTerm']);
$where[] = "\"URLSegment\" LIKE '%$term%' OR \"Title\" LIKE '%$term%' OR \"MenuTitle\" LIKE '%$term%' OR \"Content\" LIKE '%$term%'";
}
// Match against date
if (isset($data['SiteTreeFilterDate'])) {
$date = $data['SiteTreeFilterDate'];
$date = ((int)substr($date,6,4)) . '-' . ((int)substr($date,3,2)) . '-' . ((int)substr($date,0,2));
$where[] = "\"LastEdited\" > '$date'";
}
// Match against exact ClassName
if (isset($data['ClassName']) && $data['ClassName'] != 'Any') {
$klass = Convert::raw2sql($data['ClassName']);
$where[] = "\"ClassName\" = '$klass'";
}
// Partial string match against a variety of fields
foreach (CMSMain::T_SiteTreeFilterOptions() as $key => $value) {
if (!empty($data[$key])) {
$match = Convert::raw2sql($data[$key]);
$where[] = "\"$key\" LIKE '%$match%'";
}
}
$where = empty($where) ? '' : 'WHERE (' . implode(') AND (',$where) . ')';
$parents = array();
/* Do the actual search */
$res = DB::query('SELECT "ParentID", "ID" FROM "SiteTree" '.$where);
return $res;
}
}