'Content',
'admin/content/add' => 'Add',
'admin/content/node' => 'Edit',
'admin/build' => 'Structure',
'admin/build/views' => '',
'admin/build/block' => '',
'admin/build/menu' => '',
'admin/user' => 'People',
'admin/user/permissions' => '',
'admin/user/user' => '',
'admin/settings' => 'Configuration',
'admin/settings/date-time' => '',
'admin/settings/filters' => '',
'admin/settings/language' => '',
'admin/settings/performance' => '',
'admin/settings/site' => '',
'admin/themes' => 'Appearance',
'admin/modules' => '',
);
foreach ($include as $path => $title) {
if (!empty($items[$path])) {
$items[$path]['title'] = !empty($title) ? $title : $items[$path]['title'];
$items[$path]['options']['admin'] = TRUE;
}
}
// Apparently node/add has no description. Add one.
$items['admin/content/add']['description'] = 'Create new content on your site.';
$items['admin/content/add']['weight'] = -20;
$items['admin/content/node']['weight'] = -19;
}
/**
* Helper to clone portions of the menu tree to a duplicate location.
*/
function admin_menu_clone_items($search, $replace, $items) {
$offset = count(explode('/', $replace)) - count(explode('/', $search));
$clone = array();
foreach ($items as $path => $item) {
if (strpos($path, $search) === 0) {
$clone_path = str_replace($search, $replace, $path);
// Adjust argument offsets if the search and replace paths have a
// different arg counts.
if ($offset != 0) {
foreach (array('page arguments', 'access arguments', 'load arguments', 'title arguments') as $arg_key) {
if (!empty($item[$arg_key])) {
foreach ($item[$arg_key] as $k => $v) {
if (is_numeric($v)) {
$item[$arg_key][$k] = $v + $offset;
}
}
}
}
}
$clone[$clone_path] = $item;
}
}
return $clone;
}
/**
* Implementation of hook_form_alter() for system_admin_theme_settings.
*/
function admin_form_system_admin_theme_settings_alter(&$form) {
// Add in our stealth theme as an option
$form['admin_theme']['#options']['admin'] = t('Admin');
}
/**
* Implementation of hook_form_alter() for node_filter_form.
*/
function admin_form_node_admin_content_alter(&$form) {
// If the admin theme has been inited, do some additional work.
global $theme;
if ($theme == 'admin') {
unset($form['admin']['options']['#type']);
unset($form['admin']['options']['#prefix']);
unset($form['admin']['options']['#suffix']);
$form['admin']['options']['#theme'] = 'admin_manage_options';
}
}
function admin_form_user_admin_account_alter(&$form) {
// If the admin theme has been inited, do some additional work.
global $theme;
if ($theme == 'admin') {
unset($form['options']['#type']);
unset($form['options']['#prefix']);
unset($form['options']['#suffix']);
$form['options']['#theme'] = 'admin_manage_options';
}
}
/**
* Implementation of hook_system_info_alter().
* Throw a flag that tells us we need to reinstantiate the admin theme.
*/
function admin_system_info_alter(&$info, &$theme) {
static $once;
if (!isset($once)) {
$once = TRUE;
variable_set('admin_theme_invalidated', TRUE);
}
}
/**
* Implementation of hook_perm().
*/
function admin_perm() {
return array('admin menu', 'admin inline');
}
/**
* Implementation of hook_theme().
*/
function admin_theme($cache, $type, $theme, $path) {
$items = array();
$items['admin_toolbar'] = array(
'arguments' => array('tree' => array()),
'template' => 'admin-toolbar',
'path' => drupal_get_path('module', 'admin') .'/toolbar',
'file' => 'theme.inc',
);
$items['admin_links'] = array(
'arguments' => array('links' => array()),
'template' => 'admin-links',
'path' => drupal_get_path('module', 'admin') .'/toolbar',
'file' => 'theme.inc',
);
$items['admin_manage_options'] = array(
'arguments' => array('form' => array()),
'path' => drupal_get_path('module', 'admin') .'/theme',
'file' => 'template.php',
);
return $items;
}
/**
* Wrapper to check whether various admin features are accessible to the
* current user and compatible with the current theme.
*/
function admin_is_enabled($op = 'admin menu') {
if (user_access($op)) {
global $theme_info;
// If the theme does not specify some flag for this feature, assume
// it is compatible.
if (!isset($theme_info->info['admin'][$op]) || (isset($theme_info->info['admin'][$op]) && !empty($theme_info->info['admin'][$op]))) {
return TRUE;
}
}
return FALSE;
}
/**
* Retrieve the admin links for a given object.
*/
function admin_get_links($type, $object) {
$links = array();
if (admin_is_enabled('admin inline')) {
$links = module_invoke_all('admin_link', $type, $object);
drupal_alter('admin_link', $links, $type, $object);
}
return $links;
}
/**
* Implementation of hook_admin_link() on behalf of the node module.
*/
function node_admin_link($type, $object) {
$links = array();
if ($type == 'node') {
if (node_access('update', $object)) {
$links['node-edit'] = array(
'title' => t('Edit'),
'href' => "node/{$object->nid}/edit",
'attributes' => array('class' => 'icon-edit'),
'query' => array('destination' => $_GET['q']),
);
}
if (node_access('delete', $object)) {
$links['node-delete'] = array(
'title' => t('Delete'),
'href' => "node/{$object->nid}/delete",
'attributes' => array('class' => 'icon-delete'),
'query' => array('destination' => $_GET['q']),
);
}
}
return $links;
}
/**
* Implementation of hook_admin_link() on behalf of the block module.
*/
function block_admin_link($type, $object) {
$links = array();
if ($type == 'block') {
if (user_access('administer blocks')) {
$links['block-configure'] = array(
'title' => t('Configure'),
'href' => "admin/build/block/configure/{$object->module}/{$object->delta}",
'attributes' => array('class' => 'icon-configure'),
'query' => array('destination' => $_GET['q']),
);
}
}
return $links;
}
/**
* Implementation of hook_admin_link() on behalf of the views module.
*/
function views_admin_link($type, $object) {
$links = array();
$view_name = '';
if (user_access('administer views')) {
switch ($type) {
case 'block':
// If this is a Views block and not a special (exposed filter, etc.) block...
if ($object->module == 'views' && strpos($object->delta, '-') !== 0) {
$split = explode('-', $object->delta);
$view_name = array_shift($split);
}
break;
case 'views':
// Bail on block/attachment views or views using the node row plugin to prevent collisions.
if ($object->display_handler->get_option('row_plugin') != 'node' && !in_array(get_class($object->display_handler), array('views_plugin_display_attachment', 'views_plugin_display_block'))) {
$view_name = $object->name;
}
break;
}
if (!empty($view_name)) {
$links['views-edit'] = array(
'title' => t('Edit view'),
'href' => "admin/build/views/edit/{$view_name}",
'attributes' => array('class' => 'icon-edit'),
'query' => array('destination' => $_GET['q']),
);
}
}
return $links;
}
/**
* Implementation of hook_theme_registry_alter().
*/
function admin_theme_registry_alter(&$theme_registry) {
$hooks = array(
'page',
'block',
'views_view',
'node',
);
foreach ($hooks as $hook) {
if (empty($theme_registry[$hook]['preprocess functions']) || !in_array('admin_preprocess_'. $hook, $theme_registry[$hook]['preprocess functions'])) {
$theme_registry[$hook]['preprocess functions'][] = 'admin_preprocess_'. $hook;
}
}
// If the admin theme has been inited, do some additional work.
global $theme;
if ($theme == 'admin') {
// Slap a preprocessor on at the very front of the stack for rebuilding the admin theme.
if (!in_array('admin_page_alter', $theme_registry['page']['preprocess functions'])) {
array_unshift($theme_registry['page']['preprocess functions'], 'admin_page_alter');
}
$overrides = array('fieldset', 'node_form', 'system_settings_form', 'admin_block_content');
foreach ($overrides as $hook) {
$theme_registry[$hook]['function'] = 'admin_'. $hook;
}
}
}
/**
* Page preprocessor that runs before any others (including template_preprocess_page()).
* Check the theme rebuild flag and do so if necessary.
*/
function admin_page_alter(&$vars) {
_admin_theme_rebuild();
}
/**
* Implementation of hook_preprocess_page().
*/
function admin_preprocess_page(&$vars) {
// @TODO: merge multiple menus rather than just using the first
if (admin_is_enabled('admin menu')) {
$links = admin_menu_tree();
$links = theme('admin_toolbar', $links);
$vars['admin'] = $links;
}
else {
$vars['admin'] = '';
}
}
/**
* Implementation of hook_preprocess_views_view().
*/
function admin_preprocess_views_view(&$vars) {
$admin_links = theme('admin_links', admin_get_links('views', $vars['view']));
if ($admin_links) {
$vars['pager'] .= $admin_links;
}
// Disable the Views admin links stack to prevent clutter.
$vars['admin_links'] = '';
$vars['admin_links_raw'] = '';
}
/**
* Implementation of hook_preprocess_block().
*/
function admin_preprocess_block(&$vars) {
$vars['block']->content .= theme('admin_links', admin_get_links('block', $vars['block']));
}
/**
* Implementation of hook_preprocess_node().
*/
function admin_preprocess_node(&$vars) {
$vars['content'] .= theme('admin_links', admin_get_links('node', $vars['node']));
}
/**
* Retrieve a hierarchy of links representing select portions of the
* 'admin' branch of the navigation menu.
*/
function admin_menu_tree() {
$parents = array();
$trail = menu_get_active_trail();
foreach ($trail as $item) {
if (!empty($item['mlid'])) {
$parents[] = $item['mlid'];
}
}
$tree = menu_tree_data(db_query("
SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.*
FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
WHERE ml.menu_name = '%s'
AND ml.link_path LIKE 'admin%'
AND ml.depth > 1
AND ml.depth < 4
ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", 'navigation'), $parents);
// @TODO: Cache here!
menu_tree_check_access($tree);
$links = array();
admin_menu_tree_links($tree, $links);
// Add user-specific links
global $user;
$user_links = array();
$user_links[] = array(
'title' => t('Hello !username', array('!username' => $user->name)),
'href' => 'user',
'html' => TRUE
);
$user_links[] = array('title' => t('Logout'), 'href' => "logout");
$links[0]['user'] = $user_links;
return $links;
}
/**
* Generate a links array from a menu tree array.
*/
function admin_menu_navigation_links($tree, $admin_only = FALSE) {
$links = array();
foreach ($tree as $item) {
if (!$item['link']['hidden'] && (!$admin_only || !empty($item['link']['options']['admin']))) {
$class = '';
$id = str_replace('/', '-', $item['link']['href']);
$l = $item['link']['localized_options'];
$l['href'] = $item['link']['href'];
$l['title'] = "". $item['link']['title'];
$l['attributes'] = array('id' => 'admin-link-'. $id);
$l['html'] = TRUE;
$class = ' path-'. $id;
if ($item['link']['in_active_trail']) {
$class .= ' active-trail';
}
// Keyed with the unique mlid to generate classes in theme_links().
$links['menu-'. $item['link']['mlid'] . $class] = $l;
}
}
return $links;
}
/**
* Build a hierarchy of $links arrays suitable for theme_links() from a
* menu tree.
*/
function admin_menu_tree_links($tree, &$links, $parent = 'admin', $depth = 0) {
// Create a single level of links.
$links[$depth][$parent] = array();
$l = admin_menu_navigation_links($tree, TRUE);
if (!empty($l)) {
$links[$depth][$parent] = $l;
}
// Recurse
foreach ($tree as $item) {
if (!$item['link']['hidden'] && !empty($item['link']['options']['admin'])) {
if (!empty($item['below'])) {
admin_menu_tree_links($item['below'], $links, $item['link']['href'], $depth + 1);
}
}
}
}
/**
* Rebuild the admin theme entry in the database.
*/
function _admin_theme_rebuild($force = FALSE) {
if (arg(0) == 'admin') {
$exists = db_result(db_query("SELECT count(*) FROM {system} WHERE name = 'admin' AND type = 'theme'"));
$force = !$exists ? TRUE : $force;
}
if ($force || variable_get('admin_theme_invalidated', FALSE)) {
$path = drupal_get_path('module', 'admin') .'/theme';
$theme = new StdClass();
$theme->name = 'admin';
$theme->filename = "{$path}/admin.theme.info";
$theme->engine = 'phptemplate';
$theme->owner = drupal_get_path('theme_engine', 'phptemplate') .'/phptemplate.engine';
$theme->info = system_theme_default();
db_query("DELETE FROM {system} WHERE name = 'admin' AND type = 'theme'");
db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0);
variable_set('admin_theme_invalidated', FALSE);
}
}