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

wp-graphql / wp-graphql / 15710056976

17 Jun 2025 02:27PM UTC coverage: 84.17% (-0.1%) from 84.287%
15710056976

push

github

actions-user
release: merge develop into master for v2.3.3

15925 of 18920 relevant lines covered (84.17%)

258.66 hits per line

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

92.0
/src/Model/MenuItem.php
1
<?php
2

3
namespace WPGraphQL\Model;
4

5
use Exception;
6
use GraphQL\Error\UserError;
7
use GraphQLRelay\Relay;
8
use WP_Post;
9

10
/**
11
 * Class MenuItem - Models the data for the MenuItem object type
12
 *
13
 * @property string[]      $cssClasses
14
 * @property int           $databaseId
15
 * @property ?string       $description
16
 * @property ?string       $id
17
 * @property ?string       $label
18
 * @property ?string       $linkRelationship
19
 * @property string[]|null $locations
20
 * @property ?int          $menuDatabaseId
21
 * @property ?string       $menuId
22
 * @property int           $objectId
23
 * @property ?int          $parentDatabaseId
24
 * @property ?string       $parentId
25
 * @property ?string       $target
26
 * @property ?string       $title
27
 * @property ?string       $uri
28
 * @property ?string       $url
29
 *
30
 * @package WPGraphQL\Model
31
 *
32
 * @extends \WPGraphQL\Model\Model<object|mixed>
33
 */
34
class MenuItem extends Model {
35
        /**
36
         * MenuItem constructor.
37
         *
38
         * @param \WP_Post $post The incoming WP_Post object that needs modeling
39
         *
40
         * @return void
41
         */
42
        public function __construct( WP_Post $post ) {
21✔
43
                $this->data = wp_setup_nav_menu_item( $post );
21✔
44
                parent::__construct();
21✔
45
        }
46

47
        /**
48
         * {@inheritDoc}
49
         *
50
         * If a MenuItem is not connected to a menu that's assigned to a location
51
         * it's not considered a public node.
52
         *
53
         * @throws \Exception
54
         */
55
        public function is_private() {
21✔
56

57
                // If the current user can edit theme options, consider the menu item public
58
                if ( current_user_can( 'edit_theme_options' ) ) {
21✔
59
                        return false;
3✔
60
                }
61

62
                // Get menu locations for the active theme
63
                $locations = get_theme_mod( 'nav_menu_locations' );
20✔
64

65
                // If there are no menu locations, consider the MenuItem private
66
                if ( empty( $locations ) ) {
20✔
67
                        return true;
×
68
                }
69

70
                // Get the values of the locations
71
                $location_ids = array_values( $locations );
20✔
72
                $menus        = wp_get_object_terms( $this->data->ID, 'nav_menu', [ 'fields' => 'ids' ] );
20✔
73

74
                // If there are no menus
75
                if ( empty( $menus ) ) {
20✔
76
                        return true;
×
77
                }
78

79
                if ( is_wp_error( $menus ) ) {
20✔
80
                        // translators: %s is the menu item ID.
81
                        throw new Exception( esc_html( sprintf( __( 'No menus could be found for menu item %s', 'wp-graphql' ), $this->data->ID ) ) );
×
82
                }
83

84
                $menu_id = $menus[0];
20✔
85
                if ( empty( $location_ids ) || ! in_array( $menu_id, $location_ids, true ) ) {
20✔
86
                        return true;
×
87
                }
88

89
                return false;
20✔
90
        }
91

92
        /**
93
         * {@inheritDoc}
94
         */
95
        protected function init() {
21✔
96
                if ( empty( $this->fields ) ) {
21✔
97
                        $this->fields = [
21✔
98
                                'cssClasses'       => function () {
21✔
99
                                        // If all we have is a non-array or an array with one empty
100
                                        // string, return an empty array.
101
                                        if ( ! isset( $this->data->classes ) || ! is_array( $this->data->classes ) || empty( $this->data->classes ) || empty( $this->data->classes[0] ) ) {
4✔
102
                                                return [];
1✔
103
                                        }
104

105
                                        return $this->data->classes;
3✔
106
                                },
21✔
107
                                'databaseId'       => function () {
21✔
108
                                        return absint( $this->data->ID );
21✔
109
                                },
21✔
110
                                'description'      => function () {
21✔
111
                                        return ! empty( $this->data->description ) ? $this->data->description : null;
4✔
112
                                },
21✔
113
                                'id'               => function () {
21✔
114
                                        return ! empty( $this->databaseId ) ? Relay::toGlobalId( 'post', (string) $this->databaseId ) : null;
21✔
115
                                },
21✔
116
                                'label'            => function () {
21✔
117
                                        return ! empty( $this->data->title ) ? $this->html_entity_decode( $this->data->title, 'label', true ) : null;
4✔
118
                                },
21✔
119
                                'linkRelationship' => function () {
21✔
120
                                        return ! empty( $this->data->xfn ) ? $this->data->xfn : null;
4✔
121
                                },
21✔
122
                                'locations'        => function () {
21✔
123
                                        if ( empty( $this->menuDatabaseId ) ) {
18✔
124
                                                return null;
×
125
                                        }
126

127
                                        $menu_locations = get_theme_mod( 'nav_menu_locations' );
18✔
128

129
                                        if ( empty( $menu_locations ) || ! is_array( $menu_locations ) ) {
18✔
130
                                                return null;
×
131
                                        }
132

133
                                        $locations = null;
18✔
134
                                        foreach ( $menu_locations as $location => $id ) {
18✔
135
                                                if ( absint( $id ) === ( $this->menuDatabaseId ) ) {
18✔
136
                                                        $locations[] = $location;
18✔
137
                                                }
138
                                        }
139

140
                                        return $locations;
18✔
141
                                },
21✔
142
                                'menuDatabaseId'   => function () {
21✔
143
                                        $menus = wp_get_object_terms( $this->data->ID, 'nav_menu' );
18✔
144
                                        if ( is_wp_error( $menus ) ) {
18✔
145
                                                throw new UserError( esc_html( $menus->get_error_message() ) );
×
146
                                        }
147

148
                                        return ! empty( $menus[0]->term_id ) ? $menus[0]->term_id : null;
18✔
149
                                },
21✔
150
                                'menuId'           => function () {
21✔
151
                                        return ! empty( $this->menuDatabaseId ) ? Relay::toGlobalId( 'term', (string) $this->menuDatabaseId ) : null;
18✔
152
                                },
21✔
153
                                'objectId'         => function () {
21✔
154
                                        return absint( $this->data->object_id );
×
155
                                },
21✔
156
                                'order'            => function () {
21✔
157
                                        return $this->data->menu_order;
18✔
158
                                },
21✔
159
                                'parentDatabaseId' => function () {
21✔
160
                                        return $this->data->menu_item_parent;
18✔
161
                                },
21✔
162
                                'parentId'         => function () {
21✔
163
                                        return ! empty( $this->parentDatabaseId ) ? Relay::toGlobalId( 'post', (string) $this->parentDatabaseId ) : null;
18✔
164
                                },
21✔
165
                                'path'             => function () {
21✔
166
                                        $url = $this->url;
4✔
167

168
                                        if ( ! empty( $url ) ) {
4✔
169
                                                /** @var array<string,mixed> $parsed */
170
                                                $parsed = wp_parse_url( $url );
4✔
171
                                                if ( isset( $parsed['host'] ) && strpos( home_url(), $parsed['host'] ) ) {
4✔
172
                                                        return $parsed['path'];
3✔
173
                                                }
174
                                        }
175

176
                                        return $url;
1✔
177
                                },
21✔
178
                                'target'           => function () {
21✔
179
                                        return ! empty( $this->data->target ) ? $this->data->target : null;
4✔
180
                                },
21✔
181
                                'title'            => function () {
21✔
182
                                        return ( ! empty( $this->data->attr_title ) ) ? $this->data->attr_title : null;
4✔
183
                                },
21✔
184
                                'uri'              => function () {
21✔
185
                                        $url = $this->url;
4✔
186

187
                                        return ! empty( $url ) ? str_ireplace( home_url(), '', $url ) : null;
4✔
188
                                },
21✔
189
                                'url'              => function () {
21✔
190
                                        return ! empty( $this->data->url ) ? $this->data->url : null;
4✔
191
                                },
21✔
192

193
                                // Deprecated.
194
                                'menuItemId'       => function () {
21✔
195
                                        return $this->databaseId;
14✔
196
                                },
21✔
197
                        ];
21✔
198
                }
199
        }
200
}
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