Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support featured media in REST attachment controller #4645

Closed
wants to merge 4 commits into from

Conversation

Comment on lines 1467 to 1471
$post = get_post( $attachment_id );

if ( ! $post instanceof WP_Post || 'attachment' !== $post->post_type ) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use $this->get_post and return WP_Error.

Comment on lines +1484 to +1492
_doing_it_wrong(
$method,
sprintf(
/* translators: %s: attachment mime type */
__( 'This site does not support post thumbnails on attachments with MIME type %s.' ),
$post->post_mime_type
),
'6.2.0'
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return WP_Error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain more? Why return a WP_Error here?

* @param int $attachment_id Attachment ID.
* @param string $method Method name.
*/
private function maybe_did_featured_media_wrong( $attachment_id, $method ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this method do?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is responsible for determining whether a created or updated attachment supports featured images. If an attachment is created or updated via the API with a featured image, but the attachment has a MIME type that doesn't support featured images, this method sends a _doing_it_wrong().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing it wrong is not how the REST API handles errors. I don't think this method is a good idea.

Comment on lines +175 to +176
$this->handle_featured_media( $request['featured_media'], $attachment_id );
$this->maybe_did_featured_media_wrong( $attachment_id, __METHOD__ );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->handle_featured_media( $request['featured_media'], $attachment_id );
$this->maybe_did_featured_media_wrong( $attachment_id, __METHOD__ );
$update_media = $this->handle_featured_media( $request['featured_media'], $attachment_id );
if ( is_wp_error( $update_media ) ) {
return $update_media;
}
Comment on lines +352 to +353
$this->handle_featured_media( $request['featured_media'], $data['id'] );
$this->maybe_did_featured_media_wrong( $data['id'], __METHOD__ );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->handle_featured_media( $request['featured_media'], $data['id'] );
$this->maybe_did_featured_media_wrong( $data['id'], __METHOD__ );
$update_media = $this->handle_featured_media( $request['featured_media'], $attachment_id );
if ( is_wp_error( $update_media ) ) {
return $update_media;
}
* @param int $attachment_id Attachment ID.
* @param string $method Method name.
*/
private function maybe_did_featured_media_wrong( $attachment_id, $method ) {
Copy link
Member

@spacedmonkey spacedmonkey Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this method, let's extend handle_featured_media. Something like this.

protected function handle_featured_media( $featured_media, $post_id ) {
    if ( wp_attachment_is( 'audio', $post_id ) && post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ) ) {
         return parent::handle_featured_media( $featured_media, $post_id );
    } else if ( wp_attachment_is( 'video', $post_id ) && post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ) ) {
         return parent::handle_featured_media( $featured_media, $post_id );
    } 
   return new WP_Error( 'rest_feature_meta_update',
					sprintf(
					/* translators: %s: attachment mime type */
					__( 'This site does not support post thumbnails on attachments with MIME type %s.' ),
					$post->post_mime_type
				),
					array( 'status' => rest_authorization_required_code() )
		);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned that returning an error in this case will lead to a poor developer experience for a few reasons.

  1. Unless more code is added to roll back the work done by the method up to this point, the attachment will be left in an partially created or partially updated state in the database.
  2. An error will be returned to the client, but, again, the attachment will have been partially created or updated. For a create operation, if the client tries to correct the request and send it again, a second attachment will be created.
  3. The punishment of an error seems to me to not really fit the crime. Is setting the featured image on the wrong MIME type that big a deal?
  4. There is some precedent for a _doing_it_wrong(), for example
    if ( array_key_exists( $base, $schema['properties'] ) ) {
    $taxonomy_field_name_with_conflict = ! empty( $taxonomy->rest_base ) ? 'rest_base' : 'name';
    _doing_it_wrong(
    'register_taxonomy',
    sprintf(
    /* translators: 1: The taxonomy name, 2: The property name, either 'rest_base' or 'name', 3: The conflicting value. */
    __( 'The "%1$s" taxonomy "%2$s" property (%3$s) conflicts with an existing property on the REST API Posts Controller. Specify a custom "rest_base" when registering the taxonomy to avoid this error.' ),
    $taxonomy->name,
    $taxonomy_field_name_with_conflict,
    $base
    ),
    '5.4.0'
    );
    }
    .

For these reasons, if _doing_it_wrong() isn't going to work in this case, I think my next move would be to skip the error altogether rather than halt processing.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree. When update of meta data fails, it returns a WP_Error. Returning errors, allows user of the rest api, maybe not even have access to WP and the error log, to error that the request failed. You have to opt-in to send the featured media id to see this error. If you dont that, you need to know what you are doing.

@TimothyBJacobs
Copy link
Member

I agree using _doing_it_wrong isn't ideal. It doesn't really fit our preferred model. However, I agree we ideally don't want to leave an item in a partial state. This however is an issue throughout a lot of the REST API already, https://core.trac.wordpress.org/ticket/48822.

Another approach is to do this validation earlier which is what I'd prefer. We can add a validate_callback to the register_rest_route that does this validation. Then an error will be returned before any processing has happened.

@dlh01
Copy link
Author

dlh01 commented Jun 23, 2023

Another approach is to do this validation earlier which is what I'd prefer. We can add a validate_callback to the register_rest_route that does this validation. Then an error will be returned before any processing has happened.

Is there prior art for determining the MIME type-to-be of a new attachment that can be checked for support?

@spacedmonkey
Copy link
Member

Another approach is to do this validation earlier which is what I'd prefer. We can add a validate_callback to the register_rest_route that does this validation. Then an error will be returned before any processing has happened.

Is there prior art for determining the MIME type-to-be of a new attachment that can be checked for support?

That is a good point. We can easily check / know the mime type of the attachment on create endpoint. So we can't use validate_callback sadly.

@spacedmonkey
Copy link
Member

@TimothyBJacobs @dlh01 As a talking point, I put together a PR for this #4682

@TimothyBJacobs
Copy link
Member

We have the full request object, so we should be able to detect the mime type. I think we could use wp_check_filetype_and_ext on the temp file?

@dlh01
Copy link
Author

dlh01 commented Jun 26, 2023

We have the full request object, so we should be able to detect the mime type. I think we could use wp_check_filetype_and_ext on the temp file?

OK, that's a path I can look into, but probably not in time for 6.3 at this point.

I'll also say up-front that I don't have the experience with media component to be able to think in detail about any security risks that might come with attempting to analyze a file before it's been accepted into the media library, so any guidance about that (now or when the PR is updated) would be appreciated.

@swissspidy swissspidy closed this Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants