PluginProbe
Pods – Custom Content Types and Fields / 3.2.8.4
Pods – Custom Content Types and Fields v3.2.8.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 All 42 releases
pods / src / Pods / Whatsit / Field.php
Field.php
543 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Pods\Whatsit;
4
5 use Exception;
6 use PodsForm;
7 use Pods\Whatsit;
8
9 /**
10 * Field class.
11 *
12 * @since 2.8.0
13 */
14 class Field extends Whatsit {
15
16 /**
17 * {@inheritdoc}
18 */
19 protected static $type = 'field';
20
21 /**
22 * {@inheritdoc}
23 */
24 public function get_table_info() {
25 if ( null !== $this->_table_info ) {
26 return $this->_table_info;
27 }
28
29 $related_type = $this->get_related_object_type();
30 $related_name = $this->get_related_object_name();
31
32 if ( null === $related_type || null === $related_name ) {
33 return [];
34 }
35
36 $api = pods_api();
37
38 $table_info = $api->get_table_info( $related_type, $related_name, null, null, $this );
39
40 if ( ! $table_info ) {
41 $table_info = [];
42 }
43
44 $this->_table_info = $table_info;
45
46 return $table_info;
47 }
48
49 /**
50 * Get the type-specific object argument value.
51 *
52 * @since 2.8.9
53 *
54 * @param string $arg Argument name.
55 * @param mixed|null $default Default to use if not set.
56 * @param bool $strict Whether to check only normal arguments and not special arguments.
57 *
58 * @return null|mixed Argument value, or null if not set.
59 */
60 public function get_type_arg( $arg, $default = null, $strict = false ) {
61 return $this->get_arg( $this->get_type() . '_' . $arg, $default, $strict );
62 }
63
64 /**
65 * {@inheritdoc}
66 */
67 public function get_arg( $arg, $default = null, $strict = false, $raw = false ) {
68 if ( $raw ) {
69 return parent::get_arg( $arg, $default, $strict, $raw );
70 }
71
72 $arg = (string) $arg;
73
74 $special_args = [
75 // Pod args.
76 'pod_id' => 'get_parent_id',
77 'pod' => 'get_parent_name',
78 'pod_name' => 'get_parent_name',
79 'pod_identifier' => 'get_parent_identifier',
80 'pod_label' => 'get_parent_label',
81 'pod_description' => 'get_parent_description',
82 'pod_object' => 'get_parent_object',
83 'pod_object_type' => 'get_parent_object_type',
84 'pod_object_storage_type' => 'get_parent_object_storage_type',
85 'pod_type' => 'get_parent_type',
86 // Group args.
87 'group_id' => 'get_group_id',
88 'group_name' => 'get_group_name',
89 'group_identifier' => 'get_group_identifier',
90 'group_label' => 'get_group_label',
91 'group_description' => 'get_group_description',
92 'group_object' => 'get_group_object',
93 'group_object_type' => 'get_group_object_type',
94 'group_object_storage_type' => 'get_group_object_storage_type',
95 'group_type' => 'get_group_type',
96 ];
97
98 if ( isset( $special_args[ $arg ] ) ) {
99 return $this->{$special_args[ $arg ]}();
100 }
101
102 $type = isset( $this->args['type'] ) ? $this->args['type'] : 'invalid';
103
104 $invalid_options = [
105 0,
106 '0',
107 '',
108 '-- Select One --',
109 __( '-- Select One --', 'pods' ),
110 null,
111 ];
112
113 // Handle related object types.
114 if ( ! $strict && $type . '_object' === $arg ) {
115 if ( ! isset( $this->args[ $arg ] ) || in_array( $this->args[ $arg ], $invalid_options, true ) ) {
116 return $default;
117 }
118
119 return $this->get_related_object_type();
120 }
121
122 // Handle related object name.
123 if ( ! $strict && $type . '_val' === $arg ) {
124 if ( ! isset( $this->args[ $arg ] ) || in_array( $this->args[ $arg ], $invalid_options, true ) ) {
125 return $default;
126 }
127
128 return $this->get_related_object_name();
129 }
130
131 // Backwards compatibility with previous Pods 2.8 pre-releases.
132 if ( 'sister_id' === $arg && isset( $this->args[ $arg ] ) ) {
133 if ( in_array( $this->args[ $arg ], $invalid_options, true ) ) {
134 return $default;
135 }
136
137 return (int) $this->args[ $arg ];
138 }
139
140 return parent::get_arg( $arg, $default );
141 }
142
143 /**
144 * Determine whether this is a required field.
145 *
146 * @since 2.9.0
147 *
148 * @return bool Whether this is a required field.
149 */
150 public function is_required() {
151 return filter_var( $this->get_arg( 'required', false ), FILTER_VALIDATE_BOOLEAN );
152 }
153
154 /**
155 * Determine whether this is a unique field.
156 *
157 * @since 2.9.0
158 *
159 * @return bool Whether this is a unique field.
160 */
161 public function is_unique() {
162 $parent_object = $this->get_parent_object();
163
164 if ( ! $parent_object instanceof Pod ) {
165 return false;
166 }
167
168 // Only table-based Pods can have unique fields.
169 if ( ! $parent_object->is_table_based() ) {
170 return false;
171 }
172
173 return filter_var( $this->get_arg( 'unique', false ), FILTER_VALIDATE_BOOLEAN );
174 }
175
176 /**
177 * Determine whether this is a repeatable field.
178 *
179 * @since 2.9.0
180 *
181 * @return bool Whether this is a repeatable field.
182 */
183 public function is_repeatable() {
184 $parent_object = $this->get_parent_object();
185
186 // Only non table-based Pods can have repeatable fields.
187 if ( $parent_object instanceof Whatsit && $parent_object->is_table_based() ) {
188 return false;
189 }
190
191 $repeatable_field_types = PodsForm::repeatable_field_types();
192
193 $type = $this->get_type();
194
195 // It must be a repeatable field type.
196 if ( ! in_array( $type, $repeatable_field_types, true ) ) {
197 return false;
198 }
199
200 // Disable repeatable for WYSIWYG TinyMCE fields.
201 if ( 'wysiwyg' === $type && 'tinymce' === $this->get_arg( 'wysiwyg_editor', 'tinymce' ) ) {
202 return false;
203 }
204
205 return (
206 filter_var( $this->get_arg( 'repeatable', false ), FILTER_VALIDATE_BOOLEAN )
207 && 1 !== (int) $this->get_arg( 'repeatable_limit', 0 )
208 );
209 }
210
211 /**
212 * Get related object type from field.
213 *
214 * @since 2.8.0
215 *
216 * @return string|null The related object type, or null if not found.
217 */
218 public function get_related_object_type() {
219 // Only continue if this is a relationship field.
220 if ( ! $this->is_relationship() ) {
221 return null;
222 }
223
224 $type = $this->get_type();
225
226 // File field types are always related to the media object type.
227 if ( 'file' === $type ) {
228 return 'media';
229 }
230
231 $related_type = $this->get_arg( $type . '_object', $this->get_arg( 'pick_object', null, true ), true );
232
233 if ( '__current__' === $related_type ) {
234 $related_type = $this->get_parent_type();
235 }
236
237 if ( empty( $related_type ) && 'avatar' === $type ) {
238 $related_type = 'media';
239 }
240
241 if ( empty( $related_type ) ) {
242 return null;
243 }
244
245 return $related_type;
246 }
247
248 /**
249 * Get related object name from field.
250 *
251 * @since 2.8.0
252 *
253 * @return string|null The related object name, or null if not found.
254 */
255 public function get_related_object_name() {
256 // Only continue if this is a relationship field.
257 if ( ! $this->is_relationship() ) {
258 return null;
259 }
260
261 $is_simple_relationship = $this->is_simple_relationship();
262
263 // Only continue if this is not a simple relationship field.
264 if ( null === $is_simple_relationship || true === $is_simple_relationship ) {
265 return null;
266 }
267
268 $related_type = $this->get_related_object_type();
269
270 // Only continue if we have a related object type.
271 if ( null === $related_type ) {
272 return null;
273 }
274
275 $type = $this->get_type();
276
277 $related_name = $this->get_arg( $type . '_val', $this->get_arg( 'pick_val', $related_type, true ), true );
278
279 if ( '__current__' === $related_name ) {
280 $related_name = $this->get_parent_name();
281 }
282
283 if ( 'table' === $related_type ) {
284 $related_name = $this->get_arg( 'related_table', $related_name );
285 } elseif ( in_array( $related_type, [ 'user', 'media', 'comment' ], true ) ) {
286 $related_name = $related_type;
287 }
288
289 return $related_name;
290 }
291
292 /**
293 * Get related object data from field.
294 *
295 * @since 2.8.0
296 *
297 * @return array|null The related object data, or null if not found.
298 */
299 public function get_related_object_data() {
300 // Only continue if this is a relationship field.
301 if ( ! $this->is_relationship() ) {
302 return null;
303 }
304
305 return PodsForm::field_method( $this->args['type'], 'data', $this->args['name'], null, $this->args, null, null, true );
306 }
307
308 /**
309 * Get the related Pod object if it exists.
310 *
311 * @since 2.8.0
312 *
313 * @return Whatsit|array|null The related object, or null if not found.
314 */
315 public function get_related_object() {
316 // Only continue if this is a relationship field.
317 if ( ! $this->is_relationship() ) {
318 return null;
319 }
320
321 $table_info = $this->get_table_info();
322
323 // Check if the pod was found.
324 if ( ! $table_info || empty( $table_info['pod'] ) ) {
325 return null;
326 }
327
328 return $table_info['pod'];
329 }
330
331 /**
332 * Determine whether this is a relationship field (pick/file/etc).
333 *
334 * @since 2.8.9
335 *
336 * @return bool Whether this is a relationship field (pick/file/etc).
337 */
338 public function is_relationship() {
339 $type = $this->get_type();
340
341 $tableless_field_types = PodsForm::tableless_field_types();
342
343 return in_array( $type, $tableless_field_types, true );
344 }
345
346 /**
347 * Determine whether this is a relationship field (pick/file/etc).
348 *
349 * @since 2.9.7
350 *
351 * @return bool Whether this is a relationship field (pick/file/etc).
352 */
353 public function is_file() {
354 $type = $this->get_type();
355
356 $file_field_types = PodsForm::file_field_types();
357
358 return in_array( $type, $file_field_types, true );
359 }
360
361 /**
362 * Determine whether this is an autocomplete relationship field.
363 *
364 * @since 2.9.4
365 *
366 * @return bool Whether this is an autocomplete relationship field.
367 */
368 public function is_autocomplete_relationship() {
369 if ( ! $this->is_relationship() ) {
370 return false;
371 }
372
373 $autocomplete_formats = [
374 'autocomplete',
375 'list',
376 ];
377
378 $single_multi = $this->get_single_multi();
379
380 $default = 'single' === $single_multi ? 'dropdown' : 'list';
381
382 $format = $this->get_type_arg( 'format_' . $single_multi, $default, true );
383
384 return in_array( $format, $autocomplete_formats, true );
385 }
386
387 /**
388 * Determine whether the relationship field is a simple relationship.
389 *
390 * @since 2.8.9
391 *
392 * @return bool|null Whether the relationship field is a simple relationship, or null if not a relationship field.
393 */
394 public function is_simple_relationship() {
395 // Only continue if this is a relationship field.
396 if ( ! $this->is_relationship() ) {
397 return null;
398 }
399
400 $related_type = $this->get_related_object_type();
401
402 // Only continue if this is related to an object.
403 if ( null === $related_type ) {
404 return true;
405 }
406
407 $simple_tableless_objects = PodsForm::simple_tableless_objects();
408
409 return in_array( $related_type, $simple_tableless_objects, true );
410 }
411
412 /**
413 * Determine whether the separator is excluded for this field.
414 *
415 * @since 2.9.8
416 *
417 * @return bool Whether the separator is excluded for this field.
418 */
419 public function is_separator_excluded() {
420 $type = $this->get_type();
421
422 $separator_excluded_field_types = PodsForm::separator_excluded_field_types();
423
424 return in_array( $type, $separator_excluded_field_types, true );
425 }
426
427 /**
428 * Get the bi-directional field if it is set.
429 *
430 * @since 2.8.0
431 *
432 * @return Whatsit|null The bi-directional field if it is set.
433 */
434 public function get_bidirectional_field() {
435 // Only continue if this is a relationship field.
436 if ( ! $this->is_relationship() ) {
437 return null;
438 }
439
440 $sister_id = $this->get_arg( 'sister_id' );
441 $sister_field = $this->get_arg( 'sister_field' );
442
443 $related_field = null;
444
445 $api = pods_api();
446
447 try {
448 if ( $sister_id ) {
449 $related_field = $api->load_field( [
450 'id' => $sister_id,
451 ] );
452 } elseif ( $sister_field ) {
453 $related_object_name = $this->get_related_object_name();
454
455 if ( $related_object_name ) {
456 $related_field = $api->load_field( [
457 'name' => $sister_field,
458 'pod' => $related_object_name,
459 ] );
460 }
461 }
462 } catch ( Exception $exception ) {
463 // Do nothing.
464 }
465
466
467 // Only return if it is a valid field.
468 if ( ! $related_field instanceof Field ) {
469 return null;
470 }
471
472 return $related_field;
473 }
474
475 /**
476 * Get field value limit from field.
477 *
478 * @since 2.8.0
479 *
480 * @return int The field value limit.
481 */
482 public function get_limit() {
483 // If this is a repeatable field then use the repeatable limit (if any).
484 if ( $this->is_repeatable() ) {
485 return $this->get_arg( 'repeatable_limit', 0 );
486 }
487
488 if ( 'multi' === $this->get_single_multi() ) {
489 return (int) $this->get_type_arg( 'limit', 0 );
490 }
491
492 return 1;
493 }
494
495 /**
496 * Get whether the field allows for single or multi tableless field values.
497 *
498 * @since 2.8.22
499 *
500 * @return string Whether the field allows for single or multi tableless field values.
501 */
502 public function get_single_multi() {
503 if ( ! $this->is_relationship() ) {
504 return 'single';
505 }
506
507 $format_type = $this->get_type_arg( 'format_type', 'single' );
508
509 if ( ! $format_type ) {
510 return 'single';
511 }
512
513 return $format_type;
514 }
515
516 /**
517 * Determine whether this is a multiple value field.
518 *
519 * @since 2.9.0
520 *
521 * @return bool Whether this is a multiple value field.
522 */
523 public function is_multi_value() {
524 // This is a multiple value field if the limit is not 1 (0 for no limit or 2+).
525 return 1 !== $this->get_limit();
526 }
527
528 /**
529 * {@inheritdoc}
530 */
531 public function get_fields( array $args = [] ) {
532 return [];
533 }
534
535 /**
536 * {@inheritdoc}
537 */
538 public function get_groups( array $args = [] ) {
539 return [];
540 }
541
542 }
543