/**
 * Transforms parameters into URL by following user-defined rules.
 * This function can be overloaded by cot_url_custom().
 *
 * @param string $name Module or script name
 * @param mixed $params URL parameters as array or parameter string
 * @param string $tail URL postfix, e.g. anchor
 * @param bool $htmlspecialchars_bypass If TRUE, will not convert & to & and so on.
 * @return string Valid HTTP URL
 * @see cot_url()
 */
function cot_url_custom($name, $params = '', $tail = '', $htmlspecialchars_bypass = false)
{
    global $cfg, $cot_urltrans, $sys, $cot_url_shortcuts;
    $q_s = str_replace('%5B', '[', str_replace('%5D', ']', http_build_query($params)));
    if (isset($cot_url_shortcuts[$name][$q_s])) {
        return $cot_url_shortcuts[$name][$q_s];
    }
    // Preprocess arguments
    if (is_string($params)) {
        $params = cot_parse_str($params);
    }
    // Initialize with something very default
    $url = $name == 'plug' ? 'index.php' : 'index.php?e=' . $name;
    // Detect search areas
    $areas = array();
    if (isset($cot_urltrans[$name]) && count($cot_urltrans[$name]) > 0) {
        $areas[] = $name;
    }
    $areas[] = '*';
    // default area rules
    // Find first matching rule
    $rule = array();
    foreach ($areas as $area) {
        foreach ($cot_urltrans[$area] as $rule) {
            $matched = true;
            foreach ($rule['params'] as $key => $val) {
                if (!isset($params[$key]) || empty($params[$key]) || is_array($val) && !in_array($params[$key], $val) || $val != '*' && $params[$key] != $val) {
                    $matched = false;
                    break;
                }
            }
            if ($matched) {
                $url = $rule['trans'];
                break 2;
            }
        }
    }
    // Some special substitutions
    $spec['_area'] = $name;
    $spec['_host'] = $sys['host'];
    $spec['_rhost'] = $_SERVER['HTTP_HOST'];
    $spec['_path'] = COT_SITE_URI;
    // Transform the data into URL
    if (preg_match_all('#\\{(.+?)\\}#', $url, $matches, PREG_SET_ORDER)) {
        foreach ($matches as $m) {
            if ($p = mb_strpos($m[1], '(')) {
                // Callback
                $func = mb_substr($m[1], 0, $p);
                $arg = mb_substr($m[1], $p + 1, mb_strpos($m[1], ')') - $p - 1);
                $sub = empty($arg) ? $func($params, $spec) : $func($params, $spec, $arg);
                $url = str_replace($m[0], $sub, $url);
            } elseif (mb_strpos($m[1], '!$') === 0) {
                // Unset
                $var = mb_substr($m[1], 2);
                $url = str_replace($m[0], '', $url);
                unset($params[$var]);
            } else {
                // Substitute
                $var = mb_substr($m[1], 1);
                if (isset($spec[$var])) {
                    $url = str_replace($m[0], $spec[$var], $url);
                } elseif (isset($params[$var])) {
                    $url = str_replace($m[0], rawurlencode($params[$var]), $url);
                    unset($params[$var]);
                } else {
                    $url = str_replace($m[0], rawurlencode($GLOBALS[$var]), $url);
                }
            }
        }
    }
    // Support for i18n parameter
    if (isset($params['l']) && isset($cfg['plugin']['i18n']['rewrite']) && $cfg['plugin']['i18n']['rewrite']) {
        // Add with slash at the beginning of the URL
        $pos = strpos($url, $sys['site_uri']);
        if ($sys['site_uri'] != '/' && $pos !== false) {
            $url = substr_replace($url, $sys['site_uri'] . rawurlencode($params['l']) . '/', $pos, mb_strlen($sys['site_uri']));
        } else {
            $p = mb_strpos($url, '://');
            if ($p === false) {
                $url = mb_strpos($url, '/') === 0 ? '/' . rawurlencode($params['l']) . $url : rawurlencode($params['l']) . '/' . $url;
            } else {
                $p = mb_strpos($url, '/', $p + 3);
                $url = $p === false ? $url . '/' . rawurlencode($params['l']) : mb_substr($url, 0, $p) . rawurlencode($params['l']) . '/' . mb_substr($url, $p + 1);
            }
        }
        unset($params['l']);
    }
    // Append query string if needed
    if (!empty($params)) {
        $sep = $htmlspecialchars_bypass ? '&' : '&';
        $url_tail = version_compare(PHP_VERSION, '5.4.0', '>=') ? http_build_query($params, '', $sep, PHP_QUERY_RFC3986) : str_replace('+', '%20', http_build_query($params, '', $sep));
        if (!empty($url_tail)) {
            $url .= (mb_strpos($url, '?') === false ? '?' : $sep) . $url_tail;
        }
    }
    // Almost done
    $url .= $tail;
    $url = str_replace('&', '&', $url);
    return $url;
}
Example #2
0
/**
 * Constructs a modified version of a current URL.
 * @param  array   $params                  Modified params
 * @param  string  $tail                    URL postfix, e.g. anchor
 * @param  bool    $htmlspecialchars_bypass If TRUE, will not convert & to & and so on.
 * @param  bool    $ignore_appendix         If TRUE, $cot_url_appendix will be ignored for this URL
 * @return string                           Valid HTTP URL
 */
function cot_url_modify($params = array(), $tail = '', $htmlspecialchars_bypass = false, $ignore_appendix = false)
{
    // Preprocess arguments
    if (is_string($params)) {
        $params = cot_parse_str($params);
    }
    if (!is_array($params)) {
        $params = array();
    }
    $area = defined('COT_PLUG') ? 'plug' : cot::$env['ext'];
    $params = array_merge($_GET, $params);
    if (!defined('COT_PLUG')) {
        unset($params['e']);
    }
    unset($params['rwr']);
    return cot_url($area, $params, $tail, $htmlspecialchars_bypass, $ignore_appendix);
}