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 / Model / SettingGroup.php

SettingGroup.php in WPGraphQL trunk, at src/Model/SettingGroup.php

177 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPGraphQL\Model;
4
5 use GraphQLRelay\Relay;
6
7 /**
8 * Class SettingGroup - Models the data for a settings group
9 *
10 * This is the data-layer Model for a settings group (general, reading,
11 * discussion, permalink, etc.), giving each group a globally unique
12 * identifier so it can be resolved as a Node. Not to be confused with
13 * \WPGraphQL\Type\ObjectType\SettingGroup, which registers the GraphQL
14 * object types for setting groups.
15 *
16 * @property ?string $id
17 *
18 * @package WPGraphQL\Model
19 *
20 * @extends \WPGraphQL\Model\Model<array<string,array<string,mixed>>>
21 */
22 class SettingGroup extends Model {
23 /**
24 * The normalized settings group key (e.g. "general", "permalink").
25 *
26 * @var string
27 */
28 protected $group_key;
29
30 /**
31 * SettingGroup constructor.
32 *
33 * @param string $group_key The normalized settings group key.
34 * @param array<string,array<string,mixed>> $settings The group's entries from the normalized settings map.
35 *
36 * @throws \Exception
37 */
38 public function __construct( string $group_key, array $settings ) {
39 $this->group_key = $group_key;
40 $this->data = $settings;
41
42 parent::__construct();
43 }
44
45 /**
46 * {@inheritDoc}
47 *
48 * Setting groups are publicly readable by default; individual settings
49 * within a group can restrict reads at the field level.
50 */
51 protected function is_private() {
52 return false;
53 }
54
55 /**
56 * {@inheritDoc}
57 *
58 * Uses the group's registered GraphQL type name (e.g. `GeneralSettings`)
59 * so model-layer filters and debug messages identify the specific group
60 * rather than a generic model class name.
61 */
62 protected function get_model_name() {
63 if ( empty( $this->model_name ) ) {
64 $this->model_name = \WPGraphQL\Type\ObjectType\SettingGroup::get_type_name( $this->group_key );
65 }
66
67 return $this->model_name;
68 }
69
70 /**
71 * Returns the normalized settings group key the model was loaded for.
72 */
73 public function get_group_key(): string {
74 return $this->group_key;
75 }
76
77 /**
78 * {@inheritDoc}
79 */
80 protected function init() {
81 if ( empty( $this->fields ) ) {
82 $this->fields = [
83 'id' => function () {
84 return Relay::toGlobalId( 'setting_group', $this->group_key );
85 },
86 ];
87
88 foreach ( $this->data as $setting_field ) {
89 $field_key = isset( $setting_field['graphql_field_name'] ) ? (string) $setting_field['graphql_field_name'] : '';
90
91 // `id` is reserved for the node identifier.
92 if ( empty( $field_key ) || isset( $this->fields[ $field_key ] ) ) {
93 continue;
94 }
95
96 $callback = function () use ( $setting_field ) {
97 return $this->resolve_setting_value( $setting_field );
98 };
99
100 // A setting carrying `graphql_capability` is declared as a
101 // capability-gated field; the Model nulls it (with a debug
102 // message) for users lacking the capability.
103 if ( ! empty( $setting_field['graphql_capability'] ) ) {
104 $this->fields[ $field_key ] = [
105 'callback' => $callback,
106 'capability' => (string) $setting_field['graphql_capability'],
107 ];
108 continue;
109 }
110
111 $this->fields[ $field_key ] = $callback;
112 }
113 }
114 }
115
116 /**
117 * Resolves the value of a single setting entry: reads the option, casts it
118 * by the entry's declared type, gives the entry's own `graphql_resolve`
119 * callback the first pass, then applies the `graphql_setting_field_value`
120 * filter.
121 *
122 * This is the single value-resolution path for settings; the grouped and
123 * flat read surfaces both resolve through the model.
124 *
125 * @param array<string,mixed> $setting_field The setting entry from the normalized settings map.
126 *
127 * @return mixed
128 */
129 private function resolve_setting_value( array $setting_field ) {
130 $option = ! empty( $setting_field['key'] ) ? get_option( (string) $setting_field['key'] ) : null;
131
132 switch ( $setting_field['type'] ?? '' ) {
133 case 'integer':
134 case 'int':
135 $value = absint( $option );
136 break;
137 case 'string':
138 $value = (string) $option;
139 break;
140 case 'boolean':
141 case 'bool':
142 $value = (bool) $option;
143 break;
144 case 'number':
145 case 'float':
146 $value = (float) $option;
147 break;
148 default:
149 $value = ! empty( $option ) ? $option : null;
150 break;
151 }
152
153 /**
154 * Give the setting's own resolver, declared as `graphql_resolve`
155 * in the normalized settings map, the first pass at the value.
156 */
157 if ( isset( $setting_field['graphql_resolve'] ) && is_callable( $setting_field['graphql_resolve'] ) ) {
158 $value = call_user_func( $setting_field['graphql_resolve'], $value, $setting_field, $this->group_key );
159 }
160
161 /**
162 * Filters the resolved value of a single settings field before it is returned in the Schema.
163 *
164 * This gives extensions a seam to normalize or override a setting's resolved value
165 * without adding one-off special cases to the core resolver.
166 *
167 * @param mixed $value The resolved (and type-cast) value of the setting field.
168 * @param array<string,mixed> $setting_field The setting field config, including its `key` and `type`.
169 * @param string $group_name The name of the settings group the field belongs to.
170 *
171 * @hookGroup settings
172 * @since 2.18.0
173 */
174 return apply_filters( 'graphql_setting_field_value', $value, $setting_field, $this->group_key );
175 }
176 }
177