PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.6.4.1
JetFormBuilder — Dynamic Blocks Form Builder v3.6.4.1
3.6.4.1 3.6.4 3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / generators / get-from-users.php
jetformbuilder / includes / generators Last commit date
base-v2.php 3 months ago base.php 2 years ago get-from-db.php 3 weeks ago get-from-rest-api.php 3 months ago get-from-users.php 3 weeks ago get-related-posts.php 3 months ago legacy-parser.php 3 months ago num-range-manual.php 3 months ago num-range.php 3 months ago registry.php 3 weeks ago
get-from-users.php
363 lines
1 <?php
2 /**
3 * WordPress Users Generator.
4 *
5 * Generates a list of WordPress users as options for Select/Checkbox/Radio fields.
6 * Supports filtering by role and configurable value/label fields.
7 *
8 * @package Jet_Form_Builder\Generators
9 */
10
11 namespace Jet_Form_Builder\Generators;
12
13 // If this file is called directly, abort.
14 if ( ! defined( 'WPINC' ) ) {
15 die;
16 }
17
18 /**
19 * Get_From_Users class.
20 *
21 * Generates options from WordPress users list.
22 */
23 class Get_From_Users extends Base_V2 {
24
25 /**
26 * Returns generator ID.
27 *
28 * @return string
29 */
30 public function get_id() {
31 return 'get_from_users';
32 }
33
34 /**
35 * Returns generator name.
36 *
37 * @return string
38 */
39 public function get_name() {
40 return __( 'Get values list from WordPress Users', 'jet-form-builder' );
41 }
42
43 /**
44 * Returns structured settings schema.
45 *
46 * @return array
47 */
48 public function get_settings_schema(): array {
49 return array(
50 'roles' => array(
51 'type' => 'array',
52 'default' => array(),
53 'label' => __( 'Filter by Roles (optional)', 'jet-form-builder' ),
54 'control' => 'select',
55 'multiple' => true,
56 'options' => $this->get_roles_options(),
57 'help' => __( 'Select roles to include. Leave empty to include all roles.', 'jet-form-builder' ),
58 ),
59 'value_field' => array(
60 'type' => 'string',
61 'default' => 'ID',
62 'label' => __( 'Option Value', 'jet-form-builder' ),
63 'control' => 'select',
64 'options' => array(
65 array( 'value' => 'ID', 'label' => __( 'User ID', 'jet-form-builder' ) ),
66 array( 'value' => 'user_login', 'label' => __( 'Username (login)', 'jet-form-builder' ) ),
67 array( 'value' => 'user_email', 'label' => __( 'Email', 'jet-form-builder' ) ),
68 array( 'value' => 'user_nicename', 'label' => __( 'Nicename (slug)', 'jet-form-builder' ) ),
69 ),
70 ),
71 'label_field' => array(
72 'type' => 'string',
73 'default' => 'display_name',
74 'label' => __( 'Option Label', 'jet-form-builder' ),
75 'control' => 'select',
76 'options' => array(
77 array( 'value' => 'display_name', 'label' => __( 'Display Name', 'jet-form-builder' ) ),
78 array( 'value' => 'user_login', 'label' => __( 'Username (login)', 'jet-form-builder' ) ),
79 array( 'value' => 'user_email', 'label' => __( 'Email', 'jet-form-builder' ) ),
80 ),
81 ),
82 'include_current' => array(
83 'type' => 'boolean',
84 'default' => true,
85 'label' => __( 'Include Current User', 'jet-form-builder' ),
86 'control' => 'toggle',
87 ),
88 'orderby' => array(
89 'type' => 'string',
90 'default' => 'display_name',
91 'label' => __( 'Order By', 'jet-form-builder' ),
92 'control' => 'select',
93 'options' => array(
94 array( 'value' => 'display_name', 'label' => __( 'Display Name', 'jet-form-builder' ) ),
95 array( 'value' => 'user_login', 'label' => __( 'Username', 'jet-form-builder' ) ),
96 array( 'value' => 'registered', 'label' => __( 'Registration Date', 'jet-form-builder' ) ),
97 array( 'value' => 'ID', 'label' => __( 'User ID', 'jet-form-builder' ) ),
98 ),
99 ),
100 'number' => array(
101 'type' => 'number',
102 'default' => -1,
103 'label' => __( 'Max Users', 'jet-form-builder' ),
104 'control' => 'number',
105 'min' => -1,
106 'help' => __( 'Set to -1 to include all users.', 'jet-form-builder' ),
107 ),
108 );
109 }
110
111 /**
112 * Whether this generator supports auto-update/cascading feature.
113 *
114 * @return bool
115 */
116 public function supports_auto_update(): bool {
117 return true;
118 }
119
120 /**
121 * Returns context field hints for the editor.
122 * Signals that a single listened field provides the role to filter by.
123 *
124 * @return array
125 */
126 public function get_auto_update_context_fields(): array {
127 return array(
128 array(
129 'single' => true,
130 'description' => __( 'The Trigger Field value can narrow the configured "Filter by Roles" setting when it matches a saved Trigger Field choice or an allowed server-side role. If validation fails, the static roles are used.', 'jet-form-builder' ),
131 'example' => __( 'Select the field whose saved option values should be allowed as dynamic user roles, for example: editor or subscriber.', 'jet-form-builder' ),
132 ),
133 );
134 }
135
136 /**
137 * Returns the auto-update value type supported by this generator.
138 *
139 * @return string
140 */
141 public function get_auto_update_value_type(): string {
142 return 'scalar_or_array';
143 }
144
145 /**
146 * Empty trigger should fall back to the static roles configuration.
147 *
148 * @return string
149 */
150 public function get_auto_update_empty_context_policy(): string {
151 return 'fallback_to_static';
152 }
153
154 /**
155 * Generates options with context from a dependent field.
156 * Narrows the saved roles setting with the value from the listened field.
157 *
158 * @param array $settings Parsed settings from block attributes.
159 * @param array $context Associative array ['field_name' => 'value'] from dependent fields.
160 *
161 * @return array Generated options
162 */
163 public function generate_with_context( array $settings, array $context = array() ): array {
164 if ( ! empty( $context ) ) {
165 $context_value = reset( $context );
166 $context_roles = array();
167
168 // Support both single role (scalar) and multi-role (checkbox/multi-select array).
169 if ( is_array( $context_value ) ) {
170 $context_roles = $this->sanitize_roles_list( $context_value );
171 } else {
172 $role = sanitize_key( (string) $context_value );
173 if ( $role ) {
174 $context_roles = array( $role );
175 }
176 }
177
178 if ( ! empty( $context_roles ) ) {
179 $runtime = $settings['_jfb_runtime'] ?? array();
180 $block_attrs = $settings['_jfb_block_attrs'] ?? array();
181 $validate_dynamic = apply_filters(
182 'jet-form-builder/generators/get-from-users/validate_dynamic_roles',
183 true,
184 $context_roles,
185 $settings,
186 $context,
187 $runtime,
188 $block_attrs
189 );
190
191 if ( ! $validate_dynamic ) {
192 $settings['roles'] = array_values( $context_roles );
193
194 return $this->generate( $settings );
195 }
196
197 $registered_roles = $this->get_registered_roles();
198 $allowed_roles = $runtime['allowed_roles'] ?? array();
199 $allowed_roles = apply_filters(
200 'jet-form-builder/generators/get-from-users/allowed-roles',
201 $allowed_roles,
202 $context_roles,
203 $settings,
204 $context,
205 $runtime,
206 $block_attrs
207 );
208 $allowed_roles = $this->sanitize_roles_list( $allowed_roles );
209 $context_roles = array_intersect( $context_roles, $registered_roles );
210
211 if ( ! empty( $allowed_roles ) ) {
212 $context_roles = array_intersect( $context_roles, $allowed_roles );
213 } else {
214 $context_roles = array();
215 }
216
217 $saved_roles = $this->normalize_saved_roles( $settings['roles'] ?? array() );
218 $roles = empty( $saved_roles ) ? $context_roles : array_intersect( $context_roles, $saved_roles );
219
220 if ( ! empty( $roles ) ) {
221 $settings['roles'] = array_values( $roles );
222 }
223 }
224 }
225
226 return $this->generate( $settings );
227 }
228
229 /**
230 * Normalize configured roles into a sanitized list.
231 *
232 * @param mixed $saved_roles Configured roles.
233 *
234 * @return array
235 */
236 private function normalize_saved_roles( $saved_roles ): array {
237 if ( is_array( $saved_roles ) ) {
238 return $this->sanitize_roles_list( $saved_roles );
239 }
240
241 return $this->sanitize_roles_list(
242 array_map( 'trim', explode( ',', (string) $saved_roles ) )
243 );
244 }
245
246 /**
247 * Sanitize a list of role slugs.
248 *
249 * @param mixed $roles List of roles.
250 *
251 * @return array
252 */
253 private function sanitize_roles_list( $roles ): array {
254 if ( ! is_array( $roles ) ) {
255 return array();
256 }
257
258 $roles = array_filter(
259 array_map(
260 static function ( $role ) {
261 return sanitize_key( (string) $role );
262 },
263 $roles
264 )
265 );
266
267 return array_values( array_unique( $roles ) );
268 }
269
270 /**
271 * Return the registered WordPress role slugs.
272 *
273 * @return array
274 */
275 private function get_registered_roles(): array {
276 $roles = wp_roles();
277
278 if ( ! $roles || empty( $roles->roles ) || ! is_array( $roles->roles ) ) {
279 return array();
280 }
281
282 return $this->sanitize_roles_list( array_keys( $roles->roles ) );
283 }
284
285 /**
286 * Returns WP roles as options array for multi-select.
287 *
288 * @return array
289 */
290 private function get_roles_options(): array {
291 $options = array();
292
293 foreach ( wp_roles()->roles as $slug => $role ) {
294 $options[] = array(
295 'value' => $slug,
296 'label' => translate_user_role( $role['name'] ),
297 );
298 }
299
300 return $options;
301 }
302
303 /**
304 * Generates options from WordPress users.
305 *
306 * @param array $args Settings from schema.
307 *
308 * @return array
309 */
310 public function generate( $args ) {
311 $query_args = array(
312 'orderby' => $args['orderby'] ?? 'display_name',
313 'order' => 'ASC',
314 'fields' => 'all',
315 );
316
317 $number = intval( $args['number'] ?? -1 );
318 if ( $number > 0 ) {
319 $query_args['number'] = $number;
320 }
321
322 // Filter by roles (array from multi-select)
323 $roles = $args['roles'] ?? array();
324 if ( is_array( $roles ) ) {
325 $roles = array_filter( $roles );
326 } else {
327 // Backward compat: handle legacy comma-separated string
328 $roles = array_filter( array_map( 'trim', explode( ',', (string) $roles ) ) );
329 }
330 if ( ! empty( $roles ) ) {
331 $query_args['role__in'] = array_values( $roles );
332 }
333
334 // Exclude current user if needed
335 $include_current = isset( $args['include_current'] ) ? (bool) $args['include_current'] : true;
336 if ( ! $include_current ) {
337 $current_user_id = get_current_user_id();
338 if ( $current_user_id ) {
339 $query_args['exclude'] = array( $current_user_id );
340 }
341 }
342
343 $users = get_users( $query_args );
344
345 $value_field = $args['value_field'] ?? 'ID';
346 $label_field = $args['label_field'] ?? 'display_name';
347
348 $result = array();
349
350 foreach ( $users as $user ) {
351 $value = $user->$value_field ?? $user->ID;
352 $label = $user->$label_field ?? $user->display_name;
353
354 $result[] = array(
355 'value' => strval( $value ),
356 'label' => strval( $label ),
357 );
358 }
359
360 return $result;
361 }
362 }
363