Example #1
0
/**
 * Attempt to use mod_rewrite to improve this URL.
 *
 * @param  ID_TEXT		The name of the zone for this
 * @param  array			A map of variables to include in our URL
 * @param  boolean		Force inclusion of the index.php name into a short URL, so something may tack on extra parameters to the result here
 * @return ?URLPATH		The improved URL (NULL: couldn't do anything)
 */
function _url_rewrite_params($zone_name, $vars, $force_index_php = false)
{
    global $URL_REMAPPINGS;
    if ($URL_REMAPPINGS === NULL) {
        $old_style = get_option('htm_short_urls') != '1';
        require_code('url_remappings');
        $URL_REMAPPINGS = get_remappings($old_style);
    }
    // Find mapping
    foreach ($URL_REMAPPINGS as $_remapping) {
        list($remapping, $target, $require_full_coverage) = $_remapping;
        //		if (count($remapping)!=$num_vars) continue;
        $good = true;
        $last_key_num = count($remapping);
        $loop_cnt = 0;
        foreach ($remapping as $key => $val) {
            $loop_cnt++;
            $last = $loop_cnt == $last_key_num;
            if (!is_string($val) && $val !== NULL) {
                $val = strval($val);
            }
            if (array_key_exists($key, $vars) && is_integer($vars[$key])) {
                $vars[$key] = strval($vars[$key]);
            }
            if (!((isset($vars[$key]) || $val === NULL && $key == 'type' && array_key_exists('id', $vars)) && ($key != 'page' || $vars[$key] != '' || $val === '') && (!array_key_exists($key, $vars) || $vars[$key] != '' || !$last) && ($val === NULL || $vars[$key] == $val))) {
                $good = false;
                break;
            }
        }
        if ($require_full_coverage) {
            foreach ($_GET as $key => $val) {
                if (!is_string($val)) {
                    continue;
                }
                if (substr($key, 0, 5) == 'keep_' && !skippable_keep($key, $val)) {
                    $good = false;
                }
            }
            foreach ($vars as $key => $val) {
                if (!array_key_exists($key, $remapping) && $val !== NULL && ($key != 'page' || $vars[$key] != '')) {
                    $good = false;
                }
            }
        }
        if ($good) {
            // We've found one, now let's sort out the target
            $makeup = $target;
            if ($GLOBALS['DEBUG_MODE']) {
                foreach ($vars as $key => $val) {
                    if (is_integer($val)) {
                        $vars[$key] = strval($val);
                    }
                }
            }
            $extra_vars = array();
            foreach (array_keys($remapping) as $key) {
                if (!isset($vars[$key])) {
                    continue;
                }
                $val = $vars[$key];
                unset($vars[$key]);
                $makeup = str_replace(strtoupper($key), ocp_url_encode_mini($val, true), $makeup);
            }
            if (!$require_full_coverage) {
                $extra_vars += $vars;
            }
            $makeup = str_replace('TYPE', 'misc', $makeup);
            if ($makeup == '') {
                $makeup .= get_zone_default_page($zone_name) . '.htm';
            }
            if ($extra_vars != array() || $force_index_php) {
                if (get_option('htm_short_urls') != '1') {
                    $makeup .= '/index.php';
                }
                $first = true;
                foreach ($extra_vars as $key => $val) {
                    if ($val === NULL) {
                        continue;
                    }
                    if (is_integer($key)) {
                        $key = strval($key);
                    }
                    if ($val === SELF_REDIRECT) {
                        $val = get_self_url(true, true);
                    }
                    $makeup .= ($first ? '?' : '&') . $key . '=' . ocp_url_encode($val, true);
                    $first = false;
                }
            }
            return $makeup;
        }
    }
    return NULL;
}
Example #2
0
/**
 * Convert a local URL to a page-link.
 *
 * @param  URLPATH		The URL to convert. Note it may not be a short URL, and it must be based on the local base URL (else failure WILL occur).
 * @param  boolean		Whether to only convert absolute URLs. Turn this on if you're not sure what you're passing is a URL not and you want to be extra safe.
 * @param  boolean		Whether to only allow perfect conversions.
 * @return string			The page link (blank: could not convert).
 */
function _url_to_pagelink($url, $abs_only = false, $perfect_only = true)
{
    if ($abs_only && substr($url, 0, 7) != 'http://' && substr($url, 0, 8) != 'https://') {
        return '';
    }
    // Try and strip any variants of the base URL from our $url variable, to make it relative
    $non_www_base_url = str_replace('http://www.', 'http://', get_base_url());
    $www_base_url = str_replace('http://', 'http://www.', get_base_url());
    $url = preg_replace('#^' . str_replace('#', '\\#', preg_quote(get_base_url() . '/')) . '#', '', $url);
    $url = preg_replace('#^' . str_replace('#', '\\#', preg_quote($non_www_base_url . '/')) . '#', '', $url);
    $url = preg_replace('#^' . str_replace('#', '\\#', preg_quote($www_base_url . '/')) . '#', '', $url);
    if (substr($url, 0, 7) == 'http://') {
        return '';
    }
    if (substr($url, 0, 8) == 'https://') {
        return '';
    }
    if (substr($url, 0, 1) != '/') {
        $url = '/' . $url;
    }
    // Parse the URL
    if (strpos($url, '&') !== false && strpos($url, '?') === false) {
        $url = preg_replace('#&#', '?', $url, 1);
    }
    // Old-style short URLs workl like this (no first ?, just &)
    $parsed_url = @parse_url($url);
    if ($parsed_url === false) {
        require_code('site');
        attach_message(do_lang_tempcode('HTTP_DOWNLOAD_BAD_URL', escape_html($url)), 'warn');
        return '';
    }
    // Work out the zone
    $slash_pos = strpos($parsed_url['path'], '/', 1);
    $zone = $slash_pos !== false ? substr($parsed_url['path'], 1, $slash_pos - 1) : '';
    if (!in_array($zone, find_all_zones())) {
        $zone = '';
        $slash_pos = false;
    }
    $parsed_url['path'] = $slash_pos === false ? substr($parsed_url['path'], 1) : substr($parsed_url['path'], $slash_pos + 1);
    // everything AFTER the zone
    $parsed_url['path'] = preg_replace('#/index\\.php$#', '', $parsed_url['path']);
    $attributes = array();
    $attributes['page'] = '';
    // hopefully will get overwritten with a real one
    // Convert short URL path info into extra implied attribute data
    require_code('url_remappings');
    foreach (array(false, true) as $method) {
        $mappings = get_remappings($method);
        foreach ($mappings as $mapping) {
            if (is_null($mapping)) {
                continue;
            }
            list($params, $match_string, ) = $mapping;
            $match_string_pattern = preg_replace('#[A-Z]+#', '[^\\&\\?]+', preg_quote($match_string));
            $zones = find_all_zones();
            if (preg_match('#^' . $match_string_pattern . '$#', $parsed_url['path']) != 0) {
                $attributes = array_merge($attributes, $params);
                $bits_pattern = explode('/', preg_replace('#\\.htm$#', '', $match_string));
                $bits_real = explode('/', preg_replace('#\\.htm$#', '', $parsed_url['path']), count($bits_pattern));
                foreach ($bits_pattern as $i => $bit) {
                    if (array_key_exists(strtolower($bit), $params) && strtoupper($bit) == $bit && is_null($params[strtolower($bit)])) {
                        $attributes[strtolower($bit)] = $bits_real[$i];
                    }
                }
                break;
            }
        }
    }
    if ($attributes == array('page' => '') && $parsed_url['path'] != '') {
        if (strpos($parsed_url['path'], '/pg/') === false && strpos($parsed_url['path'], '.htm') === false && $parsed_url['path'] != 'index.php') {
            return '';
        }
    }
    // Parse query string component into the waiting (and partly-filled-already) attribute data array
    if (array_key_exists('query', $parsed_url)) {
        $bits = explode('&', $parsed_url['query']);
        foreach ($bits as $bit) {
            $_bit = explode('=', $bit, 2);
            if (count($_bit) == 2) {
                $attributes[$_bit[0]] = $_bit[1];
                if (strpos($attributes[$_bit[0]], ':') !== false) {
                    if ($perfect_only) {
                        return '';
                    }
                    // Could not convert this URL to a page-link, because it contains a colon
                    unset($attributes[$_bit[0]]);
                }
            }
        }
    }
    // Put it together
    $page_link = $zone . ':' . $attributes['page'];
    if (array_key_exists('type', $attributes)) {
        $page_link .= ':' . $attributes['type'];
    } elseif (array_key_exists('id', $attributes)) {
        $page_link .= ':';
    }
    if (array_key_exists('id', $attributes)) {
        $page_link .= ':' . urldecode($attributes['id']);
    }
    foreach ($attributes as $key => $val) {
        if (!is_string($val)) {
            $val = strval($val);
        }
        if ($key != 'page' && $key != 'type' && $key != 'id') {
            $page_link .= ':' . $key . '=' . urldecode($val);
        }
    }
    // Hash bit?
    if (array_key_exists('fragment', $parsed_url)) {
        $page_link .= '#' . $parsed_url['fragment'];
    }
    return $page_link;
}