Ticket #53450: 53450.patch
| File 53450.patch, 6.0 KB (added by , 5 years ago) |
|---|
-
src/wp-includes/class-wp-meta-query.php
From 4d5175f395ec404bd0dbc99978705b9a5b9170a1 Mon Sep 17 00:00:00 2001 From: Jan Thiel <jan@hive-it.de> Date: Fri, 18 Jun 2021 17:48:04 +0200 Subject: [PATCH] Adds the new LIKE based compare operators STARTSWITH, ENDSWITH, NOT STARTSWITH, NOT ENDSWITH to the meta query value compares. They allow more performant regular query cases than REGEXP which would be the alternative. --- src/wp-includes/class-wp-meta-query.php | 20 +++++ tests/phpunit/tests/query/metaQuery.php | 104 ++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/src/wp-includes/class-wp-meta-query.php b/src/wp-includes/class-wp-meta-query.php index 5a1b0c41479..a2339b79248 100644
a b class WP_Meta_Query { 102 102 * @since 5.1.0 Introduced $compare_key clause parameter, which enables LIKE key matches. 103 103 * @since 5.3.0 Increased the number of operators available to $compare_key. Introduced $type_key, 104 104 * which enables the $key to be cast to a new data type for comparisons. 105 * @since 5.9.0 Adds LIKE based STARTSWITH and ENDSWITH operators for value compares 105 106 * 106 107 * @param array $meta_query { 107 108 * Array of meta query clauses. When first-order clauses or sub-clauses use strings as … … class WP_Meta_Query { 123 124 * @type string $value Meta value to filter by. 124 125 * @type string $compare MySQL operator used for comparing the $value. Accepts '=', 125 126 * '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 127 * 'STARTSWITH', 'NOT STARTSWITH', 'ENDSWITH', 'NOT ENDSWITH', 126 128 * 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'REGEXP', 127 129 * 'NOT REGEXP', 'RLIKE', 'EXISTS' or 'NOT EXISTS'. 128 130 * Default is 'IN' when `$value` is an array, '=' otherwise. … … public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) 509 511 '=', 510 512 '!=', 511 513 'LIKE', 514 'STARTSWITH', 515 'ENDSWITH', 512 516 'NOT LIKE', 517 'NOT STARTSWITH', 518 'NOT ENDSWITH', 513 519 'IN', 514 520 'NOT IN', 515 521 'EXISTS', … … public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) 713 719 $where = $wpdb->prepare( '%s', $meta_value ); 714 720 break; 715 721 722 case 'STARTSWITH': 723 case 'NOT STARTSWITH': 724 $meta_compare = $meta_compare === 'STARTSWITH' ? 'LIKE' : 'NOT LIKE'; 725 $meta_value = $wpdb->esc_like( $meta_value ) . '%'; 726 $where = $wpdb->prepare( '%s', $meta_value ); 727 break; 728 729 case 'ENDSSWITH': 730 case 'NOT ENDSWITH': 731 $meta_compare = $meta_compare === 'ENDSSWITH' ? 'LIKE' : 'NOT LIKE'; 732 $meta_value = '%' . $wpdb->esc_like( $meta_value ); 733 $where = $wpdb->prepare( '%s', $meta_value ); 734 break; 735 716 736 // EXISTS with a value is interpreted as '='. 717 737 case 'EXISTS': 718 738 $meta_compare = '='; -
tests/phpunit/tests/query/metaQuery.php
diff --git a/tests/phpunit/tests/query/metaQuery.php b/tests/phpunit/tests/query/metaQuery.php index 5acec55d3f9..239173893e1 100644
a b public function test_meta_query_single_query_compare_not_like() { 271 271 $this->assertSameSets( $expected, $query->posts ); 272 272 } 273 273 274 public function test_meta_query_single_query_compare_startswith() { 275 $p1 = self::factory()->post->create(); 276 $p2 = self::factory()->post->create(); 277 278 add_post_meta( $p1, 'foo', 'bar' ); 279 280 $query = new WP_Query( 281 array( 282 'update_post_meta_cache' => false, 283 'update_post_term_cache' => false, 284 'fields' => 'ids', 285 'meta_query' => array( 286 array( 287 'key' => 'foo', 288 'value' => 'ba', 289 'compare' => 'STARTSWITH', 290 ), 291 ), 292 ) 293 ); 294 295 $expected = array( $p1 ); 296 $this->assertSameSets( $expected, $query->posts ); 297 } 298 299 public function test_meta_query_single_query_compare_not_startswith() { 300 $p1 = self::factory()->post->create(); 301 $p2 = self::factory()->post->create(); 302 $p3 = self::factory()->post->create(); 303 304 add_post_meta( $p1, 'foo', 'bar' ); 305 add_post_meta( $p2, 'foo', 'rab' ); 306 307 $query = new WP_Query( 308 array( 309 'update_post_meta_cache' => false, 310 'update_post_term_cache' => false, 311 'fields' => 'ids', 312 'meta_query' => array( 313 array( 314 'key' => 'foo', 315 'value' => 'ba', 316 'compare' => 'NOT STARTSWITH', 317 ), 318 ), 319 ) 320 ); 321 322 $expected = array( $p2 ); 323 $this->assertSameSets( $expected, $query->posts ); 324 } 325 326 public function test_meta_query_single_query_compare_endswith() { 327 $p1 = self::factory()->post->create(); 328 $p2 = self::factory()->post->create(); 329 330 add_post_meta( $p1, 'foo', 'bar' ); 331 332 $query = new WP_Query( 333 array( 334 'update_post_meta_cache' => false, 335 'update_post_term_cache' => false, 336 'fields' => 'ids', 337 'meta_query' => array( 338 array( 339 'key' => 'foo', 340 'value' => 'ar', 341 'compare' => 'ENDSWITH', 342 ), 343 ), 344 ) 345 ); 346 347 $expected = array( $p1 ); 348 $this->assertSameSets( $expected, $query->posts ); 349 } 350 351 public function test_meta_query_single_query_compare_not_endswith() { 352 $p1 = self::factory()->post->create(); 353 $p2 = self::factory()->post->create(); 354 $p3 = self::factory()->post->create(); 355 356 add_post_meta( $p1, 'foo', 'bar' ); 357 add_post_meta( $p2, 'foo', 'rab' ); 358 359 $query = new WP_Query( 360 array( 361 'update_post_meta_cache' => false, 362 'update_post_term_cache' => false, 363 'fields' => 'ids', 364 'meta_query' => array( 365 array( 366 'key' => 'foo', 367 'value' => 'ar', 368 'compare' => 'NOT ENDSWITH', 369 ), 370 ), 371 ) 372 ); 373 374 $expected = array( $p2 ); 375 $this->assertSameSets( $expected, $query->posts ); 376 } 377 274 378 public function test_meta_query_single_query_compare_between_not_between() { 275 379 $p1 = self::factory()->post->create(); 276 380 $p2 = self::factory()->post->create();
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)