Make WordPress Core

Changeset 54530


Ignore:
Timestamp:
10/17/2022 11:47:41 AM (2 years ago)
Author:
audrasjb
Message:

Query: Validate relation in WP_Date_Query.

Props dd32, johnjamesjacoby, martinkrcho, ehtis, paulkevan, peterwilsoncc.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-date-query.php

    r54133 r54530  
    151151        }
    152152
    153         if ( isset( $date_query['relation'] ) && 'OR' === strtoupper( $date_query['relation'] ) ) {
    154             $this->relation = 'OR';
     153        if ( isset( $date_query['relation'] ) ) {
     154            $this->relation = $this->sanitize_relation( $date_query['relation'] );
    155155        } else {
    156156            $this->relation = 'AND';
     
    220220            $this->validate_date_values( $queries );
    221221        }
     222
     223        // Sanitize the relation parameter.
     224        $queries['relation'] = $this->sanitize_relation( $queries['relation'] );
    222225
    223226        foreach ( $queries as $key => $q ) {
     
    10421045        return $wpdb->prepare( "DATE_FORMAT( $column, %s ) $compare %f", $format, $time );
    10431046    }
     1047
     1048    /**
     1049     * Sanitizes a 'relation' operator.
     1050     *
     1051     * @since 6.0.3
     1052     *
     1053     * @param string $relation Raw relation key from the query argument.
     1054     * @return string Sanitized relation ('AND' or 'OR').
     1055     */
     1056    public function sanitize_relation( $relation ) {
     1057        if ( 'OR' === strtoupper( $relation ) ) {
     1058            return 'OR';
     1059        } else {
     1060            return 'AND';
     1061        }
     1062    }
    10441063}
  • trunk/tests/phpunit/tests/date/query.php

    r54217 r54530  
    11461146        $this->assertSame( array( $p1, $p2 ), $q->posts );
    11471147    }
     1148
     1149    /**
     1150     * @covers WP_Date_Query::get_sql
     1151     */
     1152    public function test_relation_in_query_and() {
     1153        $date_query = array(
     1154            'relation' => 'AND',
     1155            array(
     1156                'before'    => array(
     1157                    'year'  => 2021,
     1158                    'month' => 9,
     1159                    'day'   => 20,
     1160                ),
     1161                'after'     => array(
     1162                    'year'  => 2019,
     1163                    'month' => 2,
     1164                    'day'   => 25,
     1165                ),
     1166                'inclusive' => true,
     1167            ),
     1168            array(
     1169                'before'    => array(
     1170                    'year'  => 2016,
     1171                    'month' => 9,
     1172                    'day'   => 11,
     1173                ),
     1174                'after'     => array(
     1175                    'year'  => 2014,
     1176                    'month' => 5,
     1177                    'day'   => 12,
     1178                ),
     1179                'inclusive' => false,
     1180            ),
     1181        );
     1182
     1183        $q = new WP_Date_Query( $date_query );
     1184
     1185        $sql = $q->get_sql();
     1186
     1187        $parts = mb_split( '\)\s+AND\s+\(', $sql );
     1188        $this->assertIsArray( $parts, 'SQL query cannot be split into multiple parts using operator AND.' );
     1189        $this->assertEquals( 2, count( $parts ), 'SQL query does not contain correct number of AND operators.' );
     1190
     1191        $this->assertStringNotContainsString( 'OR', $sql, 'SQL query contains conditions joined by operator OR.' );
     1192    }
     1193
     1194    /**
     1195     * @covers WP_Date_Query::get_sql
     1196     */
     1197    public function test_relation_in_query_or() {
     1198        $date_query = array(
     1199            'relation' => 'OR',
     1200            array(
     1201                'before'    => array(
     1202                    'year'  => 2021,
     1203                    'month' => 9,
     1204                    'day'   => 20,
     1205                ),
     1206                'after'     => array(
     1207                    'year'  => 2019,
     1208                    'month' => 2,
     1209                    'day'   => 25,
     1210                ),
     1211                'inclusive' => true,
     1212            ),
     1213            array(
     1214                'before'    => array(
     1215                    'year'  => 2016,
     1216                    'month' => 9,
     1217                    'day'   => 11,
     1218                ),
     1219                'after'     => array(
     1220                    'year'  => 2014,
     1221                    'month' => 5,
     1222                    'day'   => 12,
     1223                ),
     1224                'inclusive' => false,
     1225            ),
     1226        );
     1227
     1228        $q = new WP_Date_Query( $date_query );
     1229
     1230        $sql = $q->get_sql();
     1231
     1232        $this->assertStringContainsString( 'OR', $sql, 'SQL query does not contain conditions joined by operator OR.' );
     1233
     1234        $parts = mb_split( '\)\s+OR\s+\(', $sql );
     1235        $this->assertIsArray( $parts, 'SQL query cannot be split into multiple parts using operator OR.' );
     1236        $this->assertEquals( 2, count( $parts ), 'SQL query does not contain correct number of OR operators.' );
     1237
     1238        // Checking number of occurrences of AND while skipping the one at the beginning.
     1239        $this->assertSame( 2, substr_count( substr( $sql, 5 ), 'AND' ), 'SQL query does not contain expected number conditions joined by operator AND.' );
     1240    }
     1241
     1242    /**
     1243     * @covers WP_Date_Query::get_sql
     1244     */
     1245    public function test_relation_in_query_unsupported() {
     1246        $date_query = array(
     1247            'relation' => 'UNSUPPORTED',
     1248            array(
     1249                'before'    => array(
     1250                    'year'  => 2021,
     1251                    'month' => 9,
     1252                    'day'   => 20,
     1253                ),
     1254                'after'     => array(
     1255                    'year'  => 2019,
     1256                    'month' => 2,
     1257                    'day'   => 25,
     1258                ),
     1259                'inclusive' => true,
     1260            ),
     1261            array(
     1262                'before'    => array(
     1263                    'year'  => 2016,
     1264                    'month' => 9,
     1265                    'day'   => 11,
     1266                ),
     1267                'after'     => array(
     1268                    'year'  => 2014,
     1269                    'month' => 5,
     1270                    'day'   => 12,
     1271                ),
     1272                'inclusive' => false,
     1273            ),
     1274        );
     1275
     1276        $q = new WP_Date_Query( $date_query );
     1277
     1278        $sql = $q->get_sql();
     1279
     1280        $parts = mb_split( '\)\s+AND\s+\(', $sql );
     1281        $this->assertIsArray( $parts, 'SQL query cannot be split into multiple parts using operator AND.' );
     1282        $this->assertEquals( 2, count( $parts ), 'SQL query does not contain correct number of AND operators.' );
     1283
     1284        $this->assertStringNotContainsString( 'OR', $sql, 'SQL query contains conditions joined by operator OR.' );
     1285    }
    11481286}
  • trunk/tests/phpunit/tests/term/taxQuery.php

    r54402 r54530  
    336336    /**
    337337     * @ticket 18105
     338     * @covers WP_Tax_Query::get_sql
    338339     */
    339340    public function test_get_sql_relation_and_operator_in() {
     
    382383        $this->assertSame( 3, substr_count( $sql['join'], 'JOIN' ) );
    383384
     385        // Checking number of occurrences of AND while skipping the one at the beginning.
     386        $this->assertSame( 2, substr_count( substr( $sql['where'], 5 ), 'AND' ), 'SQL query does not contain expected number conditions joined by operator AND.' );
     387
     388        $this->assertStringNotContainsString( 'OR', $sql['where'], 'SQL query contains conditions joined by operator OR.' );
     389
    384390        _unregister_taxonomy( 'wptests_tax' );
    385391    }
     
    387393    /**
    388394     * @ticket 18105
     395     * @covers WP_Tax_Query::get_sql
    389396     */
    390397    public function test_get_sql_nested_relation_or_operator_in() {
     
    435442
    436443        $this->assertSame( 2, substr_count( $sql['join'], 'JOIN' ) );
     444        $this->assertSame( 2, substr_count( $sql['where'], 'OR' ), 'SQL query does not contain expected number conditions joined by operator OR.' );
     445        $this->assertStringNotContainsString( 'AND', substr( $sql['where'], 5 ), 'SQL query contains conditions joined by operator AND.' );
    437446
    438447        _unregister_taxonomy( 'wptests_tax' );
     
    496505        _unregister_taxonomy( 'wptests_tax' );
    497506    }
     507
     508    /**
     509     * @ticket 18105
     510     * @covers WP_Tax_Query::get_sql
     511     */
     512    public function test_get_sql_relation_unsupported() {
     513        register_taxonomy( 'wptests_tax', 'post' );
     514
     515        $t1 = self::factory()->term->create(
     516            array(
     517                'taxonomy' => 'wptests_tax',
     518            )
     519        );
     520        $t2 = self::factory()->term->create(
     521            array(
     522                'taxonomy' => 'wptests_tax',
     523            )
     524        );
     525        $t3 = self::factory()->term->create(
     526            array(
     527                'taxonomy' => 'wptests_tax',
     528            )
     529        );
     530
     531        $tq = new WP_Tax_Query(
     532            array(
     533                'relation' => 'UNSUPPORTED',
     534                array(
     535                    'taxonomy' => 'wptests_tax',
     536                    'field'    => 'term_id',
     537                    'terms'    => $t1,
     538                ),
     539                array(
     540                    'taxonomy' => 'wptests_tax',
     541                    'field'    => 'term_id',
     542                    'terms'    => $t2,
     543                ),
     544                array(
     545                    'taxonomy' => 'wptests_tax',
     546                    'field'    => 'term_id',
     547                    'terms'    => $t3,
     548                ),
     549            )
     550        );
     551
     552        global $wpdb;
     553        $sql = $tq->get_sql( $wpdb->posts, 'ID' );
     554
     555        // Checking number of occurrences of AND while skipping the one at the beginning.
     556        $this->assertSame( 2, substr_count( substr( $sql['where'], 5 ), 'AND' ), 'SQL query does not contain expected number conditions joined by operator AND.' );
     557
     558        $this->assertStringNotContainsString( 'UNSUPPORTED', $sql['where'], 'SQL query contains unsupported relation operator.' );
     559        $this->assertStringNotContainsString( 'OR', $sql['where'], 'SQL query contains conditions joined by operator OR.' );
     560
     561        _unregister_taxonomy( 'wptests_tax' );
     562    }
    498563}
Note: See TracChangeset for help on using the changeset viewer.