From 1ac20eae82da66f4e29480d97ff8e1d5312ed59b Mon Sep 17 00:00:00 2001 From: brettp Date: Fri, 17 Sep 2010 18:46:58 +0000 Subject: Refs #2450: Added documentation for actions. git-svn-id: http://code.elgg.org/elgg/trunk@6949 36083f99-b078-4883-b0ff-0f9b5a30f544 --- engine/handlers/action_handler.php | 3 + engine/lib/actions.php | 151 ++++++++++++++++++++++++++++++------- 2 files changed, 127 insertions(+), 27 deletions(-) (limited to 'engine') diff --git a/engine/handlers/action_handler.php b/engine/handlers/action_handler.php index 8a1f1276b..a6bdaeae9 100644 --- a/engine/handlers/action_handler.php +++ b/engine/handlers/action_handler.php @@ -6,6 +6,9 @@ * from http://site/action/. Anything after 'action/' is considered the action * and will be passed to {@link action()}. * + * @warning This sets the input named 'action' to the current action. When calling + * an action, get_input('action') will always return the action name. + * * @package Elgg.Core * @subpackage Actions * @link http://docs.elgg.org/Tutorials/Actions diff --git a/engine/lib/actions.php b/engine/lib/actions.php index cdad8ebab..b889476b3 100644 --- a/engine/lib/actions.php +++ b/engine/lib/actions.php @@ -1,21 +1,56 @@ actions[$action]['public'] || get_loggedin_userid()) { // Trigger action event - // @todo This is only called before the primary action is called. We need to rethink actions for 1.5 + // @todo This is only called before the primary action is called. $event_result = true; $event_result = trigger_plugin_hook('action', $action, null, $event_result); // Include action - // Event_result being false doesn't produce an error - + // Event_result being false doesn't produce an error // since i assume this will be handled in the hook itself. // @todo make this better! if ($event_result) { if (!include($CONFIG->actions[$action]['file'])) { - register_error(sprintf(elgg_echo('actionundefined'),$action)); + register_error(sprintf(elgg_echo('actionundefined'), $action)); } } } else { @@ -75,19 +110,47 @@ function action($action, $forwarder = "") { register_error(elgg_echo('actionunauthorized')); } } else { - register_error(sprintf(elgg_echo('actionundefined'),$action)); + register_error(sprintf(elgg_echo('actionundefined'), $action)); } forward($CONFIG->url . $forwarder); } /** - * Registers a particular action in memory + * Registers an action. + * + * Actions are registered to a single file in the system and are executed + * either by the URL http://elggsite.org/action/action_name or by calling + * {@link action()}. + * + * $file must be the full path of the file to register, or a path relative + * to the core actions/ dir. + * + * Actions should be namedspaced for your plugin. Example: + * + * register_action('myplugin/save_settings', ...); + * + * + * @tip Put action files under the actions/ directory of your plugin. + * + * @tip You don't need to include engine/start.php, call {@link gatekeeper()}, + * or call {@link admin_gatekeeper()}. + * + * @internal Actions are saved in $CONFIG->actions as an array in the form: + * + * array( + * 'file' => '/location/to/file.php', + * 'public' => BOOL If false, user must be logged in. + * 'admin' => BOOL If true, user must be admin (implies plugin = false) + * ) + * * * @param string $action The name of the action (eg "register", "account/settings/save") * @param boolean $public Can this action be accessed by people not logged into the system? * @param string $filename Optionally, the filename where this action is located * @param boolean $admin_only Whether this action is only available to admin users. + * @see action() + * @see http://docs.elgg.org/Actions */ function register_action($action, $public = false, $filename = "", $admin_only = false) { global $CONFIG; @@ -119,6 +182,7 @@ function register_action($action, $public = false, $filename = "", $admin_only = * @param string $event Events API required parameters * @param string $object_type Events API required parameters * @param string $object Events API required parameters + * @todo remove */ function actions_init($event, $object_type, $object) { register_action("error"); @@ -126,9 +190,21 @@ function actions_init($event, $object_type, $object) { } /** - * Validate an action token, returning true if valid and false if not + * Validate an action token. + * + * Calls to actions will automatically validate tokens. + * If tokens are not present or invalid, the action will be + * denied and the user will be redirected to the front page. * - * @return unknown + * Plugin authors should never have to manually validate action tokens. + * + * @access private + * @param bool $visibleerrors Emit {@link register_error()} errors on failure? + * @param mixed $token The token to test against. Pulls from $_REQUEST['__elgg_token'] if NULL. + * @param mixed $ts The time stamp to test against. Pulls from $_REQUEST['__elgg_ts'] if NULL. + * @return bool + * @see generate_action_token() + * @link http://docs.elgg.org/Actions/Tokens */ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL) { if (!$token) { @@ -181,11 +257,16 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL) } /** -* Action gatekeeper. +* Validates the presence of action tokens. +* +* This function is called for all actions. If action tokens are missing, +* the user will be forwarded to the site front page and an error emitted. +* * This function verifies form input for security features (like a generated token), and forwards * the page if they are invalid. * -* Place at the head of actions. +* @access private +* @return mixed True if valid, or redirects to front page and exists. */ function action_gatekeeper() { if (validate_action_token()) { @@ -197,30 +278,41 @@ function action_gatekeeper() { } /** - * Generate a token for the current user suitable for being placed in a hidden field in action forms. + * Generate an action token. + * + * Action tokens are based on timestamps as returned by {@link time()}. + * They are valid for one hour. + * + * Action tokens should be passed to all actions name __elgg_ts and __elgg_token. + * + * @warning Action tokens are required for all actions. * * @param int $timestamp Unix timestamp + * @see @elgg_view input/securitytoken + * @see @elgg_view input/form + * @example actions/manual_tokens.php */ function generate_action_token($timestamp) { - // Get input values $site_secret = get_site_secret(); - - // Current session id $session_id = session_id(); - // Session token $st = $_SESSION['__elgg_session']; if (($site_secret) && ($session_id)) { - return md5($site_secret.$timestamp.$session_id.$st); + return md5($site_secret . $timestamp . $session_id . $st); } return FALSE; } /** - * Initialise the site secret. + * Initialise the site secret hash. + * + * Used during installation and saves as a datalist. * + * @return mixed The site secret hash or false + * @access private + * @todo Move to better file. */ function init_site_secret() { $secret = md5(rand().microtime()); @@ -232,8 +324,13 @@ function init_site_secret() { } /** - * Retrieve the site secret. + * Returns the site secret. + * + * Used to generate difficult to guess hashes for sessions and action tokens. * + * @return string Site secret. + * @access private + * @todo Move to better file. */ function get_site_secret() { $secret = datalist_get('__site_secret__'); @@ -257,4 +354,4 @@ function elgg_action_exist($action) { return (isset($CONFIG->actions[$action]) && file_exists($CONFIG->actions[$action]['file'])); } -register_elgg_event_handler("init","system","actions_init"); +register_elgg_event_handler("init", "system", "actions_init"); \ No newline at end of file -- cgit v1.2.3