/**
 * Merge user defined arguments into defaults array.
 *
 * This function is used to allow for both string or array
 * to be merged into another array.
 *
 *
 * @param string|array $args Value to merge with $defaults
 * @param array $defaults Array that serves as the defaults.
 * @return array Merged user defined values with defaults.
 */
function cm_parse_args($args, $defaults = '')
{
    if (is_object($args)) {
        $r = get_object_vars($args);
    } elseif (is_array($args)) {
        $r =& $args;
    } else {
        cm_parse_str($args, $r);
    }
    if (is_array($defaults)) {
        return array_merge($defaults, $r);
    }
    return $r;
}
/**
 * Retrieve a modified URL query string.
 *
 * You can rebuild the URL and append a new query variable to the URL query by
 * using this function. You can also retrieve the full URL with query data.
 *
 * Adding a single key & value or an associative array. Setting a key value to
 * emptystring removes the key. Omitting oldquery_or_uri uses the $_SERVER
 * value.
 *
 * @since 1.5.0
 *
 * @param mixed $param1 Either newkey or an associative_array
 * @param mixed $param2 Either newvalue or oldquery or uri
 * @param mixed $param3 Optional. Old query or uri
 * @return string New URL query string.
 */
function add_query_arg()
{
    $ret = '';
    if (is_array(func_get_arg(0))) {
        if (@func_num_args() < 2 || false === @func_get_arg(1)) {
            $uri = $_SERVER['REQUEST_URI'];
        } else {
            $uri = @func_get_arg(1);
        }
    } else {
        if (@func_num_args() < 3 || false === @func_get_arg(2)) {
            $uri = $_SERVER['REQUEST_URI'];
        } else {
            $uri = @func_get_arg(2);
        }
    }
    if ($frag = strstr($uri, '#')) {
        $uri = substr($uri, 0, -strlen($frag));
    } else {
        $frag = '';
    }
    if (preg_match('|^https?://|i', $uri, $matches)) {
        $protocol = $matches[0];
        $uri = substr($uri, strlen($protocol));
    } else {
        $protocol = '';
    }
    if (strpos($uri, '?') !== false) {
        $parts = explode('?', $uri, 2);
        if (1 == count($parts)) {
            $base = '?';
            $query = $parts[0];
        } else {
            $base = $parts[0] . '?';
            $query = $parts[1];
        }
    } elseif (!empty($protocol) || strpos($uri, '=') === false) {
        $base = $uri . '?';
        $query = '';
    } else {
        $base = '';
        $query = $uri;
    }
    cm_parse_str($query, $qs);
    $qs = urlencode_deep($qs);
    // this re-URL-encodes things that were already in the query string
    if (is_array(func_get_arg(0))) {
        $kayvees = func_get_arg(0);
        $qs = array_merge($qs, $kayvees);
    } else {
        $qs[func_get_arg(0)] = func_get_arg(1);
    }
    foreach ((array) $qs as $k => $v) {
        if ($v === false) {
            unset($qs[$k]);
        }
    }
    $ret = build_query($qs);
    $ret = trim($ret, '?');
    $ret = preg_replace('#=(&|$)#', '$1', $ret);
    $ret = $protocol . $base . $ret . $frag;
    $ret = rtrim($ret, '?');
    return $ret;
}