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

Feature/#17 Adding mediaItem mutations. #189

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9fc2256
#17 - Adding new enum for media item status.
hughdevore Aug 4, 2017
51e81be
#17 - Fixing mediaItem mime type field.
hughdevore Aug 4, 2017
06a6cfa
#17 - Adding mediaItem mutations.
hughdevore Aug 4, 2017
c717e11
#17 - Adding mediaItem mutation tests.
hughdevore Aug 4, 2017
ee7ab0e
Merge branch 'develop' into feature/#17-mediaItem-mutations
hughdevore Aug 4, 2017
4a4f57f
#17 Adding code review changes.
hughdevore Aug 9, 2017
dfed277
Merge branch 'feature/#17-mediaItem-mutations' of https://github.com/…
hughdevore Aug 9, 2017
c03dbff
#17 Updating unit tests.
hughdevore Aug 11, 2017
f48b55d
Updating code for testing.
hughdevore Aug 11, 2017
6a1fd48
#17 Fixing php55 fatal error.
hughdevore Aug 11, 2017
2cf1b04
#17 Fixing php55 fatal error.
hughdevore Aug 11, 2017
6c84219
#17 Finalizing unit tests.
hughdevore Aug 11, 2017
e4c1471
#17 Finalizing unit tests.
hughdevore Aug 11, 2017
aba78fa
#17 Finalizing unit tests.
hughdevore Aug 12, 2017
605ed38
#17 Finalizing unit tests.
hughdevore Aug 12, 2017
0cd6beb
#17 Adding more unit tests and code cleanup.
hughdevore Aug 14, 2017
7a5b928
#17 Adding more unit tests.
hughdevore Aug 14, 2017
598668c
#17 Adding unit tests.
hughdevore Aug 14, 2017
424dc47
#17 Adding unit tests and code cleanup.
hughdevore Aug 14, 2017
e703053
#17 Adding unit tests and code cleanup.
hughdevore Aug 14, 2017
7e4aba7
#17 Adding unit tests and code cleanup.
hughdevore Aug 14, 2017
fbba5fb
#17 Adding unit tests and code cleanup.
hughdevore Aug 14, 2017
989c1de
#17 Adding unit tests and code cleanup.
hughdevore Aug 15, 2017
c08d852
#17 Adding unit tests and code cleanup.
hughdevore Aug 15, 2017
6110808
#17 Adding unit tests and code cleanup.
hughdevore Aug 15, 2017
8351a52
#17 Adding final code review changes.
hughdevore Aug 15, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/Type/Enum/MediaItemStatusEnumType.php
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;

}

}
4 changes: 2 additions & 2 deletions src/Type/MediaItem/MediaItemType.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ public static function fields( $fields ) {
},
],
'mimeType' => [
'type' => Types::string(),
'type' => Types::string(),
'description' => __( 'The mime type of the mediaItem', 'wp-graphql' ),
function( \WP_Post $post, $args, $context, ResolveInfo $info ) {
'resolve' =>function( \WP_Post $post, $args, $context, ResolveInfo $info ) {
return ! empty( $post->post_mime_type ) ? $post->post_mime_type : null;
},
],
Expand Down
224 changes: 224 additions & 0 deletions src/Type/MediaItem/Mutation/MediaItemCreate.php
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 );
Copy link
Collaborator

Choose a reason for hiding this comment

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

not a big deal, but I'd prefer a line break between this and the next code comment block


/**
* 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 );
Copy link
Collaborator

Choose a reason for hiding this comment

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

line break


/**
* 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 );
Copy link
Collaborator

Choose a reason for hiding this comment

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

line break


/**
* 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 )
);

}
}
Loading