-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Feature/#17 Adding mediaItem mutations.
- Loading branch information
Showing
9 changed files
with
1,733 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
|
||
namespace WPGraphQL\Type\Enum; | ||
|
||
use WPGraphQL\Type\WPEnumType; | ||
|
||
/** | ||
* Class MediaItemStatusEnumType | ||
* | ||
* This defines an EnumType with allowed post stati for attachments in WordPress. | ||
* Attachments do not have the same status capabilities as other post types, see here | ||
* for reference: https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php#L3072 | ||
* | ||
* @package WPGraphQL\Type\Enum | ||
*/ | ||
class MediaItemStatusEnumType extends WPEnumType { | ||
|
||
/** | ||
* This holds the enum values array | ||
* | ||
* @var array $values | ||
*/ | ||
private static $values; | ||
|
||
public function __construct() { | ||
$config = [ | ||
'name' => 'mediaItemStatus', | ||
'description' => __( 'The status of the media item object.', 'wp-graphql' ), | ||
'values' => self::values(), | ||
]; | ||
parent::__construct( $config ); | ||
} | ||
|
||
/** | ||
* values | ||
* Creates a list of post_stati that can be used to query by. | ||
* | ||
* @return array | ||
*/ | ||
private static function values() { | ||
|
||
/** | ||
* Set the default, if no values are built dynamically | ||
* | ||
*/ | ||
self::$values = [ | ||
'name' => 'inherit', | ||
'value' => 'inherit', | ||
]; | ||
|
||
/** | ||
* Get the dynamic list of post_stati | ||
*/ | ||
$post_stati = [ | ||
'inherit', | ||
'private', | ||
'trash', | ||
'auto-draft', | ||
]; | ||
|
||
/** | ||
* If there are $post_stati, create the $values based on them | ||
*/ | ||
if ( ! empty( $post_stati ) && is_array( $post_stati ) ) { | ||
/** | ||
* Reset the array | ||
*/ | ||
self::$values = []; | ||
/** | ||
* Loop through the post_stati | ||
*/ | ||
foreach ( $post_stati as $status ) { | ||
self::$values[ $status ] = [ | ||
'name' => strtoupper( preg_replace( '/[^A-Za-z0-9]/i', '_', $status ) ), | ||
'description' => sprintf( __( 'Objects with the %1$s status', 'wp-graphql' ), $status ), | ||
'value' => $status, | ||
]; | ||
} | ||
} | ||
|
||
/** | ||
* Return the $values | ||
*/ | ||
return self::$values; | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
<?php | ||
|
||
namespace WPGraphQL\Type\MediaItem\Mutation; | ||
|
||
use GraphQLRelay\Relay; | ||
use WPGraphQL\Types; | ||
|
||
/** | ||
* Class MediaItemCreate | ||
* | ||
* @package WPGraphQL\Type\MediaItem\Mutation | ||
*/ | ||
class MediaItemCreate { | ||
|
||
/** | ||
* Holds the mutation field definition | ||
* | ||
* @var array mutation | ||
*/ | ||
private static $mutation = []; | ||
|
||
/** | ||
* Defines the create mutation for MediaItems | ||
* | ||
* @var \WP_Post_Type $post_type_object | ||
* | ||
* @return array|mixed | ||
*/ | ||
public static function mutate( \WP_Post_Type $post_type_object ) { | ||
|
||
/** | ||
* Set the name of the mutation being performed | ||
*/ | ||
$mutation_name = 'createMediaItem'; | ||
|
||
self::$mutation['mediaItem'] = Relay::mutationWithClientMutationId( [ | ||
'name' => esc_html( $mutation_name ), | ||
'description' => __( 'Create mediaItems', 'wp-graphql' ), | ||
'inputFields' => self::input_fields( $post_type_object ), | ||
'outputFields' => [ | ||
'mediaItem' => [ | ||
'type' => Types::post_object( $post_type_object->name ), | ||
'resolve' => function( $payload ) { | ||
return get_post( $payload['id'] ); | ||
}, | ||
], | ||
], | ||
'mutateAndGetPayload' => function( $input ) use ( $post_type_object, $mutation_name ) { | ||
|
||
/** | ||
* Stop now if a user isn't allowed to upload a mediaItem | ||
*/ | ||
if ( ! current_user_can( 'upload_files' ) ) { | ||
throw new \Exception( __( 'Sorry, you are not allowed to upload mediaItems', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* If the mediaItem being created is being assigned to another user that's not the current user, make sure | ||
* the current user has permission to edit others mediaItems | ||
*/ | ||
if ( ! empty( $input['authorId'] ) && get_current_user_id() !== $input['authorId'] && ! current_user_can( $post_type_object->cap->edit_others_posts ) ) { | ||
throw new \Exception( __( 'Sorry, you are not allowed to create mediaItems as this user', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* Set the file name, whether it's a local file or from a URL. | ||
* Then set the url for the uploaded file | ||
*/ | ||
$file_name = basename( $input['filePath'] ); | ||
$uploaded_file_url = $input['filePath']; | ||
|
||
/** | ||
* Require the file.php file from wp-admin. This file includes the | ||
* download_url and wp_handle_sideload methods | ||
*/ | ||
require_once( ABSPATH . 'wp-admin/includes/file.php' ); | ||
|
||
/** | ||
* If the mediaItem file is from a local server, use wp_upload_bits before saving it to the uploads folder | ||
*/ | ||
if ( 'file' === parse_url( $input['filePath'], PHP_URL_SCHEME) ) { | ||
$uploaded_file = wp_upload_bits( $file_name, null, file_get_contents( $input['filePath'] ) ); | ||
$uploaded_file_url = $uploaded_file['url']; | ||
} | ||
|
||
/** | ||
* URL data for the mediaItem, timeout value is the default, see: | ||
* https://developer.wordpress.org/reference/functions/download_url/ | ||
*/ | ||
$timeout_seconds = 300; | ||
$temp_file = download_url( $uploaded_file_url, $timeout_seconds ); | ||
|
||
/** | ||
* Handle the error from download_url if it occurs | ||
*/ | ||
if ( is_wp_error( $temp_file ) ) { | ||
throw new \Exception( __( 'Sorry, the URL for this file is invalid, it must be a valid URL', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* Build the file data for side loading | ||
*/ | ||
$file_data = [ | ||
'name' => $file_name, | ||
'type' => $input['fileType'], | ||
'tmp_name' => $temp_file, | ||
'error' => 0, | ||
'size' => filesize( $temp_file ), | ||
]; | ||
|
||
/** | ||
* Tells WordPress to not look for the POST form fields that would normally be present as | ||
* we downloaded the file from a remote server, so there will be no form fields | ||
* The default is true | ||
*/ | ||
$overrides = [ | ||
'test_form' => false, | ||
]; | ||
|
||
/** | ||
* Insert the mediaItem and retrieve it's data | ||
*/ | ||
$file = wp_handle_sideload( $file_data, $overrides ); | ||
|
||
/** | ||
* Handle the error from wp_handle_sideload if it occurs | ||
*/ | ||
if ( ! empty( $file['error'] ) ) { | ||
throw new \Exception( __( 'Sorry, the URL for this file is invalid, it must be a path to the mediaItem file', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* Insert the mediaItem object and get the ID | ||
*/ | ||
$media_item_args = MediaItemMutation::prepare_media_item( $input, $post_type_object, $mutation_name, $file ); | ||
|
||
/** | ||
* Get the post parent and if it's not set, set it to false | ||
*/ | ||
$attachment_parent_id = ( ! empty( $media_item_args['post_parent'] ) ? $media_item_args['post_parent'] : false ); | ||
|
||
/** | ||
* Stop now if a user isn't allowed to edit the parent post | ||
*/ | ||
$parent = get_post( $attachment_parent_id ); | ||
|
||
if ( null !== get_post( $attachment_parent_id ) ) { | ||
$post_parent_type = get_post_type_object( $parent->post_type ); | ||
if ( ! current_user_can( $post_parent_type->cap->edit_post, $attachment_parent_id ) ) { | ||
throw new \Exception( __( 'Sorry, you are not allowed to upload mediaItems to this post', 'wp-graphql' ) ); | ||
} | ||
} | ||
|
||
/** | ||
* Insert the mediaItem | ||
*/ | ||
$attachment_id = wp_insert_attachment( $media_item_args, $file['file'], $attachment_parent_id ); | ||
|
||
/** | ||
* Handle the error from wp_insert_attachment if it occurs | ||
*/ | ||
if ( 0 === $attachment_id ) { | ||
throw new \Exception( __( 'Sorry, the mediaItem failed to create', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* Check if the wp_generate_attachment_metadata method exists and include it if not | ||
*/ | ||
require_once( ABSPATH . 'wp-admin/includes/image.php' ); | ||
|
||
/** | ||
* Generate and update the mediaItem's metadata | ||
*/ | ||
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $file['file'] ); | ||
$attachment_data_update = wp_update_attachment_metadata( $attachment_id, $attachment_data ); | ||
|
||
/** | ||
* Handle the error from wp_update_attachment_metadata if it occurs | ||
*/ | ||
if ( false === $attachment_data_update ) { | ||
throw new \Exception( __( 'Sorry, the mediaItem metadata failed to update', 'wp-graphql' ) ); | ||
} | ||
|
||
/** | ||
* Update alt text postmeta for mediaItem | ||
*/ | ||
MediaItemMutation::update_additional_media_item_data( $attachment_id, $input, $post_type_object, $mutation_name ); | ||
|
||
return [ | ||
'id' => $attachment_id, | ||
]; | ||
|
||
}, | ||
|
||
] ); | ||
|
||
return ! empty( self::$mutation['mediaItem'] ) ? self::$mutation['mediaItem'] : null; | ||
} | ||
|
||
/** | ||
* Add the filePath as a nonNull field for create mutations as its required | ||
* to create a media item | ||
* | ||
* @param \WP_Post_Type $post_type_object | ||
* | ||
* @return array | ||
*/ | ||
private static function input_fields( $post_type_object ) { | ||
|
||
/** | ||
* Update mutations require an filePath to be passed | ||
*/ | ||
return array_merge( | ||
[ | ||
'filePath' => [ | ||
'type' => Types::non_null( Types::string() ), | ||
'description' => __( 'The URL or file path to the mediaItem', 'wp-graphql' ), | ||
], | ||
], | ||
MediaItemMutation::input_fields( $post_type_object ) | ||
); | ||
|
||
} | ||
} |
Oops, something went wrong.