Ticket #24093: 24093.5.patch
File 24093.5.patch, 23.2 KB (added by , 10 years ago) |
---|
-
src/wp-includes/meta.php
diff --git src/wp-includes/meta.php src/wp-includes/meta.php index afbf954..176a5db 100644
class WP_Meta_Query { 987 987 988 988 // First-order clause. 989 989 } else if ( $this->is_first_order_clause( $query ) ) { 990 if ( isset( $query['value'] ) && array() === $query['value'] ) { 991 unset( $query['value'] ); 992 } 993 990 994 $clean_queries[] = $query; 991 995 992 996 // Otherwise, it's a nested query, so we recurse. … … class WP_Meta_Query { 1167 1171 * } 1168 1172 */ 1169 1173 protected function get_sql_clauses() { 1170 $sql = $this->get_sql_for_query( $this->queries ); 1174 /* 1175 * $queries are passed by reference to get_sql_for_query() for recursion. 1176 * To keep $this->queries unaltered, pass a copy. 1177 */ 1178 $queries = $this->queries; 1179 $sql = $this->get_sql_for_query( $queries ); 1171 1180 1172 1181 if ( ! empty( $sql['where'] ) ) { 1173 1182 $sql['where'] = ' AND ' . $sql['where']; … … class WP_Meta_Query { 1195 1204 * @type string $where SQL fragment to append to the main WHERE clause. 1196 1205 * } 1197 1206 */ 1198 protected function get_sql_for_query( $query, $depth = 0 ) {1207 protected function get_sql_for_query( &$query, $depth = 0 ) { 1199 1208 $sql_chunks = array( 1200 1209 'join' => array(), 1201 1210 'where' => array(), … … class WP_Meta_Query { 1211 1220 $indent .= " "; 1212 1221 } 1213 1222 1214 foreach ( $query as $key => $clause ) {1223 foreach ( $query as $key => &$clause ) { 1215 1224 if ( 'relation' === $key ) { 1216 1225 $relation = $query['relation']; 1217 1226 } else if ( is_array( $clause ) ) { … … class WP_Meta_Query { 1278 1287 * @type string $where SQL fragment to append to the main WHERE clause. 1279 1288 * } 1280 1289 */ 1281 public function get_sql_for_clause( $clause, $parent_query ) {1290 public function get_sql_for_clause( &$clause, $parent_query ) { 1282 1291 global $wpdb; 1283 1292 1284 1293 $sql_chunks = array( … … class WP_Meta_Query { 1286 1295 'join' => array(), 1287 1296 ); 1288 1297 1289 $i = count( $this->table_aliases );1290 $alias = $i ? 'mt' . $i : $this->meta_table;1291 1292 1298 if ( isset( $clause['compare'] ) ) { 1293 $ meta_compare= strtoupper( $clause['compare'] );1299 $clause['compare'] = strtoupper( $clause['compare'] ); 1294 1300 } else { 1295 $ meta_compare= isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '=';1301 $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '='; 1296 1302 } 1297 1303 1298 if ( ! in_array( $ meta_compare, array(1304 if ( ! in_array( $clause['compare'], array( 1299 1305 '=', '!=', '>', '>=', '<', '<=', 1300 1306 'LIKE', 'NOT LIKE', 1301 1307 'IN', 'NOT IN', … … class WP_Meta_Query { 1303 1309 'EXISTS', 'NOT EXISTS', 1304 1310 'REGEXP', 'NOT REGEXP', 'RLIKE' 1305 1311 ) ) ) { 1306 $ meta_compare= '=';1312 $clause['compare'] = '='; 1307 1313 } 1308 1314 1309 /* 1310 * There are a number of different query structures that get 1311 * built in different ways. 1312 * 1. Key-only clauses - (a) clauses without a 'value' key that 1313 * appear in the context of an OR relation and do not use 1314 * 'NOT EXISTS' as the 'compare', or (b) clauses with an 1315 * empty array for 'value'. 1316 */ 1317 if ( ! empty( $clause['key'] ) && ( 1318 ( ! array_key_exists( 'value', $clause ) && 'NOT EXISTS' !== $meta_compare && 'OR' === $parent_query['relation'] ) || 1319 ( isset( $clause['value'] ) && is_array( $clause['value'] ) && empty( $clause['value'] ) ) 1320 ) ) { 1321 1322 $alias = $this->meta_table; 1323 $sql_chunks['join'][] = " INNER JOIN $this->meta_table ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column)"; 1324 $sql_chunks['where'][] = $wpdb->prepare( "$this->meta_table.meta_key = %s", trim( $clause['key'] ) ); 1325 1326 // 2. NOT EXISTS. 1327 } else if ( 'NOT EXISTS' === $meta_compare ) { 1328 $join = " LEFT JOIN $this->meta_table"; 1329 $join .= $i ? " AS $alias" : ''; 1330 $join .= $wpdb->prepare( " ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key = %s )", $clause['key'] ); 1331 $sql_chunks['join'][] = $join; 1315 $meta_compare = $clause['compare']; 1332 1316 1333 $sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL'; 1317 // First build the JOIN clause, if one is required. 1318 $join = ''; 1334 1319 1335 // 3. EXISTS and other key-only queries. 1336 } else if ( 'EXISTS' === $meta_compare || ( ! empty( $clause['key'] ) && ! array_key_exists( 'value', $clause ) ) ) { 1337 $join = " INNER JOIN $this->meta_table"; 1338 $join .= $i ? " AS $alias" : ''; 1339 $join .= " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column )"; 1340 $sql_chunks['join'][] = $join; 1320 // We prefer to avoid joins if possible. Look for an existing join compatible with this clause. 1321 $alias = $this->find_compatible_table_alias( $clause, $parent_query ); 1322 if ( false === $alias ) { 1323 $i = count( $this->table_aliases ); 1324 $alias = $i ? 'mt' . $i : $this->meta_table; 1341 1325 1342 $sql_chunks['where'][] = $wpdb->prepare( $alias . '.meta_key = %s', trim( $clause['key'] ) ); 1326 // JOIN clauses for NOT EXISTS have their own syntax. 1327 if ( 'NOT EXISTS' === $meta_compare ) { 1328 $join .= " LEFT JOIN $this->meta_table"; 1329 $join .= $i ? " AS $alias" : ''; 1330 $join .= $wpdb->prepare( " ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key = %s )", $clause['key'] ); 1331 $sql_chunks['join'][] = $join; 1343 1332 1344 // 4. Clauses that have a value. 1345 } else if ( array_key_exists( 'value', $clause ) ) { 1346 $join = " INNER JOIN $this->meta_table"; 1347 $join .= $i ? " AS $alias" : ''; 1348 $join .= " ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column)"; 1333 // All other JOIN clauses. 1334 } else { 1335 $alias = $this->find_compatible_table_alias( $clause, $parent_query ); 1336 if ( false === $alias ) { 1337 $alias = $i ? 'mt' . $i : $this->meta_table; 1338 1339 $join .= " INNER JOIN $this->meta_table"; 1340 $join .= $i ? " AS $alias" : ''; 1341 $join .= " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column )"; 1342 } 1343 } 1344 1345 $this->table_aliases[] = $alias; 1349 1346 $sql_chunks['join'][] = $join; 1347 } 1350 1348 1351 if ( ! empty( $clause['key'] ) ) { 1349 // Save the alias to this clause, for future siblings to find. 1350 $clause['alias'] = $alias; 1351 1352 // Next, build the WHERE clause. 1353 $where = ''; 1354 1355 // meta_key. 1356 if ( array_key_exists( 'key', $clause ) ) { 1357 if ( 'NOT EXISTS' === $meta_compare ) { 1358 $sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL'; 1359 } else { 1352 1360 $sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) ); 1353 1361 } 1362 } 1354 1363 1364 // meta_value. 1365 if ( array_key_exists( 'value', $clause ) ) { 1366 $meta_value = $clause['value']; 1355 1367 $meta_type = $this->get_cast_for_type( isset( $clause['type'] ) ? $clause['type'] : '' ); 1356 1368 1357 $meta_value = isset( $clause['value'] ) ? $clause['value'] : '';1358 1359 1369 if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { 1360 1370 if ( ! is_array( $meta_value ) ) { 1361 1371 $meta_value = preg_split( '/[,\s]+/', $meta_value ); … … class WP_Meta_Query { 1364 1374 $meta_value = trim( $meta_value ); 1365 1375 } 1366 1376 1367 if ( 'IN' == substr( $meta_compare, -2 ) ) { 1368 $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')'; 1369 } elseif ( 'BETWEEN' == substr( $meta_compare, -7 ) ) { 1370 $meta_value = array_slice( $meta_value, 0, 2 ); 1371 $meta_compare_string = '%s AND %s'; 1372 } elseif ( 'LIKE' == $meta_compare || 'NOT LIKE' == $meta_compare ) { 1373 $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%'; 1374 $meta_compare_string = '%s'; 1375 } else { 1376 $meta_compare_string = '%s'; 1377 switch ( $meta_compare ) { 1378 case 'IN' : 1379 case 'NOT IN' : 1380 $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')'; 1381 $where = $wpdb->prepare( $meta_compare_string, $meta_value ); 1382 break; 1383 1384 case 'BETWEEN' : 1385 case 'NOT BETWEEN' : 1386 $meta_value = array_slice( $meta_value, 0, 2 ); 1387 $where = $wpdb->prepare( '%s AND %s', $meta_value ); 1388 break; 1389 1390 case 'LIKE' : 1391 case 'NOT LIKE' : 1392 $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%'; 1393 $where = $wpdb->prepare( '%s', $meta_value ); 1394 break; 1395 1396 default : 1397 $where = $wpdb->prepare( '%s', $meta_value ); 1398 break; 1399 1377 1400 } 1378 1401 1379 $sql_chunks['where'][] = $wpdb->prepare( "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string}", $meta_value ); 1402 if ( $where ) { 1403 $sql_chunks['where'][] = "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$where}"; 1404 } 1380 1405 } 1381 1406 1382 1407 /* … … class WP_Meta_Query { 1387 1412 $sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' ); 1388 1413 } 1389 1414 1390 $this->table_aliases[] = $alias;1391 1392 1415 return $sql_chunks; 1393 1416 } 1417 1418 /** 1419 * Identify an existing table alias that is compatible with the current query clause. 1420 * 1421 * We avoid unnecessary table joins by allowing each clause to look for 1422 * an existing table alias that is compatible with the query that it 1423 * needs to perform. An existing alias is compatible if (a) it is a 1424 * sibling of $clause (ie, it's under the scope of the same relation), 1425 * and (b) the combination of operator and relation between the clauses 1426 * allows for a shared table join. In the case of WP_Meta_Query, this 1427 * only applies to IN clauses that are connected by the relation OR. 1428 * 1429 * @since 4.1.0 1430 * @access protected 1431 * 1432 * @param array $clause Query clause. 1433 * @param array $parent_query Parent query of $clause. 1434 * @return string|bool Table alias if found, otherwise false. 1435 */ 1436 protected function find_compatible_table_alias( $clause, $parent_query ) { 1437 $alias = false; 1438 1439 if ( 'OR' === $parent_query['relation'] ) { 1440 $compatible_compares = array( '=', 'IN', 'BETWEEN', 'LIKE', 'REGEXP', 'RLIKE', '>', '>=', '<', '<=' ); 1441 } else { 1442 $compatible_compares = array( '!=', 'NOT IN', 'NOT LIKE' ); 1443 } 1444 1445 foreach ( $parent_query as $sibling ) { 1446 // If the sibling has no alias yet, there's nothing to check. 1447 if ( empty( $sibling['alias'] ) ) { 1448 continue; 1449 } 1450 1451 // We're only interested in siblings that are first-order clauses. 1452 if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) { 1453 continue; 1454 } 1455 1456 // Clauses joined by AND can share a join only if they also share a key. 1457 if ( 'AND' === $parent_query['relation'] && $sibling['key'] !== $clause['key'] ) { 1458 continue; 1459 } 1460 1461 $clause_compare = strtoupper( $clause['compare'] ); 1462 $sibling_compare = strtoupper( $sibling['compare'] ); 1463 if ( in_array( $clause_compare, $compatible_compares ) && in_array( $sibling_compare, $compatible_compares ) ) { 1464 $alias = $sibling['alias']; 1465 break; 1466 } 1467 } 1468 1469 return $alias; 1470 } 1394 1471 } 1395 1472 1396 1473 /** -
tests/phpunit/tests/meta/query.php
diff --git tests/phpunit/tests/meta/query.php tests/phpunit/tests/meta/query.php index 390ccc9..ceee7cf 100644
class Tests_Meta_Query extends WP_UnitTestCase { 73 73 74 74 $sql = $query->get_sql( 'post', $wpdb->posts, 'ID' ); 75 75 76 $this->assertEquals( 2, substr_count( $sql['join'], 'INNER JOIN' ) );76 $this->assertEquals( 1, substr_count( $sql['join'], 'INNER JOIN' ) ); 77 77 } 78 78 79 79 /** … … class Tests_Meta_Query extends WP_UnitTestCase { 476 476 477 477 $sql = $query->get_sql( 'post', $wpdb->posts, 'ID', $this ); 478 478 479 // We should have 2 joins - one for my_first_key and one for my_second_key 480 $this->assertEquals( 2, substr_count( $sql['join'], 'JOIN' ) ); 481 482 // The WHERE should check my_third_key against an unaliased table 483 $this->assertEquals( 1, substr_count( $sql['where'], "$wpdb->postmeta.meta_key = 'my_third_key'" ) ); 484 479 $this->assertEquals( 3, substr_count( $sql['join'], 'JOIN' ) ); 485 480 } 486 481 487 482 /** … … class Tests_Meta_Query extends WP_UnitTestCase { 546 541 // NOT EXISTS compare queries are not key-only so should not be non-aliased 547 542 $this->assertSame( 0, substr_count( $sql['where'], "$wpdb->postmeta.meta_key = 'baz'" ) ); 548 543 549 // When a value exists, it's not a key-only query550 $this->assertSame( 0, substr_count( $sql['where'], "$wpdb->postmeta.meta_key = 'barry'" ) );551 552 544 // 'AND' queries don't have key-only queries 553 545 $query2 = new WP_Meta_Query( array( 554 546 'relation' => 'AND', -
tests/phpunit/tests/post/query.php
diff --git tests/phpunit/tests/post/query.php tests/phpunit/tests/post/query.php index 250f132..adf683c 100644
class Tests_Post_Query extends WP_UnitTestCase { 647 647 } 648 648 649 649 /** 650 * @ticket 24093 651 */ 652 public function test_meta_query_relation_or_compare_equals() { 653 $posts = $this->factory->post->create_many( 4 ); 654 add_post_meta( $posts[0], 'color', 'orange' ); 655 add_post_meta( $posts[1], 'color', 'blue' ); 656 add_post_meta( $posts[1], 'vegetable', 'onion' ); 657 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 658 659 $query = new WP_Query( array( 660 'meta_query' => array( 661 'relation' => 'OR', 662 array( 663 'key' => 'vegetable', 664 'value' => 'onion', 665 'compare' => '=', 666 ), 667 array( 668 'key' => 'vegetable', 669 'value' => 'shallot', 670 'compare' => '=', 671 ), 672 ), 673 'update_post_meta_cache' => false, 674 'update_post_term_cache' => false, 675 'fields' => 'ids', 676 ) ); 677 678 $expected = array( $posts[1], $posts[2] ); 679 $this->assertEqualSets( $expected, $query->posts ); 680 } 681 682 /** 683 * @ticket 24093 684 */ 685 public function test_meta_query_relation_or_compare_equals_different_keys() { 686 $posts = $this->factory->post->create_many( 4 ); 687 add_post_meta( $posts[0], 'color', 'orange' ); 688 add_post_meta( $posts[1], 'color', 'blue' ); 689 add_post_meta( $posts[1], 'vegetable', 'onion' ); 690 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 691 692 $query = new WP_Query( array( 693 'meta_query' => array( 694 'relation' => 'OR', 695 array( 696 'key' => 'vegetable', 697 'value' => 'onion', 698 'compare' => '=', 699 ), 700 array( 701 'key' => 'color', 702 'value' => 'orange', 703 'compare' => '=', 704 ), 705 ), 706 'update_post_meta_cache' => false, 707 'update_post_term_cache' => false, 708 'fields' => 'ids', 709 ) ); 710 711 $expected = array( $posts[0], $posts[1] ); 712 $this->assertEqualSets( $expected, $query->posts ); 713 } 714 715 /** 716 * @ticket 24093 717 */ 718 public function test_meta_query_relation_or_compare_equals_and_in() { 719 $posts = $this->factory->post->create_many( 4 ); 720 add_post_meta( $posts[0], 'color', 'orange' ); 721 add_post_meta( $posts[1], 'color', 'blue' ); 722 add_post_meta( $posts[1], 'vegetable', 'onion' ); 723 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 724 725 $query = new WP_Query( array( 726 'meta_query' => array( 727 'relation' => 'OR', 728 array( 729 'key' => 'vegetable', 730 'value' => 'onion', 731 'compare' => '=', 732 ), 733 array( 734 'key' => 'color', 735 'value' => array( 'orange', 'green' ), 736 'compare' => 'IN', 737 ), 738 ), 739 'update_post_meta_cache' => false, 740 'update_post_term_cache' => false, 741 'fields' => 'ids', 742 ) ); 743 744 $expected = array( $posts[0], $posts[1] ); 745 $this->assertEqualSets( $expected, $query->posts ); 746 } 747 748 /** 749 * @ticket 24093 750 */ 751 public function test_meta_query_relation_or_compare_equals_and_like() { 752 $posts = $this->factory->post->create_many( 4 ); 753 add_post_meta( $posts[0], 'color', 'orange' ); 754 add_post_meta( $posts[1], 'color', 'blue' ); 755 add_post_meta( $posts[1], 'vegetable', 'onion' ); 756 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 757 758 $query = new WP_Query( array( 759 'meta_query' => array( 760 'relation' => 'OR', 761 array( 762 'key' => 'vegetable', 763 'value' => 'onion', 764 'compare' => '=', 765 ), 766 array( 767 'key' => 'vegetable', 768 'value' => 'hall', 769 'compare' => 'LIKE', 770 ), 771 ), 772 'update_post_meta_cache' => false, 773 'update_post_term_cache' => false, 774 'fields' => 'ids', 775 ) ); 776 777 $expected = array( $posts[1], $posts[2] ); 778 $this->assertEqualSets( $expected, $query->posts ); 779 } 780 781 /** 782 * @ticket 24093 783 */ 784 public function test_meta_query_relation_or_compare_equals_and_between() { 785 $posts = $this->factory->post->create_many( 4 ); 786 add_post_meta( $posts[0], 'number_of_colors', '2' ); 787 add_post_meta( $posts[1], 'number_of_colors', '5' ); 788 add_post_meta( $posts[1], 'vegetable', 'onion' ); 789 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 790 791 $query = new WP_Query( array( 792 'meta_query' => array( 793 'relation' => 'OR', 794 array( 795 'key' => 'vegetable', 796 'value' => 'shallot', 797 'compare' => '=', 798 ), 799 array( 800 'key' => 'number_of_colors', 801 'value' => array( 1, 3 ), 802 'compare' => 'BETWEEN', 803 'type' => 'SIGNED', 804 ), 805 ), 806 'update_post_meta_cache' => false, 807 'update_post_term_cache' => false, 808 'fields' => 'ids', 809 ) ); 810 811 $expected = array( $posts[0], $posts[2] ); 812 $this->assertEqualSets( $expected, $query->posts ); 813 } 814 815 /** 816 * @ticket 24093 817 */ 818 public function test_meta_query_relation_and_compare_in_same_keys() { 819 $posts = $this->factory->post->create_many( 4 ); 820 add_post_meta( $posts[0], 'color', 'orange' ); 821 add_post_meta( $posts[1], 'color', 'blue' ); 822 add_post_meta( $posts[1], 'vegetable', 'onion' ); 823 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 824 add_post_meta( $posts[3], 'vegetable', 'banana' ); 825 add_post_meta( $posts[3], 'vegetable', 'onion' ); 826 827 $query = new WP_Query( array( 828 'meta_query' => array( 829 'relation' => 'AND', 830 array( 831 'key' => 'vegetable', 832 'value' => array( 'onion', 'shallot' ), 833 'compare' => 'IN', 834 ), 835 array( 836 'key' => 'vegetable', 837 'value' => array( 'banana' ), 838 'compare' => 'IN', 839 ), 840 ), 841 'update_post_meta_cache' => false, 842 'update_post_term_cache' => false, 843 'fields' => 'ids', 844 ) ); 845 846 $expected = array( $posts[3] ); 847 $this->assertEqualSets( $expected, $query->posts ); 848 } 849 850 /** 851 * @ticket 24093 852 */ 853 public function test_meta_query_relation_and_compare_in_different_keys() { 854 $posts = $this->factory->post->create_many( 4 ); 855 add_post_meta( $posts[0], 'color', 'orange' ); 856 add_post_meta( $posts[1], 'color', 'blue' ); 857 add_post_meta( $posts[1], 'vegetable', 'onion' ); 858 add_post_meta( $posts[1], 'vegetable', 'shallot' ); 859 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 860 add_post_meta( $posts[3], 'vegetable', 'banana' ); 861 862 $query = new WP_Query( array( 863 'meta_query' => array( 864 'relation' => 'AND', 865 array( 866 'key' => 'vegetable', 867 'value' => array( 'onion', 'shallot' ), 868 'compare' => 'IN', 869 ), 870 array( 871 'key' => 'color', 872 'value' => array( 'blue' ), 873 'compare' => 'IN', 874 ), 875 ), 876 'update_post_meta_cache' => false, 877 'update_post_term_cache' => false, 878 'fields' => 'ids', 879 ) ); 880 881 $expected = array( $posts[1] ); 882 $this->assertEqualSets( $expected, $query->posts ); 883 } 884 885 /** 886 * @ticket 24093 887 */ 888 public function test_meta_query_relation_and_compare_not_equals() { 889 $posts = $this->factory->post->create_many( 4 ); 890 add_post_meta( $posts[0], 'color', 'orange' ); 891 add_post_meta( $posts[1], 'color', 'blue' ); 892 add_post_meta( $posts[1], 'vegetable', 'onion' ); 893 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 894 add_post_meta( $posts[3], 'vegetable', 'banana' ); 895 896 $query = new WP_Query( array( 897 'meta_query' => array( 898 'relation' => 'AND', 899 array( 900 'key' => 'vegetable', 901 'value' => 'onion', 902 'compare' => '!=', 903 ), 904 array( 905 'key' => 'vegetable', 906 'value' => 'shallot', 907 'compare' => '!=', 908 ), 909 ), 910 'update_post_meta_cache' => false, 911 'update_post_term_cache' => false, 912 'fields' => 'ids', 913 ) ); 914 915 $expected = array( $posts[3] ); 916 $this->assertEqualSets( $expected, $query->posts ); 917 } 918 919 /** 920 * @ticket 24093 921 */ 922 public function test_meta_query_relation_and_compare_not_equals_different_keys() { 923 $posts = $this->factory->post->create_many( 4 ); 924 925 // !shallot, but orange. 926 add_post_meta( $posts[0], 'color', 'orange' ); 927 add_post_meta( $posts[0], 'vegetable', 'onion' ); 928 929 // !orange, but shallot. 930 add_post_meta( $posts[1], 'color', 'blue' ); 931 add_post_meta( $posts[1], 'vegetable', 'shallot' ); 932 933 // Neither. 934 add_post_meta( $posts[2], 'color', 'blue' ); 935 add_post_meta( $posts[2], 'vegetable', 'onion' ); 936 937 $query = new WP_Query( array( 938 'meta_query' => array( 939 'relation' => 'AND', 940 array( 941 'key' => 'vegetable', 942 'value' => 'shallot', 943 'compare' => '!=', 944 ), 945 array( 946 'key' => 'color', 947 'value' => 'orange', 948 'compare' => '!=', 949 ), 950 ), 951 'update_post_meta_cache' => false, 952 'update_post_term_cache' => false, 953 'fields' => 'ids', 954 ) ); 955 956 $expected = array( $posts[2] ); 957 $this->assertEqualSets( $expected, $query->posts ); 958 } 959 960 /** 961 * @ticket 24093 962 */ 963 public function test_meta_query_relation_and_compare_not_equals_not_in() { 964 $posts = $this->factory->post->create_many( 4 ); 965 add_post_meta( $posts[0], 'color', 'orange' ); 966 add_post_meta( $posts[1], 'color', 'blue' ); 967 add_post_meta( $posts[1], 'vegetable', 'onion' ); 968 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 969 add_post_meta( $posts[3], 'vegetable', 'banana' ); 970 971 $query = new WP_Query( array( 972 'meta_query' => array( 973 'relation' => 'AND', 974 array( 975 'key' => 'vegetable', 976 'value' => 'onion', 977 'compare' => '!=', 978 ), 979 array( 980 'key' => 'vegetable', 981 'value' => array( 'shallot' ), 982 'compare' => 'NOT IN', 983 ), 984 ), 985 'update_post_meta_cache' => false, 986 'update_post_term_cache' => false, 987 'fields' => 'ids', 988 ) ); 989 990 $expected = array( $posts[3] ); 991 $this->assertEqualSets( $expected, $query->posts ); 992 } 993 994 /** 995 * @ticket 24093 996 */ 997 public function test_meta_query_relation_and_compare_not_equals_and_not_like() { 998 $posts = $this->factory->post->create_many( 4 ); 999 add_post_meta( $posts[0], 'color', 'orange' ); 1000 add_post_meta( $posts[1], 'color', 'blue' ); 1001 add_post_meta( $posts[1], 'vegetable', 'onion' ); 1002 add_post_meta( $posts[2], 'vegetable', 'shallot' ); 1003 add_post_meta( $posts[3], 'vegetable', 'banana' ); 1004 1005 $query = new WP_Query( array( 1006 'meta_query' => array( 1007 'relation' => 'AND', 1008 array( 1009 'key' => 'vegetable', 1010 'value' => 'onion', 1011 'compare' => '!=', 1012 ), 1013 array( 1014 'key' => 'vegetable', 1015 'value' => 'hall', 1016 'compare' => 'NOT LIKE', 1017 ), 1018 ), 1019 'update_post_meta_cache' => false, 1020 'update_post_term_cache' => false, 1021 'fields' => 'ids', 1022 ) ); 1023 1024 $expected = array( $posts[3] ); 1025 $this->assertEqualSets( $expected, $query->posts ); 1026 } 1027 1028 /** 650 1029 * @ticket 23033 651 1030 * @group meta 652 1031 */ … … class Tests_Post_Query extends WP_UnitTestCase { 1040 1419 $post_id6 = $this->factory->post->create(); 1041 1420 add_post_meta( $post_id6, 'baz', 0 ); 1042 1421 1043 $ posts = get_posts( array( 'meta_key' => 'foo', 'meta_value' => '0' ) );1044 $this->assertEquals( 1, count ( $ posts ) );1045 foreach ( $ posts as $post ) {1422 $q = new WP_Query( array( 'meta_key' => 'foo', 'meta_value' => '0' ) ); 1423 $this->assertEquals( 1, count ( $q->posts ) ); 1424 foreach ( $q->posts as $post ) { 1046 1425 $this->assertInstanceOf( 'WP_Post', $post ); 1047 1426 $this->assertEquals( 'raw', $post->filter ); 1048 1427 } 1049 $this->assertEquals( $post_id, $ posts[0]->ID );1428 $this->assertEquals( $post_id, $q->posts[0]->ID ); 1050 1429 1051 1430 $posts = get_posts( array( 'meta_key' => 'bar', 'meta_value' => '0' ) ); 1052 1431 $this->assertEquals( 2, count ( $posts ) );