mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
FEATURE Added CMSMenu and CMSMenuItem and adjusted existing LeftAndMain subclasses to use new notation.See #2872 (thanks to hamish for the patch!)
API CHANGE Removed LeftAndMain::add_menu_item(), LeftAndMain::remove_menu_item(), LeftAndMain::replace_menu_item(), LeftAndMain::clear_menu() MINOR Disabled LeftAndMainTest, now covered by CMSMenuTest git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@65095 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
1cb3bbd8b2
commit
2cdf57053f
26
_config.php
26
_config.php
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* URL rules for the CMS module
|
||||
* Extended URL rules for the CMS module
|
||||
*
|
||||
* @package cms
|
||||
*/
|
||||
@ -8,31 +8,21 @@ Director::addRules(50, array(
|
||||
'processes//$Action/$ID/$Batch' => 'BatchProcess_Controller',
|
||||
'silverstripe' => '->admin',
|
||||
'cms' => '->admin',
|
||||
'admin/security//$Action/$ID/$OtherID' => 'SecurityAdmin',
|
||||
'admin/help//$Action/$ID' => 'CMSHelp',
|
||||
'admin/reports//$Action/$ID' => 'ReportAdmin',
|
||||
'admin/assets//$Action/$ID' => 'AssetAdmin',
|
||||
'admin/comments//$Action' => 'CommentAdmin',
|
||||
'admin/ReportField//$Action/$ID/$Type/$OtherID' => 'ReportField_Controller',
|
||||
'admin/bulkload//$Action/$ID/$OtherID' => 'BulkLoaderAdmin',
|
||||
'admin//ImageEditor/$Action' => 'ImageEditor',
|
||||
'admin/cms//$Action/$ID/$OtherID' => 'CMSMain',
|
||||
'admin//$Action/$ID/$OtherID' => 'CMSMain',
|
||||
'admin/cms//$Action/$ID/$OtherID' => 'CMSMain',
|
||||
'PageComment//$Action/$ID' => 'PageComment_Controller',
|
||||
'dev/buildcache' => 'RebuildStaticCacheTask',
|
||||
));
|
||||
|
||||
// Built-in modules
|
||||
LeftAndMain::populate_default_menu();
|
||||
CMSMenu::populate_menu();
|
||||
|
||||
// If there are reports, add the ReportAdmin tab in CMS
|
||||
if(ReportAdmin::has_reports()) {
|
||||
LeftAndMain::add_menu_item(
|
||||
'reports',
|
||||
_t('LeftAndMain.REPORTS', 'Reports', PR_HIGH, 'Menu title'),
|
||||
'admin/reports/',
|
||||
'ReportAdmin'
|
||||
);
|
||||
}
|
||||
CMSMenu::add_link(
|
||||
'Help',
|
||||
_t('LeftAndMain.HELP', 'Help', PR_HIGH, 'Menu title'),
|
||||
'http://userhelp.silverstripe.com'
|
||||
);
|
||||
|
||||
?>
|
||||
|
@ -8,6 +8,12 @@
|
||||
*/
|
||||
class AssetAdmin extends LeftAndMain {
|
||||
|
||||
static $url_segment = 'assets';
|
||||
|
||||
static $url_rule = '/$Action/$ID';
|
||||
|
||||
static $menu_title = 'Files & Images';
|
||||
|
||||
public static $tree_class = "File";
|
||||
|
||||
/**
|
||||
@ -39,8 +45,8 @@ class AssetAdmin extends LeftAndMain {
|
||||
'deleteUnusedThumbnails' => 'ADMIN'
|
||||
);
|
||||
|
||||
public function Link($action = null) {
|
||||
return "admin/assets/$action";
|
||||
public function getMenuTitle() {
|
||||
return _t('LeftAndMain.ASSETS', 'Files & Images', PR_HIGH, 'Menu title');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,18 @@
|
||||
*/
|
||||
class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionProvider {
|
||||
|
||||
static $url_segment = '';
|
||||
|
||||
static $url_rule = '/$Action/$ID/$OtherID';
|
||||
|
||||
// Maintain a lower priority than other administration sections
|
||||
// so that Director does not think they are actions of CMSMain
|
||||
static $url_priority = 40;
|
||||
|
||||
static $menu_title = 'Site Content';
|
||||
|
||||
static $menu_priority = 10;
|
||||
|
||||
static $tree_class = "SiteTree";
|
||||
|
||||
static $subitem_class = "Member";
|
||||
@ -90,6 +102,10 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
Requirements::javascript('gallery/javascript/GalleryPage_CMS.js');
|
||||
}
|
||||
|
||||
public function getMenuTitle() {
|
||||
return _t('LeftAndMain.CMSMAIN', 'Site Content', PR_HIGH, 'Menu title');
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is set to true, the "switchView" context in the
|
||||
* template is shown, with links to the staging and publish site.
|
||||
@ -483,10 +499,6 @@ JS;
|
||||
return $newItem;
|
||||
}
|
||||
|
||||
public function Link($action = null) {
|
||||
return "admin/$action";
|
||||
}
|
||||
|
||||
public function deletefromlive($urlParams, $form) {
|
||||
$id = $_REQUEST['ID'];
|
||||
Versioned::reading_stage('Live');
|
||||
|
202
code/CMSMenu.php
Normal file
202
code/CMSMenu.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* The object manages the main CMS menu
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSMenu extends Object implements Iterator
|
||||
{
|
||||
|
||||
protected static $menu_items = array();
|
||||
|
||||
/**
|
||||
* Generate CMS main menu items by collecting valid
|
||||
* subclasses of {@link LeftAndMain}
|
||||
*/
|
||||
public static function populate_menu() {
|
||||
$cmsClasses = self::get_cms_classes();
|
||||
foreach($cmsClasses as $cmsClass) {
|
||||
self::add_controller($cmsClass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a LeftAndMain controller to the CMS menu.
|
||||
*
|
||||
* @param string $controllerClass The class name of the controller
|
||||
* @return The result of the operation
|
||||
* @todo A director rule is added when a controller link is added, but it won't be removed
|
||||
* when the item is removed. Functionality needed in {@link Director}.
|
||||
*/
|
||||
public static function add_controller($controllerClass) {
|
||||
$controller = singleton($controllerClass);
|
||||
Director::addRules($controller->stat('url_priority', true),
|
||||
array(Controller::join_links($controller->Link(), $controller->stat('url_rule', true)) => $controllerClass)
|
||||
);
|
||||
return self::add_menu_item(
|
||||
$controllerClass,
|
||||
$controller->getMenuTitle(),
|
||||
$controller->Link(),
|
||||
$controllerClass,
|
||||
$controller->stat('menu_priority')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an arbitrary URL to the CMS menu.
|
||||
*
|
||||
* @param string $code A unique identifier (used to create a CSS ID and as it's key in {@link $menu_items}
|
||||
* @param string $menuTitle The link's title in the CMS menu
|
||||
* @param string $url The url of the link
|
||||
* @param integer $priority The menu priority (sorting order) of the menu item
|
||||
* @return boolean The result of the operation.
|
||||
*/
|
||||
public static function add_link($code, $menuTitle, $url, $priority = -1) {
|
||||
return self::add_menu_item($code, $menuTitle, $url, null, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a navigation item to the main administration menu showing in the top bar.
|
||||
*
|
||||
* @uses {@link CMSMenu::$menu_items}
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
|
||||
* {@link remove_menu_item}. Also used as a CSS-class for icon customization.
|
||||
* @param string $menuTitle Localized title showing in the menu bar
|
||||
* @param string $url A relative URL that will be linked in the menu bar.
|
||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||
* If blank, it's assumed that this is public, and always shown to users who
|
||||
* have the rights to access some other part of the admin area.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1) {
|
||||
$menuItems = self::$menu_items;
|
||||
|
||||
if(isset($menuItems[$code])) return false;
|
||||
|
||||
return self::replace_menu_item($code, $menuTitle, $url, $controllerClass, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single menu item by its code value.
|
||||
*
|
||||
* @param string $code
|
||||
* @return array
|
||||
*/
|
||||
public static function get_menu_item($code) {
|
||||
$menuItems = self::$menu_items;
|
||||
return (isset($menuItems[$code])) ? $menuItems[$code] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all menu entries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_menu_items() {
|
||||
return self::$menu_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing item from the menu.
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item
|
||||
*/
|
||||
public static function remove_menu_item($code) {
|
||||
$menuItems = self::$menu_items;
|
||||
if(isset($menuItems[$code])) unset($menuItems[$code]);
|
||||
// replace the whole array
|
||||
self::$menu_items = $menuItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the entire menu
|
||||
*
|
||||
*/
|
||||
public static function clear_menu() {
|
||||
self::$menu_items = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a navigation item to the main administration menu showing in the top bar.
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
|
||||
* {@link remove_menu_item}. Also used as a CSS-class for icon customization.
|
||||
* @param string $menuTitle Localized title showing in the menu bar
|
||||
* @param string $url A relative URL that will be linked in the menu bar.
|
||||
* Make sure to add a matching route via {@link Director::addRules()} to this url.
|
||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||
* If blank, it's assumed that this is public, and always shown to users who
|
||||
* have the rights to access some other part of the admin area.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1) {
|
||||
$menuItems = self::$menu_items;
|
||||
$menuItems[$code] = new CMSMenuItem($menuTitle, $url, $controllerClass, $priority);
|
||||
foreach($menuItems as $key => $menuItem) {
|
||||
$menuPriority[$key] = $menuItem->priority;
|
||||
}
|
||||
array_multisort($menuPriority, SORT_DESC, $menuItems);
|
||||
|
||||
self::$menu_items = $menuItems;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility funciton to retrieve subclasses of a given class that
|
||||
* are instantiable (ie, not abstract) and have a valid menu title.
|
||||
*
|
||||
* @todo A variation of this function could probably be moved to {@link ClassInfo}
|
||||
* @param string $root The root class to begin finding subclasses
|
||||
* @param boolean $recursive Look for subclasses recursively?
|
||||
* @return array Valid, unique subclasses
|
||||
*/
|
||||
public static function get_cms_classes($root = 'LeftAndMain', $recursive = true) {
|
||||
$subClasses = array_values(ClassInfo::subclassesFor($root));
|
||||
foreach($subClasses as $className) {
|
||||
if($recursive && $className != $root) {
|
||||
$subClasses = array_merge($subClasses, array_values(ClassInfo::subclassesFor($className)));
|
||||
}
|
||||
}
|
||||
$subClasses = array_unique($subClasses);
|
||||
foreach($subClasses as $key => $className) {
|
||||
// Test that the class is not abstract and it has a valid menu title
|
||||
$classReflection = new ReflectionClass($className);
|
||||
if(!$classReflection->isInstantiable()) {
|
||||
unset($subClasses[$key]);
|
||||
} else {
|
||||
if(singleton($className)->getMenuTitle() == '') {
|
||||
unset($subClasses[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $subClasses;
|
||||
}
|
||||
|
||||
// Iterator Interface Methods
|
||||
public function key() {
|
||||
return key(self::$menu_items);
|
||||
}
|
||||
|
||||
public function current() {
|
||||
return current(self::$menu_items);
|
||||
}
|
||||
|
||||
public function next() {
|
||||
return next(self::$menu_items);
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
return reset(self::$menu_items);
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
return (bool)self::current();
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
49
code/CMSMenuItem.php
Normal file
49
code/CMSMenuItem.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* A simple CMS menu item
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSMenuItem extends Object
|
||||
{
|
||||
/**
|
||||
* The (translated) menu title
|
||||
* @var string $title
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* Relative URL
|
||||
* @var string $url
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* Parent controller class name
|
||||
* @var string $controller
|
||||
*/
|
||||
public $controller;
|
||||
|
||||
/**
|
||||
* Menu priority (sort order)
|
||||
* @var integer $priority
|
||||
*/
|
||||
public $priority;
|
||||
|
||||
/**
|
||||
* Create a new CMS Menu Item
|
||||
* @param string $title
|
||||
* @param string $url
|
||||
* @param string $controller Controller class name
|
||||
* @param integer $priority The sort priority of the item
|
||||
*/
|
||||
public function __construct($title, $url, $controller = null, $priority = -1) {
|
||||
$this->title = $title;
|
||||
$this->url = $url;
|
||||
$this->controller = $controller;
|
||||
$this->priority = $priority;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
@ -5,6 +5,13 @@
|
||||
* @subpackage comments
|
||||
*/
|
||||
class CommentAdmin extends LeftAndMain {
|
||||
|
||||
static $url_segment = 'comments';
|
||||
|
||||
static $url_rule = '/$Action';
|
||||
|
||||
static $menu_title = 'Comments';
|
||||
|
||||
static $allowed_actions = array(
|
||||
'approvedmarked',
|
||||
'deleteall',
|
||||
@ -22,9 +29,9 @@ class CommentAdmin extends LeftAndMain {
|
||||
Requirements::css(CMS_DIR . 'css/CommentAdmin.css');
|
||||
}
|
||||
|
||||
public function Link($action = null) {
|
||||
return "admin/comments/$action";
|
||||
}
|
||||
public function getMenuTitle() {
|
||||
return _t('LeftAndMain.COMMENTS', 'Comments', PR_HIGH, 'Menu title');
|
||||
}
|
||||
|
||||
public function showtable($params) {
|
||||
return $this->getLastFormIn($this->renderWith('CommentAdmin_right'));
|
||||
|
@ -11,15 +11,26 @@
|
||||
*/
|
||||
class LeftAndMain extends Controller {
|
||||
|
||||
static $tree_class = null;
|
||||
|
||||
/**
|
||||
* Default menu items for the core cms functionality,
|
||||
* set in cms/_config.php.
|
||||
* The 'base' url for CMS administration areas.
|
||||
* Note that if this is changed, many javascript
|
||||
* behaviours need to be updated with the correct url
|
||||
*
|
||||
* @var array
|
||||
* @var string $url_base
|
||||
*/
|
||||
protected static $menu_items = array();
|
||||
protected static $url_base = "admin";
|
||||
|
||||
static $url_segment;
|
||||
|
||||
static $url_rule;
|
||||
|
||||
static $menu_title;
|
||||
|
||||
static $menu_priority = 0;
|
||||
|
||||
static $url_priority = 50;
|
||||
|
||||
static $tree_class = null;
|
||||
|
||||
static $ForceReload;
|
||||
|
||||
@ -233,8 +244,22 @@ class LeftAndMain extends Controller {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Link() {
|
||||
user_error('LeftAndMain::Link(): Please implement in your subclass', E_USER_ERROR);
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links(
|
||||
$this->stat('url_base', true),
|
||||
$this->stat('url_segment', true),
|
||||
'/', // trailing slash needed if $action is null!
|
||||
"$action"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override {@link getMenuTitle} in child classes to make the menu title translatable for that class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMenuTitle() {
|
||||
return $this->stat('menu_title');
|
||||
}
|
||||
|
||||
public function show($params) {
|
||||
@ -281,11 +306,11 @@ class LeftAndMain extends Controller {
|
||||
|
||||
// Encode into DO set
|
||||
$menu = new DataObjectSet();
|
||||
foreach($this->stat('menu_items') as $code => $menuItem) {
|
||||
if(isset($menuItem['controllerClass']) && $this->hasMethod('alternateMenuDisplayCheck')) {
|
||||
$isAllowed = $this->alternateMenuDisplayCheck($menuItem['controllerClass']);
|
||||
} elseif(isset($menuItem['controllerClass'])) {
|
||||
$isAllowed = Permission::check("CMS_ACCESS_" . $menuItem['controllerClass']);
|
||||
foreach(singleton('CMSMenu') as $code => $menuItem) {
|
||||
if(isset($menuItem->controller) && $this->hasMethod('alternateMenuDisplayCheck')) {
|
||||
$isAllowed = $this->alternateMenuDisplayCheck($menuItem->controller);
|
||||
} elseif(isset($menuItem->controller)) {
|
||||
$isAllowed = Permission::check("CMS_ACCESS_" . $menuItem->controller);
|
||||
} else {
|
||||
$isAllowed = true;
|
||||
}
|
||||
@ -293,10 +318,11 @@ class LeftAndMain extends Controller {
|
||||
if(!$isAllowed) continue;
|
||||
|
||||
$linkingmode = "";
|
||||
if(!(strpos($this->Link(), $menuItem['url']) === false)) {
|
||||
// HACK Hardcoding assumptions about the first default menu item
|
||||
if($code == "content") {
|
||||
if($this->Link() == "admin/")
|
||||
|
||||
if(!(strpos($this->Link(), $menuItem->url) === false)) {
|
||||
// default menu is the one with a blank {@link url_segment}
|
||||
if(singleton($menuItem->controller)->stat('url_segment') == '') {
|
||||
if($this->Link() == $this->stat('url_base').'/')
|
||||
$linkingmode = "current";
|
||||
} else {
|
||||
$linkingmode = "current";
|
||||
@ -304,9 +330,9 @@ class LeftAndMain extends Controller {
|
||||
}
|
||||
|
||||
$menu->push(new ArrayData(array(
|
||||
"Title" => Convert::raw2xml($menuItem['title']),
|
||||
"Title" => Convert::raw2xml($menuItem->title),
|
||||
"Code" => $code,
|
||||
"Link" => $menuItem['url'],
|
||||
"Link" => $menuItem->url,
|
||||
"LinkingMode" => $linkingmode
|
||||
)));
|
||||
}
|
||||
@ -938,149 +964,6 @@ JS;
|
||||
return $record->$methodName($data, $form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the default entries for the CMS main menu.
|
||||
*/
|
||||
public static function populate_default_menu() {
|
||||
self::add_menu_item(
|
||||
"content",
|
||||
_t('LeftAndMain.SITECONTENT',"Site Content",PR_HIGH,"Menu title"),
|
||||
"admin/",
|
||||
"CMSMain"
|
||||
);
|
||||
self::add_menu_item(
|
||||
"files",
|
||||
_t('LeftAndMain.FILESIMAGES',"Files & Images",PR_HIGH,"Menu title"),
|
||||
"admin/assets/",
|
||||
"AssetAdmin"
|
||||
);
|
||||
self::add_menu_item(
|
||||
"security",
|
||||
_t('LeftAndMain.SECURITY',"Security",PR_HIGH,'Menu title'),
|
||||
"admin/security/",
|
||||
"SecurityAdmin"
|
||||
);
|
||||
self::add_menu_item(
|
||||
"comments",
|
||||
_t('LeftAndMain.COMMENTS',"Comments",PR_HIGH,'Menu title'),
|
||||
"admin/comments/",
|
||||
"CommentAdmin"
|
||||
);
|
||||
self::add_menu_item(
|
||||
"help",
|
||||
_t('LeftAndMain.HELP',"Help",PR_HIGH,'Menu title'),
|
||||
"http://userhelp.silverstripe.com"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a navigation item to the main administration menu showing in the top bar.
|
||||
*
|
||||
* @uses {@link LeftAndMain::$menu_items}
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
|
||||
* {@link remove_menu_item}. Also used as a CSS-class for icon customization.
|
||||
* @param string $menuTitle Localized title showing in the menu bar
|
||||
* @param string $url A relative URL that will be linked in the menu bar.
|
||||
* Make sure to add a matching route via {@link Director::addRules()} to this url.
|
||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||
* If blank, it's assumed that this is public, and always shown to users who
|
||||
* have the rights to access some other part of the admin area.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public static function add_menu_item($code, $menuTitle, $url, $controllerClass = null) {
|
||||
$menuItems = singleton('LeftAndMain')->stat('menu_items', true);
|
||||
|
||||
if(isset($menuItems[$code])) return false;
|
||||
/*
|
||||
if(isset($menuItems[$code])) {
|
||||
user_error("LeftAndMain::add_menu_item(): A menu item with code '{$menuItems}'
|
||||
already exists, can't add it. Please use replace_menu_item() to explicitly replace it",
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
return self::replace_menu_item($code, $menuTitle, $url, $controllerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single menu item by its code value.
|
||||
*
|
||||
* @param string $code
|
||||
* @return array
|
||||
*/
|
||||
public static function get_menu_item($code) {
|
||||
$menuItems = singleton('LeftAndMain')->stat('menu_items', true);
|
||||
return (isset($menuItems[$code])) ? $menuItems[$code] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all menu entries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_menu_items() {
|
||||
return singleton('LeftAndMain')->stat('menu_items', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing item from the menu.
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item
|
||||
*/
|
||||
public static function remove_menu_item($code) {
|
||||
$menuItems = singleton('LeftAndMain')->stat('menu_items', true);
|
||||
if(isset($menuItems[$code])) unset($menuItems[$code]);
|
||||
// replace the whole array
|
||||
Object::addStaticVars(
|
||||
'LeftAndMain',
|
||||
array('menu_items' => $menuItems),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the entire menu
|
||||
*
|
||||
*/
|
||||
public static function clear_menu() {
|
||||
Object::addStaticVars(
|
||||
'LeftAndMain',
|
||||
array('menu_items' => array()),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a navigation item to the main administration menu showing in the top bar.
|
||||
*
|
||||
* @param string $code Unique identifier for this menu item (e.g. used by {@link replace_menu_item()} and
|
||||
* {@link remove_menu_item}. Also used as a CSS-class for icon customization.
|
||||
* @param string $menuTitle Localized title showing in the menu bar
|
||||
* @param string $url A relative URL that will be linked in the menu bar.
|
||||
* Make sure to add a matching route via {@link Director::addRules()} to this url.
|
||||
* @param string $controllerClass The controller class for this menu, used to check permisssions.
|
||||
* If blank, it's assumed that this is public, and always shown to users who
|
||||
* have the rights to access some other part of the admin area.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public static function replace_menu_item($code, $menuTitle, $url, $controllerClass = null) {
|
||||
$menuItems = singleton('LeftAndMain')->stat('menu_items', true);
|
||||
$menuItems[$code] = array(
|
||||
'title' => $menuTitle,
|
||||
'url' => $url,
|
||||
'controllerClass' => $controllerClass
|
||||
);
|
||||
Object::addStaticVars(
|
||||
'LeftAndMain',
|
||||
array('menu_items' => $menuItems),
|
||||
true
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given javascript file as required in the CMS.
|
||||
* Filenames should be relative to the base, eg, SAPPHIRE_DIR . '/javascript/loader.js'
|
||||
|
@ -28,6 +28,8 @@
|
||||
* @package cms
|
||||
*/
|
||||
abstract class ModelAdmin extends LeftAndMain {
|
||||
|
||||
static $url_rule = '/$Action';
|
||||
|
||||
/**
|
||||
* List of all managed {@link DataObject}s in this interface.
|
||||
@ -139,19 +141,6 @@ abstract class ModelAdmin extends LeftAndMain {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return default link to this controller. This assfaced method is abstract, so we can't
|
||||
* get rid of it.
|
||||
*
|
||||
* @todo extract full URL binding from Director::addRules so that it's not tied to 'admin/crm'
|
||||
* @todo is there a way of removing the dependency on this method from the Form?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Link() {
|
||||
return Controller::join_links(Director::absoluteBaseURL(), 'admin/crm/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Base scaffolding method for returning a generic model instance.
|
||||
*/
|
||||
|
@ -13,6 +13,12 @@
|
||||
*/
|
||||
class ReportAdmin extends LeftAndMain {
|
||||
|
||||
static $url_segment = 'reports';
|
||||
|
||||
static $url_rule = '/$Action/$ID';
|
||||
|
||||
static $menu_title = 'Reports';
|
||||
|
||||
static $template_path = null; // defaults to (project)/templates/email
|
||||
|
||||
public function init() {
|
||||
@ -34,8 +40,8 @@ class ReportAdmin extends LeftAndMain {
|
||||
}
|
||||
}
|
||||
|
||||
public function Link($action = null) {
|
||||
return "admin/reports/$action";
|
||||
public function getMenuTitle() {
|
||||
return _t('LeftAndMain.REPORTS', 'Reports', PR_HIGH, 'Menu title');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,12 @@
|
||||
*/
|
||||
class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
||||
|
||||
static $url_segment = 'security';
|
||||
|
||||
static $url_rule = '/$Action/$ID/$OtherID';
|
||||
|
||||
static $menu_title = 'Security';
|
||||
|
||||
static $tree_class = 'Group';
|
||||
|
||||
static $subitem_class = 'Member';
|
||||
@ -255,8 +261,8 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
||||
return DataObject::get_by_id("Member", Session::get('currentMember'));
|
||||
}
|
||||
|
||||
public function Link($action = null) {
|
||||
return "admin/security/$action";
|
||||
public function getMenuTitle() {
|
||||
return _t('LeftAndMain.SECURITY', 'Security', PR_HIGH, 'Menu title');
|
||||
}
|
||||
|
||||
function providePermissions() {
|
||||
|
81
tests/CMSMenuTest.php
Normal file
81
tests/CMSMenuTest.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage tests
|
||||
*/
|
||||
class CMSMenuTest extends SapphireTest implements TestOnly {
|
||||
|
||||
public function testBasicMenuHandling() {
|
||||
|
||||
// Clear existing menu
|
||||
CMSMenu::clear_menu();
|
||||
$menuItems = CMSMenu::get_menu_items();
|
||||
$this->assertTrue((empty($menuItems)), 'Menu can be cleared');
|
||||
|
||||
// Add a controller to the menu and check it is as expected
|
||||
CMSMenu::add_controller('CMSMain');
|
||||
$menuItems = CMSMenu::get_menu_items();
|
||||
$menuItem = $menuItems['CMSMain'];
|
||||
$this->assertType('CMSMenuItem', $menuItem, 'Controller menu item is of class CMSMenuItem');
|
||||
$this->assertEquals($menuItem->title, singleton('CMSMain')->getMenuTitle(), 'Controller menu item has the correct title');
|
||||
$this->assertEquals($menuItem->url, singleton('CMSMain')->Link(), 'Controller menu item has the correct link');
|
||||
$this->assertEquals($menuItem->controller, 'CMSMain', 'Controller menu item has the correct controller class');
|
||||
$this->assertEquals($menuItem->priority, singleton('CMSMain')->stat('menu_priority'), 'Controller menu item has the correct priority');
|
||||
CMSMenu::clear_menu();
|
||||
|
||||
// Add a link to the menu
|
||||
CMSMenu::add_link('LinkCode', 'link title', 'http://www.example.com');
|
||||
$menuItems = CMSMenu::get_menu_items();
|
||||
$menuItem = $menuItems['LinkCode'];
|
||||
$this->assertType('CMSMenuItem', $menuItem, 'Link menu item is of class CMSMenuItem');
|
||||
$this->assertEquals($menuItem->title, 'link title', 'Link menu item has the correct title');
|
||||
$this->assertEquals($menuItem->url,'http://www.example.com', 'Link menu item has the correct link');
|
||||
$this->assertNull($menuItem->controller, 'Link menu item has no controller class');
|
||||
$this->assertEquals($menuItem->priority, -1, 'Link menu item has the correct priority');
|
||||
CMSMenu::clear_menu();
|
||||
|
||||
}
|
||||
|
||||
public function testCmsClassDetection() {
|
||||
|
||||
// Get CMS classes and check that:
|
||||
// 1.) CMSMain is included
|
||||
// 2.) LeftAndMain & ModelAdmin are excluded
|
||||
$cmsClasses = CMSMenu::get_cms_classes();
|
||||
$this->assertContains('CMSMain', $cmsClasses, 'CMSMain included in valid CMS Classes');
|
||||
$this->assertNotContains('LeftAndMain', $cmsClasses, 'LeftAndMain not included in valid CMS Classes');
|
||||
$this->assertNotContains('ModelAdmin', $cmsClasses, 'LeftAndMain not included in valid CMS Classes');
|
||||
|
||||
}
|
||||
|
||||
public function testAdvancedMenuHandling() {
|
||||
|
||||
// Populate from CMS Classes, check for existance of CMSMain
|
||||
CMSMenu::clear_menu();
|
||||
CMSMenu::populate_menu();
|
||||
$menuItem = CMSMenu::get_menu_item('CMSMain');
|
||||
$this->assertType('CMSMenuItem', $menuItem, 'CMSMain menu item exists');
|
||||
$this->assertEquals($menuItem->title, singleton('CMSMain')->getMenuTitle(), 'Menu item has the correct title');
|
||||
$this->assertEquals($menuItem->url, singleton('CMSMain')->Link(), 'Menu item has the correct link');
|
||||
$this->assertEquals($menuItem->controller, 'CMSMain', 'Menu item has the correct controller class');
|
||||
$this->assertEquals(
|
||||
$menuItem->priority,
|
||||
singleton('CMSMain')->stat('menu_priority'),
|
||||
'Menu item has the correct priority'
|
||||
);
|
||||
|
||||
// Check that menu order is correct by priority
|
||||
// Note this will break if populate_menu includes normal links (ie, as not controller)
|
||||
$menuItems = CMSMenu::get_menu_items();
|
||||
$priority = 9999; // ok, *could* be set larger, but shouldn't need to be!
|
||||
foreach($menuItems as $menuItem) {
|
||||
$this->assertEquals(
|
||||
$menuItem->priority,
|
||||
singleton($menuItem->controller)->stat('menu_priority'),
|
||||
"Menu item $menuItem->title has the correct priority"
|
||||
);
|
||||
$this->assertLessThanOrEqual($priority, $menuItem->priority, 'Menu item is of lower or equal priority');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,49 +3,9 @@
|
||||
* @package cms
|
||||
* @subpackage tests
|
||||
*/
|
||||
/*
|
||||
class LeftAndMainTest extends SapphireTest {
|
||||
|
||||
public function testMainMenuSpecification() {
|
||||
|
||||
// clear existing menu
|
||||
LeftAndMain::clear_menu();
|
||||
$allMenuItems = LeftAndMain::get_menu_items();
|
||||
$this->assertTrue((empty($allMenuItems)), 'Menu can be cleared');
|
||||
|
||||
// populate defaults and check for "content" entry
|
||||
LeftAndMain::populate_default_menu();
|
||||
$contentMenuItem = LeftAndMain::get_menu_item('content');
|
||||
$this->assertTrue((is_array($contentMenuItem)) && !empty($contentMenuItem), '"Content" menu entry exists');
|
||||
|
||||
// try duplicate adding
|
||||
$duplicateAddSuccess = LeftAndMain::add_menu_item(
|
||||
"content",
|
||||
_t('LeftAndMain.SITECONTENT',"Site Content",PR_HIGH,"Menu title"),
|
||||
"admin/",
|
||||
"CMSMain"
|
||||
);
|
||||
$this->assertTrue(($duplicateAddSuccess === false), '"Content" menu entry can\'t be readded through add_menu_item()');
|
||||
|
||||
// try replacing
|
||||
$replaceSuccess = LeftAndMain::replace_menu_item(
|
||||
"content",
|
||||
'My Custom Title',
|
||||
"mycustomroute",
|
||||
"MyCMSMain"
|
||||
);
|
||||
$replacedMenuItem = LeftAndMain::get_menu_item("content");
|
||||
$this->assertEquals($replacedMenuItem['title'],'My Custom Title');
|
||||
$this->assertEquals($replacedMenuItem['url'],'mycustomroute');
|
||||
$this->assertEquals($replacedMenuItem['controllerClass'],'MyCMSMain');
|
||||
|
||||
// try removing
|
||||
LeftAndMain::remove_menu_item("content");
|
||||
$removedMenuItem = LeftAndMain::get_menu_item("content");
|
||||
$this->assertTrue(($removedMenuItem === false), 'Menu item can be removed');
|
||||
|
||||
// restore default menu
|
||||
LeftAndMain::populate_default_menu();
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
?>
|
Loading…
Reference in New Issue
Block a user