Overview
  • Namespace
  • Class

Namespaces

  • WPGraphQL
    • Data
    • Type
      • Avatar
      • Comment
        • Connection
      • CommentAuthor
      • EditLock
      • Enum
      • MediaItem
        • Mutation
      • Plugin
        • Connection
      • PostObject
        • Connection
        • Mutation
      • PostType
      • Setting
      • Taxonomy
      • TermObject
        • Connection
        • Mutation
      • Theme
        • Connection
      • Union
      • User
        • Connection
        • Mutation
    • Utils

Classes

  • WPGraphQL\AppContext
  • WPGraphQL\Data\Config
  • WPGraphQL\Data\ConnectionResolver
  • WPGraphQL\Data\DataSource
  • WPGraphQL\Data\Loader
  • WPGraphQL\Router
  • WPGraphQL\Type\Avatar\AvatarType
  • WPGraphQL\Type\Comment\CommentQuery
  • WPGraphQL\Type\Comment\CommentType
  • WPGraphQL\Type\Comment\Connection\CommentConnectionArgs
  • WPGraphQL\Type\Comment\Connection\CommentConnectionDefinition
  • WPGraphQL\Type\Comment\Connection\CommentConnectionResolver
  • WPGraphQL\Type\CommentAuthor\CommentAuthorQuery
  • WPGraphQL\Type\CommentAuthor\CommentAuthorType
  • WPGraphQL\Type\EditLock\EditLockType
  • WPGraphQL\Type\Enum\MediaItemStatusEnumType
  • WPGraphQL\Type\Enum\MimeTypeEnumType
  • WPGraphQL\Type\Enum\PostObjectFieldFormatEnumType
  • WPGraphQL\Type\Enum\PostStatusEnumType
  • WPGraphQL\Type\Enum\PostTypeEnumType
  • WPGraphQL\Type\Enum\RelationEnumType
  • WPGraphQL\Type\Enum\TaxonomyEnumType
  • WPGraphQL\Type\MediaItem\MediaItemType
  • WPGraphQL\Type\MediaItem\Mutation\MediaItemCreate
  • WPGraphQL\Type\MediaItem\Mutation\MediaItemDelete
  • WPGraphQL\Type\MediaItem\Mutation\MediaItemMutation
  • WPGraphQL\Type\MediaItem\Mutation\MediaItemUpdate
  • WPGraphQL\Type\Plugin\Connection\PluginConnectionDefinition
  • WPGraphQL\Type\Plugin\Connection\PluginConnectionResolver
  • WPGraphQL\Type\Plugin\PluginQuery
  • WPGraphQL\Type\Plugin\PluginType
  • WPGraphQL\Type\PostObject\Connection\PostObjectConnectionArgs
  • WPGraphQL\Type\PostObject\Connection\PostObjectConnectionArgsDateQuery
  • WPGraphQL\Type\PostObject\Connection\PostObjectConnectionDefinition
  • WPGraphQL\Type\PostObject\Connection\PostObjectConnectionResolver
  • WPGraphQL\Type\PostObject\Mutation\PostObjectCreate
  • WPGraphQL\Type\PostObject\Mutation\PostObjectDelete
  • WPGraphQL\Type\PostObject\Mutation\PostObjectMutation
  • WPGraphQL\Type\PostObject\Mutation\PostObjectUpdate
  • WPGraphQL\Type\PostObject\Mutation\TermObjectDelete
  • WPGraphQL\Type\PostObject\PostObjectQuery
  • WPGraphQL\Type\PostObject\PostObjectType
  • WPGraphQL\Type\PostType\PostTypeType
  • WPGraphQL\Type\RootMutationType
  • WPGraphQL\Type\RootQueryType
  • WPGraphQL\Type\Setting\SettingQuery
  • WPGraphQL\Type\Setting\SettingType
  • WPGraphQL\Type\Taxonomy\TaxonomyType
  • WPGraphQL\Type\TermObject\Connection\TermObjectConnectionArgs
  • WPGraphQL\Type\TermObject\Connection\TermObjectConnectionDefinition
  • WPGraphQL\Type\TermObject\Connection\TermObjectConnectionResolver
  • WPGraphQL\Type\TermObject\Mutation\TermObjectCreate
  • WPGraphQL\Type\TermObject\Mutation\TermObjectMutation
  • WPGraphQL\Type\TermObject\Mutation\TermObjectUpdate
  • WPGraphQL\Type\TermObject\TermObjectQuery
  • WPGraphQL\Type\TermObject\TermObjectType
  • WPGraphQL\Type\Theme\Connection\ThemeConnectionDefinition
  • WPGraphQL\Type\Theme\Connection\ThemeConnectionResolver
  • WPGraphQL\Type\Theme\ThemeType
  • WPGraphQL\Type\Union\CommentAuthorUnionType
  • WPGraphQL\Type\Union\PostObjectUnionType
  • WPGraphQL\Type\Union\TermObjectUnionType
  • WPGraphQL\Type\User\Connection\UserConnectionArgs
  • WPGraphQL\Type\User\Connection\UserConnectionDefinition
  • WPGraphQL\Type\User\Connection\UserConnectionResolver
  • WPGraphQL\Type\User\Mutation\UserCreate
  • WPGraphQL\Type\User\Mutation\UserDelete
  • WPGraphQL\Type\User\Mutation\UserMutation
  • WPGraphQL\Type\User\Mutation\UserUpdate
  • WPGraphQL\Type\User\UserQuery
  • WPGraphQL\Type\User\UserType
  • WPGraphQL\Type\WPEnumType
  • WPGraphQL\Type\WPInputObjectType
  • WPGraphQL\Type\WPObjectType
  • WPGraphQL\Types
  • WPGraphQL\Utils\InstrumentSchema
  • WPGraphQL\WPSchema

Interfaces

  • WPGraphQL\Data\ConnectionResolverInterface
  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 
<?php

namespace WPGraphQL\Type\PostObject\Mutation;

use GraphQL\Error\UserError;
use GraphQLRelay\Relay;
use WPGraphQL\Types;

/**
 * Class PostObjectUpdate
 *
 * @package WPGraphQL\Type\PostObject\Mutation
 */
class PostObjectUpdate {

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

    /**
     * Defines the Update mutation for PostTypeObjects
     *
     * @param \WP_Post_Type $post_type_object
     *
     * @return array|mixed
     */
    public static function mutate( \WP_Post_Type $post_type_object ) {

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

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

            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( __( 'Updates %1$s objects', 'wp-graphql' ), $post_type_object->graphql_single_name ),
                'inputFields'         => self::input_fields( $post_type_object ),
                '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;
                    $existing_post = get_post( absint( $id_parts['id'] ) );

                    /**
                     * If there's no existing post, throw an exception
                     */
                    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 UserError( sprintf( __( 'No %1$s could be found to update', 'wp-graphql' ), $post_type_object->graphql_single_name ) );
                    }

                    if ( $post_type_object->name !== $existing_post->post_type ) {
                        // translators: The first placeholder is an ID and the second placeholder is the name of the post type being edited
                        throw new UserError( sprintf( __( 'The id %1$d is not of the type "%2$s"', 'wp-graphql' ), $id_parts['id'], $post_type_object->name ) );
                    }

                    /**
                     * Stop now if a user isn't allowed to edit posts
                     */
                    if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {
                        // translators: the $post_type_object->graphql_single_name placeholder is the name of the object being mutated
                        throw new UserError( sprintf( __( 'Sorry, you are not allowed to update a %1$s', 'wp-graphql' ), $post_type_object->graphql_single_name ) );
                    }

                    /**
                     * If the mutation is setting the author to be someone other than the user making the request
                     * 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['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 UserError( sprintf( __( 'Sorry, you are not allowed to update %1$s as this user.', 'wp-graphql' ), $post_type_object->graphql_plural_name ) );
                    }

                    /**
                     * @todo: when we add support for making posts sticky, we should check permissions to make sure users can make posts sticky
                     * @see : https://github.com/WordPress/WordPress/blob/e357195ce303017d517aff944644a7a1232926f7/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php#L640-L642
                     */

                    /**
                     * @todo: when we add support for assigning terms to posts, we should check permissions to make sure they can assign terms
                     * @see : https://github.com/WordPress/WordPress/blob/e357195ce303017d517aff944644a7a1232926f7/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php#L644-L646
                     */

                    /**
                     * insert the post object and get the ID
                     */
                    $post_args       = PostObjectMutation::prepare_post_object( $input, $post_type_object, $mutation_name );
                    $post_args['ID'] = absint( $id_parts['id'] );

                    /**
                     * Insert the post and retrieve the ID
                     */
                    $post_id = wp_update_post( wp_slash( (array) $post_args ), true );

                    /**
                     * Throw an exception if the post failed to update
                     */
                    if ( is_wp_error( $post_id ) ) {
                        throw new UserError( __( 'The object failed to update but no error was provided', '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)
                     *
                     * The input for the postObjectMutation will be passed, along with the $new_post_id for the
                     * postObject that was updated so that relations can be set, meta can be updated, etc.
                     */
                    PostObjectMutation::update_additional_post_object_data( $post_id, $input, $post_type_object, $mutation_name );

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

                },
            ]);

        endif; // End if().

        return ! empty( self::$mutation[ $post_type_object->graphql_single_name ] ) ? self::$mutation[ $post_type_object->graphql_single_name ] : null;

    }

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

        /**
         * Update mutations require an ID to be passed
         */
        return array_merge(
            [
                'id' => [
                    'type'        => Types::non_null( Types::id() ),
                    // translators: the placeholder is the name of the type of post object being updated
                    'description' => sprintf( __( 'The ID of the %1$s object', 'wp-graphql' ), $post_type_object->graphql_single_name ),
                ],
            ],
            PostObjectMutation::input_fields( $post_type_object )
        );

    }

}
API documentation generated by ApiGen