Changeset 45807
- Timestamp:
- 08/15/2019 05:16:21 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api.php
r45771 r45807 1160 1160 $value = (array) $value; 1161 1161 } 1162 1163 if ( $value instanceof JsonSerializable ) { 1164 $value = $value->jsonSerialize(); 1165 } 1166 1162 1167 if ( ! is_array( $value ) ) { 1163 1168 /* translators: 1: parameter, 2: type name */ … … 1171 1176 return $is_valid; 1172 1177 } 1173 } elseif ( isset( $args['additionalProperties'] ) && false === $args['additionalProperties'] ) { 1174 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) ); 1178 } elseif ( isset( $args['additionalProperties'] ) ) { 1179 if ( false === $args['additionalProperties'] ) { 1180 return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not a valid property of Object.' ), $property ) ); 1181 } 1182 1183 if ( is_array( $args['additionalProperties'] ) ) { 1184 $is_valid = rest_validate_value_from_schema( $v, $args['additionalProperties'], $param . '[' . $property . ']' ); 1185 if ( is_wp_error( $is_valid ) ) { 1186 return $is_valid; 1187 } 1188 } 1175 1189 } 1176 1190 } … … 1299 1313 $value = (array) $value; 1300 1314 } 1315 1316 if ( $value instanceof JsonSerializable ) { 1317 $value = $value->jsonSerialize(); 1318 } 1319 1301 1320 if ( ! is_array( $value ) ) { 1302 1321 return array(); … … 1306 1325 if ( isset( $args['properties'][ $property ] ) ) { 1307 1326 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['properties'][ $property ] ); 1308 } elseif ( isset( $args['additionalProperties'] ) && false === $args['additionalProperties'] ) { 1309 unset( $value[ $property ] ); 1327 } elseif ( isset( $args['additionalProperties'] ) ) { 1328 if ( false === $args['additionalProperties'] ) { 1329 unset( $value[ $property ] ); 1330 } elseif ( is_array( $args['additionalProperties'] ) ) { 1331 $value[ $property ] = rest_sanitize_value_from_schema( $v, $args['additionalProperties'] ); 1332 } 1310 1333 } 1311 1334 } -
trunk/src/wp-includes/rest-api/fields/class-wp-rest-meta-fields.php
r45681 r45807 144 144 */ 145 145 if ( is_null( $meta[ $name ] ) ) { 146 $args = $this->get_registered_fields()[ $meta_key ]; 147 148 if ( $args['single'] ) { 149 $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); 150 151 if ( is_wp_error( rest_validate_value_from_schema( $current, $args['schema'] ) ) ) { 152 return new WP_Error( 153 'rest_invalid_stored_value', 154 /* translators: %s: custom field key */ 155 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), 156 array( 'status' => 500 ) 157 ); 158 } 159 } 160 146 161 $result = $this->delete_meta_value( $object_id, $meta_key, $name ); 147 162 if ( is_wp_error( $result ) ) { … … 151 166 } 152 167 153 $is_valid = rest_validate_value_from_schema( $meta[ $name ], $args['schema'], 'meta.' . $name ); 168 $value = $meta[ $name ]; 169 170 if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { 171 return new WP_Error( 172 'rest_invalid_stored_value', 173 /* translators: %s: custom field key */ 174 sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), 175 array( 'status' => 500 ) 176 ); 177 } 178 179 $is_valid = rest_validate_value_from_schema( $value, $args['schema'], 'meta.' . $name ); 154 180 if ( is_wp_error( $is_valid ) ) { 155 181 $is_valid->add_data( array( 'status' => 400 ) ); … … 157 183 } 158 184 159 $value = rest_sanitize_value_from_schema( $ meta[ $name ], $args['schema'] );185 $value = rest_sanitize_value_from_schema( $value, $args['schema'] ); 160 186 161 187 if ( $args['single'] ) { … … 261 287 } 262 288 263 // `delete_metadata` removes _all_ instances of the value, so only call once. 264 $to_remove = array_unique( $to_remove ); 289 // `delete_metadata` removes _all_ instances of the value, so only call once. Otherwise, 290 // `delete_metadata` will return false for subsequent calls of the same value. 291 // Use serialization to produce a predictable string that can be used by array_unique. 292 $to_remove = array_map( 'maybe_unserialize', array_unique( array_map( 'maybe_serialize', $to_remove ) ) ); 265 293 266 294 foreach ( $to_remove as $value ) { … … 394 422 $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; 395 423 396 if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number' ) ) ) { 424 if ( null === $rest_args['schema']['default'] ) { 425 $rest_args['schema']['default'] = $this->get_default_for_type( $type ); 426 } 427 428 $rest_args['schema'] = $this->default_additional_properties_to_false( $rest_args['schema'] ); 429 430 if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ) ) ) { 397 431 continue; 398 432 } 399 433 400 434 if ( empty( $rest_args['single'] ) ) { 401 $rest_args['schema']['items'] = array( 402 'type' => $rest_args['type'], 435 $rest_args['schema'] = array( 436 'type' => 'array', 437 'items' => $rest_args['schema'], 403 438 ); 404 $rest_args['schema']['type'] = 'array';405 439 } 406 440 … … 453 487 */ 454 488 public static function prepare_value( $value, $request, $args ) { 455 $type = $args['schema']['type']; 456 457 // For multi-value fields, check the item type instead. 458 if ( 'array' === $type && ! empty( $args['schema']['items']['type'] ) ) { 459 $type = $args['schema']['items']['type']; 460 } 461 462 switch ( $type ) { 463 case 'string': 464 $value = (string) $value; 465 break; 466 case 'integer': 467 $value = (int) $value; 468 break; 469 case 'number': 470 $value = (float) $value; 471 break; 472 case 'boolean': 473 $value = (bool) $value; 474 break; 475 } 476 477 // Don't allow objects to be output. 478 if ( is_object( $value ) && ! ( $value instanceof JsonSerializable ) ) { 489 490 if ( $args['single'] ) { 491 $schema = $args['schema']; 492 } else { 493 $schema = $args['schema']['items']; 494 } 495 496 if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { 479 497 return null; 480 498 } 481 499 482 return $value;500 return rest_sanitize_value_from_schema( $value, $schema ); 483 501 } 484 502 … … 500 518 return $value; 501 519 } 520 521 /** 522 * Recursively add additionalProperties = false to all objects in a schema if no additionalProperties setting 523 * is specified. 524 * 525 * This is needed to restrict properties of objects in meta values to only 526 * registered items, as the REST API will allow additional properties by 527 * default. 528 * 529 * @since 5.3.0 530 * 531 * @param array $schema The schema array. 532 * @return array 533 */ 534 protected function default_additional_properties_to_false( $schema ) { 535 switch ( $schema['type'] ) { 536 case 'object': 537 foreach ( $schema['properties'] as $key => $child_schema ) { 538 $schema['properties'][ $key ] = $this->default_additional_properties_to_false( $child_schema ); 539 } 540 541 if ( ! isset( $schema['additionalProperties'] ) ) { 542 $schema['additionalProperties'] = false; 543 } 544 break; 545 case 'array': 546 $schema['items'] = $this->default_additional_properties_to_false( $schema['items'] ); 547 break; 548 } 549 550 return $schema; 551 } 552 553 /** 554 * Gets the default value for a schema type. 555 * 556 * @since 5.3.0 557 * 558 * @param string $type 559 * @return mixed 560 */ 561 protected function get_default_for_type( $type ) { 562 switch ( $type ) { 563 case 'string': 564 return ''; 565 case 'boolean': 566 return false; 567 case 'integer': 568 return 0; 569 case 'number': 570 return 0.0; 571 case 'array': 572 return array(); 573 case 'object': 574 return array(); 575 default: 576 return null; 577 } 578 } 502 579 } -
trunk/tests/phpunit/includes/class-basic-object.php
r45580 r45807 7 7 * @since 4.7.0 8 8 */ 9 10 trigger_error( __FILE__ . ' is deprecated since version 5.0.0 with no alternative available.' );11 9 12 10 /** -
trunk/tests/phpunit/includes/functions.php
r45607 r45807 1 1 <?php 2 require_once __DIR__ . '/class-basic-object.php'; 2 3 3 4 /** -
trunk/tests/phpunit/tests/rest-api/rest-post-meta-fields.php
r44113 r45807 1177 1177 1178 1178 /** 1179 * @ticket 383231179 * @ticket 38323 1180 1180 * @dataProvider data_get_subtype_meta_value 1181 1181 */ … … 1229 1229 1230 1230 /** 1231 * @ticket 383231231 * @ticket 38323 1232 1232 * @dataProvider data_set_subtype_meta_value 1233 1233 */ … … 1257 1257 $this->assertEquals( 403, $response->get_status() ); 1258 1258 $this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) ); 1259 1259 1260 return; 1260 1261 } … … 1299 1300 1300 1301 /** 1301 * @ticket 420691302 * @ticket 42069 1302 1303 * @dataProvider data_update_value_return_success_with_same_value 1303 1304 */ … … 1349 1350 1350 1351 /** 1352 * @ticket 43392 1353 */ 1354 public function test_object_single() { 1355 $this->grant_write_permission(); 1356 1357 register_post_meta( 1358 'post', 1359 'object', 1360 array( 1361 'single' => true, 1362 'type' => 'object', 1363 'show_in_rest' => array( 1364 'schema' => array( 1365 'type' => 'object', 1366 'properties' => array( 1367 'project' => array( 1368 'type' => 'string', 1369 ), 1370 ), 1371 ), 1372 ), 1373 ) 1374 ); 1375 1376 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1377 $request->set_body_params( 1378 array( 1379 'meta' => array( 1380 'object' => array( 1381 'project' => 'WordPress', 1382 ), 1383 ), 1384 ) 1385 ); 1386 1387 $response = rest_get_server()->dispatch( $request ); 1388 $data = $response->get_data(); 1389 1390 $this->assertArrayHasKey( 'object', $data['meta'] ); 1391 $this->assertArrayHasKey( 'project', $data['meta']['object'] ); 1392 $this->assertEquals( 'WordPress', $data['meta']['object']['project'] ); 1393 1394 $meta = get_post_meta( self::$post_id, 'object', true ); 1395 $this->assertArrayHasKey( 'project', $meta ); 1396 $this->assertEquals( 'WordPress', $meta['project'] ); 1397 } 1398 1399 /** 1400 * @ticket 43392 1401 */ 1402 public function test_object_multiple() { 1403 $this->grant_write_permission(); 1404 1405 register_post_meta( 1406 'post', 1407 'object', 1408 array( 1409 'single' => false, 1410 'type' => 'object', 1411 'show_in_rest' => array( 1412 'schema' => array( 1413 'type' => 'object', 1414 'properties' => array( 1415 'project' => array( 1416 'type' => 'string', 1417 ), 1418 ), 1419 ), 1420 ), 1421 ) 1422 ); 1423 1424 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1425 $request->set_body_params( 1426 array( 1427 'meta' => array( 1428 'object' => array( 1429 array( 1430 'project' => 'WordPress', 1431 ), 1432 array( 1433 'project' => 'bbPress', 1434 ), 1435 ), 1436 ), 1437 ) 1438 ); 1439 1440 $response = rest_get_server()->dispatch( $request ); 1441 $data = $response->get_data(); 1442 1443 $this->assertArrayHasKey( 'object', $data['meta'] ); 1444 $this->assertCount( 2, $data['meta']['object'] ); 1445 1446 $this->assertArrayHasKey( 'project', $data['meta']['object'][0] ); 1447 $this->assertEquals( 'WordPress', $data['meta']['object'][0]['project'] ); 1448 1449 $this->assertArrayHasKey( 'project', $data['meta']['object'][1] ); 1450 $this->assertEquals( 'bbPress', $data['meta']['object'][1]['project'] ); 1451 1452 $meta = get_post_meta( self::$post_id, 'object' ); 1453 1454 $this->assertCount( 2, $meta ); 1455 1456 $this->assertArrayHasKey( 'project', $meta[0] ); 1457 $this->assertEquals( 'WordPress', $meta[0]['project'] ); 1458 1459 $this->assertArrayHasKey( 'project', $meta[1] ); 1460 $this->assertEquals( 'bbPress', $meta[1]['project'] ); 1461 } 1462 1463 /** 1464 * @ticket 43392 1465 */ 1466 public function test_array_single() { 1467 $this->grant_write_permission(); 1468 1469 register_post_meta( 1470 'post', 1471 'list', 1472 array( 1473 'single' => true, 1474 'type' => 'array', 1475 'show_in_rest' => array( 1476 'schema' => array( 1477 'type' => 'array', 1478 'items' => array( 1479 'type' => 'string', 1480 ), 1481 ), 1482 ), 1483 ) 1484 ); 1485 1486 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1487 $request->set_body_params( 1488 array( 1489 'meta' => array( 1490 'list' => array( 'WordPress', 'bbPress' ), 1491 ), 1492 ) 1493 ); 1494 1495 $response = rest_get_server()->dispatch( $request ); 1496 $data = $response->get_data(); 1497 1498 $this->assertArrayHasKey( 'list', $data['meta'] ); 1499 $this->assertEquals( array( 'WordPress', 'bbPress' ), $data['meta']['list'] ); 1500 1501 $meta = get_post_meta( self::$post_id, 'list', true ); 1502 $this->assertEquals( array( 'WordPress', 'bbPress' ), $meta ); 1503 } 1504 1505 /** 1506 * @ticket 43392 1507 */ 1508 public function test_array_of_objects_multiple() { 1509 $this->grant_write_permission(); 1510 1511 register_post_meta( 1512 'post', 1513 'list_of_objects', 1514 array( 1515 'single' => false, 1516 'type' => 'array', 1517 'show_in_rest' => array( 1518 'schema' => array( 1519 'type' => 'array', 1520 'items' => array( 1521 'type' => 'object', 1522 'properties' => array( 1523 'version' => array( 1524 'type' => 'string', 1525 ), 1526 'artist' => array( 1527 'type' => 'string', 1528 ), 1529 ), 1530 ), 1531 ), 1532 ), 1533 ) 1534 ); 1535 1536 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1537 $request->set_body_params( 1538 array( 1539 'meta' => array( 1540 'list_of_objects' => array( 1541 // Meta 1 1542 array( 1543 array( 1544 'version' => '5.2', 1545 'artist' => 'Jaco', 1546 ), 1547 array( 1548 'version' => '5.1', 1549 'artist' => 'Betty', 1550 ), 1551 ), 1552 // Meta 2 1553 array( 1554 array( 1555 'version' => '4.9', 1556 'artist' => 'Tipton', 1557 ), 1558 ), 1559 ), 1560 ), 1561 ) 1562 ); 1563 1564 $response = rest_get_server()->dispatch( $request ); 1565 $data = $response->get_data(); 1566 1567 $this->assertArrayHasKey( 'list_of_objects', $data['meta'] ); 1568 $this->assertCount( 2, $data['meta']['list_of_objects'] ); 1569 1570 $this->assertEquals( 1571 array( 1572 array( 1573 'version' => '5.2', 1574 'artist' => 'Jaco', 1575 ), 1576 array( 1577 'version' => '5.1', 1578 'artist' => 'Betty', 1579 ), 1580 ), 1581 $data['meta']['list_of_objects'][0] 1582 ); 1583 1584 $this->assertEquals( 1585 array( 1586 array( 1587 'version' => '4.9', 1588 'artist' => 'Tipton', 1589 ), 1590 ), 1591 $data['meta']['list_of_objects'][1] 1592 ); 1593 1594 $meta = get_post_meta( self::$post_id, 'list_of_objects' ); 1595 1596 $this->assertCount( 2, $meta ); 1597 1598 $this->assertEquals( 1599 array( 1600 array( 1601 'version' => '5.2', 1602 'artist' => 'Jaco', 1603 ), 1604 array( 1605 'version' => '5.1', 1606 'artist' => 'Betty', 1607 ), 1608 ), 1609 $meta[0] 1610 ); 1611 1612 $this->assertEquals( 1613 array( 1614 array( 1615 'version' => '4.9', 1616 'artist' => 'Tipton', 1617 ), 1618 ), 1619 $meta[1] 1620 ); 1621 } 1622 1623 /** 1624 * @ticket 43392 1625 */ 1626 public function test_php_objects_returned_as_null() { 1627 register_post_meta( 1628 'post', 1629 'object', 1630 array( 1631 'single' => true, 1632 'type' => 'object', 1633 'show_in_rest' => array( 1634 'schema' => array( 1635 'type' => 'object', 1636 'properties' => array( 1637 'project' => array( 1638 'type' => 'string', 1639 ), 1640 ), 1641 ), 1642 ), 1643 ) 1644 ); 1645 1646 $basic = new Basic_Object(); 1647 $basic->project = 'WordPress'; 1648 update_post_meta( self::$post_id, 'object', $basic ); 1649 1650 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1651 $response = rest_get_server()->dispatch( $request ); 1652 $data = $response->get_data(); 1653 1654 $this->assertArrayHasKey( 'object', $data['meta'] ); 1655 $this->assertNull( $data['meta']['object'] ); 1656 } 1657 1658 /** 1659 * @ticket 43392 1660 */ 1661 public function test_php_objects_returned_as_null_multiple() { 1662 register_post_meta( 1663 'post', 1664 'object', 1665 array( 1666 'single' => false, 1667 'type' => 'object', 1668 'show_in_rest' => array( 1669 'schema' => array( 1670 'type' => 'object', 1671 'properties' => array( 1672 'project' => array( 1673 'type' => 'string', 1674 ), 1675 ), 1676 ), 1677 ), 1678 ) 1679 ); 1680 1681 $basic = new Basic_Object(); 1682 $basic->project = 'WordPress'; 1683 add_post_meta( self::$post_id, 'object', array( 'project' => 'bbPress' ) ); 1684 add_post_meta( self::$post_id, 'object', $basic ); 1685 1686 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1687 $response = rest_get_server()->dispatch( $request ); 1688 $data = $response->get_data(); 1689 1690 $this->assertArrayHasKey( 'object', $data['meta'] ); 1691 $this->assertCount( 2, $data['meta']['object'] ); 1692 $this->assertEquals( array( 'project' => 'bbPress' ), $data['meta']['object'][0] ); 1693 $this->assertNull( $data['meta']['object'][1] ); 1694 } 1695 1696 /** 1697 * @ticket 43392 1698 */ 1699 public function test_php_jsonserializable_object_returns_value() { 1700 require_once __DIR__ . '/../../includes/class-jsonserializable-object.php'; 1701 1702 register_post_meta( 1703 'post', 1704 'object', 1705 array( 1706 'single' => true, 1707 'type' => 'object', 1708 'show_in_rest' => array( 1709 'schema' => array( 1710 'type' => 'object', 1711 'properties' => array( 1712 'project' => array( 1713 'type' => 'string', 1714 ), 1715 ), 1716 ), 1717 ), 1718 ) 1719 ); 1720 1721 update_post_meta( self::$post_id, 'object', new JsonSerializable_Object( array( 'project' => 'WordPress' ) ) ); 1722 1723 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1724 $response = rest_get_server()->dispatch( $request ); 1725 $data = $response->get_data(); 1726 1727 $this->assertArrayHasKey( 'object', $data['meta'] ); 1728 $this->assertEquals( array( 'project' => 'WordPress' ), $data['meta']['object'] ); 1729 } 1730 1731 /** 1732 * @ticket 43392 1733 */ 1734 public function test_updating_meta_to_null_for_key_with_existing_php_object_does_not_delete_meta_value() { 1735 $this->grant_write_permission(); 1736 1737 register_post_meta( 1738 'post', 1739 'object', 1740 array( 1741 'single' => true, 1742 'type' => 'object', 1743 'show_in_rest' => array( 1744 'schema' => array( 1745 'type' => 'object', 1746 'properties' => array( 1747 'project' => array( 1748 'type' => 'string', 1749 ), 1750 ), 1751 ), 1752 ), 1753 ) 1754 ); 1755 1756 $basic = new Basic_Object(); 1757 $basic->project = 'WordPress'; 1758 update_post_meta( self::$post_id, 'object', $basic ); 1759 1760 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1761 $request->set_body_params( 1762 array( 1763 'meta' => array( 1764 'object' => null, 1765 ), 1766 ) 1767 ); 1768 1769 $response = rest_get_server()->dispatch( $request ); 1770 $this->assertEquals( 500, $response->get_status() ); 1771 } 1772 1773 /** 1774 * @ticket 43392 1775 */ 1776 public function test_updating_non_single_meta_to_null_for_key_with_existing_php_object_does_not_set_meta_value_to_null() { 1777 $this->grant_write_permission(); 1778 1779 register_post_meta( 1780 'post', 1781 'object', 1782 array( 1783 'single' => false, 1784 'type' => 'object', 1785 'show_in_rest' => array( 1786 'schema' => array( 1787 'type' => 'object', 1788 'properties' => array( 1789 'project' => array( 1790 'type' => 'string', 1791 ), 1792 ), 1793 ), 1794 ), 1795 ) 1796 ); 1797 1798 $basic = new Basic_Object(); 1799 $basic->project = 'WordPress'; 1800 add_post_meta( self::$post_id, 'object', array( 'project' => 'bbPress' ) ); 1801 add_post_meta( self::$post_id, 'object', $basic ); 1802 1803 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1804 $request->set_body_params( 1805 array( 1806 'meta' => array( 1807 'object' => array( 1808 array( 'project' => 'BuddyPress' ), 1809 null, 1810 ), 1811 ), 1812 ) 1813 ); 1814 1815 $response = rest_get_server()->dispatch( $request ); 1816 $this->assertEquals( 500, $response->get_status() ); 1817 } 1818 1819 /** 1820 * @ticket 43392 1821 */ 1822 public function test_object_rejects_additional_properties_by_default() { 1823 $this->grant_write_permission(); 1824 1825 register_post_meta( 1826 'post', 1827 'object', 1828 array( 1829 'single' => true, 1830 'type' => 'object', 1831 'show_in_rest' => array( 1832 'schema' => array( 1833 'type' => 'object', 1834 'properties' => array( 1835 'project' => array( 1836 'type' => 'string', 1837 ), 1838 ), 1839 ), 1840 ), 1841 ) 1842 ); 1843 1844 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1845 $request->set_body_params( 1846 array( 1847 'meta' => array( 1848 'object' => array( 1849 'project' => 'BuddyPress', 1850 'awesomeness' => 100, 1851 ), 1852 ), 1853 ) 1854 ); 1855 1856 $response = rest_get_server()->dispatch( $request ); 1857 $this->assertEquals( 400, $response->get_status() ); 1858 } 1859 1860 /** 1861 * @ticket 43392 1862 */ 1863 public function test_object_allows_additional_properties_if_explicitly_set() { 1864 $this->grant_write_permission(); 1865 1866 $value = array( 1867 'project' => 'BuddyPress', 1868 'awesomeness' => 100, 1869 ); 1870 1871 register_post_meta( 1872 'post', 1873 'object', 1874 array( 1875 'single' => true, 1876 'type' => 'object', 1877 'show_in_rest' => array( 1878 'schema' => array( 1879 'type' => 'object', 1880 'additionalProperties' => true, 1881 'properties' => array( 1882 'project' => array( 1883 'type' => 'string', 1884 ), 1885 ), 1886 ), 1887 ), 1888 ) 1889 ); 1890 1891 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1892 $request->set_body_params( 1893 array( 1894 'meta' => array( 1895 'object' => $value, 1896 ), 1897 ) 1898 ); 1899 1900 $response = rest_get_server()->dispatch( $request ); 1901 $this->assertEquals( 200, $response->get_status() ); 1902 $this->assertEquals( $value, $response->get_data()['meta']['object'] ); 1903 1904 $this->assertEquals( $value, get_post_meta( self::$post_id, 'object', true ) ); 1905 } 1906 1907 /** 1908 * @ticket 43392 1909 */ 1910 public function test_object_allows_additional_properties_and_uses_its_schema() { 1911 $this->grant_write_permission(); 1912 1913 $value = array( 1914 'project' => 'BuddyPress', 1915 'awesomeness' => 'fabulous', 1916 ); 1917 1918 register_post_meta( 1919 'post', 1920 'object', 1921 array( 1922 'single' => true, 1923 'type' => 'object', 1924 'show_in_rest' => array( 1925 'schema' => array( 1926 'type' => 'object', 1927 'additionalProperties' => array( 1928 'type' => 'number', 1929 ), 1930 'properties' => array( 1931 'project' => array( 1932 'type' => 'string', 1933 ), 1934 ), 1935 ), 1936 ), 1937 ) 1938 ); 1939 1940 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1941 $request->set_body_params( 1942 array( 1943 'meta' => array( 1944 'object' => $value, 1945 ), 1946 ) 1947 ); 1948 1949 $response = rest_get_server()->dispatch( $request ); 1950 $this->assertEquals( 400, $response->get_status() ); 1951 } 1952 1953 /** 1954 * @ticket 43392 1955 */ 1956 public function test_invalid_meta_value_are_set_to_null_in_response() { 1957 register_post_meta( 1958 'post', 1959 'email', 1960 array( 1961 'single' => true, 1962 'type' => 'string', 1963 'show_in_rest' => array( 1964 'schema' => array( 1965 'type' => 'string', 1966 'format' => 'email', 1967 ), 1968 ), 1969 ) 1970 ); 1971 1972 update_post_meta( self::$post_id, 'email', 'invalid_meta_value' ); 1973 1974 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1975 $response = rest_get_server()->dispatch( $request ); 1976 1977 $this->assertNull( $response->get_data()['meta']['email'] ); 1978 } 1979 1980 /** 1981 * @ticket 43392 1982 */ 1983 public function test_meta_values_are_not_set_to_null_in_response_if_type_safely_serializable() { 1984 register_post_meta( 1985 'post', 1986 'boolean', 1987 array( 1988 'single' => true, 1989 'show_in_rest' => true, 1990 'type' => 'boolean', 1991 ) 1992 ); 1993 1994 update_post_meta( self::$post_id, 'boolean', 'true' ); 1995 1996 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 1997 $response = rest_get_server()->dispatch( $request ); 1998 1999 $this->assertTrue( $response->get_data()['meta']['boolean'] ); 2000 } 2001 2002 /** 2003 * @ticket 43392 2004 */ 2005 public function test_update_multi_meta_value_object() { 2006 register_post_meta( 2007 'post', 2008 'object', 2009 array( 2010 'single' => false, 2011 'type' => 'object', 2012 'show_in_rest' => array( 2013 'schema' => array( 2014 'type' => 'object', 2015 'properties' => array( 2016 'project' => array( 2017 'type' => 'string', 2018 ), 2019 ), 2020 ), 2021 ), 2022 ) 2023 ); 2024 2025 add_post_meta( 2026 self::$post_id, 2027 'object', 2028 array( 2029 'project' => 'WordPress', 2030 ) 2031 ); 2032 add_post_meta( 2033 self::$post_id, 2034 'object', 2035 array( 2036 'project' => 'bbPress', 2037 ) 2038 ); 2039 2040 $this->grant_write_permission(); 2041 2042 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 2043 $request->set_body_params( 2044 array( 2045 'meta' => array( 2046 'object' => array( 2047 array( 'project' => 'WordPress' ), 2048 array( 'project' => 'BuddyPress' ), 2049 ), 2050 ), 2051 ) 2052 ); 2053 2054 $response = rest_get_server()->dispatch( $request ); 2055 $this->assertEquals( 200, $response->get_status() ); 2056 2057 $data = $response->get_data(); 2058 $this->assertArrayHasKey( 'object', $data['meta'] ); 2059 2060 $this->assertCount( 2, $data['meta']['object'] ); 2061 $this->assertEquals( array( 'project' => 'WordPress' ), $data['meta']['object'][0] ); 2062 $this->assertEquals( array( 'project' => 'BuddyPress' ), $data['meta']['object'][1] ); 2063 2064 $meta = get_post_meta( self::$post_id, 'object' ); 2065 $this->assertCount( 2, $meta ); 2066 $this->assertEquals( array( 'project' => 'WordPress' ), $meta[0] ); 2067 $this->assertEquals( array( 'project' => 'BuddyPress' ), $meta[1] ); 2068 } 2069 2070 /** 2071 * @ticket 43392 2072 */ 2073 public function test_update_multi_meta_value_array() { 2074 register_post_meta( 2075 'post', 2076 'list', 2077 array( 2078 'type' => 'array', 2079 'show_in_rest' => array( 2080 'schema' => array( 2081 'type' => 'array', 2082 'items' => array( 2083 'type' => 'string', 2084 ), 2085 ), 2086 ), 2087 ) 2088 ); 2089 2090 add_post_meta( self::$post_id, 'list', array( 'WordPress', 'bbPress' ) ); 2091 add_post_meta( self::$post_id, 'list', array( 'WordCamp' ) ); 2092 2093 $this->grant_write_permission(); 2094 2095 $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 2096 $request->set_body_params( 2097 array( 2098 'meta' => array( 2099 'list' => array( 2100 array( 'WordPress', 'bbPress' ), 2101 array( 'BuddyPress' ), 2102 ), 2103 ), 2104 ) 2105 ); 2106 2107 $response = rest_get_server()->dispatch( $request ); 2108 $this->assertEquals( 200, $response->get_status() ); 2109 2110 $data = $response->get_data(); 2111 $this->assertArrayHasKey( 'list', $data['meta'] ); 2112 2113 $this->assertCount( 2, $data['meta']['list'] ); 2114 $this->assertEquals( array( 'WordPress', 'bbPress' ), $data['meta']['list'][0] ); 2115 $this->assertEquals( array( 'BuddyPress' ), $data['meta']['list'][1] ); 2116 2117 $meta = get_post_meta( self::$post_id, 'list' ); 2118 $this->assertCount( 2, $meta ); 2119 $this->assertEquals( array( 'WordPress', 'bbPress' ), $meta[0] ); 2120 $this->assertEquals( array( 'BuddyPress' ), $meta[1] ); 2121 } 2122 2123 /** 1351 2124 * Internal function used to disable an insert query which 1352 2125 * will trigger a wpdb error for testing purposes.
Note: See TracChangeset
for help on using the changeset viewer.