/** * Standardize a URL into an array of values that can be accurately compared with another * * Preps URL, by removing any UTF Left-to-right Mark (LRM), usually found as a suffix, * translating the URL to lower-case, removing prefix http[s]//:, * any embedded index.php and any trailing slash or #bookmark, * and breaks up ?keyword=value queries into array elements. * * Structure/Elements of Array returned: * [host] - domain.com - all subdomains, including www., are included * [path] - dir/file.ext * [query] - any Queries (e.g. - "?kw=val&kw2=val2") broken up as follows: * [$keyword] => [$value] => $equalsign * $value - blank if not present * $equalsign - bool indicating if = was present in URL * Format prior to Version 7.0: * [$keyword] => $value with preceding equals sign, only if equals sign was present * To simplify processing of this Array, zero length strings and empty arrays are used, * rather than NULL entries or missing array elements. * * @param string $url URL to create an array from, in special format for accurate comparison * @return array array of standardized attributes of the URL (see structure above) */ function jr_mt_prep_url($url) { /* Handle troublesome %E2%80%8E UTF Left-to-right Mark (LRM) suffix first. */ if (FALSE === strpos($url, '%E2%80%8E')) { if (FALSE === strpos(rawurlencode($url), '%E2%80%8E')) { $url_clean = $url; } else { $url_clean = rawurldecode(str_replace('%E2%80%8E', '', rawurlencode($url))); /* mb_str_replace() does not exist because str_replace() is binary-safe. */ } } else { $url_clean = str_replace('%E2%80%8E', '', $url); } $url_clean = str_replace('\\', '/', trim($url_clean)); /* parse_url(), especially before php Version 5.4.7, has a history of problems when Scheme is not present, especially for LocalHost as a Host, so add a prefix of http:// if :// is not found */ if (FALSE === strpos($url_clean, '://')) { $url_clean = "http://{$url_clean}"; } $parse_array = parse_url(jr_mt_strtolower($url_clean)); /* Get rid of URL components that do not matter to us in our comparison of URLs */ foreach (array('scheme', 'user', 'pass', 'fragment') as $component) { unset($parse_array[$component]); } /* Remove standard HTTP Port 80 and HTTPS Port 443, if present. */ $parse_array['port'] = jr_mt_non_default_port($parse_array, 'port'); if (isset($parse_array['path'])) { /* Remove any index.php occurences in path, since these can be spurious in IIS and perhaps other environments. */ $parse_array['path'] = str_replace('index.php', '', $parse_array['path']); /* Remove leading and trailing slashes from path */ $parse_array['path'] = rtrim($parse_array['path'], "/\\"); } else { $parse_array['path'] = ''; } /* Take /?keyword=value&keyword=value URL query parameters and break them up into array( keyword => value => equals?, keyword => value => equals? ) */ if (isset($parse_array['query'])) { $parms = explode('&', $parse_array['query']); $parse_array['query'] = array(); foreach ($parms as $parm) { if (FALSE === strpos($parm, '=')) { $parse_array['query'][$parm][''] = FALSE; } else { $kwv = explode('=', $parm); $parse_array['query'][$kwv[0]][$kwv[1]] = TRUE; } /* Remember the presence of the Equals Sign ("=") in each Query to differentiate between a URL Prefix with a Query Keyword followed by an Equals Sign, and one without. For example, "address" would match address2=abc, while "address=" would not. */ } } else { $parse_array['query'] = array(); } return $parse_array; }
/** * Returns FALSE for Current Theme * */ function jr_mt_chosen() { $settings = get_option('jr_mt_settings'); /* $queries - array of [keyword] => array( value, value, ... ) in the current URL. */ $queries = jr_mt_query_array(); /* KnowHow ThemeForest Paid Theme special processing: if s= is present, and 'knowhow' is either the active WordPress Theme or is specified in any Settings, then automatically select the KnowHow theme. */ if (isset($queries['s']) && in_array('knowhow', jr_mt_themes_defined(), TRUE)) { return 'knowhow'; } /* Non-Admin page, i.e. - Public Site, etc. Begin by checking for any Query keywords specified by the Admin in Settings, complicated by the fact that Override entries take precedence. */ if (!empty($settings['query'])) { if (!empty($_SERVER['QUERY_STRING'])) { /* Check Override entries */ foreach ($settings['override']['query'] as $override_keyword => $override_value_array) { if (isset($queries[$override_keyword])) { foreach ($override_value_array as $override_value_untyped => $bool) { $override_value = (string) $override_value_untyped; if (in_array($override_value, $queries[$override_keyword], TRUE)) { $override_found[] = array($override_keyword, $override_value); } } } } if (!isset($overrides_found)) { /* Look for both keyword=value settings and keyword=* settings, with keyword=value taking precedence (sorted out later). */ foreach ($settings['query'] as $query_settings_keyword => $value_array) { if (isset($queries[$query_settings_keyword])) { foreach ($value_array as $query_settings_value_untyped => $theme) { $query_settings_value = (string) $query_settings_value_untyped; if (in_array($query_settings_value, $queries[$query_settings_keyword], TRUE)) { $query_found[] = array($query_settings_keyword, $query_settings_value); } } if (isset($value_array['*'])) { $keyword_found[] = $query_settings_keyword; } } } } } } /* Handle Overrides: First, for Override keyword=value query in URL. Second, for previous Override detected by PHP cookie. */ if (isset($override_found)) { /* If sticky, create JavaScript Sticky Cookie, and PHP Sticky Cookie. No matter what: return Theme from the first Override found. */ $keyword = $override_found[0][0]; $value = $override_found[0][1]; if (isset($settings['remember']['query'][$keyword][$value])) { jr_mt_js_sticky_query($keyword, $value); jr_mt_cookie('php', 'put', "{$keyword}={$value}"); } return $settings['query'][$keyword][$value]; } else { /* Is there a previous Override Query for this Site Visitor? If so, use it, but only if it is still valid. */ if (FALSE !== ($cookie = jr_mt_cookie('php', 'get'))) { list($keyword, $value) = explode('=', $cookie); if (isset($settings['override']['query'][$keyword][$value])) { /* If sticky, create JavaScript Sticky Cookie, and renew PHP Sticky Cookie. No matter what: Return Theme */ if (isset($settings['remember']['query'][$keyword][$value])) { jr_mt_js_sticky_query($keyword, $value); jr_mt_cookie('php', 'put', "{$keyword}={$value}"); } return $settings['query'][$keyword][$value]; } } } /* Handle Non-Overrides: keyword=value query in URL with matching setting entry. */ if (isset($query_found)) { $query_keyword_found = $query_found[0][0]; $query_value_found = $query_found[0][1]; /* Probably makes sense to give preference to the Sticky ones */ foreach ($query_found as $query_kwval_array) { if (isset($settings['remember']['query'][$query_kwval_array[0]][$query_kwval_array[1]])) { $query_keyword_found = $query_kwval_array[0]; $query_value_found = $query_kwval_array[1]; /* Create JavaScript Sticky Cookie, and PHP Sticky Cookie. */ jr_mt_js_sticky_query($query_keyword_found, $query_value_found); jr_mt_cookie('php', 'put', "{$query_keyword_found}={$query_value_found}"); break; } } /* Return Theme */ return $settings['query'][$query_keyword_found][$query_value_found]; } /* Handle Keyword wildcards: keyword=* setting entry that matches keyword in URL query. */ if (isset($keyword_found)) { return $settings['query'][$keyword_found[0]]['*']; } /* Now look at URL entries: $settings['url'] and ['url_prefix'] Version 6.0 Logic Design to maximize performance on high traffic sites without Caching: For current URL, determine Site Alias in use - Best Match - from an array of matching Site Aliases, determine "Best", some measure of Longest Prep current URL for matching Check for match in "URL" plugin entries that have been pre-prepped with this Site Alias Check for match in "URL Prefix" plugin entries that have been pre-prepped with this Site Alias Check for match in "URL Prefix with Asterisk" plugin entries that have been pre-prepped with this Site Alias */ if (0 === ($port = jr_mt_non_default_port($_SERVER, 'SERVER_PORT'))) { $url_port = ''; } else { $url_port = ':' . $port; } $prep_url = jr_mt_prep_url($current_url = parse_url(JR_MT_HOME_URL, PHP_URL_SCHEME) . '://' . $_SERVER['SERVER_NAME'] . $url_port . $_SERVER['REQUEST_URI']); $match = array(); foreach ($settings['aliases'] as $key => $alias_array) { if (jr_mt_same_prefix_url($alias_array['prep'], $prep_url)) { $match[] = $key; } } if (empty($match)) { /* Maybe not the best thing to do, but if Site Alias is not defined, always use Current Theme. */ return FALSE; } $site_alias_key = jr_mt_best_match_alias($settings['aliases'], $match); foreach ($settings['url'] as $settings_array) { if (jr_mt_same_url($settings_array['prep'][$site_alias_key], $prep_url)) { return $settings_array['theme']; } } foreach ($settings['url_prefix'] as $settings_array) { if (jr_mt_same_prefix_url($settings_array['prep'][$site_alias_key], $prep_url)) { return $settings_array['theme']; } } foreach ($settings['url_asterisk'] as $settings_array) { if (jr_mt_same_prefix_url_asterisk($settings_array['prep'][$site_alias_key], $prep_url)) { return $settings_array['theme']; } } /* Theme to use for All /wp-admin/admin-ajax.php usage. Selected near the end to allow Queries to take precedence. */ if (!empty($settings['ajax_all']) && FALSE !== strpos($_SERVER['REQUEST_URI'], 'admin-ajax.php')) { return $settings['ajax_all']; } /* Must check for Home near the end as queries override Home is determined in an odd way: (1) Remove all Queries (2) Match against Site Address (URL) specified in Admin General Settings (3) Check if any non-Permalink keywords are present, such as p= or page_id= and cause a non-match if present */ if ('' !== $settings['site_home']) { /* Check for Home Page, with or without Query. */ $prep_url_no_query = $prep_url; $prep_url_no_query['query'] = array(); if (jr_mt_same_url(JR_MT_HOME_URL, $prep_url_no_query)) { $home = TRUE; $internal_settings = get_option('jr_mt_internal_settings'); if (isset($internal_settings['query_vars']) && is_array($internal_settings['query_vars'])) { foreach ($prep_url['query'] as $keyword => $value) { /* Check for any non-Permalink Query Keyword */ if (in_array($keyword, $internal_settings['query_vars'], TRUE)) { $home = FALSE; break; } } } if ($home) { return $settings['site_home']; } else { /* Check for Settings specifying the current Page, Post or Attachment specified with kw=val Query default Permalinks. */ foreach ($settings['url'] as $settings_array) { if (isset($settings_array['id_kw']) && isset($prep_url['query'][$settings_array['id_kw']]) && $prep_url['query'][$settings_array['id_kw']] === $settings_array['id']) { return $settings_array['theme']; } } } } } /* All Pages and All Posts settings are checked second to last, just before Everything Else. url_to_postid() only works after JR_MT_PAGE_CONDITIONAL is set. But alternate means can be used with default Permalinks. First, see if any All Pages or All Posts setting exists. */ if (jr_mt_all_posts_pages()) { if (defined('JR_MT_PAGE_CONDITIONAL')) { if (0 !== ($id = url_to_postid($current_url))) { if (NULL !== ($post = get_post($id))) { $type = $post->post_type; if ('post' === $type) { if ('' !== $settings['all_posts']) { return $settings['all_posts']; } } else { if ('page' === $type) { if ('' !== $settings['all_pages']) { return $settings['all_pages']; } } } } } } else { $permalink = get_option('permalink_structure'); if (empty($permalink)) { if ('' !== $settings['all_posts']) { if (isset($queries['p'])) { return $settings['all_posts']; } } if ('' !== $settings['all_pages']) { if (isset($queries['page_id'])) { return $settings['all_pages']; } } } } } /* This is the Theme for Everything Advanced Setting. A Setting of Blank uses WordPress Current Theme value, i.e. - the Setting is not set. */ if ('' === $settings['current']) { return FALSE; } else { return $settings['current']; } }