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 / Data / Connection / MenuItemConnectionResolver.php

MenuItemConnectionResolver.php in WPGraphQL trunk, at src/Data/Connection/MenuItemConnectionResolver.php

137 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPGraphQL\Data\Connection;
3
4 use GraphQL\Type\Definition\ResolveInfo;
5 use WPGraphQL\AppContext;
6 use WPGraphQL\Utils\Utils;
7
8 /**
9 * Class MenuItemConnectionResolver
10 *
11 * @package WPGraphQL\Data\Connection
12 */
13 class MenuItemConnectionResolver extends PostObjectConnectionResolver {
14
15 /**
16 * {@inheritDoc}
17 */
18 public function __construct( $source, array $args, AppContext $context, ResolveInfo $info ) {
19 parent::__construct( $source, $args, $context, $info, 'nav_menu_item' );
20 }
21
22 /**
23 * {@inheritDoc}
24 */
25 protected function prepare_query_args( array $args ): array {
26 /**
27 * Prepare for later use
28 */
29 $last = ! empty( $args['last'] ) ? $args['last'] : null;
30
31 $menu_locations = get_theme_mod( 'nav_menu_locations' );
32
33 $query_args = parent::prepare_query_args( $args );
34 $query_args['orderby'] = 'menu_order';
35 $query_args['order'] = isset( $last ) ? 'DESC' : 'ASC';
36
37 if ( isset( $args['where']['parentDatabaseId'] ) ) {
38 $query_args['meta_key'] = '_menu_item_menu_item_parent';
39 $query_args['meta_value'] = (int) $args['where']['parentDatabaseId']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
40 }
41
42 if ( ! empty( $args['where']['parentId'] ) || ( isset( $args['where']['parentId'] ) && 0 === (int) $args['where']['parentId'] ) ) {
43 $query_args['meta_key'] = '_menu_item_menu_item_parent';
44 $query_args['meta_value'] = $args['where']['parentId']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
45 }
46
47 // Get unique list of location term IDs as the default limitation of locations to allow public queries for.
48 // Public queries should only be allowed to query for Menu Items assigned to a Menu Location.
49 $locations = is_array( $menu_locations ) && ! empty( $menu_locations ) ? array_unique( array_values( $menu_locations ) ) : [];
50
51 // Whether a location was explicitly requested via the `location` where arg.
52 $has_explicit_location = ! empty( $args['where']['location'] );
53
54 // If the location argument is set, set the argument to the input argument
55 if ( $has_explicit_location ) {
56 $locations = isset( $menu_locations[ $args['where']['location'] ] ) ? [ $menu_locations[ $args['where']['location'] ] ] : []; // We use an empty array to prevent fetching all media items if the location has no items assigned.
57
58 } elseif ( current_user_can( 'edit_theme_options' ) ) {
59 // If the $locations are NOT set, let a user with proper capability query all menu items.
60 $locations = null;
61 }
62
63 /**
64 * Filter whether the menu item connection should be restricted to items
65 * assigned to a registered menu location.
66 *
67 * By default, public (unauthenticated) requests are limited to menu items
68 * assigned to a menu location. Return `false` to allow public requests to
69 * query menu items belonging to menus that are not assigned to any location
70 * (e.g. when using the "Make Menus and Menu Items public" recipe, which also
71 * flips the MenuItem Model privacy gate via `graphql_data_is_private`).
72 *
73 * An explicit `location` where arg always restricts to that location and is
74 * unaffected by this filter.
75 *
76 * @param bool $restrict_to_locations Whether to restrict the connection to assigned menu locations. Default true.
77 * @param int[]|null $locations The menu location term IDs the connection is being restricted to, or null when unrestricted (privileged user).
78 * @param array<string,mixed> $args The GraphQL args passed to the resolver.
79 * @param array<string,mixed> $unfiltered_args Array of arguments input in the field as part of the GraphQL query.
80 *
81 * @hookGroup connections
82 * @since 2.18.0
83 */
84 $restrict_to_locations = $has_explicit_location || apply_filters( 'graphql_menu_item_connection_restrict_to_locations', true, $locations, $args, $this->get_unfiltered_args() );
85
86 // Only query for menu items in assigned locations.
87 if ( $restrict_to_locations && isset( $locations ) ) {
88
89 // unset the location arg
90 // we don't need this passed as a taxonomy parameter to wp_query
91 unset( $query_args['location'] );
92
93 $query_args['tax_query'][] = [
94 'taxonomy' => 'nav_menu',
95 'field' => 'term_id',
96 'terms' => $locations,
97 'include_children' => false,
98 'operator' => 'IN',
99 ];
100 }
101
102 return $query_args;
103 }
104
105 /**
106 * {@inheritDoc}
107 */
108 protected function prepare_args( array $args ): array {
109 if ( ! empty( $args['where'] ) ) {
110 // Ensure all IDs are converted to database IDs.
111 foreach ( $args['where'] as $input_key => $input_value ) {
112 if ( empty( $input_value ) ) {
113 continue;
114 }
115
116 switch ( $input_key ) {
117 case 'parentId':
118 $args['where'][ $input_key ] = Utils::get_database_id_from_id( $input_value );
119 break;
120 }
121 }
122 }
123
124 /**
125 *
126 * Filters the GraphQL args before they are used in get_query_args().
127 *
128 * @param array<string,mixed> $args The GraphQL args passed to the resolver.
129 * @param array<string,mixed> $unfiltered_args Array of arguments input in the field as part of the GraphQL query.
130 *
131 * @hookGroup connections
132 * @since 1.11.0
133 */
134 return apply_filters( 'graphql_menu_item_connection_args', $args, $this->get_unfiltered_args() );
135 }
136 }
137