mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
ENHANCEMENT Unifying tree logic in most LeftAndMain subclasses: CMSMain, SecurityAdmin, AssetAdmin. Using a common LeftAndMainMarkingFilter. Allowing for custom node counts in SecurityAdmin and AssetAdmin.
API CHANGE Renamed CMSMain->getfilteredsubtree() to doSearchTree() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92848 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
1bc268e287
commit
9c3ecea1e7
@ -256,58 +256,14 @@ HTML;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the entire site tree as a nested UL.
|
|
||||||
* @return string HTML for site tree
|
|
||||||
*/
|
|
||||||
public function SiteTreeAsUL() {
|
public function SiteTreeAsUL() {
|
||||||
$obj = singleton('Folder');
|
return $this->getSiteTreeFor($this->stat('tree_class'), null, 'ChildFolders');
|
||||||
$obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
|
|
||||||
$obj->markPartialTree(30, null, "ChildFolders");
|
|
||||||
|
|
||||||
if($p = $this->currentPage()) $obj->markToExpose($p);
|
|
||||||
|
|
||||||
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
|
||||||
$siteTreeList = $obj->getChildrenAsUL(
|
|
||||||
'',
|
|
||||||
'"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
|
||||||
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" class=\"" . ($child->hasChildFolders() ? " contents" : "") . "\" >" . $child->TreeTitle . "</a>" ',
|
|
||||||
$this,
|
|
||||||
true,
|
|
||||||
"ChildFolders"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Wrap the root if needs be
|
|
||||||
$rootLink = $this->Link() . 'show/root';
|
|
||||||
$baseUrl = Director::absoluteBaseURL() . "assets";
|
|
||||||
if(!isset($rootID)) {
|
|
||||||
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-root\" class=\"Root\"><a href=\"$rootLink\"><strong>{$baseUrl}</strong></a>"
|
|
||||||
. $siteTreeList . "</li></ul>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $siteTree;
|
public function getCMSTreeTitle() {
|
||||||
|
return Director::absoluteBaseURL() . "assets";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a subtree of items underneat the given folder.
|
|
||||||
*/
|
|
||||||
public function getsubtree() {
|
|
||||||
$obj = DataObject::get_by_id('Folder', $_REQUEST['ID']);
|
|
||||||
$obj->setMarkingFilter('ClassName', ClassInfo::subclassesFor('Folder'));
|
|
||||||
$obj->markPartialTree();
|
|
||||||
|
|
||||||
$results = $obj->getChildrenAsUL(
|
|
||||||
'',
|
|
||||||
'"<li id=\"record-$child->ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
|
||||||
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle . "</a>" ',
|
|
||||||
$this,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
return substr(trim($results), 4, -5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
// Data saving handlers
|
// Data saving handlers
|
||||||
@ -319,7 +275,8 @@ HTML;
|
|||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
'SyncForm',
|
'SyncForm',
|
||||||
new FieldSet(),
|
new FieldSet(
|
||||||
|
),
|
||||||
new FieldSet(
|
new FieldSet(
|
||||||
$btn = new FormAction('doSync', _t('FILESYSTEMSYNC','Look for new files'))
|
$btn = new FormAction('doSync', _t('FILESYSTEMSYNC','Look for new files'))
|
||||||
)
|
)
|
||||||
|
@ -50,7 +50,6 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
|||||||
'AddForm',
|
'AddForm',
|
||||||
'SiteTreeAsUL',
|
'SiteTreeAsUL',
|
||||||
'getshowdeletedsubtree',
|
'getshowdeletedsubtree',
|
||||||
'getfilteredsubtree',
|
|
||||||
'SearchTreeForm',
|
'SearchTreeForm',
|
||||||
'ReportForm',
|
'ReportForm',
|
||||||
'LangForm',
|
'LangForm',
|
||||||
@ -132,30 +131,11 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
|||||||
Versioned::prepopulate_versionnumber_cache("SiteTree", "Stage");
|
Versioned::prepopulate_versionnumber_cache("SiteTree", "Stage");
|
||||||
Versioned::prepopulate_versionnumber_cache("SiteTree", "Live");
|
Versioned::prepopulate_versionnumber_cache("SiteTree", "Live");
|
||||||
|
|
||||||
return $this->getSiteTreeFor("SiteTree");
|
return $this->getSiteTreeFor($this->stat('tree_class'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function getMarkingFilter($params) {
|
||||||
* Use a CMSSiteTreeFilter to only get certain nodes
|
return new CMSMainMarkingFilter($params);
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getfilteredsubtree($data, $form) {
|
|
||||||
$params = $form->getData();
|
|
||||||
|
|
||||||
// Get the tree
|
|
||||||
$tree = $this->getSiteTreeFor(
|
|
||||||
$this->stat('tree_class'),
|
|
||||||
$data['ID'],
|
|
||||||
null,
|
|
||||||
array(new CMSMainMarkingFilter($params), 'mark')
|
|
||||||
);
|
|
||||||
|
|
||||||
// Trim off the outer tag
|
|
||||||
$tree = ereg_replace('^[ \t\r\n]*<ul[^>]*>','', $tree);
|
|
||||||
$tree = ereg_replace('</ul[^>]*>[ \t\r\n]*$','', $tree);
|
|
||||||
|
|
||||||
return $tree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateDataTreeHints() {
|
public function generateDataTreeHints() {
|
||||||
@ -186,7 +166,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function generateTreeStylingJS() {
|
public function generateTreeStylingJS() {
|
||||||
$classes = ClassInfo::subclassesFor('SiteTree');
|
$classes = ClassInfo::subclassesFor($this->stat('tree_class'));
|
||||||
foreach($classes as $class) {
|
foreach($classes as $class) {
|
||||||
$obj = singleton($class);
|
$obj = singleton($class);
|
||||||
if($obj instanceof HiddenClass) continue;
|
if($obj instanceof HiddenClass) continue;
|
||||||
@ -1114,7 +1094,7 @@ JS;
|
|||||||
_t('CMSMain_left.ss.CLEAR', 'Clear')
|
_t('CMSMain_left.ss.CLEAR', 'Clear')
|
||||||
),
|
),
|
||||||
new FormAction(
|
new FormAction(
|
||||||
'getfilteredsubtree',
|
'doSearchTree',
|
||||||
_t('CMSMain_left.ss.SEARCH', 'Search')
|
_t('CMSMain_left.ss.SEARCH', 'Search')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1124,6 +1104,10 @@ JS;
|
|||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doSearchTree($data, $form) {
|
||||||
|
return $this->getsubtree($this->request);
|
||||||
|
}
|
||||||
|
|
||||||
function publishall() {
|
function publishall() {
|
||||||
ini_set("memory_limit", -1);
|
ini_set("memory_limit", -1);
|
||||||
ini_set('max_execution_time', 0);
|
ini_set('max_execution_time', 0);
|
||||||
@ -1357,24 +1341,12 @@ JS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CMSMainMarkingFilter {
|
class CMSMainMarkingFilter extends LeftAndMainMarkingFilter{
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array Request params (unsanitized)
|
|
||||||
*/
|
|
||||||
protected $params = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $params Request params (unsanitized)
|
|
||||||
*/
|
|
||||||
function __construct($params = null) {
|
|
||||||
$this->ids = array();
|
|
||||||
$this->expanded = array();
|
|
||||||
$this->params = $params;
|
|
||||||
|
|
||||||
|
protected function getQuery($params) {
|
||||||
$where = array();
|
$where = array();
|
||||||
|
|
||||||
$SQL_params = Convert::raw2sql($this->params);
|
$SQL_params = Convert::raw2sql($params);
|
||||||
foreach($SQL_params as $name => $val) {
|
foreach($SQL_params as $name => $val) {
|
||||||
switch($name) {
|
switch($name) {
|
||||||
// Match against URLSegment, Title, MenuTitle & Content
|
// Match against URLSegment, Title, MenuTitle & Content
|
||||||
@ -1402,38 +1374,13 @@ class CMSMainMarkingFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$where = empty($where) ? '' : 'WHERE (' . implode(') AND (',$where) . ')';
|
return new SQLQuery(
|
||||||
|
array("ParentID", "ID"),
|
||||||
$parents = array();
|
'SiteTree',
|
||||||
|
$where
|
||||||
/* Do the actual search */
|
);
|
||||||
$res = DB::query('SELECT "ParentID", "ID" FROM "SiteTree" '.$where);
|
|
||||||
if (!$res) return;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to recurse up the tree, finding ParentIDs for each ID until we run out of parents */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mark($node) {
|
|
||||||
$id = $node->ID;
|
|
||||||
if(array_key_exists((int) $id, $this->expanded)) $node->markOpened();
|
|
||||||
return array_key_exists((int) $id, $this->ids) ? $this->ids[$id] : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -452,6 +452,10 @@ class LeftAndMain extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function SiteTreeAsUL() {
|
||||||
|
return $this->getSiteTreeFor($this->stat('tree_class'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a site tree displaying the nodes under the given objects.
|
* Get a site tree displaying the nodes under the given objects.
|
||||||
*
|
*
|
||||||
@ -498,7 +502,6 @@ class LeftAndMain extends Controller {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Wrap the root if needs be.
|
// Wrap the root if needs be.
|
||||||
|
|
||||||
if(!$rootID) {
|
if(!$rootID) {
|
||||||
$rootLink = '#';
|
$rootLink = '#';
|
||||||
|
|
||||||
@ -518,14 +521,12 @@ class LeftAndMain extends Controller {
|
|||||||
* If ID = 0, then get the whole tree.
|
* If ID = 0, then get the whole tree.
|
||||||
*/
|
*/
|
||||||
public function getsubtree($request) {
|
public function getsubtree($request) {
|
||||||
// Get the tree
|
|
||||||
$minNodeCount = (is_numeric($request->getVar('minNodeCount'))) ? $request->getVar('minNodeCount') : NULL;
|
|
||||||
$tree = $this->getSiteTreeFor(
|
$tree = $this->getSiteTreeFor(
|
||||||
$this->stat('tree_class'),
|
$this->stat('tree_class'),
|
||||||
$request->getVar('ID'),
|
$request->getVar('ID'),
|
||||||
null,
|
null,
|
||||||
null,
|
array($this->getMarkingFilter($request->requestVars()), 'mark'),
|
||||||
$minNodeCount
|
$request->getVar('minNodeCount')
|
||||||
);
|
);
|
||||||
|
|
||||||
// Trim off the outer tag
|
// Trim off the outer tag
|
||||||
@ -535,6 +536,14 @@ class LeftAndMain extends Controller {
|
|||||||
return $tree;
|
return $tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $params
|
||||||
|
* @return LeftAndMainMarkingFilter
|
||||||
|
*/
|
||||||
|
protected function getMarkingFilter($params) {
|
||||||
|
return new LeftAndMainMarkingFilter($params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save handler
|
* Save handler
|
||||||
*/
|
*/
|
||||||
@ -1217,4 +1226,72 @@ JS;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LeftAndMainMarkingFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Request params (unsanitized)
|
||||||
|
*/
|
||||||
|
protected $params = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $params Request params (unsanitized)
|
||||||
|
*/
|
||||||
|
function __construct($params = null) {
|
||||||
|
$this->ids = array();
|
||||||
|
$this->expanded = array();
|
||||||
|
$parents = array();
|
||||||
|
|
||||||
|
$q = $this->getQuery($params);
|
||||||
|
$res = $q->execute();
|
||||||
|
if (!$res) return;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to recurse up the tree,
|
||||||
|
// finding ParentIDs for each ID until we run out of parents
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getQuery($params) {
|
||||||
|
$where = array();
|
||||||
|
|
||||||
|
$SQL_params = Convert::raw2sql($params);
|
||||||
|
if(isset($SQL_params['ID'])) unset($SQL_params['ID']);
|
||||||
|
foreach($SQL_params as $name => $val) {
|
||||||
|
switch($name) {
|
||||||
|
default:
|
||||||
|
// Partial string match against a variety of fields
|
||||||
|
if(!empty($val) && singleton("SiteTree")->hasDatabaseField($name)) {
|
||||||
|
$where[] = "\"$name\" LIKE '%$val%'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SQLQuery(
|
||||||
|
array("ParentID", "ID"),
|
||||||
|
'SiteTree',
|
||||||
|
$where
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mark($node) {
|
||||||
|
$id = $node->ID;
|
||||||
|
if(array_key_exists((int) $id, $this->expanded)) $node->markOpened();
|
||||||
|
return array_key_exists((int) $id, $this->ids) ? $this->ids[$id] : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
?>
|
?>
|
@ -183,34 +183,8 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
|||||||
return FormResponse::respond();
|
return FormResponse::respond();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function getCMSTreeTitle() {
|
||||||
* Return the entire site tree as a nested set of ULs.
|
return _t('SecurityAdmin.SGROUPS', 'Security Groups');
|
||||||
* @return string Unordered list <UL> HTML
|
|
||||||
*/
|
|
||||||
public function SiteTreeAsUL() {
|
|
||||||
$obj = singleton($this->stat('tree_class'));
|
|
||||||
$obj->markPartialTree();
|
|
||||||
|
|
||||||
if($p = $this->currentPage()) $obj->markToExpose($p);
|
|
||||||
|
|
||||||
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
|
||||||
$siteTreeList = $obj->getChildrenAsUL(
|
|
||||||
'',
|
|
||||||
'"<li id=\"record-$child->ID\" class=\"$child->class " . ($child->Locked ? " nodelete" : "") . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
|
||||||
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle . "</a>" ',
|
|
||||||
$this,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// Wrap the root if needs be
|
|
||||||
$rootLink = $this->Link() . 'show/root';
|
|
||||||
$rootTitle = _t('SecurityAdmin.SGROUPS', 'Security Groups');
|
|
||||||
if(!isset($rootID)) {
|
|
||||||
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-root\" class=\"Root\"><a href=\"$rootLink\"><strong>{$rootTitle}</strong></a>"
|
|
||||||
. $siteTreeList . "</li></ul>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $siteTree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function EditedMember() {
|
public function EditedMember() {
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set new URL
|
// Set new URL
|
||||||
$('#sitetree')[0].setCustomURL(this.attr('action') + '&action_getfilteredsubtree=1', data);
|
$('#sitetree')[0].setCustomURL(this.attr('action') + '&action_doSearchTree=1', data);
|
||||||
|
|
||||||
// Disable checkbox tree controls that currently don't work with search.
|
// Disable checkbox tree controls that currently don't work with search.
|
||||||
// @todo: Make them work together
|
// @todo: Make them work together
|
||||||
@ -91,7 +91,7 @@
|
|||||||
// disable buttons to avoid multiple submission
|
// disable buttons to avoid multiple submission
|
||||||
//this.find(':submit').attr('disabled', true);
|
//this.find(':submit').attr('disabled', true);
|
||||||
|
|
||||||
this.find(':submit[name=action_getfilteredsubtree]').addClass('loading');
|
this.find(':submit[name=action_doSearchTree]').addClass('loading');
|
||||||
|
|
||||||
this._reloadSitetree();
|
this._reloadSitetree();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user