• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wp-graphql / wp-graphql / 17334288077

29 Aug 2025 09:07PM UTC coverage: 84.593% (+0.4%) from 84.169%
17334288077

push

github

actions-user
chore: update changeset for PR #3410

15884 of 18777 relevant lines covered (84.59%)

260.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.75
/src/Registry/Utils/PostObject.php
1
<?php
2

3
namespace WPGraphQL\Registry\Utils;
4

5
use GraphQL\Type\Definition\ResolveInfo;
6
use WPGraphQL;
7
use WPGraphQL\AppContext;
8
use WPGraphQL\Data\Connection\CommentConnectionResolver;
9
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;
10
use WPGraphQL\Data\Connection\TermObjectConnectionResolver;
11
use WPGraphQL\Model\Post;
12
use WPGraphQL\Type\Connection\Comments;
13
use WPGraphQL\Type\Connection\PostObjects;
14
use WPGraphQL\Type\Connection\TermObjects;
15
use WP_Post_Type;
16

17
/**
18
 * Class PostObject
19
 *
20
 * @package WPGraphQL\Data
21
 * @since   1.12.0
22
 */
23
class PostObject {
24

25
        /**
26
         * Registers a post_type type to the schema as either a GraphQL object, interface, or union.
27
         *
28
         * @param \WP_Post_Type $post_type_object Post type.
29
         *
30
         * @return void
31
         * @throws \Exception
32
         */
33
        public static function register_types( WP_Post_Type $post_type_object ) {
601✔
34
                $single_name = $post_type_object->graphql_single_name;
601✔
35

36
                $config = [
601✔
37
                        'description' => static function () use ( $post_type_object, $single_name ) {
601✔
38
                                return ! empty( $post_type_object->graphql_description )
20✔
39
                                        ? $post_type_object->graphql_description
19✔
40
                                        : ( ! empty( $post_type_object->description )
8✔
41
                                                ? $post_type_object->description
×
42
                                        /* translators: post object singular name w/ description */
8✔
43
                                                : sprintf( __( 'The %s type', 'wp-graphql' ), $single_name )
20✔
44
                                        );
20✔
45
                        },
601✔
46
                        'connections' => static::get_connections( $post_type_object ),
601✔
47
                        'interfaces'  => static::get_interfaces( $post_type_object ),
601✔
48
                        'fields'      => static::get_fields( $post_type_object ),
601✔
49
                        'model'       => Post::class,
601✔
50
                ];
601✔
51

52
                // Register as GraphQL objects.
53
                if ( 'object' === $post_type_object->graphql_kind ) {
601✔
54
                        register_graphql_object_type( $single_name, $config );
601✔
55

56
                        // Register fields to the Type used for attachments (MediaItem)
57
                        if ( 'attachment' === $post_type_object->name && true === $post_type_object->show_in_graphql && isset( $post_type_object->graphql_single_name ) ) {
601✔
58
                                self::register_attachment_fields( $post_type_object );
600✔
59
                        }
60

61
                        return;
601✔
62
                }
63

64
                /**
65
                 * Register as GraphQL interfaces or unions.
66
                 *
67
                 * It's assumed that the types used in `resolveType` have already been registered to the schema.
68
                 */
69

70
                // Bail early if graphql_resolve_type isnt a vallable callback.
71
                if ( empty( $post_type_object->graphql_resolve_type ) || ! is_callable( $post_type_object->graphql_resolve_type ) ) {
3✔
72
                        graphql_debug(
1✔
73
                                sprintf(
1✔
74
                                        // translators: %1$s is the post type name, %2$s is the graphql kind.
75
                                        __( '%1$s is registered as a GraphQL %2$s, but has no way to resolve the type. Ensure "graphql_resolve_type" is a valid callback function', 'wp-graphql' ),
1✔
76
                                        $single_name,
1✔
77
                                        $post_type_object->graphql_kind
1✔
78
                                ),
1✔
79
                                [ 'registered_post_type_object' => $post_type_object ]
1✔
80
                        );
1✔
81

82
                        return;
1✔
83
                }
84

85
                $config['resolveType'] = $post_type_object->graphql_resolve_type;
3✔
86

87
                if ( 'interface' === $post_type_object->graphql_kind ) {
3✔
88
                        register_graphql_interface_type( $single_name, $config );
1✔
89

90
                        return;
1✔
91
                } elseif ( 'union' === $post_type_object->graphql_kind ) {
2✔
92

93
                        // Bail early if graphql_union_types is not defined.
94
                        if ( empty( $post_type_object->graphql_union_types ) || ! is_array( $post_type_object->graphql_union_types ) ) {
2✔
95
                                graphql_debug(
1✔
96
                                        __( 'Registering a post type with "graphql_kind" => "union" requires "graphql_union_types" to be a valid array of possible GraphQL type names.', 'wp-graphql' ),
1✔
97
                                        [ 'registered_post_type_object' => $post_type_object ]
1✔
98
                                );
1✔
99

100
                                return;
1✔
101
                        }
102

103
                        // Set the possible types for the union.
104
                        $config['typeNames'] = $post_type_object->graphql_union_types;
1✔
105

106
                        register_graphql_union_type( $single_name, $config );
1✔
107
                }
108
        }
109

110
        /**
111
         * Gets all the connections for the given post type.
112
         *
113
         * @param \WP_Post_Type $post_type_object
114
         *
115
         * @return array<string,array<string,mixed>>
116
         */
117
        protected static function get_connections( WP_Post_Type $post_type_object ) {
601✔
118
                $connections = [];
601✔
119

120
                // Comments.
121
                if ( post_type_supports( $post_type_object->name, 'comments' ) ) {
601✔
122
                        $connections['comments'] = [
601✔
123
                                'toType'         => 'Comment',
601✔
124
                                'connectionArgs' => Comments::get_connection_args(),
601✔
125
                                'resolve'        => static function ( Post $post, $args, $context, $info ) {
601✔
126
                                        if ( $post->isRevision ) {
3✔
127
                                                $id = $post->parentDatabaseId;
×
128
                                        } else {
129
                                                $id = $post->databaseId;
3✔
130
                                        }
131

132
                                        $resolver = new CommentConnectionResolver( $post, $args, $context, $info );
3✔
133

134
                                        return $resolver->set_query_arg( 'post_id', absint( $id ) )->get_connection();
3✔
135
                                },
601✔
136
                        ];
601✔
137
                }
138

139
                // Revisions.
140
                if ( true === post_type_supports( $post_type_object->name, 'revisions' ) ) {
601✔
141
                        $connections['revisions'] = [
601✔
142
                                'connectionTypeName' => ucfirst( $post_type_object->graphql_single_name ) . 'ToRevisionConnection',
601✔
143
                                'toType'             => $post_type_object->graphql_single_name,
601✔
144
                                'queryClass'         => 'WP_Query',
601✔
145
                                'connectionArgs'     => PostObjects::get_connection_args( [], $post_type_object ),
601✔
146
                                'resolve'            => static function ( Post $post, $args, $context, $info ) {
601✔
147
                                        $resolver = new PostObjectConnectionResolver( $post, $args, $context, $info, 'revision' );
3✔
148
                                        $resolver->set_query_arg( 'post_parent', $post->databaseId );
3✔
149

150
                                        return $resolver->get_connection();
3✔
151
                                },
601✔
152
                        ];
601✔
153
                }
154

155
                // Used to ensure TermNode connection doesn't get registered multiple times.
156
                $already_registered = false;
601✔
157
                $allowed_taxonomies = WPGraphQL::get_allowed_taxonomies( 'objects' );
601✔
158

159
                foreach ( $allowed_taxonomies as $tax_object ) {
601✔
160
                        if ( ! in_array( $post_type_object->name, $tax_object->object_type, true ) ) {
601✔
161
                                continue;
600✔
162
                        }
163

164
                        // TermNode.
165
                        if ( ! $already_registered ) {
601✔
166
                                $connections['terms'] = [
601✔
167
                                        'toType'         => 'TermNode',
601✔
168
                                        'queryClass'     => 'WP_Term_Query',
601✔
169
                                        'connectionArgs' => TermObjects::get_connection_args(
601✔
170
                                                [
601✔
171
                                                        'taxonomies' => [
601✔
172
                                                                'type'        => [ 'list_of' => 'TaxonomyEnum' ],
601✔
173
                                                                'description' => static function () {
601✔
174
                                                                        return __( 'The Taxonomy to filter terms by', 'wp-graphql' );
14✔
175
                                                                },
601✔
176
                                                        ],
601✔
177
                                                ]
601✔
178
                                        ),
601✔
179
                                        'resolve'        => static function ( Post $post, $args, AppContext $context, ResolveInfo $info ) {
601✔
180
                                                $taxonomies = \WPGraphQL::get_allowed_taxonomies();
×
181
                                                $object_id  = true === $post->isPreview && ! empty( $post->parentDatabaseId ) ? $post->parentDatabaseId : $post->databaseId;
×
182

183
                                                if ( empty( $object_id ) ) {
×
184
                                                        return null;
×
185
                                                }
186

187
                                                $resolver = new TermObjectConnectionResolver( $post, $args, $context, $info, $taxonomies );
×
188
                                                $resolver->set_query_arg( 'object_ids', absint( $object_id ) );
×
189
                                                return $resolver->get_connection();
×
190
                                        },
601✔
191
                                ];
601✔
192

193
                                // We won't need to register this connection again.
194
                                $already_registered = true;
601✔
195
                        }
196

197
                        // TermObjects.
198
                        $connections[ $tax_object->graphql_plural_name ] = [
601✔
199
                                'toType'         => $tax_object->graphql_single_name,
601✔
200
                                'queryClass'     => 'WP_Term_Query',
601✔
201
                                'connectionArgs' => TermObjects::get_connection_args(),
601✔
202
                                'resolve'        => static function ( Post $post, $args, AppContext $context, $info ) use ( $tax_object ) {
601✔
203
                                        $object_id = true === $post->isPreview && ! empty( $post->parentDatabaseId ) ? $post->parentDatabaseId : $post->databaseId;
15✔
204

205
                                        if ( empty( $object_id ) || ! absint( $object_id ) ) {
15✔
206
                                                return null;
×
207
                                        }
208

209
                                        $resolver = new TermObjectConnectionResolver( $post, $args, $context, $info, $tax_object->name );
15✔
210
                                        $resolver->set_query_arg( 'object_ids', absint( $object_id ) );
15✔
211

212
                                        return $resolver->get_connection();
15✔
213
                                },
601✔
214
                        ];
601✔
215
                }
216

217
                // Merge with connections set in register_post_type.
218
                if ( ! empty( $post_type_object->graphql_connections ) ) {
601✔
219
                        $connections = array_merge( $connections, $post_type_object->graphql_connections );
1✔
220
                }
221

222
                // Remove excluded connections.
223
                if ( ! empty( $post_type_object->graphql_exclude_connections ) ) {
601✔
224
                        foreach ( $post_type_object->graphql_exclude_connections as $connection_name ) {
1✔
225
                                unset( $connections[ lcfirst( $connection_name ) ] );
1✔
226
                        }
227
                }
228

229
                return $connections;
601✔
230
        }
231

232
        /**
233
         * Gets all the interfaces for the given post type.
234
         *
235
         * @param \WP_Post_Type $post_type_object Post type.
236
         *
237
         * @return string[]
238
         */
239
        protected static function get_interfaces( WP_Post_Type $post_type_object ) {
601✔
240
                $interfaces = [ 'Node', 'ContentNode', 'DatabaseIdentifier', 'NodeWithTemplate' ];
601✔
241

242
                if ( true === $post_type_object->public ) {
601✔
243
                        $interfaces[] = 'UniformResourceIdentifiable';
601✔
244
                }
245

246
                // Only post types that are publicly_queryable are previewable
247
                if ( 'attachment' !== $post_type_object->name && ( true === $post_type_object->publicly_queryable || true === $post_type_object->public ) ) {
601✔
248
                        $interfaces[] = 'Previewable';
601✔
249
                }
250

251
                if ( post_type_supports( $post_type_object->name, 'title' ) ) {
601✔
252
                        $interfaces[] = 'NodeWithTitle';
601✔
253
                }
254

255
                if ( post_type_supports( $post_type_object->name, 'editor' ) ) {
601✔
256
                        $interfaces[] = 'NodeWithContentEditor';
601✔
257
                }
258

259
                if ( post_type_supports( $post_type_object->name, 'author' ) ) {
601✔
260
                        $interfaces[] = 'NodeWithAuthor';
601✔
261
                }
262

263
                if ( post_type_supports( $post_type_object->name, 'thumbnail' ) ) {
601✔
264
                        $interfaces[] = 'NodeWithFeaturedImage';
601✔
265
                }
266

267
                if ( post_type_supports( $post_type_object->name, 'excerpt' ) ) {
601✔
268
                        $interfaces[] = 'NodeWithExcerpt';
601✔
269
                }
270

271
                if ( post_type_supports( $post_type_object->name, 'comments' ) ) {
601✔
272
                        $interfaces[] = 'NodeWithComments';
601✔
273
                }
274

275
                if ( post_type_supports( $post_type_object->name, 'trackbacks' ) ) {
601✔
276
                        $interfaces[] = 'NodeWithTrackbacks';
601✔
277
                }
278

279
                if ( post_type_supports( $post_type_object->name, 'revisions' ) ) {
601✔
280
                        $interfaces[] = 'NodeWithRevisions';
601✔
281
                }
282

283
                if ( post_type_supports( $post_type_object->name, 'page-attributes' ) ) {
601✔
284
                        $interfaces[] = 'NodeWithPageAttributes';
600✔
285
                }
286

287
                if ( $post_type_object->hierarchical || in_array(
601✔
288
                        $post_type_object->name,
601✔
289
                        [
601✔
290
                                'attachment',
601✔
291
                                'revision',
601✔
292
                        ],
601✔
293
                        true
601✔
294
                ) ) {
601✔
295
                        $interfaces[] = 'HierarchicalContentNode';
600✔
296
                }
297

298
                if ( true === $post_type_object->show_in_nav_menus ) {
601✔
299
                        $interfaces[] = 'MenuItemLinkable';
601✔
300
                }
301

302
                // Merge with interfaces set in register_post_type.
303
                if ( ! empty( $post_type_object->graphql_interfaces ) ) {
601✔
304
                        $interfaces = array_merge( $interfaces, $post_type_object->graphql_interfaces );
1✔
305
                }
306

307
                // Remove excluded interfaces.
308
                if ( ! empty( $post_type_object->graphql_exclude_interfaces ) ) {
601✔
309
                        $interfaces = array_diff( $interfaces, $post_type_object->graphql_exclude_interfaces );
1✔
310
                }
311

312
                return $interfaces;
601✔
313
        }
314

315
        /**
316
         * Registers common post type fields on schema type corresponding to provided post type object.
317
         *
318
         * @param \WP_Post_Type $post_type_object Post type.
319
         *
320
         * @return array<string,array<string,mixed>>
321
         * @todo make protected after \Type\ObjectType\PostObject::get_fields() is removed.
322
         */
323
        public static function get_fields( WP_Post_Type $post_type_object ) {
601✔
324
                $single_name = $post_type_object->graphql_single_name;
601✔
325
                $fields      = [
601✔
326
                        'id'                => [
601✔
327
                                'description' => static function () use ( $post_type_object ) {
601✔
328
                                        return sprintf(
20✔
329
                                                /* translators: %s: custom post-type name */
330
                                                __( 'The globally unique identifier of the %s object.', 'wp-graphql' ),
20✔
331
                                                $post_type_object->name
20✔
332
                                        );
20✔
333
                                },
601✔
334
                        ],
601✔
335
                        $single_name . 'Id' => [
601✔
336
                                'type'              => [
601✔
337
                                        'non_null' => 'Int',
601✔
338
                                ],
601✔
339
                                'deprecationReason' => static function () {
601✔
340
                                        return __( 'Deprecated in favor of the databaseId field', 'wp-graphql' );
20✔
341
                                },
601✔
342
                                'description'       => static function () {
601✔
343
                                        return __( 'The id field matches the WP_Post->ID field.', 'wp-graphql' );
20✔
344
                                },
601✔
345
                                'resolve'           => static function ( Post $post ) {
601✔
346
                                        return absint( $post->databaseId );
50✔
347
                                },
601✔
348
                        ],
601✔
349
                        'hasPassword'       => [
601✔
350
                                'type'        => 'Boolean',
601✔
351
                                'description' => static function () use ( $post_type_object ) {
601✔
352
                                        return sprintf(
20✔
353
                                                // translators: %s: custom post-type name.
354
                                                __( 'Whether the %s object is password protected.', 'wp-graphql' ),
20✔
355
                                                $post_type_object->name
20✔
356
                                        );
20✔
357
                                },
601✔
358
                        ],
601✔
359
                        'password'          => [
601✔
360
                                'type'        => 'String',
601✔
361
                                'description' => static function () use ( $post_type_object ) {
601✔
362
                                        return sprintf(
20✔
363
                                                // translators: %s: custom post-type name.
364
                                                __( 'The password for the %s object.', 'wp-graphql' ),
20✔
365
                                                $post_type_object->name
20✔
366
                                        );
20✔
367
                                },
601✔
368
                        ],
601✔
369
                ];
601✔
370

371
                if ( 'page' === $post_type_object->name ) {
601✔
372
                        $fields['isFrontPage'] = [
600✔
373
                                'type'        => [ 'non_null' => 'Bool' ],
600✔
374
                                'description' => static function () {
600✔
375
                                        return __( 'Whether this page is set to the static front page.', 'wp-graphql' );
19✔
376
                                },
600✔
377
                        ];
600✔
378

379
                        $fields['isPostsPage'] = [
600✔
380
                                'type'        => [ 'non_null' => 'Bool' ],
600✔
381
                                'description' => static function () {
600✔
382
                                        return __( 'Whether this page is set to the blog posts page.', 'wp-graphql' );
19✔
383
                                },
600✔
384
                        ];
600✔
385

386
                        $fields['isPrivacyPage'] = [
600✔
387
                                'type'        => [ 'non_null' => 'Bool' ],
600✔
388
                                'description' => static function () {
600✔
389
                                        return __( 'Whether this page is set to the privacy page.', 'wp-graphql' );
19✔
390
                                },
600✔
391
                        ];
600✔
392
                }
393

394
                if ( 'post' === $post_type_object->name ) {
601✔
395
                        $fields['isSticky'] = [
601✔
396
                                'type'        => [ 'non_null' => 'Bool' ],
601✔
397
                                'description' => static function () {
601✔
398
                                        return __( 'Whether this page is sticky', 'wp-graphql' );
18✔
399
                                },
601✔
400
                        ];
601✔
401
                }
402

403
                // Merge with fields set in register_post_type.
404
                if ( ! empty( $post_type_object->graphql_fields ) ) {
601✔
405
                        $fields = array_merge( $fields, $post_type_object->graphql_fields );
2✔
406
                }
407

408
                // Remove excluded fields.
409
                if ( ! empty( $post_type_object->graphql_exclude_fields ) ) {
601✔
410
                        foreach ( $post_type_object->graphql_exclude_fields as $field_name ) {
1✔
411
                                unset( $fields[ $field_name ] );
1✔
412
                        }
413
                }
414

415
                return $fields;
601✔
416
        }
417

418
        /**
419
         * Register fields to the Type used for attachments (MediaItem).
420
         *
421
         * @param \WP_Post_Type $post_type_object Post type.
422
         */
423
        private static function register_attachment_fields( WP_Post_Type $post_type_object ): void {
600✔
424
                /**
425
                 * Register fields custom to the MediaItem Type
426
                 */
427
                register_graphql_fields(
600✔
428
                        $post_type_object->graphql_single_name,
600✔
429
                        [
600✔
430
                                'caption'      => [
600✔
431
                                        'type'        => 'String',
600✔
432
                                        'description' => static function () {
600✔
433
                                                return __( 'The caption for the resource', 'wp-graphql' );
18✔
434
                                        },
600✔
435
                                        'args'        => [
600✔
436
                                                'format' => [
600✔
437
                                                        'type'        => 'PostObjectFieldFormatEnum',
600✔
438
                                                        'description' => static function () {
600✔
439
                                                                return __( 'Format of the field output', 'wp-graphql' );
18✔
440
                                                        },
600✔
441
                                                ],
600✔
442
                                        ],
600✔
443
                                        'resolve'     => static function ( $source, $args ) {
600✔
444
                                                if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
7✔
445
                                                        // @codingStandardsIgnoreLine.
446
                                                        return $source->captionRaw;
×
447
                                                }
448

449
                                                // @codingStandardsIgnoreLine.
450
                                                return $source->captionRendered;
7✔
451
                                        },
600✔
452
                                ],
600✔
453
                                'altText'      => [
600✔
454
                                        'type'        => 'String',
600✔
455
                                        'description' => static function () {
600✔
456
                                                return __( 'Alternative text to display when resource is not displayed', 'wp-graphql' );
18✔
457
                                        },
600✔
458
                                ],
600✔
459
                                'srcSet'       => [
600✔
460
                                        'type'        => 'string',
600✔
461
                                        'args'        => [
600✔
462
                                                'size' => [
600✔
463
                                                        'type'        => 'MediaItemSizeEnum',
600✔
464
                                                        'description' => static function () {
600✔
465
                                                                return __( 'Size of the MediaItem to calculate srcSet with', 'wp-graphql' );
18✔
466
                                                        },
600✔
467
                                                ],
600✔
468
                                        ],
600✔
469
                                        'description' => static function () {
600✔
470
                                                return __( 'The srcset attribute specifies the URL of the image to use in different situations. It is a comma separated string of urls and their widths.', 'wp-graphql' );
18✔
471
                                        },
600✔
472
                                        'resolve'     => static function ( $source, $args ) {
600✔
473
                                                $size = 'medium';
3✔
474
                                                if ( ! empty( $args['size'] ) ) {
3✔
475
                                                        $size = $args['size'];
1✔
476
                                                }
477

478
                                                $src_set = wp_get_attachment_image_srcset( $source->ID, $size );
3✔
479

480
                                                return ! empty( $src_set ) ? $src_set : null;
3✔
481
                                        },
600✔
482
                                ],
600✔
483
                                'sizes'        => [
600✔
484
                                        'type'        => 'string',
600✔
485
                                        'args'        => [
600✔
486
                                                'size' => [
600✔
487
                                                        'type'        => 'MediaItemSizeEnum',
600✔
488
                                                        'description' => static function () {
600✔
489
                                                                return __( 'Size of the MediaItem to calculate sizes with', 'wp-graphql' );
18✔
490
                                                        },
600✔
491
                                                ],
600✔
492
                                        ],
600✔
493
                                        'description' => static function () {
600✔
494
                                                return __( 'The sizes attribute value for an image.', 'wp-graphql' );
18✔
495
                                        },
600✔
496
                                        'resolve'     => static function ( $source, $args ) {
600✔
497
                                                $size = 'medium';
1✔
498
                                                if ( ! empty( $args['size'] ) ) {
1✔
499
                                                        $size = $args['size'];
1✔
500
                                                }
501

502
                                                $image = wp_get_attachment_image_src( $source->ID, $size );
1✔
503
                                                if ( $image ) {
1✔
504
                                                        list( $src, $width, $height ) = $image;
1✔
505
                                                        $sizes                        = wp_calculate_image_sizes(
1✔
506
                                                                [
1✔
507
                                                                        absint( $width ),
1✔
508
                                                                        absint( $height ),
1✔
509
                                                                ],
1✔
510
                                                                $src,
1✔
511
                                                                null,
1✔
512
                                                                $source->ID
1✔
513
                                                        );
1✔
514

515
                                                        return ! empty( $sizes ) ? $sizes : null;
1✔
516
                                                }
517

518
                                                return null;
×
519
                                        },
600✔
520
                                ],
600✔
521
                                'description'  => [
600✔
522
                                        'type'        => 'String',
600✔
523
                                        'description' => static function () {
600✔
524
                                                return __( 'Description of the image (stored as post_content)', 'wp-graphql' );
18✔
525
                                        },
600✔
526
                                        'args'        => [
600✔
527
                                                'format' => [
600✔
528
                                                        'type'        => 'PostObjectFieldFormatEnum',
600✔
529
                                                        'description' => static function () {
600✔
530
                                                                return __( 'Format of the field output', 'wp-graphql' );
18✔
531
                                                        },
600✔
532
                                                ],
600✔
533
                                        ],
600✔
534
                                        'resolve'     => static function ( $source, $args ) {
600✔
535
                                                if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
8✔
536
                                                        // @codingStandardsIgnoreLine.
537
                                                        return $source->descriptionRaw;
×
538
                                                }
539

540
                                                // @codingStandardsIgnoreLine.
541
                                                return $source->descriptionRendered;
8✔
542
                                        },
600✔
543
                                ],
600✔
544
                                'mediaItemUrl' => [
600✔
545
                                        'type'        => 'String',
600✔
546
                                        'description' => static function () {
600✔
547
                                                return __( 'Url of the mediaItem', 'wp-graphql' );
18✔
548
                                        },
600✔
549
                                ],
600✔
550
                                'mediaType'    => [
600✔
551
                                        'type'        => 'String',
600✔
552
                                        'description' => static function () {
600✔
553
                                                return __( 'Type of resource', 'wp-graphql' );
18✔
554
                                        },
600✔
555
                                ],
600✔
556
                                'sourceUrl'    => [
600✔
557
                                        'type'        => 'String',
600✔
558
                                        'description' => static function () {
600✔
559
                                                return __( 'Url of the mediaItem', 'wp-graphql' );
18✔
560
                                        },
600✔
561
                                        'args'        => [
600✔
562
                                                'size' => [
600✔
563
                                                        'type'        => 'MediaItemSizeEnum',
600✔
564
                                                        'description' => static function () {
600✔
565
                                                                return __( 'Size of the MediaItem to return', 'wp-graphql' );
18✔
566
                                                        },
600✔
567
                                                ],
600✔
568
                                        ],
600✔
569
                                        'resolve'     => static function ( $image, $args ) {
600✔
570
                                                if ( empty( $args['size'] ) ) {
8✔
571
                                                        return $image->sourceUrl;
7✔
572
                                                }
573

574
                                                // @todo why do we coerce full to large?
575
                                                $size = 'full' === $args['size'] ? 'large' : $args['size'];
2✔
576

577
                                                /** @var \WPGraphQL\Model\Post $image */
578
                                                return $image->get_source_url_by_size( $size );
2✔
579
                                        },
600✔
580
                                ],
600✔
581
                                'file'         => [
600✔
582
                                        'type'        => 'String',
600✔
583
                                        'description' => static function () {
600✔
584
                                                return __( 'The filename of the mediaItem for the specified size (default size is full)', 'wp-graphql' );
18✔
585
                                        },
600✔
586
                                        'args'        => [
600✔
587
                                                'size' => [
600✔
588
                                                        'type'        => 'MediaItemSizeEnum',
600✔
589
                                                        'description' => static function () {
600✔
590
                                                                return __( 'Size of the MediaItem to return', 'wp-graphql' );
18✔
591
                                                        },
600✔
592
                                                ],
600✔
593
                                        ],
600✔
594
                                        'resolve'     => static function ( $source, $args ) {
600✔
595
                                                // If a size is specified, get the size-specific filename
596
                                                if ( ! empty( $args['size'] ) ) {
1✔
597
                                                        $size = 'full' === $args['size'] ? 'large' : $args['size'];
1✔
598

599
                                                        // Get the metadata which contains size information
600
                                                        $metadata = wp_get_attachment_metadata( $source->databaseId );
1✔
601

602
                                                        if ( ! empty( $metadata['sizes'][ $size ]['file'] ) ) {
1✔
603
                                                                return $metadata['sizes'][ $size ]['file'];
1✔
604
                                                        }
605
                                                }
606

607
                                                // Default to original file
608
                                                $attached_file = get_post_meta( $source->databaseId, '_wp_attached_file', true );
1✔
609
                                                return ! empty( $attached_file ) ? basename( $attached_file ) : null;
1✔
610
                                        },
600✔
611
                                ],
600✔
612
                                'filePath'     => [
600✔
613
                                        'type'        => 'String',
600✔
614
                                        'description' => static function () {
600✔
615
                                                return __( 'The path to the original file relative to the uploads directory', 'wp-graphql' );
18✔
616
                                        },
600✔
617
                                        'args'        => [
600✔
618
                                                'size' => [
600✔
619
                                                        'type'        => 'MediaItemSizeEnum',
600✔
620
                                                        'description' => static function () {
600✔
621
                                                                return __( 'Size of the MediaItem to return', 'wp-graphql' );
18✔
622
                                                        },
600✔
623
                                                ],
600✔
624
                                        ],
600✔
625
                                        'resolve'     => static function ( $source, $args ) {
600✔
626
                                                // Get the upload directory info
627
                                                $upload_dir           = wp_upload_dir();
1✔
628
                                                $relative_upload_path = wp_make_link_relative( $upload_dir['baseurl'] );
1✔
629

630
                                                // If a size is specified, get the size-specific path
631
                                                if ( ! empty( $args['size'] ) ) {
1✔
632
                                                        $size = 'full' === $args['size'] ? 'large' : $args['size'];
1✔
633

634
                                                        // Get the metadata which contains size information
635
                                                        $metadata = wp_get_attachment_metadata( $source->databaseId );
1✔
636

637
                                                        if ( ! empty( $metadata['sizes'][ $size ]['file'] ) ) {
1✔
638
                                                                $file_path = $metadata['file'];
1✔
639
                                                                return path_join( $relative_upload_path, dirname( $file_path ) . '/' . $metadata['sizes'][ $size ]['file'] );
1✔
640
                                                        }
641
                                                }
642

643
                                                // Default to original file path
644
                                                $attached_file = get_post_meta( $source->databaseId, '_wp_attached_file', true );
1✔
645

646
                                                if ( empty( $attached_file ) ) {
1✔
647
                                                        return null;
×
648
                                                }
649

650
                                                return path_join( $relative_upload_path, $attached_file );
1✔
651
                                        },
600✔
652
                                ],
600✔
653
                                'fileSize'     => [
600✔
654
                                        'type'        => 'Int',
600✔
655
                                        'description' => static function () {
600✔
656
                                                return __( 'The filesize in bytes of the resource', 'wp-graphql' );
18✔
657
                                        },
600✔
658
                                        'args'        => [
600✔
659
                                                'size' => [
600✔
660
                                                        'type'        => 'MediaItemSizeEnum',
600✔
661
                                                        'description' => static function () {
600✔
662
                                                                return __( 'Size of the MediaItem to return', 'wp-graphql' );
18✔
663
                                                        },
600✔
664
                                                ],
600✔
665
                                        ],
600✔
666
                                        'resolve'     => static function ( $image, $args ) {
600✔
667
                                                /**
668
                                                 * By default, use the mediaItemUrl.
669
                                                 *
670
                                                 * @var \WPGraphQL\Model\Post $image
671
                                                 */
672
                                                $source_url = $image->mediaItemUrl;
3✔
673

674
                                                // If there's a url for the provided size, use that instead.
675
                                                if ( ! empty( $args['size'] ) ) {
3✔
676
                                                        $size = ( 'full' === $args['size'] ) ? 'large' : $args['size'];
1✔
677

678
                                                        $source_url = $image->get_source_url_by_size( $size ) ?: $source_url;
1✔
679
                                                }
680

681
                                                // If there's no source_url, return null.
682
                                                if ( empty( $source_url ) ) {
3✔
683
                                                        return null;
×
684
                                                }
685

686
                                                $path_parts    = pathinfo( $source_url );
3✔
687
                                                $original_file = get_attached_file( absint( $image->databaseId ) );
3✔
688
                                                $filesize_path = ! empty( $original_file ) ? path_join( dirname( $original_file ), $path_parts['basename'] ) : null;
3✔
689

690
                                                return ! empty( $filesize_path ) ? filesize( $filesize_path ) : null;
3✔
691
                                        },
600✔
692
                                ],
600✔
693
                                'mimeType'     => [
600✔
694
                                        'type'        => 'String',
600✔
695
                                        'description' => static function () {
600✔
696
                                                return __( 'The mime type of the mediaItem', 'wp-graphql' );
18✔
697
                                        },
600✔
698
                                ],
600✔
699
                                'mediaDetails' => [
600✔
700
                                        'type'        => 'MediaDetails',
600✔
701
                                        'description' => static function () {
600✔
702
                                                return __( 'Details about the mediaItem', 'wp-graphql' );
18✔
703
                                        },
600✔
704
                                ],
600✔
705
                        ]
600✔
706
                );
600✔
707
        }
708
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc