@@ -543,6 +543,7 @@ public function edit_media_item_permissions_check( $request ) {
543543 * Applies edits to a media item and creates a new attachment record.
544544 *
545545 * @since 5.5.0
546+ * @since 6.9.0 Adds flips capability and editable fields for the newly-created attachment post.
546547 *
547548 * @param WP_REST_Request $request Full details about the request.
548549 * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure.
@@ -584,6 +585,20 @@ public function edit_media_item( $request ) {
584585 } else {
585586 $ modifiers = array ();
586587
588+ if ( isset ( $ request ['flip ' ]['horizontal ' ] ) || isset ( $ request ['flip ' ]['vertical ' ] ) ) {
589+ $ flip_args = array (
590+ 'vertical ' => isset ( $ request ['flip ' ]['vertical ' ] ) ? (bool ) $ request ['flip ' ]['vertical ' ] : false ,
591+ 'horizontal ' => isset ( $ request ['flip ' ]['horizontal ' ] ) ? (bool ) $ request ['flip ' ]['horizontal ' ] : false ,
592+ );
593+
594+ $ modifiers [] = array (
595+ 'type ' => 'flip ' ,
596+ 'args ' => array (
597+ 'flip ' => $ flip_args ,
598+ ),
599+ );
600+ }
601+
587602 if ( ! empty ( $ request ['rotation ' ] ) ) {
588603 $ modifiers [] = array (
589604 'type ' => 'rotate ' ,
@@ -637,6 +652,21 @@ public function edit_media_item( $request ) {
637652 foreach ( $ modifiers as $ modifier ) {
638653 $ args = $ modifier ['args ' ];
639654 switch ( $ modifier ['type ' ] ) {
655+ case 'flip ' :
656+ /*
657+ * Flips the current image.
658+ * The vertical flip is the first argument (flip along horizontal axis), the horizontal flip is the second argument (flip along vertical axis).
659+ * See: WP_Image_Editor::flip()
660+ */
661+ $ result = $ image_editor ->flip ( $ args ['flip ' ]['vertical ' ], $ args ['flip ' ]['horizontal ' ] );
662+ if ( is_wp_error ( $ result ) ) {
663+ return new WP_Error (
664+ 'rest_image_flip_failed ' ,
665+ __ ( 'Unable to flip this image. ' ),
666+ array ( 'status ' => 500 )
667+ );
668+ }
669+ break ;
640670 case 'rotate ' :
641671 // Rotation direction: clockwise vs. counterclockwise.
642672 $ rotate = 0 - $ args ['angle ' ];
@@ -711,23 +741,30 @@ public function edit_media_item( $request ) {
711741 return $ saved ;
712742 }
713743
714- // Create new attachment post.
715- $ new_attachment_post = array (
716- 'post_mime_type ' => $ saved ['mime-type ' ],
717- 'guid ' => $ uploads ['url ' ] . "/ $ filename " ,
718- 'post_title ' => $ image_name ,
719- 'post_content ' => '' ,
720- );
744+ // Grab original attachment post so we can use it to set defaults.
745+ $ original_attachment_post = get_post ( $ attachment_id );
721746
722- // Copy post_content, post_excerpt, and post_title from the edited image's attachment post.
723- $ attachment_post = get_post ( $ attachment_id );
747+ // Check request fields and assign default values.
748+ $ new_attachment_post = $ this ->prepare_item_for_database ( $ request );
749+ $ new_attachment_post ->post_mime_type = $ saved ['mime-type ' ];
750+ $ new_attachment_post ->guid = $ uploads ['url ' ] . "/ $ filename " ;
724751
725- if ( $ attachment_post ) {
726- $ new_attachment_post ['post_content ' ] = $ attachment_post ->post_content ;
727- $ new_attachment_post ['post_excerpt ' ] = $ attachment_post ->post_excerpt ;
728- $ new_attachment_post ['post_title ' ] = $ attachment_post ->post_title ;
729- }
752+ // Unset ID so wp_insert_attachment generates a new ID.
753+ unset( $ new_attachment_post ->ID );
730754
755+ // Set new attachment post title with fallbacks.
756+ $ new_attachment_post ->post_title = $ new_attachment_post ->post_title ?? $ original_attachment_post ->post_title ?? $ image_name ;
757+
758+ // Set new attachment post caption (post_excerpt).
759+ $ new_attachment_post ->post_excerpt = $ new_attachment_post ->post_excerpt ?? $ original_attachment_post ->post_excerpt ?? '' ;
760+
761+ // Set new attachment post description (post_content) with fallbacks.
762+ $ new_attachment_post ->post_content = $ new_attachment_post ->post_content ?? $ original_attachment_post ->post_content ?? '' ;
763+
764+ // Set post parent if set in request, else the default of `0` (no parent).
765+ $ new_attachment_post ->post_parent = $ new_attachment_post ->post_parent ?? 0 ;
766+
767+ // Insert the new attachment post.
731768 $ new_attachment_id = wp_insert_attachment ( wp_slash ( $ new_attachment_post ), $ saved ['path ' ], 0 , true );
732769
733770 if ( is_wp_error ( $ new_attachment_id ) ) {
@@ -740,8 +777,8 @@ public function edit_media_item( $request ) {
740777 return $ new_attachment_id ;
741778 }
742779
743- // Copy the image alt text from the edited image .
744- $ image_alt = get_post_meta ( $ attachment_id , '_wp_attachment_image_alt ' , true );
780+ // First, try to use the alt text from the request. If not set, copy the image alt text from the original attachment .
781+ $ image_alt = isset ( $ request [ ' alt_text ' ] ) ? sanitize_text_field ( $ request [ ' alt_text ' ] ) : get_post_meta ( $ attachment_id , '_wp_attachment_image_alt ' , true );
745782
746783 if ( ! empty ( $ image_alt ) ) {
747784 // update_post_meta() expects slashed.
@@ -1480,17 +1517,19 @@ protected function check_upload_size( $file ) {
14801517 * Gets the request args for the edit item route.
14811518 *
14821519 * @since 5.5.0
1520+ * @since 6.9.0 Adds flips capability and editable fields for the newly-created attachment post.
14831521 *
14841522 * @return array
14851523 */
14861524 protected function get_edit_media_item_args () {
1487- return array (
1525+ $ args = array (
14881526 'src ' => array (
14891527 'description ' => __ ( 'URL to the edited image file. ' ),
14901528 'type ' => 'string ' ,
14911529 'format ' => 'uri ' ,
14921530 'required ' => true ,
14931531 ),
1532+ // The `modifiers` param takes precedence over the older format.
14941533 'modifiers ' => array (
14951534 'description ' => __ ( 'Array of image edits. ' ),
14961535 'type ' => 'array ' ,
@@ -1503,6 +1542,43 @@ protected function get_edit_media_item_args() {
15031542 'args ' ,
15041543 ),
15051544 'oneOf ' => array (
1545+ array (
1546+ 'title ' => __ ( 'Flip ' ),
1547+ 'properties ' => array (
1548+ 'type ' => array (
1549+ 'description ' => __ ( 'Flip type. ' ),
1550+ 'type ' => 'string ' ,
1551+ 'enum ' => array ( 'flip ' ),
1552+ ),
1553+ 'args ' => array (
1554+ 'description ' => __ ( 'Flip arguments. ' ),
1555+ 'type ' => 'object ' ,
1556+ 'required ' => array (
1557+ 'flip ' ,
1558+ ),
1559+ 'properties ' => array (
1560+ 'flip ' => array (
1561+ 'description ' => __ ( 'Flip direction. ' ),
1562+ 'type ' => 'object ' ,
1563+ 'required ' => array (
1564+ 'horizontal ' ,
1565+ 'vertical ' ,
1566+ ),
1567+ 'properties ' => array (
1568+ 'horizontal ' => array (
1569+ 'description ' => __ ( 'Whether to flip in the horizontal direction. ' ),
1570+ 'type ' => 'boolean ' ,
1571+ ),
1572+ 'vertical ' => array (
1573+ 'description ' => __ ( 'Whether to flip in the vertical direction. ' ),
1574+ 'type ' => 'boolean ' ,
1575+ ),
1576+ ),
1577+ ),
1578+ ),
1579+ ),
1580+ ),
1581+ ),
15061582 array (
15071583 'title ' => __ ( 'Rotation ' ),
15081584 'properties ' => array (
@@ -1600,5 +1676,33 @@ protected function get_edit_media_item_args() {
16001676 'maximum ' => 100 ,
16011677 ),
16021678 );
1679+
1680+ /*
1681+ * Get the args based on the post schema. This calls `rest_get_endpoint_args_for_schema()`,
1682+ * which also takes care of sanitization and validation.
1683+ */
1684+ $ update_item_args = $ this ->get_endpoint_args_for_item_schema ( WP_REST_Server::EDITABLE );
1685+
1686+ if ( isset ( $ update_item_args ['caption ' ] ) ) {
1687+ $ args ['caption ' ] = $ update_item_args ['caption ' ];
1688+ }
1689+
1690+ if ( isset ( $ update_item_args ['description ' ] ) ) {
1691+ $ args ['description ' ] = $ update_item_args ['description ' ];
1692+ }
1693+
1694+ if ( isset ( $ update_item_args ['title ' ] ) ) {
1695+ $ args ['title ' ] = $ update_item_args ['title ' ];
1696+ }
1697+
1698+ if ( isset ( $ update_item_args ['post ' ] ) ) {
1699+ $ args ['post ' ] = $ update_item_args ['post ' ];
1700+ }
1701+
1702+ if ( isset ( $ update_item_args ['alt_text ' ] ) ) {
1703+ $ args ['alt_text ' ] = $ update_item_args ['alt_text ' ];
1704+ }
1705+
1706+ return $ args ;
16031707 }
16041708}
0 commit comments