From ff31226fdeb972aac2f37f0098240cb366a9bb26 Mon Sep 17 00:00:00 2001 From: brettp Date: Wed, 5 May 2010 19:14:48 +0000 Subject: Merged 18_new_admin branch to trunk. git-svn-id: http://code.elgg.org/elgg/trunk@5977 36083f99-b078-4883-b0ff-0f9b5a30f544 --- engine/lib/actions.php | 13 +++ engine/lib/admin.php | 251 ++++++++++++++++++++++++++++++++++-------------- engine/lib/plugins.php | 80 ++++++++++++++- engine/lib/sessions.php | 7 -- 4 files changed, 269 insertions(+), 82 deletions(-) (limited to 'engine/lib') diff --git a/engine/lib/actions.php b/engine/lib/actions.php index 7e8e43f40..304179828 100644 --- a/engine/lib/actions.php +++ b/engine/lib/actions.php @@ -236,5 +236,18 @@ function get_site_secret() { return $secret; } +/** + * Check if an action is registered and its file exists. + * + * @param string $action + * @return BOOL + * @since 1.8 + */ +function elgg_action_exist($action) { + global $CONFIG; + + return (isset($CONFIG->actions[$action]) && file_exists($CONFIG->actions[$action]['file'])); +} + // Register some actions *************************************************** register_elgg_event_handler("init","system","actions_init"); diff --git a/engine/lib/admin.php b/engine/lib/admin.php index 8d9ffeba0..73e891332 100644 --- a/engine/lib/admin.php +++ b/engine/lib/admin.php @@ -28,53 +28,108 @@ * @param string $view The view to extend, by default this is 'admin/main'. * @param int $priority Optional priority to govern the appearance in the list. */ -function extend_elgg_admin_page( $new_admin_view, $view = 'admin/main', $priority = 500) { - return elgg_extend_view($view, $new_admin_view, $priority); +function extend_elgg_admin_page($new_admin_view, $view = 'admin/main', $priority = 500) { + elgg_deprecated_notice('extend_elgg_admin_page() does nothing now. Extend admin views manually. See http://docs.elgg.org/', 1.8); + //return elgg_extend_view($view, $new_admin_view, $priority); } /** - * Initialise the admin page. + * Add an admin area section or child section (aka tab). + * + * Used in conjuction with http://elgg.org/admin/section/child_section style + * page handler. + * + * @param string $section_id Globally unique section id. + * @param string $section_title Human readable section title. + * @param string $parent_id If a child section, the parent section id. Cannot have grandchildren. */ -function admin_init() { - // Add plugin main menu option (last) - extend_elgg_admin_page('admin/main_opt/statistics', 'admin/main'); - extend_elgg_admin_page('admin/main_opt/site', 'admin/main'); - extend_elgg_admin_page('admin/main_opt/user', 'admin/main'); - extend_elgg_admin_page('admin/main_opt/plugins', 'admin/main', 999); // Always last - - register_action('admin/user/ban', false, "", true); - register_action('admin/user/unban', false, "", true); - register_action('admin/user/delete', false, "", true); - register_action('admin/user/resetpassword', false, "", true); - register_action('admin/user/makeadmin', false, "", true); - register_action('admin/user/removeadmin', false, "", true); - register_action('admin/site/update_basic', false, "", true); - register_action('admin/menu_items', false, "", true); - - - // Page handler - register_page_handler('admin', 'admin_settings_page_handler'); +function elgg_add_admin_section($section_id, $section_title, $parent_id = NULL) { + global $CONFIG; + + if (!isset($CONFIG->admin_sections)) { + $CONFIG->admin_sections = array(); + } + + // have to support adding a child section to a missing parent + // because of plugin order problems. A plugin can extend + // an admin section added by different plugin lower in the load priority. + if ($parent_id) { + if (!isset($CONFIG->admin_sections[$parent_id])) { + $CONFIG->admin_sections[$parent_id] = array('children' => array()); + } + + if (!isset($CONFIG->admin_sections[$parent_id][$section_id])) { + $CONFIG->admin_sections[$parent_id]['children'][$section_id] = array('title' => $section_title); + return TRUE; + } else { + return FALSE; + } + } else { + // children can be defined before parents + if (!isset($CONFIG->admin_sections[$section_id])) { + $CONFIG->admin_sections[$section_id] = array( + 'title' => $section_title, + 'children' => array() + ); + return TRUE; + } else { + // allow to define this since children can be defined before the parent. + $CONFIG->admin_sections[$section_id] = array( + 'title' => $section_title + ); + } + } } /** - * Add submenu items for admin page. - * - * @return unknown_type + * Initialise the admin page. */ -function admin_pagesetup() { - if (get_context() == 'admin') { - global $CONFIG; - - add_submenu_item(elgg_echo('admin:statistics'), $CONFIG->wwwroot . 'pg/admin/statistics/'); - add_submenu_item(elgg_echo('admin:site'), $CONFIG->wwwroot . 'pg/admin/site/'); - add_submenu_item(elgg_echo('admin:user'), $CONFIG->wwwroot . 'pg/admin/user/'); - add_submenu_item(elgg_echo('admin:plugins'), $CONFIG->wwwroot . 'pg/admin/plugins/'); - add_submenu_item(elgg_echo('admin:menu_items'), $CONFIG->wwwroot . 'pg/admin/menu_items/'); - } +function admin_init() { + register_action('admin/user/ban', FALSE, "", TRUE); + register_action('admin/user/unban', FALSE, "", TRUE); + register_action('admin/user/delete', FALSE, "", TRUE); + register_action('admin/user/resetpassword', FALSE, "", TRUE); + register_action('admin/user/makeadmin', FALSE, "", TRUE); + register_action('admin/user/removeadmin', FALSE, "", TRUE); + + register_action('admin/site/update_basic', FALSE, "", TRUE); + register_action('admin/site/update_advanced', FALSE, "", TRUE); + + register_action('admin/menu_items', FALSE, "", TRUE); + + register_action('admin/plugins/simple_update_states', FALSE, '', TRUE); + + + // admin area overview and basic site settings + elgg_add_admin_section('overview', elgg_echo('admin:overview')); + elgg_add_admin_section('site', elgg_echo('admin:site')); + elgg_add_admin_section('basic', elgg_echo('admin:site:basic'), 'site'); + elgg_add_admin_section('advanced', elgg_echo('admin:site:advanced'), 'site'); + + // appearance + elgg_add_admin_section('appearance', elgg_echo('admin:appearance')); + //elgg_add_admin_section('basic', elgg_echo('admin:appearance'), 'appearance'); + elgg_add_admin_section('menu_items', elgg_echo('admin:menu_items'), 'appearance'); + + // users + elgg_add_admin_section('users', elgg_echo('admin:users')); + elgg_add_admin_section('online', elgg_echo('admin:users:online'), 'users'); + elgg_add_admin_section('add', elgg_echo('admin:users:add'), 'users'); + elgg_add_admin_section('find', elgg_echo('admin:users:find'), 'users'); + + // plugins + elgg_add_admin_section('plugins', elgg_echo('admin:plugins')); + elgg_add_admin_section('simple', elgg_echo('admin:plugins:simple'), 'plugins'); + elgg_add_admin_section('advanced', elgg_echo('admin:plugins:advanced'), 'plugins'); + + // handled in the admin sidemenu so we don't have to generate this on every page load. + //elgg_add_admin_section('plugin_settings', elgg_echo('admin:plugin_settings')); + + register_page_handler('admin', 'admin_settings_page_handler'); } /** - * Handle admin pages. + * Handle admin pages. Expects corresponding views as admin/section/subsection * * @param $page * @return unknown_type @@ -82,72 +137,124 @@ function admin_pagesetup() { function admin_settings_page_handler($page) { global $CONFIG; - $path = $CONFIG->path . "admin/index.php"; + admin_gatekeeper(); - if ($page[0]) { - switch ($page[0]) { - case 'user' : $path = $CONFIG->path . "admin/user.php"; break; - case 'statistics' : $path = $CONFIG->path . "admin/statistics.php"; break; - case 'plugins' : $path = $CONFIG->path . "admin/plugins.php"; break; - case 'site' : $path = $CONFIG->path . "admin/site.php"; break; - case 'menu_items' : $path = $CONFIG->path . 'admin/menu_items.php'; break; - } + // default to overview + if (!isset($page[0]) || empty($page[0])) { + $page = array('overview'); } - if ($page[1]) { - set_input('username', $page[1]); + // was going to fix this in the page_handler() function but + // it's commented to explicitly return a string if there's a trailing / + if (empty($page[count($page)-1])) { + array_pop($page); } - include($path); + $vars = array('page' => $page); + + // special page for plugin settings since we create the form for them + if ($page[0] == 'plugin_settings' && isset($page[1]) && elgg_view_exists("settings/{$page[1]}/edit")) { + $view = '/admin/components/plugin_settings'; + $vars['plugin'] = $page[1]; + $vars['entity'] = find_plugin_settings($page[1]); + $title = elgg_echo("admin:plugin_settings:{$page[1]}"); + } else { + $view = 'admin/' . implode('/', $page); + $title = elgg_echo('admin:' . implode(':', $page)); + } + + // allow a place to store helper views outside of the web-accessible views + if ($page[0] == 'components' || !($content = elgg_view($view, $vars))) { + $title = elgg_echo('admin:unknown_section'); + $content = elgg_echo('admin:unknown_section'); + } + + $body = elgg_view('admin/components/admin_page_layout', array('content' => $content, 'page' => $page)); + page_draw($title, $body); } /** - * Write a persistent message to the administrator's notification window. + * Write a persistent message to the admin view. + * Useful to alert the admin to take a certain action. + * The id is a unique ID that can be cleared once the admin + * completes the action. * - * Currently this writes a message to the admin store, we may want to come up with another way at some point. + * eg: add_admin_notice('twitter_service_no_api', + * 'Before your users can use Twitter services on this site, you must set up + * the Twitter API key in the Twitter Services Settings'); * - * @param string $subject Subject of the message + * @param string $id A unique ID that your plugin can remember * @param string $message Body of the message */ -function send_admin_message($subject, $message) { - $subject = sanitise_string($subject); - $message = sanitise_string($message); - - if (($subject) && ($message)) { - $admin_message = new ElggObject(); - $admin_message->subtype = 'admin_message'; - $admin_message->access_id = ACCESS_PUBLIC; - $admin_message->title = $subject; - $admin_message->description = $message; - - return $admin_message->save(); +function elgg_add_admin_notice($id, $message) { + if ($id && $message) { + $admin_notice = new ElggObject(); + $admin_notice->subtype = 'admin_notice'; + // admins can see ACCESS_PRIVATE but no one else can. + $admin_notice->access_id = ACCESS_PRIVATE; + $admin_notice->admin_notice_id = $id; + $admin_notice->description = $message; + + return $admin_notice->save(); } return false; } + +/** + * Remove an admin notice by ID. + * + * eg In actions/twitter_service/save_settings: + * if (is_valid_twitter_api_key()) { + * delete_admin_notice('twitter_services_no_api'); + * } + * + * @param string $id The unique ID assigned in add_admin_notice() + */ +function elgg_delete_admin_notice($id) { + if (!$id) { + return FALSE; + } + $result = TRUE; + if ($notices = elgg_get_entities_from_metadata(array('metadata_name' => 'admin_notice_id', 'metadata_value' => $id))) { + // in case a bad plugin adds many, let it remove them all at once. + foreach ($notices as $notice) { + $result = ($result && $notice->delete()); + } + return $result; + } + return FALSE; +} + /** * List all admin messages. * * @param int $limit Limit */ -function list_admin_messages($limit = 10) { - return elgg_list_entities(array( +function elgg_get_admin_notices($limit = 10) { + return elgg_get_entities_from_metadata(array( 'type' => 'object', - 'subtype' => 'admin_message', + 'subtype' => 'admin_notice', 'limit' => $limit )); } /** - * Remove an admin message. - * - * @param int $guid The + * Check if an admin notice is currently active. + * @param string $id The unique ID used to register the notice. */ -function clear_admin_message($guid) { - return delete_entity($guid); +function elgg_admin_notice_exists($id) { + $notice = elgg_get_entities_from_metadata(array( + 'type' => 'object', + 'subtype' => 'admin_notice', + 'metadata_name_value_pair' => array('name' => 'admin_notice_id', 'value' => $id) + )); + + return ($notice) ? TRUE : FALSE; } -/// Register init functions + +// Register init functions register_elgg_event_handler('init', 'system', 'admin_init'); register_elgg_event_handler('pagesetup', 'system', 'admin_pagesetup'); diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php index 0e62914e2..b365585c8 100644 --- a/engine/lib/plugins.php +++ b/engine/lib/plugins.php @@ -354,6 +354,11 @@ function load_plugin_manifest($plugin) { } } + // handle plugins that don't define a name + if (!isset($elements['name'])) { + $elements['name'] = ucwords($plugin); + } + return $elements; } @@ -677,6 +682,10 @@ function enable_plugin($plugin, $site_guid = 0) { throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); } + if (!$plugin_info = load_plugin_manifest($plugin)) { + return FALSE; + } + // getMetadata() doesn't return an array if only one plugin is enabled if ($enabled = $site->enabled_plugins) { if (!is_array($enabled)) { @@ -689,8 +698,42 @@ function enable_plugin($plugin, $site_guid = 0) { $enabled[] = $plugin; $enabled = array_unique($enabled); - $return = $site->setMetaData('enabled_plugins', $enabled); - $ENABLED_PLUGINS_CACHE = $enabled; + if ($return = $site->setMetaData('enabled_plugins', $enabled)) { + + // for other plugins that want to hook into this. + if ($return && !trigger_elgg_event('enable', 'plugin', array('plugin' => $plugin, 'manifest' => $plugin_info))) { + $return = FALSE; + } + + // for this plugin's on_enable + if ($return && isset($plugin_info['on_enable'])) { + // pull in the actual plugin's start so the on_enable function is callabe + // NB: this will not run re-run the init hooks! + $start = "{$CONFIG->pluginspath}$plugin/start.php"; + if (!file_exists($start) || !include($start)) { + $return = FALSE; + } + + // need language files for the messages + $translations = "{$CONFIG->pluginspath}$plugin/languages/"; + register_translations($translations); + if (!is_callable($plugin_info['on_enable'])) { + $return = FALSE; + } else { + $on_enable = call_user_func($plugin_info['on_enable']); + // allow null to mean "I don't care" like other subsystems + $return = ($on_disable === FALSE) ? FALSE : TRUE; + } + } + + // disable the plugin if the on_enable or trigger results failed + if (!$return) { + array_pop($enabled); + $site->setMetaData('enabled_plugins', $enabled); + } + + $ENABLED_PLUGINS_CACHE = $enabled; + } return $return; } @@ -721,6 +764,10 @@ function disable_plugin($plugin, $site_guid = 0) { throw new InvalidClassException(sprintf(elgg_echo('InvalidClassException:NotValidElggStar'), $site_guid, "ElggSite")); } + if (!$plugin_info = load_plugin_manifest($plugin)) { + return FALSE; + } + // getMetadata() doesn't return an array if only one plugin is enabled if ($enabled = $site->enabled_plugins) { if (!is_array($enabled)) { @@ -730,6 +777,8 @@ function disable_plugin($plugin, $site_guid = 0) { $enabled = array(); } + $old_enabled = $enabled; + // remove the disabled plugin from the array if (FALSE !== $i = array_search($plugin, $enabled)) { unset($enabled[$i]); @@ -738,7 +787,32 @@ function disable_plugin($plugin, $site_guid = 0) { // if we're unsetting all the plugins, this will return an empty array. // it will fail with FALSE, though. $return = (FALSE === $site->enabled_plugins = $enabled) ? FALSE : TRUE; - $ENABLED_PLUGINS_CACHE = $enabled; + + if ($return) { + // for other plugins that want to hook into this. + if ($return && !trigger_elgg_event('disable', 'plugin', array('plugin' => $plugin, 'manifest' => $plugin_info))) { + $return = FALSE; + } + + // for this plugin's on_disable + if ($return && isset($plugin_info['on_disable'])) { + if (!is_callable($plugin_info['on_disable'])) { + $return = FALSE; + } else { + $on_disable = call_user_func($plugin_info['on_disable']); + // allow null to mean "I don't care" like other subsystems + $return = ($on_disable === FALSE) ? FALSE : TRUE; + } + } + + // disable the plugin if the on_enable or trigger results failed + if (!$return) { + $site->enabled_plugins = $old_enabled; + $ENABLED_PLUGINS_CACHE = $old_enabled; + } else { + $ENABLED_PLUGINS_CACHE = $enabled; + } + } return $return; } diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php index f4b1fc69b..b5b68ebe0 100644 --- a/engine/lib/sessions.php +++ b/engine/lib/sessions.php @@ -417,13 +417,6 @@ function login(ElggUser $user, $persistent = false) { set_last_login($_SESSION['guid']); reset_login_failure_count($user->guid); // Reset any previous failed login attempts - // Set admin shortcut flag if this is an admin -// if (isadminloggedin()) { -// //@todo REMOVE THIS. -// global $is_admin; -// $is_admin = true; -// } - return true; } -- cgit v1.2.3