/** * Adds action tokens to URL * * @param str $link Full action URL * @return str URL with action tokens * @since 1.7 */ function elgg_add_action_tokens_to_url($url) { $components = parse_url($url); if (isset($components['query'])) { $query = elgg_parse_str($components['query']); } else { $query = array(); } if (isset($query['__elgg_ts']) && isset($query['__elgg_token'])) { return $url; } // append action tokens to the existing query $query['__elgg_ts'] = time(); $query['__elgg_token'] = generate_action_token($query['__elgg_ts']); $components['query'] = http_build_query($query); // rebuild the full url return elgg_http_build_url($components); }
/** * Validates HMAC signature * * @param string $url URL to vlaidate * @return bool */ public function isValid($url) { $parts = parse_url($url); if (isset($parts['query'])) { $query = elgg_parse_str($parts['query']); } else { $query = []; } if (!isset($query[self::KEY_MAC])) { // No signature found return false; } $token = $query[self::KEY_MAC]; unset($query[self::KEY_MAC]); if (isset($query[self::KEY_EXPIRES]) && $query[self::KEY_EXPIRES] < time()) { // Signature has expired return false; } ksort($query); $parts['query'] = http_build_query($query); $url = elgg_http_build_url($parts, false); return elgg_build_hmac($url)->matchesToken($token); }
/** * Adds an element or elements to a URL's query string. * * @param str $url The URL * @param array $elements Key/value pairs to add to the URL * * @return str The new URL with the query strings added * @since 1.7.0 */ function elgg_http_add_url_query_elements($url, array $elements) { $url_array = parse_url($url); if (isset($url_array['query'])) { $query = elgg_parse_str($url_array['query']); } else { $query = array(); } foreach ($elements as $k => $v) { $query[$k] = $v; } $url_array['query'] = http_build_query($query); $string = elgg_http_build_url($url_array, false); return $string; }
/** * Sets elements in a URL's query string. * * @param string $url The URL * @param array $elements Key/value pairs to set in the URL. If the value is null, the * element is removed from the URL. * * @return string The new URL with the query strings added * @since 1.7.0 */ function elgg_http_add_url_query_elements($url, array $elements) { $url_array = parse_url($url); if (isset($url_array['query'])) { $query = elgg_parse_str($url_array['query']); } else { $query = array(); } foreach ($elements as $k => $v) { if ($v === null) { unset($query[$k]); } else { $query[$k] = $v; } } // why check path? A: if no path, this may be a relative URL like "?foo=1". In this case, // the output "" would be interpreted the current URL, so in this case we *must* set // a query to make sure elements are removed. if ($query || empty($url_array['path'])) { $url_array['query'] = http_build_query($query); } else { unset($url_array['query']); } $string = elgg_http_build_url($url_array, false); return $string; }
/** * Replacement for Elgg'd native function which returns a malformatted url */ function hj_framework_http_remove_url_query_element($url, $element) { $url_array = parse_url($url); if (isset($url_array['query'])) { $query = elgg_parse_str($url_array['query']); } else { // nothing to remove. Return original URL. return $url; } if (array_key_exists($element, $query)) { unset($query[$element]); } $url_array['query'] = http_build_query($query); $string = elgg_http_build_url($url_array, false); return $string; }
/** * Redirect to the comment in context of the containing page * * @param int $comment_guid GUID of the comment * @param int $fallback_guid GUID of the containing entity * * @return void * @access private */ function _elgg_comment_redirect($comment_guid, $fallback_guid) { $fail = function () { register_error(elgg_echo('generic_comment:notfound')); forward(REFERER); }; $comment = get_entity($comment_guid); if (!$comment) { // try fallback if given $fallback = get_entity($fallback_guid); if (!$fallback) { $fail(); } register_error(elgg_echo('generic_comment:notfound_fallback')); forward($fallback->getURL()); } if (!elgg_instanceof($comment, 'object', 'comment')) { $fail(); } $container = $comment->getContainerEntity(); if (!$container) { $fail(); } // this won't work with threaded comments, but core doesn't support that yet $count = elgg_get_entities(['type' => 'object', 'subtype' => 'comment', 'container_guid' => $container->guid, 'count' => true, 'wheres' => ["e.guid < " . (int) $comment->guid]]); $limit = (int) get_input('limit'); if (!$limit) { $limit = elgg_trigger_plugin_hook('config', 'comments_per_page', [], 25); } $offset = floor($count / $limit) * $limit; if (!$offset) { $offset = null; } $url = elgg_http_add_url_query_elements($container->getURL(), ['offset' => $offset]); // make sure there's only one fragment (#) $parts = parse_url($url); $parts['fragment'] = "elgg-object-{$comment->guid}"; $url = elgg_http_build_url($parts, false); forward($url); }
/** * Redirect to the reply in context of the containing topic * * @param int $reply_guid GUID of the reply * @param int $fallback_guid GUID of the topic * * @return void * @access private */ function discussion_redirect_to_reply($reply_guid, $fallback_guid) { $fail = function () { register_error(elgg_echo('discussion:reply:error:notfound')); forward(REFERER); }; $reply = get_entity($reply_guid); if (!$reply) { // try fallback $fallback = get_entity($fallback_guid); if (!elgg_instanceof($fallback, 'object', 'discussion')) { $fail(); } register_error(elgg_echo('discussion:reply:error:notfound_fallback')); forward($fallback->getURL()); } if (!elgg_instanceof($reply, 'object', 'discussion_reply')) { $fail(); } // start with topic URL $topic = $reply->getContainerEntity(); // this won't work with threaded comments, but core doesn't support that yet $count = elgg_get_entities(['type' => 'object', 'subtype' => $reply->getSubtype(), 'container_guid' => $topic->guid, 'count' => true, 'wheres' => ["e.guid < " . (int) $reply->guid]]); $limit = (int) get_input('limit', 0); if (!$limit) { $limit = _elgg_services()->config->get('default_limit'); } $offset = floor($count / $limit) * $limit; if (!$offset) { $offset = null; } $url = elgg_http_add_url_query_elements($topic->getURL(), ['offset' => $offset]); // make sure there's only one fragment (#) $parts = parse_url($url); $parts['fragment'] = "elgg-object-{$reply->guid}"; $url = elgg_http_build_url($parts, false); forward($url); }