├── .gitignore ├── README.md ├── UrlToQuery.php ├── UrlToQueryItem.php ├── composer.json ├── license └── url_to_query.php /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | ehthumbs.db 3 | Desktop.ini 4 | $RECYCLE.BIN/ 5 | .DS_Store 6 | .coverage 7 | .tox 8 | vendor/ 9 | composer.lock 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Url To Query 2 | ============ 3 | 4 | A WordPress plugin that allow resolving any kind of WordPress url (even from custom rewrite rules) to related main query arguments. 5 | 6 | #Requirements 7 | 8 | - PHP 5.4+ 9 | - WordPress 3.9+ 10 | - [Composer](https://getcomposer.org/) to install 11 | 12 | #Installation 13 | 14 | The plugin is a Composer package and can be installed in plugin directory via: 15 | 16 | ``` bash 17 | composer create-project gmazzap/url-to-query --no-dev 18 | ``` 19 | 20 | ## What & Why 21 | 22 | WP comes with a set of tools to convert custom urls into specific query variables: 23 | is possible to change the [permalink structure](http://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure), and there is also an [API](http://codex.wordpress.org/Rewrite_API/add_rewrite_rule) to add completely custom rules, however, there is **not** a way to *reverse* the process: i.e. to know to which query arguments an arbitrary url is connected to. 24 | 25 | The url *resolving* is done in core by [`parse_request`](https://github.com/WordPress/WordPress/blob/71eb75a1599be8b456b2040f7ac2235c0e6b217e/wp-includes/class-wp.php#L120) method of `WP` class saved in the global `$wp` variable. 26 | 27 | Using that method for the purpose explained above is hard/discouraged because: 28 | * it directly accesses to `$_SERVER`, `$_POST` and `$_GET` variables, making hard to parse arbitrary urls not related with current HTTP request 29 | * it triggers some action hooks strictly related to current HTTP request parsing, that makes no sense to trigger for arbitrary urls 30 | * it accesses and modifies properties of global `$wp` variable that should not be changed after request is parsed or very likely *things* will break 31 | 32 | This is the reason why I wrote this simple plugin, it adds a template tag **`url_to_query`** that accepts an url and returns related main query arguments. 33 | 34 | ##How to use## 35 | 36 | ``` php 37 | $args = url_to_query( 'http://example.com/sample-page' ); 38 | // $args = array( 'pagename' => 'sample-page' ); 39 | 40 | $args = url_to_query( 'http://example.com/category/uncategorized/' ) 41 | // $args = array( 'category_name' => 'uncategorized' ); 42 | ``` 43 | 44 | It is also possible to pass a relative url: 45 | 46 | ``` php 47 | $args = url_to_query( '/sample-page' ); 48 | // $args = array( 'pagename' => 'sample-page' ); 49 | ``` 50 | 51 | ###Using query string### 52 | 53 | When pretty permalinks are not used, (sometimes even in that case) WordPress can make use of query string in the 54 | urls to set query arguments. The plugin works perfectly with them: 55 | 56 | ``` php 57 | $args = url_to_query( '/?attachment_id=880' ); 58 | $args = array( 'attachment_id' => '880' ); 59 | ``` 60 | 61 | To simplify this task, `url_to_query` accepts a second argument: an array of query vars to be considered 62 | in the same way core considers `$_REQUEST` variables when an url is parsed: 63 | 64 | ``` php 65 | $args = url_to_query( '/', array( 'attachment_id' => '880' ) ); 66 | // $args = array( 'attachment_id' => '880' ); 67 | ``` 68 | 69 | Note that the array passed as second argument is not straight merged to the query vars, only valid query vars will be used, just like core does when parse urls: 70 | 71 | ``` php 72 | $args = url_to_query( '/', array( 'attachment_id' => '880', 'foo' => 'bar' ) ); 73 | // $args = array( 'attachment_id' => '880' ); 74 | ``` 75 | 76 | ###Custom rewrite rules### 77 | 78 | Plugin works with no problems with custom rewrite rules, just few things to consider: 79 | 80 | * `url_to_query` have to be called *after* query rules are added, or it can't recognize them 81 | * just like for core, rewrite rules have to be flushed before `url_to_query` can recognize a newly added rule 82 | * just like core, if the rule contains custom query variables, they have to be *allowed*, maybe using [`add_rewrite_tag`](http://codex.wordpress.org/Rewrite_API/add_rewrite_tag) 83 | or using `'query_vars'` filter (see [Codex example](http://codex.wordpress.org/Custom_Queries#Custom_Archives)) 84 | 85 | Example: 86 | 87 | ``` php 88 | add_action( 'init', 'my_rew_rules' ); 89 | 90 | function my_rew_rules() { 91 | add_rewrite_tag('%food%', '([^&]+)'); 92 | add_rewrite_tag('%variety%', '([^&]+)'); 93 | add_rewrite_rule( 94 | '^nutrition/([^/]*)/([^/]*)/?', 95 | 'index.php?page_id=12&food=$matches[1]&variety=$matches[2]', 96 | 'top' 97 | ); 98 | } 99 | 100 | add_action( 'footer' function() { 101 | $args = url_to_query( '/nutrition/cake/cherry/' ) 102 | // $args = array( 'page_id' => '12', 'food' => 'cake', 'variety' => 'cherry' ); 103 | } ); 104 | ``` 105 | 106 | ###Plugin classes### 107 | 108 | Even if plugin provides the `'url_to_query'` template tag, it internally uses two classes to resolve urls and 109 | it is possible directly use them, instead of the template tag. Indeed, only one of them should be used, the second is used internally. 110 | 111 | ``` php 112 | $resolver = new GM\UrlToQuery(); 113 | $args = $resolver->resolve( 'http://example.com/sample-page', array( 'page' => '2' ) ); 114 | // $args = array( 'pagename' => 'sample-page', 'page' => '2' ); 115 | ``` 116 | 117 | So `resolve()` method of `GM\UrlToQuery` works exactly in the same way `url_to_query` function does. 118 | 119 | The same instance of `GM\UrlToQuery` can be used to resolve different urls: 120 | 121 | ``` php 122 | $resolver = new GM\UrlToQuery(); 123 | 124 | $args1 = $resolver->resolve( 'http://example.com/sample-page', array( 'page' => '2' ) ); 125 | // $args1 = array( 'pagename' => 'sample-page', 'page' => '2' ); 126 | 127 | $args2 = $resolver->resolve( '/?attachment_id=880' ); 128 | // $args2 = array( 'attachment_id' => '880' ); 129 | 130 | $args3 = $resolver->resolve( 'http://example.com/category/uncategorized/' ); 131 | // $args3 = array( 'category_name' => 'uncategorized' ); 132 | ``` 133 | 134 | 135 | ================ 136 | 137 | # License 138 | 139 | Url_To_Query is released under MIT. 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /UrlToQuery.php: -------------------------------------------------------------------------------- 1 | use_verbose_page_rules 13 | * @var bool 14 | */ 15 | private $use_verbose; 16 | 17 | /** 18 | * Global WP object 19 | * @var \WP 20 | */ 21 | private $wp; 22 | 23 | /** 24 | * Extra variables to be added to any query resolved 25 | * @var array 26 | */ 27 | private $extra_query_vars = [ ]; 28 | 29 | /** 30 | * Array of the instantiated \GM\UrlToQueryItem objects 31 | * @var array 32 | */ 33 | private $items = [ ]; 34 | 35 | /** 36 | * Constructor 37 | * @param array $extra_query_vars Extra variables to be added to any query resolved 38 | */ 39 | function __construct( $extra_query_vars = [ ] ) { 40 | if ( is_array( $extra_query_vars ) ) { 41 | $this->extra_query_vars = $extra_query_vars; 42 | } elseif ( is_string( $extra_query_vars ) && ! empty( $extra_query_vars ) ) { 43 | parse_str( $extra_query_vars, $this->extra_query_vars ); 44 | } 45 | $this->rewrite = $GLOBALS['wp_rewrite']->wp_rewrite_rules(); 46 | $this->wp = $GLOBALS['wp']; 47 | $this->use_verbose = (bool) $GLOBALS['wp_rewrite']->use_verbose_page_rules; 48 | } 49 | 50 | /** 51 | * Resolve an url to an array of WP_Query arguments for main query 52 | * 53 | * @param string $url Url to resolve 54 | * @param type $query_string_vars Query variables to be added to the url 55 | * @return array|\WP_Error Resolved query or WP_Error is something goes wrong 56 | */ 57 | function resolve( $url = '', $query_string_vars = [ ] ) { 58 | $url = filter_var( $url, FILTER_SANITIZE_URL ); 59 | if ( ! empty( $url ) ) { 60 | $id = md5( $url . serialize( $query_string_vars ) ); 61 | if ( ! isset( $this->items[$id] ) || ! $this->items[$id] instanceof UrlToQueryItem ) { 62 | $this->items[$id] = new UrlToQueryItem( $this ); 63 | } 64 | $result = $this->items[$id]->resolve( $url, $query_string_vars ); 65 | } else { 66 | $result = new \WP_Error( 'url-to-query-bad-url' ); 67 | } 68 | return $result; 69 | } 70 | 71 | /** 72 | * Get the rewrite rules array 73 | * 74 | * @return array 75 | */ 76 | function getRewrite() { 77 | return $this->rewrite; 78 | } 79 | 80 | /** 81 | * Get the global WP object 82 | * 83 | * @return \WP 84 | */ 85 | function getWp() { 86 | return $this->wp; 87 | } 88 | 89 | /** 90 | * Get the array of extra variables to be added to resolved queries 91 | * 92 | * @return array 93 | */ 94 | function getExtraQueryVars() { 95 | return $this->extra_query_vars; 96 | } 97 | 98 | /** 99 | * Is true when $wp_rewrite->use_verbose_page_rules is true 100 | * 101 | * @return bool 102 | */ 103 | function isVerbose() { 104 | return (bool) $this->use_verbose; 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /UrlToQueryItem.php: -------------------------------------------------------------------------------- 1 | resolver = $resolver; 71 | } 72 | 73 | /** 74 | * Resolve an url to an array of WP_Query arguments for main query. 75 | * 76 | * @param string $url Url to resolve 77 | * @param type $query_string_vars Query variables to be added to the url 78 | * @return array|\WP_Error Resolved query or WP_Error is something goes wrong 79 | */ 80 | function resolve( $url = '', Array $query_string_vars = [ ] ) { 81 | if ( $this->done && empty( $this->error ) ) { 82 | return $this->query_vars; 83 | } 84 | $this->parseUrl( $url, $query_string_vars ); 85 | $rewrite = (array) $this->resolver->getRewrite(); 86 | if ( ! empty( $rewrite ) ) { 87 | list( $matches, $query ) = $this->parseRewriteRules( $rewrite ); 88 | $this->setMatchedQuery( $matches, $query ); 89 | $this->maybeAdmin(); 90 | } 91 | return $this->resolveVars(); 92 | } 93 | 94 | /** 95 | * Get the query vars after having resolved the url. 96 | * 97 | * @return array|\WP_Error Resolved query or WP_Error is something goes wrong 98 | */ 99 | function getQueryVars() { 100 | if ( ! $this->done ) { 101 | $this->error = 'not-resolved'; 102 | return $this->getError(); 103 | } 104 | return $this->query_vars; 105 | } 106 | 107 | /** 108 | * Get the matched rule after having resolved the url. 109 | * 110 | * @return string|\WP_Error Matched rule or WP_Error is something goes wrong 111 | */ 112 | function getMatchedRule() { 113 | if ( ! $this->done ) { 114 | $this->error = 'not-resolved'; 115 | return $this->getError(); 116 | } 117 | return $this->matched_rule; 118 | } 119 | 120 | /** 121 | * Get the matched rewrite rule query after having resolved the url. 122 | * 123 | * @return array|\WP_Error Matched rewrite rule query or WP_Error is something goes wrong 124 | */ 125 | function getMatchedQuery() { 126 | if ( ! $this->done ) { 127 | $this->error = 'not-resolved'; 128 | return $this->getError(); 129 | } 130 | return $this->matched_query; 131 | } 132 | 133 | /** 134 | * Get the matched rewrite rule query vars after having resolved the url. 135 | * 136 | * @return array|\WP_Error Matched rewrite rule query vars or WP_Error is something goes wrong 137 | */ 138 | function getPermalinkVars() { 139 | if ( ! $this->done ) { 140 | $this->error = 'not-resolved'; 141 | return $this->getError(); 142 | } 143 | return $this->perma_q_vars; 144 | } 145 | 146 | /** 147 | * Return a WP_Error object is something gone wrong, otherwise FALSE. 148 | * 149 | * @return bool|\WP_Error 150 | */ 151 | function getError() { 152 | return ! empty( $this->error ) ? new \WP_Error( 'url-to-query-' . $this->error ) : FALSE; 153 | } 154 | 155 | /** 156 | * Parse the url to be resolved taking only relative part and stripping out query vars. 157 | * 158 | * @param type string 159 | * @param array $query_string_vars 160 | */ 161 | private function parseUrl( $url = '', Array $query_string_vars = [ ] ) { 162 | parse_str( parse_url( $url, PHP_URL_QUERY ), $this->query_string ); 163 | $request_uri = trim( parse_url( $url, PHP_URL_PATH ), '/' ); 164 | $this->request = trim( preg_replace( '#^/*index\.php#', '', $request_uri ), '/' ); 165 | if ( ! empty( $query_string_vars ) ) { 166 | $this->query_string = array_merge( $this->query_string, $query_string_vars ); 167 | } 168 | } 169 | 170 | /** 171 | * Loop throught registered rewrite rule and check them against the url to resolve. 172 | * 173 | * @param array $rewrite 174 | * @return array 175 | * @uses \GM\UrlToQueryItem::parseRewriteRule() 176 | */ 177 | private function parseRewriteRules( Array $rewrite ) { 178 | $this->error = '404'; 179 | $request_match = $this->request; 180 | if ( empty( $request_match ) && isset( $rewrite['$'] ) ) { 181 | $this->matched_rule = '$'; 182 | $matches = [ '' ]; 183 | $query = $rewrite['$']; 184 | } else { 185 | foreach ( (array) $rewrite as $match => $query ) { 186 | $matches = $this->parseRewriteRule( $match, $query ); 187 | if ( ! is_null( $this->matched_rule ) ) { 188 | return [ $matches, $query ]; 189 | } 190 | } 191 | } 192 | return [ $matches, $query ]; 193 | } 194 | 195 | /** 196 | * Take the two part of a rewriote rule (the url and the query) and compare against the url to 197 | * be resolved to find a match. 198 | * 199 | * @param string $match The url part of the rewrite rule 200 | * @param string $query The query part of the rewrite rule 201 | * @return array 202 | */ 203 | private function parseRewriteRule( $match, $query ) { 204 | $matches = [ ]; 205 | $request_match = $this->request; 206 | if ( ! empty( $this->request ) && strpos( $match, $this->request ) === 0 ) { 207 | $request_match = $this->request . '/' . $this->request; 208 | } 209 | if ( 210 | preg_match( "#^{$match}#", $request_match, $matches ) 211 | || preg_match( "#^{$match}#", urldecode( $request_match ), $matches ) 212 | ) { 213 | $varmatch = NULL; 214 | if ( $this->resolver->isVerbose() && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) { 215 | $page = get_page_by_path( $matches[ $varmatch[1] ] ); 216 | if ( ! $page ) { 217 | return; 218 | } 219 | } 220 | $this->matched_rule = $match; 221 | } 222 | return $matches; 223 | } 224 | 225 | /** 226 | * When a rute matches, save matched query string and matched query array. 227 | * 228 | * @param array $matches Matches coming from regex compare matched rule to url 229 | * @param string $query Query part of the matched rule 230 | */ 231 | private function setMatchedQuery( $matches = [ ], $query = '' ) { 232 | if ( ! is_null( $this->matched_rule ) ) { 233 | $mathed = \WP_MatchesMapRegex::apply( preg_replace( "!^.+\?!", '', $query ), $matches ); 234 | $this->matched_query = addslashes( $mathed ); 235 | parse_str( $this->matched_query, $this->perma_q_vars ); 236 | if ( '404' === $this->error ) $this->error = NULL; 237 | } 238 | } 239 | 240 | /** 241 | * Check if the url is for admin, in that case unset all the frontend query variables 242 | */ 243 | private function maybeAdmin() { 244 | if ( empty( $this->request ) || strpos( $this->request, 'wp-admin/' ) !== FALSE ) { 245 | $this->error = NULL; 246 | if ( 247 | ! is_null( $this->perma_q_vars ) 248 | && strpos( $this->request, 'wp-admin/' ) !== FALSE 249 | ) { 250 | $this->perma_q_vars = NULL; 251 | } 252 | } 253 | } 254 | 255 | /** 256 | * Setup the query variables if a rewrite rule matched or if some variables are passed as query 257 | * string. Strips out not registered query variables and perform the 'request' filter 258 | * before saving and return found query vars. 259 | * 260 | * @return array 261 | * @uses \GM\UrlToQueryItem::parseQueryVars() 262 | * @uses \GM\UrlToQueryItem::parseTaxQueryVars() 263 | * @uses \GM\UrlToQueryItem::parseCptQueryVars() 264 | * @uses \GM\UrlToQueryItem::parsePrivateQueryVars() 265 | */ 266 | private function resolveVars() { 267 | $this->setCptQueryVars(); 268 | $wp = $this->resolver->getWp(); 269 | $public_query_vars = (array) apply_filters( 'query_vars', $wp->public_query_vars ); 270 | $extra_query_vars = (array) $this->resolver->getExtraQueryVars(); 271 | $this->parseQueryVars( $public_query_vars, $extra_query_vars ); 272 | $this->parseTaxQueryVars(); 273 | $this->parseCptQueryVars(); 274 | $this->parsePrivateQueryVars( $extra_query_vars, $wp->private_query_vars ); 275 | if ( ! is_null( $this->error ) ) { 276 | return $this->getError(); 277 | } 278 | $this->query_vars = apply_filters( 'request', $this->query_vars ); 279 | $this->done = TRUE; 280 | return $this->query_vars; 281 | } 282 | 283 | /** 284 | * Store all the query rewrite slugs for all registered post types 285 | */ 286 | private function setCptQueryVars() { 287 | foreach ( get_post_types( [ ], 'objects' ) as $post_type => $t ) { 288 | if ( $t->query_var ) $this->post_type_query_vars[$t->query_var] = $post_type; 289 | } 290 | } 291 | 292 | /** 293 | * Store query variables to be returned, merging ones coming from matched rule (if any) and ones 294 | * coming from query string or configs 295 | * 296 | * @param array $public_vars 297 | * @param array $extra 298 | * @uses \GM\UrlToQueryItem::parseQueryVar() 299 | */ 300 | private function parseQueryVars( Array $public_vars = [ ], Array $extra = [ ] ) { 301 | foreach ( $public_vars as $wpvar ) { 302 | if ( isset( $extra[$wpvar] ) ) { 303 | $this->query_vars[$wpvar] = $extra[$wpvar]; 304 | } elseif ( isset( $this->query_string[$wpvar] ) ) { 305 | $this->query_vars[$wpvar] = $this->query_string[$wpvar]; 306 | } elseif ( isset( $this->perma_q_vars[$wpvar] ) ) { 307 | $this->query_vars[$wpvar] = $this->perma_q_vars[$wpvar]; 308 | } 309 | if ( ! empty( $this->query_vars[$wpvar] ) ) { 310 | $this->parseQueryVar( $wpvar ); 311 | } 312 | } 313 | } 314 | 315 | /** 316 | * Parse a query variable, "flattening" it if is an array or an object, also set 'post_type' 317 | * and 'name' query var, if a slug of a registered post type is present among query vars 318 | * 319 | * @param string $wpvar 320 | */ 321 | private function parseQueryVar( $wpvar = '' ) { 322 | if ( ! is_array( $this->query_vars[$wpvar] ) ) { 323 | $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar]; 324 | } else { 325 | foreach ( $this->query_vars[$wpvar] as $vkey => $v ) { 326 | if ( ! is_object( $v ) ) { 327 | $this->query_vars[$wpvar][$vkey] = (string) $v; 328 | } 329 | } 330 | } 331 | if ( isset( $this->post_type_query_vars[$wpvar] ) ) { 332 | $this->query_vars['post_type'] = $this->post_type_query_vars[$wpvar]; 333 | $this->query_vars['name'] = $this->query_vars[$wpvar]; 334 | } 335 | } 336 | 337 | /** 338 | * Convert spacet to '+' in the query variables for custom taxonomies 339 | */ 340 | private function parseTaxQueryVars() { 341 | foreach ( get_taxonomies( [ ], 'objects' ) as $t ) { 342 | if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) ) { 343 | $encoded = str_replace( ' ', '+', $this->query_vars[$t->query_var] ); 344 | $this->query_vars[$t->query_var] = $encoded; 345 | } 346 | } 347 | } 348 | 349 | /** 350 | * Remove from query variables any non publicly queriable post type rewrite slug 351 | */ 352 | private function parseCptQueryVars() { 353 | if ( isset( $this->query_vars['post_type'] ) ) { 354 | $queryable = get_post_types( [ 'publicly_queryable' => TRUE ] ); 355 | if ( 356 | ! is_array( $this->query_vars['post_type'] ) 357 | && ! in_array( $this->query_vars['post_type'], $queryable, TRUE ) 358 | ) { 359 | unset( $this->query_vars['post_type'] ); 360 | } elseif ( is_array( $this->query_vars['post_type'] ) ) { 361 | $allowed = array_intersect( $this->query_vars['post_type'], $queryable ); 362 | $this->query_vars['post_type'] = $allowed; 363 | } 364 | } 365 | } 366 | 367 | /** 368 | * Look in extra query variables passed to resolver and compare to WP object private variables 369 | * if some variables are found they are added to query variables to be returned 370 | * 371 | * @param array $extra 372 | * @param array $private 373 | */ 374 | private function parsePrivateQueryVars( Array $extra = [ ], Array $private = [ ] ) { 375 | if ( ! empty( $extra ) ) { 376 | foreach ( $private as $var ) { 377 | if ( isset( $extra[$var] ) ) { 378 | $this->query_vars[$var] = $extra[$var]; 379 | } 380 | } 381 | } 382 | } 383 | 384 | } 385 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gmazzap/url-to-query", 3 | "description": "Allow resolving any kind of WordPress url to related main query arguments.", 4 | "type": "wordpress-plugin", 5 | "keywords": ["wordpress"], 6 | "homepage": "https://github.com/Giuseppe-Mazzapica/Url_To_Query", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Giuseppe Mazzapica", 11 | "email": "giuseppe.mazzapica@gmail.com", 12 | "homepage": "http://gm.zoomlab.it", 13 | "role": "Developer" 14 | } 15 | ], 16 | "support": { 17 | "issues": "https://github.com/Giuseppe-Mazzapica/Url_To_Query/issues", 18 | "source": "https://github.com/Giuseppe-Mazzapica/Url_To_Query" 19 | }, 20 | "require": { 21 | "composer/installers": "~1.0" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "GM\\": "" 26 | } 27 | }, 28 | "config": { 29 | "optimize-autoloader": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Giuseppe Mazzapica 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /url_to_query.php: -------------------------------------------------------------------------------- 1 | resolve( $url, $query_vars ); 32 | } 33 | 34 | } --------------------------------------------------------------------------------