Skip to content

Commit

Permalink
Merge 5c54f39 into ca51749
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonbahl committed Jun 15, 2017
2 parents ca51749 + 5c54f39 commit 3551a53
Show file tree
Hide file tree
Showing 15 changed files with 1,159 additions and 34 deletions.
3 changes: 1 addition & 2 deletions src/Type/PostObject/Mutation/PostObjectCreate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace WPGraphQL\Type\PostObject\Mutation;

use GraphQLRelay\Relay;
use WPGraphQL\Type\PostObject\PostObjectMutation;
use WPGraphQL\Types;

/**
Expand Down Expand Up @@ -89,7 +88,7 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
/**
* Insert the post and retrieve the ID
*/
$post_id = wp_insert_post( $post_args, true );
$post_id = wp_insert_post( wp_slash( (array) $post_args ), true );

/**
* Throw an exception if the post failed to create
Expand Down
5 changes: 3 additions & 2 deletions src/Type/PostObject/Mutation/PostObjectDelete.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
'outputFields' => [
'deletedId' => [
'type' => Types::id(),
'description' => __( 'The object before it was deleted', 'wp-graphql' ),
'description' => __( 'The ID of the deleted object', 'wp-graphql' ),
'resolve' => function( $payload ) use ( $post_type_object ) {
$deleted = (object) $payload['postObject'];
return ! empty( $deleted->ID ) ? Relay::toGlobalId( $post_type_object->name, absint( $deleted->ID ) ) : null;
Expand All @@ -74,7 +74,8 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
* Throw an exception if there's no input
*/
if ( ( empty( $post_type_object->name ) ) || ( empty( $input ) || ! is_array( $input ) ) ) {
throw new \Exception( __( 'Mutation not processed. There was no input for the mutation or the post_type_object was invalid', 'wp-graphql' ) );
// Translators: The placeholder is the name of the post type for the object being deleted
throw new \Exception( sprintf( __( 'Mutation not processed. There was no input for the mutation or the %1$s was invalid', 'wp-graphql' ), $post_type_object->graphql_single_name ) );
}

/**
Expand Down
12 changes: 6 additions & 6 deletions src/Type/PostObject/Mutation/PostObjectMutation.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace WPGraphQL\Type\PostObject;
namespace WPGraphQL\Type\PostObject\Mutation;

use GraphQLRelay\Relay;
use WPGraphQL\Types;
Expand Down Expand Up @@ -144,8 +144,8 @@ public static function prepare_post_object( $input, $post_type_object, $mutation
* NOTE: These are organized in the same order as: https://developer.wordpress.org/reference/functions/wp_insert_post/
*/
$author_id_parts = ! empty( $input['authorId'] ) ? Relay::fromGlobalId( $input['authorId'] ) : null;
if ( is_array( $author_id_parts ) && ! empty( $author_id_parts[1] ) && is_int( $author_id_parts[1] ) ) {
$insert_post_args['post_author'] = absint( $author_id_parts[1] );
if ( is_array( $author_id_parts ) && ! empty( $author_id_parts['id'] ) && is_int( $author_id_parts['id'] ) ) {
$insert_post_args['post_author'] = absint( $author_id_parts['id'] );
}

if ( ! empty( $input['date'] ) && false !== strtotime( $input['date'] ) ) {
Expand Down Expand Up @@ -205,8 +205,8 @@ public static function prepare_post_object( $input, $post_type_object, $mutation
}

$parent_id_parts = ! empty( $input['parentId'] ) ? Relay::fromGlobalId( $input['parentId'] ) : null;
if ( is_array( $parent_id_parts ) && ! empty( $parent_id_parts[1] ) && is_int( $parent_id_parts[1] ) ) {
$insert_post_args['post_parent'] = absint( $parent_id_parts[1] );
if ( is_array( $parent_id_parts ) && ! empty( $parent_id_parts['id'] ) && is_int( $parent_id_parts['id'] ) ) {
$insert_post_args['post_parent'] = absint( $parent_id_parts['id'] );
}

if ( ! empty( $input['menuOrder'] ) ) {
Expand All @@ -232,7 +232,7 @@ public static function prepare_post_object( $input, $post_type_object, $mutation
$insert_post_args = apply_filters( 'graphql_post_object_insert_post_args', $insert_post_args, $input, $post_type_object, $mutation_name );

/**
* Return the $post_id
* Return the $args
*/
return $insert_post_args;

Expand Down
40 changes: 30 additions & 10 deletions src/Type/PostObject/Mutation/PostObjectUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace WPGraphQL\Type\PostObject\Mutation;

use GraphQLRelay\Relay;
use WPGraphQL\Type\PostObject\PostObjectMutation;
use WPGraphQL\Types;

/**
Expand Down Expand Up @@ -36,19 +35,19 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
*/
$mutation_name = 'update' . ucwords( $post_type_object->graphql_single_name );

self::$mutation[ $post_type_object->graphql_single_name ] = Relay::mutationWithClientMutationId( array(
self::$mutation[ $post_type_object->graphql_single_name ] = Relay::mutationWithClientMutationId([
'name' => esc_html( $mutation_name ),
// translators: The placeholder is the name of the post type being updated
'description' => sprintf( esc_html__( 'Updates %1$s objects', 'wp-graphql' ), $post_type_object->graphql_single_name ),
'inputFields' => self::input_fields( $post_type_object ),
'outputFields' => array(
$post_type_object->graphql_single_name => array(
'outputFields' => [
$post_type_object->graphql_single_name => [
'type' => Types::post_object( $post_type_object->name ),
'resolve' => function( $payload ) {
return get_post( $payload['postObjectId'] );
},
),
),
],
],
'mutateAndGetPayload' => function( $input ) use ( $post_type_object, $mutation_name ) {

$id_parts = ! empty( $input['id'] ) ? Relay::fromGlobalId( $input['id'] ) : null;
Expand All @@ -57,7 +56,7 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
/**
* If there's no existing post, throw an exception
*/
if ( empty( $id_parts['id'] ) || false === $existing_post ) {
if ( empty( $id_parts['id'] ) || false === $existing_post || $id_parts['type'] !== $post_type_object->name ) {
// translators: the placeholder is the name of the type of post being updated
throw new \Exception( sprintf( __( 'No %1$s could be found to update', 'wp-graphql' ), $post_type_object->graphql_single_name ) );
}
Expand All @@ -80,7 +79,7 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
* make sure they have permission to edit others posts
*/
$author_id_parts = ! empty( $input['authorId'] ) ? Relay::fromGlobalId( $input['authorId'] ) : null;
if ( ! empty( $author_id_parts[0] ) && get_current_user_id() !== $author_id_parts[0] && ! current_user_can( $post_type_object->cap->edit_others_posts ) ) {
if ( ! empty( $author_id_parts['id'] ) && get_current_user_id() !== $author_id_parts['id'] && ! current_user_can( $post_type_object->cap->edit_others_posts ) ) {
// translators: the $post_type_object->graphql_single_name placeholder is the name of the object being mutated
throw new \Exception( sprintf( __( 'Sorry, you are not allowed to update %1$s as this user.', 'wp-graphql' ), $post_type_object->graphql_plural_name ) );
}
Expand All @@ -104,7 +103,7 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
/**
* Insert the post and retrieve the ID
*/
$post_id = wp_update_post( $post_args, true );
$post_id = wp_update_post( wp_slash( (array) $post_args ), true );

/**
* Throw an exception if the post failed to update
Expand All @@ -125,6 +124,17 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
throw new \Exception( __( 'The object failed to update', 'wp-graphql' ) );
}

/**
* Fires after a single term is created or updated via a GraphQL mutation
*
* The dynamic portion of the hook name, `$taxonomy->name` refers to the taxonomy of the term being mutated
*
* @param int $post_id Inserted post ID
* @param array $args The args used to insert the term
* @param string $mutation_name The name of the mutation being performed
*/
do_action( "graphql_insert_{$post_type_object->name}", $post_id, $post_args, $mutation_name );

/**
* This updates additional data not part of the posts table (postmeta, terms, other relations, etc)
*
Expand All @@ -133,12 +143,15 @@ public static function mutate( \WP_Post_Type $post_type_object ) {
*/
PostObjectMutation::update_additional_post_object_data( $post_id, $input, $post_type_object, $mutation_name );

/**
* Return the payload
*/
return [
'postObjectId' => $post_id,
];

},
) );
]);

return self::$mutation[ $post_type_object->graphql_single_name ];

Expand All @@ -148,6 +161,13 @@ public static function mutate( \WP_Post_Type $post_type_object ) {

}

/**
* Add the id as a nonNull field for update mutations
*
* @param \WP_Post_Type $post_type_object
*
* @return array
*/
private static function input_fields( $post_type_object ) {

/**
Expand Down
23 changes: 21 additions & 2 deletions src/Type/RootMutationType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

namespace WPGraphQL\Type;

use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\AppContext;
use WPGraphQL\Type\PostObject\Mutation\PostObjectCreate;
use WPGraphQL\Type\PostObject\Mutation\PostObjectDelete;
use WPGraphQL\Type\PostObject\Mutation\PostObjectUpdate;
use WPGraphQL\Type\PostObject\Mutation\TermObjectDelete;
use WPGraphQL\Type\TermObject\Mutation\TermObjectCreate;
use WPGraphQL\Type\TermObject\Mutation\TermObjectUpdate;

/**
* Class RootMutationType
Expand Down Expand Up @@ -66,6 +67,7 @@ private static function fields() {

$fields = [];
$allowed_post_types = \WPGraphQL::$allowed_post_types;
$allowed_taxonomies = \WPGraphQL::$allowed_taxonomies;

if ( ! empty( $allowed_post_types ) && is_array( $allowed_post_types ) ) {
foreach ( $allowed_post_types as $post_type ) {
Expand All @@ -88,6 +90,23 @@ private static function fields() {
} // End foreach().
} // End if().

if ( ! empty( $allowed_taxonomies ) && is_array( $allowed_taxonomies ) ) {
foreach ( $allowed_taxonomies as $taxonomy ) {

/**
* Get the taxonomy object to pass down to the schema
*/
$taxonomy_object = get_taxonomy( $taxonomy );

/**
* Root mutation for single term objects (of the specified taxonomy)
*/
$fields[ 'create' . ucwords( $taxonomy_object->graphql_single_name ) ] = TermObjectCreate::mutate( $taxonomy_object );
$fields[ 'update' . ucwords( $taxonomy_object->graphql_single_name ) ] = TermObjectUpdate::mutate( $taxonomy_object );
$fields[ 'delete' . ucwords( $taxonomy_object->graphql_single_name ) ] = TermObjectDelete::mutate( $taxonomy_object );
}
} // End if().

self::$fields = $fields;

} // End if().
Expand Down
151 changes: 151 additions & 0 deletions src/Type/TermObject/Mutation/TermObjectCreate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

namespace WPGraphQL\Type\TermObject\Mutation;

use GraphQLRelay\Relay;
use WPGraphQL\Types;

class TermObjectCreate {

/**
* Holds the mutation field definition
*
* @var array $mutation
*/
private static $mutation = [];

/**
* Defines the create mutation for TermObjects
*
* @param \WP_Taxonomy $taxonomy
*
* @return array|mixed
*/
public static function mutate( \WP_Taxonomy $taxonomy ) {

if ( ! empty( $taxonomy->graphql_single_name ) && empty( self::$mutation[ $taxonomy->graphql_single_name ] ) ) :

/**
* Set the name of the mutation being performed
*/
$mutation_name = 'create' . ucwords( $taxonomy->graphql_single_name );

self::$mutation[ $taxonomy->graphql_single_name ] = Relay::mutationWithClientMutationId( [
'name' => esc_html( $mutation_name ),
// translators: The placeholder is the name of the object type
'description' => sprintf( esc_html__( 'Create %1$s objects', 'wp-graphql' ), $taxonomy->name ),
'inputFields' => self::input_fields( $taxonomy ),
'outputFields' => [
$taxonomy->graphql_single_name => [
'type' => Types::term_object( $taxonomy->name ),
'resolve' => function( $payload ) use ( $taxonomy ) {
return get_term( $payload['id'], $taxonomy->name );
},
],
],
'mutateAndGetPayload' => function( $input ) use ( $taxonomy, $mutation_name ) {

/**
* Throw an exception if there's no input
*/
if ( ( empty( $taxonomy->name ) ) || ( empty( $input ) || ! is_array( $input ) ) ) {
throw new \Exception( __( 'Mutation not processed. There was no input for the mutation or the taxonomy was invalid', 'wp-graphql' ) );
}

/**
* Ensure the user can edit_terms
*/
if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
// translators: the $taxonomy->graphql_plural_name placeholder is the name of the object being mutated
throw new \Exception( sprintf( __( 'Sorry, you are not allowed to create %1$s', 'wp-graphql' ), $taxonomy->graphql_plural_name ) );
}

/**
* Prepare the object for insertion
*/
$args = TermObjectMutation::prepare_object( $input, $taxonomy, $mutation_name );

/**
* Ensure a name was provided
*/
if ( empty( $args['name'] ) ) {
// Translators: The placeholder is the name of the taxonomy of the term being mutated
throw new \Exception( sprintf( __( 'A name is required to create a %1$s' ), $taxonomy->name ) );
}

/**
* Insert the term
*/
$term = wp_insert_term( wp_slash( $args['name'] ), $taxonomy->name, wp_slash( (array) $args ) );

/**
* If it was an error, return the message as an exception
*/
if ( is_wp_error( $term ) ) {
$error_message = $term->get_error_message();
if ( ! empty( $error_message ) ) {
throw new \Exception( esc_html( $error_message ) );
} else {
throw new \Exception( __( 'The object failed to update but no error was provided', 'wp-graphql' ) );
}
}

/**
* If the response to creating the term didn't respond with a term_id, throw an exception
*/
if ( empty( $term['term_id'] ) ) {
throw new \Exception( __( 'The object failed to create', 'wp-graphql' ) );
}

/**
* Fires after a single term is created or updated via a GraphQL mutation
*
* The dynamic portion of the hook name, `$taxonomy->name` refers to the taxonomy of the term being mutated
*
* @param int $term_id Inserted term object
* @param array $args The args used to insert the term
* @param string $mutation_name The name of the mutation being performed
*/
do_action( "graphql_insert_{$taxonomy->name}", $term['term_id'], $args, $mutation_name );

return [
'id' => $term['term_id'],
];

},
] );

return self::$mutation[ $taxonomy->graphql_single_name ];

endif; // End if().

return self::$mutation;

}

/**
* Add the name as a nonNull field for create mutations
*
* @param \WP_Taxonomy $taxonomy
*
* @return array
*/
private static function input_fields( $taxonomy ) {

/**
* Add name as a non_null field for term creation
*/
return array_merge(
[
'name' => [
'type' => Types::non_null( Types::string() ),
// Translators: The placeholder is the name of the taxonomy for the object being mutated
'description' => sprintf( __( 'The name of the %1$s object to mutate', 'wp-graphql' ), $taxonomy->name ),
],
],
TermObjectMutation::input_fields( $taxonomy )
);

}

}

0 comments on commit 3551a53

Please sign in to comment.