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

AxeWP / wp-graphql-rank-math / 15507492505

07 Jun 2025 11:44AM UTC coverage: 86.429% (-2.0%) from 88.44%
15507492505

push

github

web-flow
dev: add support for lazy-loading `description`/`deprecationReason` config values (#121)

* chore: update strauss and deps

* dev: use callable descriptions/deprecations

* fix: dont prefix `NodeWithRankMathSeo`

* chore: fix backcompat on connections

* chore: update dep

* chore: update deps

* tests: ensure schema can build

* chore: update and cleanup

* fix: regenerate autoloader

357 of 367 new or added lines in 66 files covered. (97.28%)

60 existing lines in 60 files now uncovered.

2541 of 2940 relevant lines covered (86.43%)

11.49 hits per line

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

71.67
/src/Type/WPInterface/NodeWithSeo.php
1
<?php
2
/**
3
 * Interface for a Node with SEO data.
4
 *
5
 * @package WPGraphQL\RankMath\Type\WPInterface
6
 * @since 0.0.8
7
 */
8

9
declare( strict_types = 1 );
10

11
namespace WPGraphQL\RankMath\Type\WPInterface;
12

13
use GraphQL\Error\UserError;
14
use WPGraphQL\Model\Model;
15
use WPGraphQL\RankMath\Model\ContentNodeSeo;
16
use WPGraphQL\RankMath\Model\ContentTypeSeo;
17
use WPGraphQL\RankMath\Model\TermNodeSeo;
18
use WPGraphQL\RankMath\Model\UserSeo;
19
use WPGraphQL\RankMath\Type\WPInterface\ContentNodeSeo as WPInterfaceContentNodeSeo;
20
use WPGraphQL\RankMath\Utils\Utils;
21
use WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\InterfaceType;
22
use WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Helper\Compat;
23
use WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Interfaces\TypeWithInterfaces;
24

25
/**
26
 * Class - NodeWithSeo
27
 */
28
class NodeWithSeo extends InterfaceType implements TypeWithInterfaces {
29
        /**
30
         * {@inheritDoc}
31
         *
32
         * Overloaded so the type isn't prefixed.
33
         */
34
        public static function register(): void {
35
                // @todo Remove when WPGraphQL < 2.3.0 is dropped.
36
                $config = Compat::resolve_graphql_config( static::get_type_config() );
20✔
37
                register_graphql_interface_type( static::type_name(), $config );
20✔
38

39
                /**
40
                 * Filters the GraphQL types that have SEO data.
41
                 * This is used to register the NodeWithSeo interface to the types.
42
                 *
43
                 * @since 0.0.8
44
                 *
45
                 * @param array $types_with_seo The types that have SEO data.
46
                 */
47
                $types_with_seo = apply_filters(
20✔
48
                        'graphql_seo_types_with_seo',
20✔
49
                        [
20✔
50
                                'User',
20✔
51
                                'TermNode',
20✔
52
                                'ContentType',
20✔
53
                                'ContentNode',
20✔
54
                        ]
20✔
55
                );
20✔
56

57
                // @todo only apply to ContentTypes that have SEO data.
58

59
                register_graphql_interfaces_to_types( self::type_name(), $types_with_seo );
20✔
60

61
                // Narrow down ContentNode types.
62
                Utils::overload_graphql_field_type( 'ContentNode', 'seo', WPInterfaceContentNodeSeo::get_type_name() );
20✔
63
                // This is necessary because the filter doesn't work for inheritance.
64
                Utils::overload_graphql_field_type( 'HierarchicalContentNode', 'seo', WPInterfaceContentNodeSeo::get_type_name() );
20✔
65
        }
66

67
        /**
68
         * {@inheritDoc}
69
         */
70
        protected static function type_name(): string {
71
                return 'NodeWithRankMathSeo';
20✔
72
        }
73

74
        /**
75
         * {@inheritDoc}
76
         */
77
        public static function get_description(): string {
UNCOV
78
                return __( 'A node with RankMath SEO data.', 'wp-graphql-rank-math' );
×
79
        }
80

81
        /**
82
         * {@inheritDoc}
83
         */
84
        public static function get_fields(): array {
85
                return [
20✔
86
                        'seo' => [
20✔
87
                                'type'        => Seo::get_type_name(),
20✔
88
                                'description' => static fn () => __( 'The RankMath SEO data for the node.', 'wp-graphql-rank-math' ),
20✔
89
                                'resolve'     => static function ( $source ) {
20✔
90
                                        if ( ! $source instanceof Model ) {
7✔
91
                                                return null;
×
92
                                        }
93

94
                                        if ( empty( $source->uri ) ) {
7✔
95
                                                /**
96
                                                 * This can occur when querying the `Posts` page, since the Model "casts" it as a `ContentType` due to the lack of archive support.
97
                                                 *
98
                                                 * @see \WPGraphQL\Model\Post::$uri
99
                                                 */
100
                                                if ( $source instanceof \WPGraphQL\Model\Post && $source->isPostsPage ) {
×
101
                                                        graphql_debug(
×
102
                                                                sprintf(
×
103
                                                                        // translators: %d: The ID of the Post model being queried.
104
                                                                        esc_html__( 'Post %d is configured as the Posts archive, but is being queried as a `Page`. To get the SEO data, please query the object as a `ContentType` (e.g. via `nodeByUri`).', 'wp-graphql-rank-math' ),
×
105
                                                                        $source->databaseId,
×
106
                                                                )
×
107
                                                        );
×
108
                                                }
109
                                                return null;
×
110
                                        }
111

112
                                        $model = self::get_model_for_node( $source );
7✔
113

114
                                        if ( empty( $model ) ) {
7✔
115
                                                throw new UserError(
×
116
                                                        sprintf(
×
117
                                                                /* translators: %s: The name of the node type */
118
                                                                esc_html__( 'The %s type does not have a corresponding SEO model class.', 'wp-graphql-rank-math' ),
×
119
                                                                esc_html( get_class( $source ) )
×
120
                                                        )
×
121
                                                );
×
122
                                        }
123

124
                                        return $model;
7✔
125
                                },
20✔
126
                        ],
20✔
127
                ];
20✔
128
        }
129

130
        /**
131
         * {@inheritDoc}
132
         */
133
        public static function get_interfaces(): array {
134
                return [ 'Node' ];
20✔
135
        }
136

137
        /**
138
         * Gets the SEO model class for a given node model.
139
         *
140
         * @param \WPGraphQL\Model\Model $node_model The node model.
141
         */
142
        private static function get_model_for_node( Model $node_model ): ?Model {
143
                // A map of the node models to their corresponding SEO model classes.
144
                switch ( true ) {
145
                        case $node_model instanceof \WPGraphQL\Model\Post:
7✔
146
                                $seo_model = isset( $node_model->databaseId ) ? new ContentNodeSeo( $node_model->databaseId ) : null;
4✔
147
                                break;
4✔
148
                        case $node_model instanceof \WPGraphQL\Model\PostType:
4✔
149
                                $seo_model = isset( $node_model->name ) ? new ContentTypeSeo( $node_model->name ) : null;
1✔
150
                                break;
1✔
151
                        case $node_model instanceof \WPGraphQL\Model\Term:
3✔
152
                                $seo_model = isset( $node_model->databaseId ) ? new TermNodeSeo( $node_model->databaseId ) : null;
2✔
153
                                break;
2✔
154
                        case $node_model instanceof \WPGraphQL\Model\User:
1✔
155
                                $seo_model = isset( $node_model->databaseId ) ? new UserSeo( $node_model->databaseId ) : null;
1✔
156
                                break;
1✔
157
                        default:
158
                                $seo_model = null;
×
159
                }
160

161
                /**
162
                 * Filter the SEO model class used for a given node model.
163
                 *
164
                 * @since 0.0.8
165
                 *
166
                 * @param \WPGraphQL\Model\Model|null $seo_model The SEO model class to use.
167
                 * @param \WPGraphQL\Model\Model $node_model The Model for the node.
168
                 */
169
                $seo_model = apply_filters( 'graphql_seo_resolved_model', $seo_model, $node_model );
7✔
170

171
                return $seo_model;
7✔
172
        }
173
}
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

© 2025 Coveralls, Inc