PluginProbe
WPGraphQL / trunk
WPGraphQL vtrunk
2.22.3 2.22.2 2.22.1 2.22.0 2.21.1 2.21.0 2.20.0 2.19.0 2.18.0 2.17.0 2.16.0 2.15.1 2.15.0 2.14.1 2.14.0 2.13.0 2.2.0 2.3.0 2.3.3 2.3.6 2.3.8 2.5.0 2.5.1 2.5.2 2.5.3 All 177 releases
wp-graphql / src / Mutation / TermObjectCreate.php

TermObjectCreate.php in WPGraphQL trunk, at src/Mutation/TermObjectCreate.php

224 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPGraphQL\Mutation;
4
5 use GraphQL\Error\UserError;
6 use GraphQL\Type\Definition\ResolveInfo;
7 use WPGraphQL\AppContext;
8 use WPGraphQL\Data\TermObjectMutation;
9 use WP_Taxonomy;
10
11 class TermObjectCreate {
12 /**
13 * Registers the TermObjectCreate mutation.
14 *
15 * @param \WP_Taxonomy $taxonomy The taxonomy type of the mutation.
16 *
17 * @return void
18 */
19 public static function register_mutation( WP_Taxonomy $taxonomy ) {
20 $mutation_name = 'create' . ucwords( $taxonomy->graphql_single_name );
21
22 register_graphql_mutation(
23 $mutation_name,
24 [
25 'inputFields' => array_merge(
26 self::get_input_fields( $taxonomy ),
27 [
28 'name' => [
29 'type' => [
30 'non_null' => 'String',
31 ],
32 'description' => static function () use ( $taxonomy ) {
33 // translators: The placeholder is the name of the taxonomy for the object being mutated
34 return sprintf( __( 'The name of the %1$s object to mutate', 'wp-graphql' ), $taxonomy->name );
35 },
36 ],
37 ]
38 ),
39 'outputFields' => self::get_output_fields( $taxonomy ),
40 'mutateAndGetPayload' => self::mutate_and_get_payload( $taxonomy, $mutation_name ),
41 ]
42 );
43 }
44
45 /**
46 * Defines the mutation input field configuration.
47 *
48 * @param \WP_Taxonomy $taxonomy The taxonomy type of the mutation.
49 *
50 * @return array<string,array<string,mixed>>
51 */
52 public static function get_input_fields( WP_Taxonomy $taxonomy ) {
53 $fields = [
54 'aliasOf' => [
55 'type' => 'String',
56 'description' => static function () use ( $taxonomy ) {
57 // translators: The placeholder is the name of the taxonomy for the object being mutated
58 return sprintf( __( 'The slug that the %1$s will be an alias of', 'wp-graphql' ), $taxonomy->name );
59 },
60 ],
61 'description' => [
62 'type' => 'String',
63 'description' => static function () use ( $taxonomy ) {
64 // translators: The placeholder is the name of the taxonomy for the object being mutated
65 return sprintf( __( 'The description of the %1$s object', 'wp-graphql' ), $taxonomy->name );
66 },
67 ],
68 'slug' => [
69 'type' => 'String',
70 'description' => static function () use ( $taxonomy ) {
71 // translators: The placeholder is the name of the taxonomy for the object being mutated
72 return sprintf( __( 'If this argument exists then the slug will be checked to see if it is not an existing valid term. If that check succeeds (it is not a valid term), then it is added and the term id is given. If it fails, then a check is made to whether the taxonomy is hierarchical and the parent argument is not empty. If the second check succeeds, the term will be inserted and the term id will be given. If the slug argument is empty, then it will be calculated from the term name.', 'wp-graphql' ), $taxonomy->name );
73 },
74 ],
75 ];
76
77 /**
78 * Add a parentId field to hierarchical taxonomies to allow parents to be set
79 */
80 if ( true === $taxonomy->hierarchical ) {
81 $fields['parentId'] = [
82 'type' => 'ID',
83 'description' => static function () use ( $taxonomy ) {
84 // translators: The placeholder is the name of the taxonomy for the object being mutated
85 return sprintf( __( 'The ID of the %1$s that should be set as the parent. This field cannot be used in conjunction with parentDatabaseId', 'wp-graphql' ), $taxonomy->name );
86 },
87 ];
88 $fields['parentDatabaseId'] = [
89 'type' => 'Int',
90 'description' => static function () use ( $taxonomy ) {
91 // translators: The placeholder is the name of the taxonomy for the object being mutated
92 return sprintf( __( 'The database ID of the %1$s that should be set as the parent. This field cannot be used in conjunction with parentId', 'wp-graphql' ), $taxonomy->name );
93 },
94 ];
95 }
96
97 return $fields;
98 }
99
100 /**
101 * Defines the mutation output field configuration.
102 *
103 * @param \WP_Taxonomy $taxonomy The taxonomy type of the mutation.
104 *
105 * @return array<string,array<string,mixed>>
106 */
107 public static function get_output_fields( WP_Taxonomy $taxonomy ) {
108 return [
109 $taxonomy->graphql_single_name => [
110 'type' => $taxonomy->graphql_single_name,
111 'description' => static function () use ( $taxonomy ) {
112 // translators: Placeholder is the name of the taxonomy
113 return sprintf( __( 'The created %s', 'wp-graphql' ), $taxonomy->name );
114 },
115 'resolve' => static function ( $payload, $_args, AppContext $context ) {
116 $id = isset( $payload['termId'] ) ? absint( $payload['termId'] ) : null;
117
118 return $context->get_loader( 'term' )->load_deferred( $id );
119 },
120 ],
121 ];
122 }
123
124 /**
125 * Defines the mutation data modification closure.
126 *
127 * @param \WP_Taxonomy $taxonomy The taxonomy type of the mutation.
128 * @param string $mutation_name The name of the mutation.
129 *
130 * @return callable(array<string,mixed>$input,\WPGraphQL\AppContext $context,\GraphQL\Type\Definition\ResolveInfo $info):array<string,mixed>
131 */
132 public static function mutate_and_get_payload( WP_Taxonomy $taxonomy, string $mutation_name ) {
133 return static function ( $input, AppContext $context, ResolveInfo $info ) use ( $taxonomy, $mutation_name ) {
134
135 /**
136 * Ensure the user can edit_terms
137 */
138 if ( ! isset( $taxonomy->cap->edit_terms ) || ! current_user_can( $taxonomy->cap->edit_terms ) ) {
139 // translators: the $taxonomy->graphql_plural_name placeholder is the name of the object being mutated
140 throw new UserError( esc_html( sprintf( __( 'Sorry, you are not allowed to create %1$s', 'wp-graphql' ), $taxonomy->graphql_plural_name ) ) );
141 }
142
143 /**
144 * Prepare the object for insertion
145 */
146 $args = TermObjectMutation::prepare_object( $input, $taxonomy, $mutation_name );
147
148 /**
149 * Ensure a name was provided
150 */
151 if ( empty( $args['name'] ) ) {
152 // translators: The placeholder is the name of the taxonomy of the term being mutated
153 throw new UserError( esc_html( sprintf( __( 'A name is required to create a %1$s', 'wp-graphql' ), $taxonomy->name ) ) );
154 }
155
156 $term_name = wp_slash( $args['name'] );
157
158 if ( ! is_string( $term_name ) ) {
159 // translators: The placeholder is the name of the taxonomy of the term being mutated
160 throw new UserError( esc_html( sprintf( __( 'A valid name is required to create a %1$s', 'wp-graphql' ), $taxonomy->name ) ) );
161 }
162
163 /**
164 * Insert the term
165 */
166 $term = wp_insert_term( $term_name, $taxonomy->name, wp_slash( (array) $args ) );
167
168 /**
169 * If it was an error, return the message as an exception
170 */
171 if ( is_wp_error( $term ) ) {
172 $error_message = $term->get_error_message();
173 if ( ! empty( $error_message ) ) {
174 throw new UserError( esc_html( $error_message ) );
175 } else {
176 throw new UserError( esc_html__( 'The object failed to update but no error was provided', 'wp-graphql' ) );
177 }
178 }
179
180 /**
181 * If the response to creating the term didn't respond with a term_id, throw an exception
182 */
183 if ( empty( $term['term_id'] ) ) {
184 throw new UserError( esc_html__( 'The object failed to create', 'wp-graphql' ) );
185 }
186
187 /**
188 * Fires after a single term is created or updated via a GraphQL mutation
189 *
190 * @param int $term_id Inserted term object
191 * @param \WP_Taxonomy $taxonomy The taxonomy of the term being updated
192 * @param array<string,mixed> $args The args used to insert the term
193 * @param string $mutation_name The name of the mutation being performed
194 * @param \WPGraphQL\AppContext $context The AppContext passed down the resolve tree
195 * @param \GraphQL\Type\Definition\ResolveInfo $info The ResolveInfo passed down the resolve tree
196 *
197 * @hookGroup models
198 * @since 0.0.5
199 */
200 do_action( 'graphql_insert_term', $term['term_id'], $taxonomy, $args, $mutation_name, $context, $info );
201
202 /**
203 * Fires after a single term is created or updated via a GraphQL mutation
204 *
205 * The dynamic portion of the hook name, `$taxonomy->name` refers to the taxonomy of the term being mutated
206 *
207 * @param int $term_id Inserted term object
208 * @param array<string,mixed> $args The args used to insert the term
209 * @param string $mutation_name The name of the mutation being performed
210 * @param \WPGraphQL\AppContext $context The AppContext passed down the resolve tree
211 * @param \GraphQL\Type\Definition\ResolveInfo $info The ResolveInfo passed down the resolve tree
212 *
213 * @hookGroup models
214 * @since 0.0.5
215 */
216 do_action( "graphql_insert_{$taxonomy->name}", $term['term_id'], $args, $mutation_name, $context, $info );
217
218 return [
219 'termId' => $term['term_id'],
220 ];
221 };
222 }
223 }
224