diff options
Diffstat (limited to 'engine/lib/pageowner.php')
| -rw-r--r-- | engine/lib/pageowner.php | 341 |
1 files changed, 233 insertions, 108 deletions
diff --git a/engine/lib/pageowner.php b/engine/lib/pageowner.php index 825b41d37..bd63d08c6 100644 --- a/engine/lib/pageowner.php +++ b/engine/lib/pageowner.php @@ -1,172 +1,297 @@ <?php /** * Elgg page owner library - * Contains functions for managing page ownership + * Contains functions for managing page ownership and context * - * @package Elgg - * @subpackage Core - * @author Curverider Ltd - * @link http://elgg.org/ + * @package Elgg.Core + * @subpackage PageOwner */ /** - * Gets the page owner for the current page. - * @uses $CONFIG - * @return int|false The current page owner guid (0 if none). + * Gets the guid of the entity that owns the current page. + * + * @param int $guid Optional parameter used by elgg_set_page_owner_guid(). + * + * @return int The current page owner guid (0 if none). + * @since 1.8.0 */ +function elgg_get_page_owner_guid($guid = 0) { + static $page_owner_guid; -function page_owner() { - global $CONFIG; + if ($guid) { + $page_owner_guid = $guid; + } + + if (isset($page_owner_guid)) { + return $page_owner_guid; + } + + // return guid of page owner entity + $guid = elgg_trigger_plugin_hook('page_owner', 'system', NULL, 0); + + if ($guid) { + $page_owner_guid = $guid; + } + + return $guid; +} + +/** + * Gets the owner entity for the current page. + * + * @note Access is disabled when getting the page owner entity. + * + * @return ElggUser|ElggGroup|false The current page owner or false if none. + * + * @since 1.8.0 + */ +function elgg_get_page_owner_entity() { + $guid = elgg_get_page_owner_guid(); + if ($guid > 0) { + $ia = elgg_set_ignore_access(true); + $owner = get_entity($guid); + elgg_set_ignore_access($ia); + + return $owner; + } + + return false; +} + +/** + * Set the guid of the entity that owns this page + * + * @param int $guid The guid of the page owner + * @return void + * @since 1.8.0 + */ +function elgg_set_page_owner_guid($guid) { + elgg_get_page_owner_guid($guid); +} - $returnval = NULL; +/** + * Sets the page owner based on request + * + * Tries to figure out the page owner by looking at the URL or a request + * parameter. The request parameters used are 'username' and 'owner_guid'. If + * the page request is going through the page handling system, this function + * attempts to figure out the owner if the url fits the patterns of: + * <handler>/owner/<username> + * <handler>/friends/<username> + * <handler>/view/<entity guid> + * <handler>/add/<container guid> + * <handler>/edit/<entity guid> + * <handler>/group/<group guid> + * + * @note Access is disabled while finding the page owner for the group gatekeeper functions. + * + * + * @param string $hook 'page_owner' + * @param string $entity_type 'system' + * @param int $returnvalue Previous function's return value + * @param array $params no parameters + * + * @return int GUID + * @access private + */ +function default_page_owner_handler($hook, $entity_type, $returnvalue, $params) { - $setpageowner = set_page_owner(); - if ($setpageowner !== false) { - return $setpageowner; + if ($returnvalue) { + return $returnvalue; } - if ((!isset($returnval)) && ($username = get_input("username"))) { - if (substr_count($username,'group:')) { - preg_match('/group\:([0-9]+)/i',$username,$matches); + $ia = elgg_set_ignore_access(true); + + $username = get_input("username"); + if ($username) { + // @todo using a username of group:<guid> is deprecated + if (substr_count($username, 'group:')) { + preg_match('/group\:([0-9]+)/i', $username, $matches); $guid = $matches[1]; if ($entity = get_entity($guid)) { - $returnval = $entity->getGUID(); + elgg_set_ignore_access($ia); + return $entity->getGUID(); } } - if ((!isset($returnval)) && ($user = get_user_by_username($username))) { - $returnval = $user->getGUID(); + + if ($user = get_user_by_username($username)) { + elgg_set_ignore_access($ia); + return $user->getGUID(); } } - - if ((!isset($returnval)) && ($owner = get_input("owner_guid"))) { + $owner = get_input("owner_guid"); + if ($owner) { if ($user = get_entity($owner)) { - $returnval = $user->getGUID(); + elgg_set_ignore_access($ia); + return $user->getGUID(); } } - - if ((!isset($returnval)) && (!empty($CONFIG->page_owner_handlers) && is_array($CONFIG->page_owner_handlers))) { - foreach($CONFIG->page_owner_handlers as $handler) { - if ((!isset($returnval)) && ($guid = $handler())) { - $returnval = $guid; - } - } + // ignore root and query + $uri = current_page_url(); + $path = str_replace(elgg_get_site_url(), '', $uri); + $path = trim($path, "/"); + if (strpos($path, "?")) { + $path = substr($path, 0, strpos($path, "?")); } - if (isset($returnval)) { - // Check if this is obtainable, forwarding if not. - /* - * If the owner entity has been set, but is inaccessible then we forward to the dashboard. This - * catches a bunch of WSoDs. It doesn't have much of a performance hit since 99.999% of the time the next thing - * a page does after calling this function is to retrieve the owner entity - which is of course cashed. - */ - $owner_entity = get_entity($returnval); - if (!$owner_entity) { - - // Log an error - error_log(sprintf(elgg_echo('pageownerunavailable'), $returnval)); - - // Forward - forward(); + // @todo feels hacky + if (get_input('page', FALSE)) { + $segments = explode('/', $path); + if (isset($segments[1]) && isset($segments[2])) { + switch ($segments[1]) { + case 'owner': + case 'friends': + $user = get_user_by_username($segments[2]); + if ($user) { + elgg_set_ignore_access($ia); + return $user->getGUID(); + } + break; + case 'view': + case 'edit': + $entity = get_entity($segments[2]); + if ($entity) { + elgg_set_ignore_access($ia); + return $entity->getContainerGUID(); + } + break; + case 'add': + case 'group': + $entity = get_entity($segments[2]); + if ($entity) { + elgg_set_ignore_access($ia); + return $entity->getGUID(); + } + break; + } } - - return $returnval; } - return 0; + elgg_set_ignore_access($ia); } /** - * Gets the page owner for the current page. - * @uses $CONFIG - * @return ElggUser|false The current page owner (false if none). + * Sets the page context + * + * Views can modify their output based on the local context. You may want to + * display a list of blogs on a blog page or in a small widget. The rendered + * output could be different for those two contexts ('blog' vs 'widget'). + * + * Pages that pass through the page handling system set the context to the + * first string after the root url. Example: http://example.org/elgg/bookmarks/ + * results in the initial context being set to 'bookmarks'. + * + * The context is a stack so that for a widget on a profile, the context stack + * may contain first 'profile' and then 'widget'. + * + * If no context was been set, the default context returned is 'main'. + * + * @warning The context is not available until the page_handler runs (after + * the 'init, system' event processing has completed). + * + * @param string $context The context of the page + * @return bool + * @since 1.8.0 */ -function page_owner_entity() { +function elgg_set_context($context) { global $CONFIG; - $page_owner = page_owner(); - if ($page_owner > 0) { - return get_entity($page_owner); + + $context = trim($context); + + if (empty($context)) { + return false; } - return false; + $context = strtolower($context); + + array_pop($CONFIG->context); + array_push($CONFIG->context, $context); + + return true; } /** - * Adds a page owner handler - a function that will - * return the page owner if required - * (Such functions are required to return false if they don't know) - * @uses $CONFIG - * @param string $functionname The name of the function to call - * @return mixed The guid of the owner or false + * Get the current context. + * + * Since context is a stack, this is equivalent to a peek. + * + * @return string|NULL + * @since 1.8.0 */ - -function add_page_owner_handler($functionname) { +function elgg_get_context() { global $CONFIG; - if (empty($CONFIG->page_owner_handlers)) { - $CONFIG->page_owner_handlers = array(); - } - if (is_callable($functionname)) { - $CONFIG->page_owner_handlers[] = $functionname; + + if (!$CONFIG->context) { + return null; } + + return $CONFIG->context[count($CONFIG->context) - 1]; } /** - * Allows a page to manually set a page owner + * Push a context onto the top of the stack * - * @param int $entitytoset The GUID of the page owner - * @return int|false Either the page owner we've just set, or false if unset + * @param string $context The context string to add to the context stack + * @return void + * @since 1.8.0 */ -function set_page_owner($entitytoset = -1) { - static $entity; - - if (!isset($entity)) { - $entity = false; - } +function elgg_push_context($context) { + global $CONFIG; - if ($entitytoset > -1) { - $entity = $entitytoset; - } + array_push($CONFIG->context, $context); +} - return $entity; +/** + * Removes and returns the top context string from the stack + * + * @return string|NULL + * @since 1.8.0 + */ +function elgg_pop_context() { + global $CONFIG; + return array_pop($CONFIG->context); } /** - * Sets the functional context of a page + * Check if this context exists anywhere in the stack * - * @param string $context The context of the page - * @return string|false Either the context string, or false on failure + * This is useful for situations with more than one element in the stack. For + * example, a widget has a context of 'widget'. If a widget view needs to render + * itself differently based on being on the dashboard or profile pages, it + * can check the stack. + * + * @param string $context The context string to check for + * @return bool + * @since 1.8.0 */ -function set_context($context) { +function elgg_in_context($context) { global $CONFIG; - if (!empty($context)) { - $context = trim($context); - $context = strtolower($context); - $CONFIG->context = $context; - return $context; - } else { - return false; - } + + return in_array($context, $CONFIG->context); } /** - * Returns the functional context of a page + * Initializes the page owner functions * - * @return string The context, or 'main' if no context has been provided + * @note This is on the 'boot, system' event so that the context is set up quickly. + * + * @return void + * @access private */ -function get_context() { - global $CONFIG; - if (isset($CONFIG->context) && !empty($CONFIG->context)) { - return $CONFIG->context; - } - if ($context = get_plugin_name(true)) { - return $context; +function page_owner_boot() { + + elgg_register_plugin_hook_handler('page_owner', 'system', 'default_page_owner_handler'); + + // Bootstrap the context stack by setting its first entry to the handler. + // This is the first segment of the URL and the handler is set by the rewrite rules. + // @todo this does not work for actions + $handler = get_input('handler', FALSE); + if ($handler) { + elgg_set_context($handler); } - return "main"; } -if (defined('context')) { - global $CONFIG; - $CONFIG->context = context; -}
\ No newline at end of file +elgg_register_event_handler('boot', 'system', 'page_owner_boot'); |
