Issues (2873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

classes/PodsUI.php (109 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * @package Pods
5
 */
6
class PodsUI {
7
8
	/**
9
	 * @var null Nonce for security
10
	 */
11
	private $_nonce = null;
12
13
	// internal
14
	/**
15
	 * @var bool|PodsData
16
	 */
17
	private $pods_data = false;
18
19
	/**
20
	 * @var array
21
	 */
22
	private $actions = array(
23
		'manage',
24
		'add',
25
		'edit',
26
		'duplicate',
27
		'save',
28
		// 'view',
29
		'delete',
30
		'reorder',
31
		'export',
32
	);
33
34
	/**
35
	 * @var array
36
	 */
37
	private $ui_page = array();
38
39
	/**
40
	 * @var bool
41
	 */
42
	private $unique_identifier = false;
43
44
	// base
45
	public $x = array();
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $x. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
46
47
	/**
48
	 * @var array|bool|mixed|null|Pods
49
	 */
50
	public $pod = false;
51
52
	/**
53
	 * @var int
54
	 */
55
	public $id = 0;
56
57
	/**
58
	 * @var string
59
	 */
60
	public $num = '';
61
	// allows multiple co-existing PodsUI instances with separate functionality in URL
62
	/**
63
	 * @var array
64
	 */
65
	public static $excluded = array(
66
		'do',
67
		'id',
68
		'pg',
69
		'search',
70
		'filter_*',
71
		'orderby',
72
		'orderby_dir',
73
		'limit',
74
		'action',
75
		'action_bulk',
76
		'action_bulk_ids',
77
		'_wpnonce',
78
		'view',
79
		'export',
80
		'export_type',
81
		'export_delimiter',
82
		'remove_export',
83
		'updated',
84
		'duplicate',
85
		'message',
86
	);
87
	// used in var_update
88
	public static $allowed = array(
89
		'page',
90
		'post_type',
91
	);
92
93
	// ui
94
	/**
95
	 * @var bool
96
	 */
97
	public $item = false;
98
	// to be set with localized string
99
	/**
100
	 * @var bool
101
	 */
102
	public $items = false;
103
	// to be set with localized string
104
	/**
105
	 * @var bool
106
	 */
107
	public $heading = false;
108
	// to be set with localized string array
109
	/**
110
	 * @var bool
111
	 */
112
	public $header = false;
113
	// to be set with localized string array
114
	/**
115
	 * @var bool
116
	 */
117
	public $label = false;
118
	// to be set with localized string array
119
	/**
120
	 * @var bool
121
	 */
122
	public $icon = false;
123
124
	/**
125
	 * @var bool
126
	 */
127
	public $css = false;
128
	// set to a URL of stylesheet to include
129
	/**
130
	 * @var bool
131
	 */
132
	public $wpcss = false;
133
	// set to true to include WP Admin stylesheets
134
	/**
135
	 * @var array
136
	 */
137
	public $fields = array(
138
		'manage'    => array(),
139
		'search'    => array(),
140
		'form'      => array(),
141
		'add'       => array(),
142
		'edit'      => array(),
143
		'duplicate' => array(),
144
		'view'      => array(),
145
		'reorder'   => array(),
146
		'export'    => array(),
147
	);
148
149
	/**
150
	 * @var bool
151
	 */
152
	public $searchable = true;
153
154
	/**
155
	 * @var bool
156
	 */
157
	public $sortable = true;
158
159
	/**
160
	 * @var bool
161
	 */
162
	public $pagination = true;
163
164
	/**
165
	 * @var bool
166
	 */
167
	public $pagination_total = true;
168
169
	/**
170
	 * @var array
171
	 */
172
	public $export = array(
173
		'on'      => false,
174
		'formats' => array(
175
			'csv'  => ',',
176
			'tsv'  => "\t",
177
			'xml'  => false,
178
			'json' => false,
179
		),
180
		'url'     => false,
181
		'type'    => false,
182
	);
183
184
	/**
185
	 * @var array
186
	 */
187
	public $reorder = array(
188
		'on'          => false,
189
		'limit'       => 250,
190
		'orderby'     => false,
191
		'orderby_dir' => 'ASC',
192
		'sql'         => null,
193
	);
194
195
	/**
196
	 * @var array
197
	 */
198
	public $screen_options = array();
199
	// set to 'page' => 'Text'; false hides link
200
	/**
201
	 * @var array
202
	 */
203
	public $help = array();
204
	// set to 'page' => 'Text'; 'page' => array('link' => 'yourhelplink'); false hides link
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
205
	// data
206
	/**
207
	 * @var bool
208
	 */
209
	public $search = false;
210
211
	/**
212
	 * @var bool
213
	 */
214
	public $filters_enhanced = false;
215
216
	/**
217
	 * @var array
218
	 */
219
	public $filters = array();
220
221
	/**
222
	 * @var string
223
	 */
224
	public $view = false;
225
226
	/**
227
	 * @var array
228
	 */
229
	public $views = array();
230
231
	/**
232
	 * @var bool
233
	 */
234
	public $search_across = true;
235
236
	/**
237
	 * @var bool
238
	 */
239
	public $search_across_picks = false;
240
241
	/**
242
	 * @var bool
243
	 */
244
	public $default_none = false;
245
246
	/**
247
	 * @var array
248
	 */
249
	public $where = array(
250
		'manage'  => null,
251
		/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
252
		'edit' => null,
253
        'duplicate' => null,
254
        'delete' => null,*/
255
		'reorder' => null,
256
	);
257
258
	/**
259
	 * @var bool
260
	 */
261
	public $orderby = false;
262
263
	/**
264
	 * @var string
265
	 */
266
	public $orderby_dir = 'DESC';
267
268
	/**
269
	 * @var int
270
	 */
271
	public $limit = 25;
272
273
	/**
274
	 * @var int
275
	 */
276
	public $page = 1;
277
278
	/**
279
	 * @var int
280
	 */
281
	public $total = 0;
282
283
	/**
284
	 * @var int
285
	 */
286
	public $total_found = 0;
287
288
	/**
289
	 * @var array
290
	 */
291
	public $session = array(
292
		'search',
293
		'filters',
294
	);
295
	// allowed: search, filters, show_per_page, orderby (priority over usermeta)
296
	/**
297
	 * @var array
298
	 */
299
	public $user = array(
300
		'show_per_page',
301
		'orderby',
302
	);
303
	// allowed: search, filters, show_per_page, orderby (priority under session)
304
	// advanced data
305
	/**
306
	 * @var array
307
	 */
308
	public $sql = array(
309
		'table'       => null,
310
		'field_id'    => 'id',
311
		'field_index' => 'name',
312
		'select'      => null,
313
		'sql'         => null,
314
	);
315
316
	/**
317
	 * @var array
318
	 */
319
	public $params = array();
320
321
	/**
322
	 * @var bool|array
323
	 */
324
	public $data = false;
325
326
	/**
327
	 * @var bool|array
328
	 */
329
	public $data_full = false;
330
331
	/**
332
	 * @var array
333
	 */
334
	public $data_keys = array();
335
336
	/**
337
	 * @var array
338
	 */
339
	public $row = array();
340
341
	// actions
342
	/**
343
	 * @var string
344
	 */
345
	public $action = 'manage';
346
347
	/**
348
	 * @var string
349
	 */
350
	public $action_bulk = false;
351
352
	/**
353
	 * @var array
354
	 */
355
	public $bulk = array();
356
357
	/**
358
	 * @var array
359
	 */
360
	public $action_after = array(
361
		'add'       => 'edit',
362
		'edit'      => 'edit',
363
		'duplicate' => 'edit',
364
	);
365
	// set action to 'manage'
366
	/**
367
	 * @var bool
368
	 */
369
	public $do = false;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $do. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
370
371
	/**
372
	 * @var array
373
	 */
374
	public $action_links = array(
375
		'manage'    => null,
376
		'add'       => null,
377
		'edit'      => null,
378
		'duplicate' => null,
379
		'view'      => null,
380
		'delete'    => null,
381
		'reorder'   => null,
382
	);
383
	// custom links (ex. /my-link/{@id}/
384
	/**
385
	 * @var array
386
	 */
387
	public $actions_disabled = array(
388
		'view',
389
		'export',
390
	);
391
	// disable actions
392
	/**
393
	 * @var array
394
	 */
395
	public $actions_hidden = array();
396
	// hide actions to not show them but allow them
397
	/**
398
	 * @var array
399
	 */
400
	public $actions_custom = array();
401
	// overwrite existing actions or add your own
402
	/**
403
	 * @var array
404
	 */
405
	public $actions_bulk = array();
406
	// enabled bulk actions
407
	/**
408
	 * @var array
409
	 */
410
	public $restrict = array(
411
		'manage'          => null,
412
		'edit'            => null,
413
		'duplicate'       => null,
414
		'delete'          => null,
415
		'reorder'         => null,
416
		'author_restrict' => null,
417
	);
418
419
	/**
420
	 * @var array
421
	 */
422
	public $extra = array(
423
		'total' => null,
424
	);
425
426
	/**
427
	 * @var string
428
	 */
429
	public $style = 'post_type';
430
431
	/**
432
	 * @var bool
433
	 */
434
	public $save = false;
435
	// Allow custom save handling for tables that aren't Pod-based
436
	/**
437
	 * Generate UI for Data Management
438
	 *
439
	 * @param mixed $options    Object, Array, or String containing Pod or Options to be used
440
	 * @param bool  $deprecated Set to true to support old options array from Pods UI plugin
441
	 *
442
	 * @return \PodsUI
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
443
	 *
444
	 * @license http://www.gnu.org/licenses/gpl-2.0.html
445
	 * @since   2.0
446
	 */
447
	public function __construct( $options, $deprecated = false ) {
448
449
		$this->_nonce = pods_v( '_wpnonce', 'request' );
450
451
		$object = null;
452
453
		if ( is_object( $options ) ) {
454
			$object  = $options;
455
			$options = array();
456
457
			if ( isset( $object->ui ) ) {
458
				$options = (array) $object->ui;
459
460
				unset( $object->ui );
461
			}
462
463
			if ( is_object( $object ) && ( 'Pods' == get_class( $object ) || 'Pod' == get_class( $object ) ) ) {
464
				$this->pod =& $object;
465
			}
466
		}
467
468
		if ( ! is_array( $options ) ) {
469
			// @todo need to come back to this and allow for multi-dimensional strings
470
			// like: option=value&option2=value2&option3=key[val],key2[val2]&option4=this,that,another
471
			if ( false !== strpos( $options, '=' ) || false !== strpos( $options, '&' ) ) {
472
				parse_str( $options, $options );
473
			} else {
474
				$options = array( 'pod' => $options );
475
			}
476
		}
477
478
		if ( ! is_object( $object ) && isset( $options['pod'] ) ) {
479
			if ( is_object( $options['pod'] ) ) {
480
				$this->pod = $options['pod'];
481
			} elseif ( isset( $options['id'] ) ) {
482
				$this->pod = pods( $options['pod'], $options['id'] );
483
			} else {
484
				$this->pod = pods( $options['pod'] );
485
			}
486
487
			unset( $options['pod'] );
488
		} elseif ( is_object( $object ) ) {
489
			$this->pod = $object;
490
		}
491
492
		if ( false !== $deprecated || ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) ) ) {
493
			$options = $this->setup_deprecated( $options );
494
		}
495
496
		if ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) && is_object( $this->pod->_data ) ) {
0 ignored issues
show
The property _data does not exist on object<Pod>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
497
			$this->pods_data =& $this->pod->_data;
0 ignored issues
show
The property _data does not exist on object<Pod>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
498
		} elseif ( is_object( $this->pod ) && 'Pods' == get_class( $this->pod ) && is_object( $this->pod->data ) ) {
499
			$this->pods_data =& $this->pod->data;
500
		} elseif ( is_object( $this->pod ) ) {
501
			$this->pods_data = pods_data( $this->pod->pod );
502
		} elseif ( ! is_object( $this->pod ) ) {
503
			$this->pods_data = pods_data( $this->pod );
504
		}
505
506
		$options = $this->do_hook( 'pre_init', $options );
507
508
		$this->setup( $options );
509
510
		if ( is_object( $this->pods_data ) && is_object( $this->pod ) && 0 < $this->id ) {
511
			if ( $this->id != $this->pods_data->id ) {
512
				$this->row = $this->pods_data->fetch( $this->id );
513
			} else {
514
				$this->row = $this->pods_data->row;
515
			}
516
		}
517
518
		if ( ( ! is_object( $this->pod ) || 'Pods' != get_class( $this->pod ) ) && false === $this->sql['table'] && false === $this->data ) {
519
			echo $this->error( __( '<strong>Error:</strong> Pods UI needs a Pods object or a Table definition to run from, see the User Guide for more information.', 'pods' ) );
520
521
			return false;
0 ignored issues
show
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
522
		}
523
524
		// Assign pod labels
525
		// @todo This is also done in setup(), maybe a better / more central way?
526
		if ( is_object( $this->pod ) && ! empty( $this->pod->pod_data['options'] ) ) {
527
			$pod_options = $this->pod->pod_data['options'];
528
			$pod_options = apply_filters( 'pods_advanced_content_type_pod_data_' . $this->pod->pod_data['name'], $pod_options, $this->pod->pod_data['name'] );
529
			$pod_options = apply_filters( 'pods_advanced_content_type_pod_data', $pod_options, $this->pod->pod_data['name'] );
530
531
			$this->label = array_merge( $this->label, $pod_options );
532
		}
533
534
		$this->go();
535
	}
536
537
	/**
538
	 * @param $deprecated_options
539
	 *
540
	 * @return array
541
	 */
542
	public function setup_deprecated( $deprecated_options ) {
543
544
		$options = array();
545
546
		if ( isset( $deprecated_options['id'] ) ) {
547
			$options['id'] = $deprecated_options['id'];
548
		}
549
		if ( isset( $deprecated_options['action'] ) ) {
550
			$options['action'] = $deprecated_options['action'];
551
		}
552
		if ( isset( $deprecated_options['num'] ) ) {
553
			$options['num'] = $deprecated_options['num'];
554
		}
555
556
		if ( isset( $deprecated_options['title'] ) ) {
557
			$options['items'] = $deprecated_options['title'];
558
		}
559
		if ( isset( $deprecated_options['item'] ) ) {
560
			$options['item'] = $deprecated_options['item'];
561
		}
562
563
		if ( isset( $deprecated_options['label'] ) ) {
564
			$options['label'] = array(
565
				'add'       => $deprecated_options['label'],
566
				'edit'      => $deprecated_options['label'],
567
				'duplicate' => $deprecated_options['label'],
568
			);
569
		}
570
		if ( isset( $deprecated_options['label_add'] ) ) {
571
			if ( isset( $options['label'] ) ) {
572
				$options['label']['add'] = $deprecated_options['label_add'];
573
			} else {
574
				$options['label'] = array( 'add' => $deprecated_options['label_add'] );
575
			}
576
		}
577
		if ( isset( $deprecated_options['label_edit'] ) ) {
578
			if ( isset( $options['label'] ) ) {
579
				$options['label']['edit'] = $deprecated_options['label_edit'];
580
			} else {
581
				$options['label'] = array( 'edit' => $deprecated_options['label_edit'] );
582
			}
583
		}
584
		if ( isset( $deprecated_options['label_duplicate'] ) ) {
585
			if ( isset( $options['label'] ) ) {
586
				$options['label']['duplicate'] = $deprecated_options['label_duplicate'];
587
			} else {
588
				$options['label'] = array( 'duplicate' => $deprecated_options['label_duplicate'] );
589
			}
590
		}
591
592
		if ( isset( $deprecated_options['icon'] ) ) {
593
			$options['icon'] = $deprecated_options['icon'];
594
		}
595
596
		if ( isset( $deprecated_options['columns'] ) ) {
597
			$options['fields'] = array( 'manage' => $deprecated_options['columns'] );
598
		}
599
		if ( isset( $deprecated_options['reorder_columns'] ) ) {
600
			if ( isset( $options['fields'] ) ) {
601
				$options['fields']['reorder'] = $deprecated_options['reorder_columns'];
602
			} else {
603
				$options['fields'] = array( 'reorder' => $deprecated_options['reorder_columns'] );
604
			}
605
		}
606
		if ( isset( $deprecated_options['add_fields'] ) ) {
607
			if ( isset( $options['fields'] ) ) {
608
				if ( ! isset( $options['fields']['add'] ) ) {
609
					$options['fields']['add'] = $deprecated_options['add_fields'];
610
				}
611
				if ( ! isset( $options['fields']['edit'] ) ) {
612
					$options['fields']['edit'] = $deprecated_options['add_fields'];
613
				}
614
				if ( ! isset( $options['fields']['duplicate'] ) ) {
615
					$options['fields']['duplicate'] = $deprecated_options['add_fields'];
616
				}
617
			} else {
618
				$options['fields'] = array(
619
					'add'       => $deprecated_options['add_fields'],
620
					'edit'      => $deprecated_options['add_fields'],
621
					'duplicate' => $deprecated_options['add_fields'],
622
				);
623
			}
624
		}
625
		if ( isset( $deprecated_options['edit_fields'] ) ) {
626
			if ( isset( $options['fields'] ) ) {
627
				if ( ! isset( $options['fields']['add'] ) ) {
628
					$options['fields']['add'] = $deprecated_options['edit_fields'];
629
				}
630
				if ( ! isset( $options['fields']['edit'] ) ) {
631
					$options['fields']['edit'] = $deprecated_options['edit_fields'];
632
				}
633
				if ( ! isset( $options['fields']['duplicate'] ) ) {
634
					$options['fields']['duplicate'] = $deprecated_options['edit_fields'];
635
				}
636
			} else {
637
				$options['fields'] = array(
638
					'add'       => $deprecated_options['edit_fields'],
639
					'edit'      => $deprecated_options['edit_fields'],
640
					'duplicate' => $deprecated_options['edit_fields'],
641
				);
642
			}
643
		}
644
		if ( isset( $deprecated_options['duplicate_fields'] ) ) {
645
			if ( isset( $options['fields'] ) ) {
646
				$options['fields']['duplicate'] = $deprecated_options['duplicate_fields'];
647
			} else {
648
				$options['fields'] = array( 'duplicate' => $deprecated_options['duplicate_fields'] );
649
			}
650
		}
651
652
		if ( isset( $deprecated_options['session_filters'] ) && false === $deprecated_options['session_filters'] ) {
653
			$options['session'] = false;
654
		}
655
		if ( isset( $deprecated_options['user_per_page'] ) ) {
656
			if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) {
657
				$options['user'] = array( 'orderby' );
658
			} else {
659
				$options['user'] = false;
660
			}
661
		}
662
		if ( isset( $deprecated_options['user_sort'] ) ) {
663
			if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) {
664
				$options['user'] = array( 'show_per_page' );
665
			} else {
666
				$options['user'] = false;
667
			}
668
		}
669
670
		if ( isset( $deprecated_options['custom_list'] ) ) {
671
			if ( isset( $options['actions_custom'] ) ) {
672
				$options['actions_custom']['manage'] = $deprecated_options['custom_list'];
673
			} else {
674
				$options['actions_custom'] = array( 'manage' => $deprecated_options['custom_list'] );
675
			}
676
		}
677
		if ( isset( $deprecated_options['custom_reorder'] ) ) {
678
			if ( isset( $options['actions_custom'] ) ) {
679
				$options['actions_custom']['reorder'] = $deprecated_options['custom_reorder'];
680
			} else {
681
				$options['actions_custom'] = array( 'reorder' => $deprecated_options['custom_reorder'] );
682
			}
683
		}
684
		if ( isset( $deprecated_options['custom_add'] ) ) {
685
			if ( isset( $options['actions_custom'] ) ) {
686
				$options['actions_custom']['add'] = $deprecated_options['custom_add'];
687
			} else {
688
				$options['actions_custom'] = array( 'add' => $deprecated_options['custom_add'] );
689
			}
690
		}
691
		if ( isset( $deprecated_options['custom_edit'] ) ) {
692
			if ( isset( $options['actions_custom'] ) ) {
693
				$options['actions_custom']['edit'] = $deprecated_options['custom_edit'];
694
			} else {
695
				$options['actions_custom'] = array( 'edit' => $deprecated_options['custom_edit'] );
696
			}
697
		}
698
		if ( isset( $deprecated_options['custom_duplicate'] ) ) {
699
			if ( isset( $options['actions_custom'] ) ) {
700
				$options['actions_custom']['duplicate'] = $deprecated_options['custom_duplicate'];
701
			} else {
702
				$options['actions_custom'] = array( 'duplicate' => $deprecated_options['custom_duplicate'] );
703
			}
704
		}
705
		if ( isset( $deprecated_options['custom_delete'] ) ) {
706
			if ( isset( $options['actions_custom'] ) ) {
707
				$options['actions_custom']['delete'] = $deprecated_options['custom_delete'];
708
			} else {
709
				$options['actions_custom'] = array( 'delete' => $deprecated_options['custom_delete'] );
710
			}
711
		}
712
		if ( isset( $deprecated_options['custom_save'] ) ) {
713
			if ( isset( $options['actions_custom'] ) ) {
714
				$options['actions_custom']['save'] = $deprecated_options['custom_save'];
715
			} else {
716
				$options['actions_custom'] = array( 'save' => $deprecated_options['custom_save'] );
717
			}
718
		}
719
720
		if ( isset( $deprecated_options['custom_actions'] ) ) {
721
			$options['actions_custom'] = $deprecated_options['custom_actions'];
722
		}
723
		if ( isset( $deprecated_options['action_after_save'] ) ) {
724
			$options['action_after'] = array(
725
				'add'       => $deprecated_options['action_after_save'],
726
				'edit'      => $deprecated_options['action_after_save'],
727
				'duplicate' => $deprecated_options['action_after_save'],
728
			);
729
		}
730
		if ( isset( $deprecated_options['edit_link'] ) ) {
731
			if ( isset( $options['action_links'] ) ) {
732
				$options['action_links']['edit'] = $deprecated_options['edit_link'];
733
			} else {
734
				$options['action_links'] = array( 'edit' => $deprecated_options['edit_link'] );
735
			}
736
		}
737
		if ( isset( $deprecated_options['view_link'] ) ) {
738
			if ( isset( $options['action_links'] ) ) {
739
				$options['action_links']['view'] = $deprecated_options['view_link'];
740
			} else {
741
				$options['action_links'] = array( 'view' => $deprecated_options['view_link'] );
742
			}
743
		}
744
		if ( isset( $deprecated_options['duplicate_link'] ) ) {
745
			if ( isset( $options['action_links'] ) ) {
746
				$options['action_links']['duplicate'] = $deprecated_options['duplicate_link'];
747
			} else {
748
				$options['action_links'] = array( 'duplicate' => $deprecated_options['duplicate_link'] );
749
			}
750
		}
751
752
		if ( isset( $deprecated_options['reorder'] ) ) {
753
			$options['reorder'] = array(
754
				'on'      => $deprecated_options['reorder'],
755
				'orderby' => $deprecated_options['reorder'],
756
			);
757
		}
758
		if ( isset( $deprecated_options['reorder_sort'] ) && isset( $options['reorder'] ) ) {
759
			$options['reorder']['orderby'] = $deprecated_options['reorder_sort'];
760
		}
761
		if ( isset( $deprecated_options['reorder_limit'] ) && isset( $options['reorder'] ) ) {
762
			$options['reorder']['limit'] = $deprecated_options['reorder_limit'];
763
		}
764
		if ( isset( $deprecated_options['reorder_sql'] ) && isset( $options['reorder'] ) ) {
765
			$options['reorder']['sql'] = $deprecated_options['reorder_sql'];
766
		}
767
768
		if ( isset( $deprecated_options['sort'] ) ) {
769
			$options['orderby'] = $deprecated_options['sort'];
770
		}
771
		if ( isset( $deprecated_options['sortable'] ) ) {
772
			$options['sortable'] = $deprecated_options['sortable'];
773
		}
774
		if ( isset( $deprecated_options['limit'] ) ) {
775
			$options['limit'] = $deprecated_options['limit'];
776
		}
777
778
		if ( isset( $deprecated_options['where'] ) ) {
779
			if ( isset( $options['where'] ) ) {
780
				$options['where']['manage'] = $deprecated_options['where'];
781
			} else {
782
				$options['where'] = array( 'manage' => $deprecated_options['where'] );
783
			}
784
		}
785
		if ( isset( $deprecated_options['edit_where'] ) ) {
786
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
787
			if ( isset( $options[ 'where' ] ) )
788
                $options[ 'where' ][ 'edit' ] = $deprecated_options[ 'edit_where' ];
789
            else
790
                $options[ 'where' ] = array( 'edit' => $deprecated_options[ 'edit_where' ] );*/
791
792
			if ( isset( $options['restrict'] ) ) {
793
				$options['restrict']['edit'] = (array) $deprecated_options['edit_where'];
794
			} else {
795
				$options['restrict'] = array( 'edit' => (array) $deprecated_options['edit_where'] );
796
			}
797
		}
798
		if ( isset( $deprecated_options['duplicate_where'] ) ) {
799
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
800
			if ( isset( $options[ 'where' ] ) )
801
                $options[ 'where' ][ 'duplicate' ] = $deprecated_options[ 'duplicate_where' ];
802
            else
803
                $options[ 'where' ] = array( 'duplicate' => $deprecated_options[ 'duplicate_where' ] );*/
804
805
			if ( isset( $options['restrict'] ) ) {
806
				$options['restrict']['duplicate'] = (array) $deprecated_options['duplicate_where'];
807
			} else {
808
				$options['restrict'] = array( 'duplicate' => (array) $deprecated_options['duplicate_where'] );
809
			}
810
		}
811
		if ( isset( $deprecated_options['delete_where'] ) ) {
812
			/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
813
			if ( isset( $options[ 'where' ] ) )
814
                $options[ 'where' ][ 'delete' ] = $deprecated_options[ 'delete_where' ];
815
            else
816
                $options[ 'where' ] = array( 'delete' => $deprecated_options[ 'delete_where' ] );*/
817
818
			if ( isset( $options['restrict'] ) ) {
819
				$options['restrict']['delete'] = (array) $deprecated_options['delete_where'];
820
			} else {
821
				$options['restrict'] = array( 'delete' => (array) $deprecated_options['delete_where'] );
822
			}
823
		}
824
		if ( isset( $deprecated_options['reorder_where'] ) ) {
825
			if ( isset( $options['where'] ) ) {
826
				$options['where']['reorder'] = $deprecated_options['reorder_where'];
827
			} else {
828
				$options['where'] = array( 'reorder' => $deprecated_options['reorder_where'] );
829
			}
830
		}
831
832
		if ( isset( $deprecated_options['sql'] ) ) {
833
			$options['sql'] = array( 'sql' => $deprecated_options['sql'] );
834
		}
835
836
		if ( isset( $deprecated_options['search'] ) ) {
837
			$options['searchable'] = $deprecated_options['search'];
838
		}
839
		if ( isset( $deprecated_options['search_across'] ) ) {
840
			$options['search_across'] = $deprecated_options['search_across'];
841
		}
842
		if ( isset( $deprecated_options['search_across_picks'] ) ) {
843
			$options['search_across_picks'] = $deprecated_options['search_across_picks'];
844
		}
845
		if ( isset( $deprecated_options['filters'] ) ) {
846
			$options['filters'] = $deprecated_options['filters'];
847
		}
848
		if ( isset( $deprecated_options['custom_filters'] ) ) {
849
			if ( is_callable( $deprecated_options['custom_filters'] ) ) {
850
				add_filter( 'pods_ui_filters', $deprecated_options['custom_filters'] );
851
			} else {
852
				global $pods_ui_custom_filters;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
Comprehensibility Naming introduced by
The variable name $pods_ui_custom_filters exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
853
				$pods_ui_custom_filters = $deprecated_options['custom_filters'];
854
				add_filter( 'pods_ui_filters', array( $this, 'deprecated_filters' ) );
855
			}
856
		}
857
858
		if ( isset( $deprecated_options['disable_actions'] ) ) {
859
			$options['actions_disabled'] = $deprecated_options['disable_actions'];
860
		}
861
		if ( isset( $deprecated_options['hide_actions'] ) ) {
862
			$options['actions_hidden'] = $deprecated_options['hide_actions'];
863
		}
864
865
		if ( isset( $deprecated_options['wpcss'] ) ) {
866
			$options['wpcss'] = $deprecated_options['wpcss'];
867
		}
868
869
		$remaining_options = array_diff_assoc( $options, $deprecated_options );
870
871
		foreach ( $remaining_options as $option => $value ) {
872
			if ( isset( $deprecated_options[ $option ] ) && isset( $this->$option ) ) {
873
				$options[ $option ] = $value;
874
			}
875
		}
876
877
		return $options;
878
	}
879
880
	/**
881
	 *
882
	 */
883
	public function deprecated_filters() {
884
885
		global $pods_ui_custom_filters;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
Comprehensibility Naming introduced by
The variable name $pods_ui_custom_filters exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
886
		echo $pods_ui_custom_filters;
887
	}
888
889
	/**
890
	 * @param $options
891
	 *
892
	 * @return array|bool|mixed|null|PodsArray
893
	 */
894
	public function setup( $options ) {
895
896
		$options = pods_array( $options );
897
898
		$options->validate( 'num', '', 'absint' );
899
900
		if ( empty( $options->num ) ) {
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
901
			$options->num = '';
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
902
		}
903
904
		$options->validate( 'id', pods_var( 'id' . $options->num, 'get', $this->id ) );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
905
906
		$options->validate(
907
			'do', pods_var( 'do' . $options->num, 'get', $this->do ), 'in_array', array(
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
908
				'save',
909
				'create',
910
			)
911
		);
912
913
		$options->validate( 'excluded', self::$excluded, 'array_merge' );
914
915
		$options->validate( 'action', pods_var( 'action' . $options->num, 'get', $this->action, null, true ), 'in_array', $this->actions );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
916
		$options->validate( 'actions_bulk', $this->actions_bulk, 'array_merge' );
917
		$options->validate( 'action_bulk', pods_var( 'action_bulk' . $options->num, 'get', $this->action_bulk, null, true ), 'isset', $this->actions_bulk );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
918
919
		$bulk = pods_var( 'action_bulk_ids' . $options->num, 'get', array(), null, true );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
920
921
		if ( ! empty( $bulk ) ) {
922
			$bulk = (array) pods_var( 'action_bulk_ids' . $options->num, 'get', array(), null, true );
923
		} else {
924
			$bulk = array();
925
		}
926
927
		$options->validate( 'bulk', $bulk, 'array_merge', $this->bulk );
928
929
		$options->validate( 'views', $this->views, 'array' );
930
		$options->validate( 'view', pods_var( 'view' . $options->num, 'get', $this->view, null, true ), 'isset', $this->views );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
931
932
		$options->validate( 'searchable', $this->searchable, 'boolean' );
933
		$options->validate( 'search', pods_var( 'search' . $options->num ) );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
934
		$options->validate( 'search_across', $this->search_across, 'boolean' );
935
		$options->validate( 'search_across_picks', $this->search_across_picks, 'boolean' );
936
		$options->validate( 'filters', $this->filters, 'array' );
937
		$options->validate( 'filters_enhanced', $this->filters_enhanced, 'boolean' );
938
		$options->validate( 'where', $this->where, 'array_merge' );
939
940
		$options->validate( 'pagination', $this->pagination, 'boolean' );
941
		$options->validate( 'page', pods_var( 'pg' . $options->num, 'get', $this->page ), 'absint' );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
942
		$options->validate( 'limit', pods_var( 'limit' . $options->num, 'get', $this->limit ), 'int' );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
943
944
		if ( isset( $this->pods_data ) && is_object( $this->pods_data ) ) {
945
			$this->sql = array(
946
				'table'       => $this->pods_data->table,
947
				'field_id'    => $this->pods_data->field_id,
948
				'field_index' => $this->pods_data->field_index,
949
			);
950
		}
951
		$options->validate( 'sql', $this->sql, 'array_merge' );
952
953
		$options->validate(
954
			'orderby_dir', strtoupper( pods_v( 'orderby_dir' . $options['num'], 'get', $this->orderby_dir, true ) ), 'in_array', array(
955
				'ASC',
956
				'DESC',
957
			)
958
		);
959
960
		$orderby = $this->orderby;
961
962
		// Enforce strict DB column name usage
963
		if ( ! empty( $_GET[ 'orderby' . $options->num ] ) ) {
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
964
			$orderby = pods_clean_name( $_GET[ 'orderby' . $options->num ], true, false );
0 ignored issues
show
The property num does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
965
		}
966
967
		if ( ! empty( $orderby ) ) {
968
			$orderby = array(
969
				'default' => $orderby,
970
			);
971
		} else {
972
			$orderby = array();
973
		}
974
975
		$options->validate( 'orderby', $orderby, 'array_merge' );
976
		$options->validate( 'sortable', $this->sortable, 'boolean' );
977
978
		$options->validate( 'params', $this->params, 'array' );
979
980
		$options->validate( 'restrict', $this->restrict, 'array_merge' );
981
982
		// handle author restrictions
983
		if ( ! empty( $options['restrict']['author_restrict'] ) ) {
984
			$restrict = $options['restrict'];
985
986
			if ( ! is_array( $restrict['author_restrict'] ) ) {
987
				$restrict['author_restrict'] = array( $restrict['author_restrict'] => get_current_user_id() );
988
			}
989
990
			if ( null === $restrict['edit'] ) {
991
				$restrict['edit'] = $restrict['author_restrict'];
992
			}
993
994
			$options->restrict = $restrict;
0 ignored issues
show
The property restrict does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
995
		}
996
997
		if ( null !== $options['restrict']['edit'] ) {
998
			$restrict = $options['restrict'];
999
1000
			if ( null === $restrict['duplicate'] ) {
1001
				$restrict['duplicate'] = $restrict['edit'];
1002
			}
1003
1004
			if ( null === $restrict['delete'] ) {
1005
				$restrict['delete'] = $restrict['edit'];
1006
			}
1007
1008
			if ( null === $restrict['manage'] ) {
1009
				$restrict['manage'] = $restrict['edit'];
1010
			}
1011
1012
			if ( null === $restrict['reorder'] ) {
1013
				$restrict['reorder'] = $restrict['edit'];
1014
			}
1015
1016
			$options->restrict = $restrict;
0 ignored issues
show
The property restrict does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1017
		}//end if
1018
1019
		$item  = __( 'Item', 'pods' );
1020
		$items = __( 'Items', 'pods' );
1021
1022
		if ( ! is_array( $this->label ) ) {
1023
			$this->label = (array) $this->label;
1024
		}
1025
1026
		if ( is_object( $this->pod ) ) {
1027
			$pod_data = $this->pod->pod_data;
1028
			$pod_data = apply_filters( 'pods_advanced_content_type_pod_data_' . $this->pod->pod_data['name'], $pod_data, $this->pod->pod_data['name'] );
1029
			$pod_data = apply_filters( 'pods_advanced_content_type_pod_data', $pod_data, $this->pod->pod_data['name'] );
1030
1031
			$this->label = array_merge( $this->label, $pod_data['options'] );
1032
1033
			$item  = pods_v( 'label_singular', $pod_data['options'], pods_v( 'label', $pod_data, $item, true ), true );
1034
			$items = pods_v( 'label', $pod_data, $items, true );
1035
		}
1036
1037
		$options->validate( 'item', $item );
1038
		$options->validate( 'items', $items );
1039
1040
		$options->validate(
1041
			'heading', array(
1042
				'manage'    => pods_v( 'label_manage', $this->label, __( 'Manage', 'pods' ) ),
1043
				'add'       => pods_v( 'label_add_new', $this->label, __( 'Add New', 'pods' ) ),
1044
				'edit'      => pods_v( 'label_edit', $this->label, __( 'Edit', 'pods' ) ),
1045
				'duplicate' => pods_v( 'label_duplicate', $this->label, __( 'Duplicate', 'pods' ) ),
1046
				'view'      => pods_v( 'label_view', $this->label, __( 'View', 'pods' ) ),
1047
				'reorder'   => pods_v( 'label_reorder', $this->label, __( 'Reorder', 'pods' ) ),
1048
				'search'    => pods_v( 'label_search', $this->label, __( 'Search', 'pods' ) ),
1049
				'views'     => pods_v( 'label_view', $this->label, __( 'View', 'pods' ) ),
1050
			), 'array_merge'
1051
		);
1052
1053
		$options->validate(
1054
			'header', array(
1055
				'manage'    => pods_v( 'label_manage_items', $this->label, sprintf( __( 'Manage %s', 'pods' ), $options->items ) ),
0 ignored issues
show
The property items does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1056
				'add'       => pods_v( 'label_add_new_item', $this->label, sprintf( __( 'Add New %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1057
				'edit'      => pods_v( 'label_edit_item', $this->label, sprintf( __( 'Edit %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1058
				'duplicate' => pods_v( 'label_duplicate_item', $this->label, sprintf( __( 'Duplicate %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1059
				'view'      => pods_v( 'label_view_item', $this->label, sprintf( __( 'View %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1060
				'reorder'   => pods_v( 'label_reorder_items', $this->label, sprintf( __( 'Reorder %s', 'pods' ), $options->items ) ),
0 ignored issues
show
The property items does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1061
				'search'    => pods_v( 'label_search_items', $this->label, sprintf( __( 'Search %s', 'pods' ), $options->items ) ),
0 ignored issues
show
The property items does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1062
			), 'array_merge'
1063
		);
1064
1065
		$options->validate(
1066
			'label', array(
1067
				'add'       => pods_v( 'label_add_new_item', $this->label, sprintf( __( 'Add New %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1068
				'add_new'   => pods_v( 'label_add_new', $this->label, __( 'Add New', 'pods' ) ),
1069
				'edit'      => pods_v( 'label_update_item', $this->label, sprintf( __( 'Update %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1070
				'duplicate' => pods_v( 'label_duplicate_item', $this->label, sprintf( __( 'Duplicate %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1071
				'delete'    => pods_v( 'label_delete_item', $this->label, sprintf( __( 'Delete this %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1072
				'view'      => pods_v( 'label_view_item', $this->label, sprintf( __( 'View %s', 'pods' ), $options->item ) ),
0 ignored issues
show
The property item does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1073
				'reorder'   => pods_v( 'label_reorder_items', $this->label, sprintf( __( 'Reorder %s', 'pods' ), $options->items ) ),
0 ignored issues
show
The property items does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1074
			), 'array_merge'
1075
		);
1076
1077
		$options->validate(
1078
			'fields', array(
1079
				'manage' => array(
1080
					$options->sql['field_index'] => array( 'label' => __( 'Name', 'pods' ) ),
0 ignored issues
show
The property sql does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1081
				),
1082
			), 'array'
1083
		);
1084
1085
		$options->validate( 'export', $this->export, 'array_merge' );
1086
		$options->validate( 'reorder', $this->reorder, 'array_merge' );
1087
		$options->validate( 'screen_options', $this->screen_options, 'array_merge' );
1088
1089
		$options->validate(
1090
			'session', $this->session, 'in_array', array(
1091
				'search',
1092
				'filters',
1093
				'show_per_page',
1094
				'orderby',
1095
			)
1096
		);
1097
		$options->validate(
1098
			'user', $this->user, 'in_array', array(
1099
				'search',
1100
				'filters',
1101
				'show_per_page',
1102
				'orderby',
1103
			)
1104
		);
1105
1106
		$options->validate( 'action_after', $this->action_after, 'array_merge' );
1107
		$options->validate( 'action_links', $this->action_links, 'array_merge' );
1108
		$options->validate( 'actions_disabled', $this->actions_disabled, 'array' );
1109
		$options->validate( 'actions_hidden', $this->actions_hidden, 'array_merge' );
1110
		$options->validate( 'actions_custom', $this->actions_custom, 'array_merge' );
1111
1112
		if ( ! empty( $options->actions_disabled ) ) {
0 ignored issues
show
The property actions_disabled does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1113
			if ( ! empty( $options->actions_bulk ) ) {
0 ignored issues
show
The property actions_bulk does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1114
				$actions_bulk = $options->actions_bulk;
0 ignored issues
show
The property actions_bulk does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1115
1116
				foreach ( $actions_bulk as $action => $action_opt ) {
1117
					if ( in_array( $action, $options->actions_disabled ) ) {
0 ignored issues
show
The property actions_disabled does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1118
						unset( $actions_bulk[ $action ] );
1119
					}
1120
				}
1121
1122
				$options->actions_bulk = $actions_bulk;
0 ignored issues
show
The property actions_bulk does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1123
			}
1124
1125
			if ( ! empty( $options->actions_custom ) ) {
0 ignored issues
show
The property actions_custom does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1126
				$actions_custom = $options->actions_custom;
0 ignored issues
show
The property actions_custom does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1127
1128
				foreach ( $actions_custom as $action => $action_opt ) {
1129
					if ( in_array( $action, $options->actions_disabled ) ) {
0 ignored issues
show
The property actions_disabled does not exist on object<PodsArray>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1130
						unset( $actions_custom[ $action ] );
1131
					}
1132
				}
1133
1134
				$options->actions_custom = $actions_custom;
0 ignored issues
show
The property actions_custom does not exist on object<PodsArray>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1135
			}
1136
		}//end if
1137
1138
		$options->validate( 'extra', $this->extra, 'array_merge' );
1139
1140
		$options->validate( 'style', $this->style );
1141
		$options->validate( 'icon', $this->icon );
1142
		$options->validate( 'css', $this->css );
1143
		$options->validate( 'wpcss', $this->wpcss, 'boolean' );
1144
1145
		if ( true === $options['wpcss'] ) {
1146
			global $user_ID;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1147
			wp_get_current_user();
1148
1149
			$color = get_user_meta( $user_ID, 'admin_color', true );
0 ignored issues
show
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1150
			if ( strlen( $color ) < 1 ) {
1151
				$color = 'fresh';
1152
			}
1153
1154
			$this->wpcss = "colors-{$color}";
1155
		}
1156
1157
		$options = $options->dump();
1158
1159
		if ( is_object( $this->pod ) ) {
1160
			$options = $this->do_hook( $this->pod->pod . '_setup_options', $options );
1161
		}
1162
1163
		$options = $this->do_hook( 'setup_options', $options );
1164
1165
		if ( false !== $options && ! empty( $options ) ) {
1166
			foreach ( $options as $option => $value ) {
1167
				if ( isset( $this->{$option} ) ) {
1168
					$this->{$option} = $value;
1169
				} else {
1170
					$this->x[ $option ] = $value;
1171
				}
1172
			}
1173
		}
1174
1175
		$unique_identifier = pods_var( 'page' );
1176
		// wp-admin page
1177
		if ( is_object( $this->pod ) && isset( $this->pod->pod ) ) {
1178
			$unique_identifier = '_' . $this->pod->pod;
1179
		} elseif ( 0 < strlen( $this->sql['table'] ) ) {
1180
			$unique_identifier = '_' . $this->sql['table'];
1181
		}
1182
1183
		$unique_identifier .= '_' . $this->page;
1184
		if ( 0 < strlen( $this->num ) ) {
1185
			$unique_identifier .= '_' . $this->num;
1186
		}
1187
1188
		$this->unique_identifier = 'pods_ui_' . md5( $unique_identifier );
1189
1190
		$this->setup_fields();
1191
1192
		return $options;
1193
	}
1194
1195
	/**
1196
	 * @param null   $fields
1197
	 * @param string $which
1198
	 *
1199
	 * @return array|bool|mixed|null
1200
	 */
1201
	public function setup_fields( $fields = null, $which = 'fields' ) {
1202
1203
		$init = false;
1204
		if ( null === $fields ) {
1205
			if ( isset( $this->fields[ $which ] ) ) {
1206
				$fields = (array) $this->fields[ $which ];
1207
			} elseif ( isset( $this->fields['manage'] ) ) {
1208
				$fields = (array) $this->fields['manage'];
1209
			} else {
1210
				$fields = array();
1211
			}
1212
			if ( 'fields' === $which ) {
1213
				$init = true;
1214
			}
1215
		}
1216
		if ( ! empty( $fields ) ) {
1217
			// Available Attributes
1218
			// type = field type
1219
			// type = date (data validation as date)
1220
			// type = time (data validation as time)
1221
			// type = datetime (data validation as datetime)
1222
			// date_touch = use current timestamp when saving (even if readonly, if type is date-related)
1223
			// date_touch_on_create = use current timestamp when saving ONLY on create (even if readonly, if type is date-related)
1224
			// date_ongoing = use this additional field to search between as if the first is the "start" and the date_ongoing is the "end" for filter
1225
			// type = text / other (single line text box)
1226
			// type = desc (textarea)
1227
			// type = number (data validation as int float)
1228
			// type = decimal (data validation as decimal)
1229
			// type = password (single line password box)
1230
			// type = bool (checkbox)
1231
			// type = related (select box)
1232
			// related = table to relate to (if type=related) OR custom array of (key => label or comma separated values) items
1233
			// related_field = field name on table to show (if type=related) - default "name"
1234
			// related_multiple = true (ability to select multiple values if type=related)
1235
			// related_sql = custom where / order by SQL (if type=related)
1236
			// readonly = true (shows as text)
1237
			// display = false (doesn't show on form, but can be saved)
1238
			// search = this field is searchable
1239
			// filter = this field will be independently searchable (by default, searchable fields are searched by the primary search box)
1240
			// comments = comments to show for field
1241
			// comments_top = true (shows comments above field instead of below)
1242
			// real_name = the real name of the field (if using an alias for 'name')
1243
			// group_related = true (uses HAVING instead of WHERE for filtering field)
1244
			$new_fields = array();
1245
			$filterable = false;
1246
			if ( empty( $this->filters ) && ( empty( $this->fields['search'] ) || 'search' === $which ) && false !== $this->searchable ) {
1247
				$filterable    = true;
1248
				$this->filters = array();
1249
			}
1250
1251
			foreach ( $fields as $field => $attributes ) {
1252
				if ( ! is_array( $attributes ) ) {
1253
					if ( is_int( $field ) ) {
1254
						$field      = $attributes;
1255
						$attributes = array();
1256
					} else {
1257
						$attributes = array( 'label' => $attributes );
1258
					}
1259
				}
1260
1261
				if ( ! isset( $attributes['real_name'] ) ) {
1262
					$attributes['real_name'] = pods_var( 'name', $attributes, $field );
1263
				}
1264
1265
				if ( is_object( $this->pod ) && isset( $this->pod->fields ) && isset( $this->pod->fields[ $attributes['real_name'] ] ) ) {
1266
					$attributes = array_merge( $this->pod->fields[ $attributes['real_name'] ], $attributes );
1267
				}
1268
1269
				if ( ! isset( $attributes['options'] ) ) {
1270
					$attributes['options'] = array();
1271
				}
1272
				if ( ! isset( $attributes['id'] ) ) {
1273
					$attributes['id'] = '';
1274
				}
1275
				if ( ! isset( $attributes['label'] ) ) {
1276
					$attributes['label'] = ucwords( str_replace( '_', ' ', $field ) );
1277
				}
1278
				if ( ! isset( $attributes['type'] ) ) {
1279
					$attributes['type'] = 'text';
1280
				}
1281
				if ( ! isset( $attributes['options']['date_format_type'] ) ) {
1282
					$attributes['options']['date_format_type'] = 'date';
1283
				}
1284
				if ( 'related' !== $attributes['type'] || ! isset( $attributes['related'] ) ) {
1285
					$attributes['related'] = false;
1286
				}
1287
				if ( 'related' !== $attributes['type'] || ! isset( $attributes['related_id'] ) ) {
1288
					$attributes['related_id'] = 'id';
1289
				}
1290
				if ( 'related' !== $attributes['type'] || ! isset( $attributes['related_field'] ) ) {
1291
					$attributes['related_field'] = 'name';
1292
				}
1293
				if ( 'related' !== $attributes['type'] || ! isset( $attributes['related_multiple'] ) ) {
1294
					$attributes['related_multiple'] = false;
1295
				}
1296
				if ( 'related' !== $attributes['type'] || ! isset( $attributes['related_sql'] ) ) {
1297
					$attributes['related_sql'] = false;
1298
				}
1299
				if ( 'related' === $attributes['type'] && ( is_array( $attributes['related'] ) || strpos( $attributes['related'], ',' ) ) ) {
1300
					if ( ! is_array( $attributes['related'] ) ) {
1301
						$attributes['related'] = @explode( ',', $attributes['related'] );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
1302
						$related_items         = array();
1303
						foreach ( $attributes['related'] as $key => $label ) {
1304
							if ( is_numeric( $key ) ) {
1305
								$key   = $label;
1306
								$label = ucwords( str_replace( '_', ' ', $label ) );
1307
							}
1308
							$related_items[ $key ] = $label;
1309
						}
1310
						$attributes['related'] = $related_items;
1311
					}
1312
					if ( empty( $attributes['related'] ) ) {
1313
						$attributes['related'] = false;
1314
					}
1315
				}
1316
				if ( ! isset( $attributes['readonly'] ) ) {
1317
					$attributes['readonly'] = false;
1318
				}
1319
				if ( ! isset( $attributes['date_touch'] ) || 'date' !== $attributes['type'] ) {
1320
					$attributes['date_touch'] = false;
1321
				}
1322
				if ( ! isset( $attributes['date_touch_on_create'] ) || 'date' !== $attributes['type'] ) {
1323
					$attributes['date_touch_on_create'] = false;
1324
				}
1325
				if ( ! isset( $attributes['display'] ) ) {
1326
					$attributes['display'] = true;
1327
				}
1328
				if ( ! isset( $attributes['hidden'] ) ) {
1329
					$attributes['hidden'] = false;
1330
				}
1331
				if ( ! isset( $attributes['sortable'] ) || false === $this->sortable ) {
1332
					$attributes['sortable'] = $this->sortable;
1333
				}
1334
				if ( ! isset( $attributes['options']['search'] ) || false === $this->searchable ) {
1335
					$attributes['options']['search'] = $this->searchable;
1336
				}
1337
				if ( ! isset( $attributes['options']['filter'] ) || false === $this->searchable ) {
1338
					$attributes['options']['filter'] = $this->searchable;
1339
				}
1340
				/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1341
				if ( false !== $attributes[ 'options' ][ 'filter' ] && false !== $filterable )
1342
                    $this->filters[] = $field;*/
1343
				if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_label'] ) || ! in_array( $field, $this->filters ) ) {
1344
					$attributes['filter_label'] = $attributes['label'];
1345
				}
1346
				if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_default'] ) || ! in_array( $field, $this->filters ) ) {
1347
					$attributes['filter_default'] = false;
1348
				}
1349
				if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! in_array( $field, $this->filters ) ) {
1350
					$attributes['date_ongoing'] = false;
1351
				}
1352
				if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! isset( $attributes['date_ongoing_default'] ) || ! in_array( $field, $this->filters ) ) {
1353
					$attributes['date_ongoing_default'] = false;
1354
				}
1355
				if ( ! isset( $attributes['export'] ) ) {
1356
					$attributes['export'] = true;
1357
				}
1358
				if ( ! isset( $attributes['group_related'] ) ) {
1359
					$attributes['group_related'] = false;
1360
				}
1361
				if ( ! isset( $attributes['comments'] ) ) {
1362
					$attributes['comments'] = '';
1363
				}
1364
				if ( ! isset( $attributes['comments_top'] ) ) {
1365
					$attributes['comments_top'] = false;
1366
				}
1367
				if ( ! isset( $attributes['custom_view'] ) ) {
1368
					$attributes['custom_view'] = false;
1369
				}
1370
				if ( ! isset( $attributes['custom_input'] ) ) {
1371
					$attributes['custom_input'] = false;
1372
				}
1373
				if ( isset( $attributes['display_helper'] ) ) {
1374
					// pods ui backward compatibility
1375
					$attributes['custom_display'] = $attributes['display_helper'];
1376
				}
1377
				if ( ! isset( $attributes['custom_display'] ) ) {
1378
					$attributes['custom_display'] = false;
1379
				}
1380
				if ( ! isset( $attributes['custom_relate'] ) ) {
1381
					$attributes['custom_relate'] = false;
1382
				}
1383
				if ( ! isset( $attributes['custom_form_display'] ) ) {
1384
					$attributes['custom_form_display'] = false;
1385
				}
1386
				if ( ! isset( $attributes['css_values'] ) ) {
1387
					$attributes['css_values'] = true;
1388
				}
1389
				if ( 'search_columns' === $which && ! $attributes['options']['search'] ) {
1390
					continue;
1391
				}
1392
1393
				$attributes = PodsForm::field_setup( $attributes, null, $attributes['type'] );
1394
1395
				$new_fields[ $field ] = $attributes;
1396
			}//end foreach
1397
			$fields = $new_fields;
1398
		}//end if
1399
		if ( false !== $init ) {
1400
			if ( 'fields' !== $which && ! empty( $this->fields ) ) {
1401
				$this->fields = $this->setup_fields( $this->fields, 'fields' );
1402
			} else {
1403
				$this->fields['manage'] = $fields;
1404
			}
1405
1406
			if ( ! in_array( 'add', $this->actions_disabled ) || ! in_array( 'edit', $this->actions_disabled ) || ! in_array( 'duplicate', $this->actions_disabled ) ) {
1407
				if ( 'form' !== $which && isset( $this->fields['form'] ) && is_array( $this->fields['form'] ) ) {
1408
					$this->fields['form'] = $this->setup_fields( $this->fields['form'], 'form' );
1409
				} else {
1410
					$this->fields['form'] = $fields;
1411
				}
1412
1413
				if ( ! in_array( 'add', $this->actions_disabled ) ) {
1414
					if ( 'add' !== $which && isset( $this->fields['add'] ) && is_array( $this->fields['add'] ) ) {
1415
						$this->fields['add'] = $this->setup_fields( $this->fields['add'], 'add' );
1416
					}
1417
				}
1418
				if ( ! in_array( 'edit', $this->actions_disabled ) ) {
1419
					if ( 'edit' !== $which && isset( $this->fields['edit'] ) && is_array( $this->fields['edit'] ) ) {
1420
						$this->fields['edit'] = $this->setup_fields( $this->fields['edit'], 'edit' );
1421
					}
1422
				}
1423
				if ( ! in_array( 'duplicate', $this->actions_disabled ) ) {
1424
					if ( 'duplicate' !== $which && isset( $this->fields['duplicate'] ) && is_array( $this->fields['duplicate'] ) ) {
1425
						$this->fields['duplicate'] = $this->setup_fields( $this->fields['duplicate'], 'duplicate' );
1426
					}
1427
				}
1428
			}//end if
1429
1430
			if ( false !== $this->searchable ) {
1431
				if ( 'search' !== $which && isset( $this->fields['search'] ) && ! empty( $this->fields['search'] ) ) {
1432
					$this->fields['search'] = $this->setup_fields( $this->fields['search'], 'search' );
1433
				} else {
1434
					$this->fields['search'] = $fields;
1435
				}
1436
			} else {
1437
				$this->fields['search'] = false;
1438
			}
1439
1440
			if ( ! in_array( 'export', $this->actions_disabled ) ) {
1441
				if ( 'export' !== $which && isset( $this->fields['export'] ) && ! empty( $this->fields['export'] ) ) {
1442
					$this->fields['export'] = $this->setup_fields( $this->fields['export'], 'export' );
1443
				}
1444
			}
1445
1446
			if ( ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) {
1447
				if ( 'reorder' !== $which && isset( $this->fields['reorder'] ) && ! empty( $this->fields['reorder'] ) ) {
1448
					$this->fields['reorder'] = $this->setup_fields( $this->fields['reorder'], 'reorder' );
1449
				} else {
1450
					$this->fields['reorder'] = $fields;
1451
				}
1452
			}
1453
		}//end if
1454
1455
		return $this->do_hook( 'setup_fields', $fields, $which, $init );
1456
	}
1457
1458
	/**
1459
	 * @param      $msg
1460
	 * @param bool $error
1461
	 */
1462
	public function message( $msg, $error = false ) {
1463
1464
		$class = 'updated';
1465
		$hook  = 'message';
1466
		
1467
		if ( $error ) {
1468
			$class = 'error';
1469
			$hook  = 'error';
1470
		}
1471
		
1472
		$msg = $this->do_hook( $hook, $msg );
1473
		
1474
		if ( empty( $msg ) ) {
1475
			return;
1476
		}
1477
		?> 
1478
		<div id="message" class="<?php echo esc_attr( $class ); ?> fade">
1479
			<p><?php echo $msg; ?></p>
1480
		</div>
1481
		<?php
1482
	}
1483
1484
	/**
1485
	 * @param $msg
1486
	 *
1487
	 * @return bool
1488
	 */
1489
	public function error( $msg ) {
1490
1491
		$this->message( $msg, true );
1492
1493
		return false;
1494
	}
1495
1496
	/**
1497
	 * @return mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1498
	 */
1499
	public function go() {
0 ignored issues
show
This method's name is shorter than the configured minimum length of 3 characters.

Even though PHP does not care about the name of your methods, it is generally a good practice to choose method names which can be easily understood by other human readers.

Loading history...
1500
1501
		$this->do_hook( 'go' );
1502
		$_GET = pods_unsanitize( $_GET );
1503
		// fix wp sanitization
1504
		$_POST = pods_unsanitize( $_POST );
1505
		// fix wp sanitization
1506
		if ( false !== $this->css ) {
1507
			?>
1508
			<link type="text/css" rel="stylesheet" href="<?php echo esc_url( $this->css ); ?>" />
0 ignored issues
show
Stylesheets must be registered/enqueued via wp_enqueue_style
Loading history...
1509
			<?php
1510
		}
1511
		if ( false !== $this->wpcss ) {
1512
			$stylesheets = array( 'global', 'wp-admin', $this->wpcss );
1513
			foreach ( $stylesheets as $style ) {
1514
				if ( ! wp_style_is( $style, 'queue' ) && ! wp_style_is( $style, 'to_do' ) && ! wp_style_is( $style, 'done' ) ) {
1515
					wp_enqueue_style( $style );
1516
				}
1517
			}
1518
		}
1519
1520
		$this->ui_page = array( $this->action );
1521
		if ( 'add' === $this->action && ! in_array( $this->action, $this->actions_disabled ) ) {
1522
			$this->ui_page[] = 'form';
1523
			if ( 'create' === $this->do && $this->save && ! in_array( $this->do, $this->actions_disabled ) && ! empty( $_POST ) ) {
1524
				$this->ui_page[] = $this->do;
1525
				$this->save( true );
1526
				$this->manage();
1527
			} else {
1528
				$this->add();
1529
			}
1530
		} elseif ( ( 'edit' === $this->action && ! in_array( $this->action, $this->actions_disabled ) ) || ( 'duplicate' === $this->action && ! in_array( $this->action, $this->actions_disabled ) ) ) {
1531
			$this->ui_page[] = 'form';
1532
			if ( 'save' === $this->do && $this->save && ! empty( $_POST ) ) {
1533
				$this->save();
1534
			}
1535
			$this->edit( ( 'duplicate' === $this->action && ! in_array( $this->action, $this->actions_disabled ) ) ? true : false );
1536
		} elseif ( 'delete' === $this->action && ! in_array( $this->action, $this->actions_disabled ) && false !== wp_verify_nonce( $this->_nonce, 'pods-ui-action-delete' ) ) {
1537
			$this->delete( $this->id );
1538
			$this->manage();
1539
		} elseif ( 'reorder' === $this->action && ! in_array( $this->action, $this->actions_disabled ) && false !== $this->reorder['on'] ) {
1540
			if ( 'save' === $this->do ) {
1541
				$this->ui_page[] = $this->do;
1542
				$this->reorder();
1543
			}
1544
			$this->manage( true );
1545
		} elseif ( 'save' === $this->do && $this->save && ! in_array( $this->do, $this->actions_disabled ) && ! empty( $_POST ) ) {
1546
			$this->ui_page[] = $this->do;
1547
			$this->save();
1548
			$this->manage();
1549
		} elseif ( 'create' === $this->do && $this->save && ! in_array( $this->do, $this->actions_disabled ) && ! empty( $_POST ) ) {
1550
			$this->ui_page[] = $this->do;
1551
			$this->save( true );
1552
			$this->manage();
1553
		} elseif ( 'view' === $this->action && ! in_array( $this->action, $this->actions_disabled ) ) {
1554
			$this->view();
1555
		} else {
1556
			if ( isset( $this->actions_custom[ $this->action ] ) ) {
1557
				$more_args = false;
1558
1559
				if ( is_array( $this->actions_custom[ $this->action ] ) && isset( $this->actions_custom[ $this->action ]['more_args'] ) ) {
1560
					$more_args = $this->actions_custom[ $this->action ]['more_args'];
1561
				}
1562
1563
				$row = $this->row;
1564
1565
				if ( empty( $row ) ) {
1566
					$row = $this->get_row();
1567
				}
1568
1569
				if ( $this->restricted( $this->action, $row ) || ( $more_args && ! empty( $more_args['nonce'] ) && false === wp_verify_nonce( $this->_nonce, 'pods-ui-action-' . $this->action ) ) ) {
1570
					return $this->error( sprintf( __( '<strong>Error:</strong> You do not have access to this %s.', 'pods' ), $this->item ) );
1571
				} elseif ( $more_args && false !== $this->callback_action( true, $this->action, $this->id, $row ) ) {
1572
					return null;
1573
				} elseif ( false !== $this->callback_action( true, $this->action, $this->id ) ) {
1574
					return null;
1575
				}
1576
			}//end if
1577
1578
			if ( ! in_array( 'manage', $this->actions_disabled ) ) {
1579
				// handle session / user persistent settings for show_per_page, orderby, search, and filters
1580
				$methods = array( 'session', 'user' );
1581
1582
				// @todo fix this to set ($this) AND save (setting)
1583
				foreach ( $methods as $method ) {
1584
					foreach ( $this->$method as $setting ) {
1585
						if ( 'show_per_page' === $setting ) {
1586
							$value = $this->limit;
1587
						} elseif ( 'orderby' === $setting ) {
1588
							if ( empty( $this->orderby ) ) {
1589
								$value = '';
1590
							} elseif ( isset( $this->orderby['default'] ) ) {
1591
								// save this if we have a default index set
1592
								$value = $this->orderby['default'] . ' ' . ( false === strpos( $this->orderby['default'], ' ' ) ? $this->orderby_dir : '' );
1593
							} else {
1594
								$value = '';
1595
							}
1596
						} else {
1597
							$value = $this->$setting;
1598
						}
1599
1600
						pods_v_set( $value, $setting, $method );
1601
					}
1602
				}
1603
1604
				$this->manage();
1605
			}//end if
1606
		}//end if
1607
	}
1608
1609
	/**
1610
	 * @return mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1611
	 */
1612
	public function add() {
1613
1614
		if ( false !== $this->callback_action( 'add' ) ) {
1615
			return null;
1616
		}
1617
1618
		if ( $this->restricted( $this->action ) ) {
1619
			return $this->error( sprintf( __( '<strong>Error:</strong> You do not have access to this %s.', 'pods' ), $this->item ) );
1620
		}
1621
		?>
1622
		<div class="wrap pods-ui">
1623
			<div id="icon-edit-pages" class="icon32"
1624
			<?php
1625
			if ( false !== $this->icon ) {
1626
?>
1627
 style="background-position:0 0;background-size:100%;background-image:url(<?php echo esc_url( $this->icon ); ?>);"<?php } ?>>
1628
				<br /></div>
1629
			<h2>
1630
				<?php
1631
				echo wp_kses_post( $this->header['add'] );
1632
1633
				if ( ! in_array( 'manage', $this->actions_disabled ) && ! in_array( 'manage', $this->actions_hidden ) && ! $this->restricted( 'manage' ) ) {
1634
					$link = pods_query_arg(
1635
						array(
1636
							'action' . $this->num => 'manage',
1637
							'id' . $this->num     => '',
1638
						), self::$allowed, $this->exclusion()
1639
					);
1640
1641
					if ( ! empty( $this->action_links['manage'] ) ) {
1642
						$link = $this->action_links['manage'];
1643
					}
1644
					?>
1645
					<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2">&laquo; <?php echo sprintf( __( 'Back to %s', 'pods' ), $this->heading['manage'] ); ?></a>
1646
				<?php } ?>
1647
			</h2>
1648
1649
			<?php $this->form( true ); ?>
1650
		</div>
1651
		<?php
1652
	}
1653
1654
	/**
1655
	 * @param bool $duplicate
1656
	 *
1657
	 * @return mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1658
	 */
1659
	public function edit( $duplicate = false ) {
1660
1661
		if ( in_array( 'duplicate', $this->actions_disabled ) ) {
1662
			$duplicate = false;
1663
		}
1664
1665
		if ( empty( $this->row ) ) {
1666
			$this->get_row();
1667
		}
1668
1669
		if ( $duplicate && false !== $this->callback_action( 'duplicate' ) ) {
1670
			return null;
1671
		} elseif ( false !== $this->callback_action( 'edit', $duplicate ) ) {
1672
			return null;
1673
		}
1674
1675
		if ( $this->restricted( $this->action ) ) {
1676
			return $this->error( sprintf( __( '<strong>Error:</strong> You do not have access to this %s.', 'pods' ), $this->item ) );
1677
		}
1678
		?>
1679
		<div class="wrap pods-ui">
1680
			<div id="icon-edit-pages" class="icon32"
1681
			<?php
1682
			if ( false !== $this->icon ) {
1683
?>
1684
 style="background-position:0 0;background-size:100%;background-image:url(<?php echo esc_url( $this->icon ); ?>);"<?php } ?>>
1685
				<br /></div>
1686
			<h2>
1687
				<?php
1688
				echo wp_kses_post( $this->do_template( $duplicate ? $this->header['duplicate'] : $this->header['edit'] ) );
1689
1690
				if ( ! in_array( 'add', $this->actions_disabled ) && ! in_array( 'add', $this->actions_hidden ) && ! $this->restricted( 'add' ) ) {
1691
					$link = pods_query_arg(
1692
						array(
1693
							'action' . $this->num => 'add',
1694
							'id' . $this->num     => '',
1695
							'do' . $this->num = '',
1696
						), self::$allowed, $this->exclusion()
1697
					);
1698
1699
					if ( ! empty( $this->action_links['add'] ) ) {
1700
						$link = $this->action_links['add'];
1701
					}
1702
					?>
1703
					<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2"><?php echo wp_kses_post( $this->heading['add'] ); ?></a>
1704
					<?php
1705
				} elseif ( ! in_array( 'manage', $this->actions_disabled ) && ! in_array( 'manage', $this->actions_hidden ) && ! $this->restricted( 'manage' ) ) {
1706
					$link = pods_query_arg(
1707
						array(
1708
							'action' . $this->num => 'manage',
1709
							'id' . $this->num     => '',
1710
						), self::$allowed, $this->exclusion()
1711
					);
1712
1713
					if ( ! empty( $this->action_links['manage'] ) ) {
1714
						$link = $this->action_links['manage'];
1715
					}
1716
					?>
1717
					<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2">&laquo; <?php echo sprintf( __( 'Back to %s', 'pods' ), $this->heading['manage'] ); ?></a>
1718
					<?php
1719
				}//end if
1720
				?>
1721
			</h2>
1722
1723
			<?php $this->form( false, $duplicate ); ?>
1724
		</div>
1725
		<?php
1726
	}
1727
1728
	/**
1729
	 * @param bool $create
1730
	 * @param bool $duplicate
1731
	 *
1732
	 * @return bool|mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1733
	 */
1734
	public function form( $create = false, $duplicate = false ) {
1735
1736
		if ( in_array( 'duplicate', $this->actions_disabled ) ) {
1737
			$duplicate = false;
1738
		}
1739
1740
		if ( false !== $this->callback( 'form' ) ) {
1741
			return null;
1742
		}
1743
1744
		$label = $this->label['add'];
1745
		$id    = null;
1746
		$vars  = array(
1747
			'action' . $this->num => $this->action_after['add'],
1748
			'do' . $this->num     => 'create',
1749
			'id' . $this->num     => 'X_ID_X',
1750
		);
1751
1752
		$alt_vars           = $vars;
1753
		$alt_vars['action'] = 'manage';
1754
		unset( $alt_vars['id'] );
1755
1756
		if ( false === $create ) {
1757
			if ( empty( $this->row ) ) {
1758
				$this->get_row();
1759
			}
1760
1761
			if ( empty( $this->row ) && ( ! is_object( $this->pod ) || 'settings' !== $this->pod->pod_data['type'] ) ) {
1762
				return $this->error( sprintf( __( '<strong>Error:</strong> %s not found.', 'pods' ), $this->item ) );
1763
			}
1764
1765
			if ( $this->restricted( $this->action, $this->row ) ) {
1766
				return $this->error( sprintf( __( '<strong>Error:</strong> You do not have access to this %s.', 'pods' ), $this->item ) );
1767
			}
1768
1769
			$label = $this->do_template( $this->label['edit'] );
1770
			$id    = $this->row[ $this->sql['field_id'] ];
1771
			$vars  = array(
1772
				'action' . $this->num => $this->action_after['edit'],
1773
				'do' . $this->num     => 'save',
1774
				'id' . $this->num     => $id,
1775
			);
1776
1777
			$alt_vars           = $vars;
1778
			$alt_vars['action'] = 'manage';
1779
			unset( $alt_vars['id'] );
1780
1781
			if ( $duplicate ) {
1782
				$label = $this->do_template( $this->label['duplicate'] );
1783
				$id    = null;
1784
				$vars  = array(
1785
					'action' . $this->num => $this->action_after['duplicate'],
1786
					'do' . $this->num     => 'create',
1787
					'id' . $this->num     => 'X_ID_X',
1788
				);
1789
1790
				$alt_vars           = $vars;
1791
				$alt_vars['action'] = 'manage';
1792
				unset( $alt_vars['id'] );
1793
			}
1794
		} elseif ( $this->restricted( $this->action, $this->row ) ) {
1795
			return $this->error( sprintf( __( '<strong>Error:</strong> You do not have access to this %s.', 'pods' ), $this->item ) );
1796
		}//end if
1797
1798
		$fields = array();
1799
1800
		if ( isset( $this->fields[ $this->action ] ) ) {
1801
			$fields = $this->fields[ $this->action ];
1802
		}
1803
1804
		if ( is_object( $this->pod ) ) {
1805
			$object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true );
1806
1807
			if ( empty( $object_fields ) && in_array(
1808
				$this->pod->pod_data['type'], array(
1809
					'post_type',
1810
					'taxonomy',
1811
					'media',
1812
					'user',
1813
					'comment',
1814
				)
1815
			) ) {
1816
				$object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
1817
			}
1818
1819
			if ( empty( $fields ) ) {
1820
				// Add core object fields if $fields is empty
1821
				$fields = array_merge( $object_fields, $this->pod->fields );
1822
			}
1823
		}
1824
1825
		$form_fields = $fields;
1826
		// Temporary
1827
		$fields = array();
1828
1829
		foreach ( $form_fields as $k => $field ) {
1830
			$name = $k;
1831
1832
			$defaults = array(
1833
				'name' => $name,
1834
			);
1835
1836
			if ( ! is_array( $field ) ) {
1837
				$name = $field;
1838
1839
				$field = array(
1840
					'name' => $name,
1841
				);
1842
			}
1843
1844
			$field = array_merge( $defaults, $field );
1845
1846
			$field['name'] = trim( $field['name'] );
1847
1848
			$default_value = pods_var_raw( 'default', $field );
1849
			$value         = pods_var_raw( 'value', $field );
1850
1851
			if ( empty( $field['name'] ) ) {
1852
				$field['name'] = trim( $name );
1853
			}
1854
1855
			if ( isset( $object_fields[ $field['name'] ] ) ) {
1856
				$field = array_merge( $field, $object_fields[ $field['name'] ] );
1857
			} elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) {
1858
				$field = array_merge( $this->pod->fields[ $field['name'] ], $field );
1859
			}
1860
1861
			if ( pods_var_raw( 'hidden', $field, false, null, true ) ) {
1862
				$field['type'] = 'hidden';
1863
			}
1864
1865
			$fields[ $field['name'] ] = $field;
1866
1867
			if ( empty( $this->id ) && null !== $default_value ) {
1868
				$this->pod->row_override[ $field['name'] ] = $default_value;
1869
			} elseif ( ! empty( $this->id ) && null !== $value ) {
1870
				$this->pod->row[ $field['name'] ] = $value;
1871
			}
1872
		}//end foreach
1873
1874
		unset( $form_fields );
1875
		// Cleanup
1876
		$fields = $this->do_hook( 'form_fields', $fields, $this->pod );
1877
1878
		$pod            =& $this->pod;
1879
		$thank_you      = pods_query_arg( $vars, self::$allowed, $this->exclusion() );
1880
		$thank_you_alt  = pods_query_arg( $alt_vars, self::$allowed, $this->exclusion() );
1881
		$obj            =& $this;
1882
		$singular_label = $this->item;
1883
		$plural_label   = $this->items;
1884
1885
		if ( is_object( $this->pod ) && 'settings' === $this->pod->pod_data['type'] && 'settings' === $this->style ) {
1886
			pods_view( PODS_DIR . 'ui/admin/form-settings.php', compact( array_keys( get_defined_vars() ) ) );
1887
		} else {
1888
			pods_view( PODS_DIR . 'ui/admin/form.php', compact( array_keys( get_defined_vars() ) ) );
1889
		}
1890
	}
1891
1892
	/**
1893
	 * @return bool|mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1894
	 * @since 2.3.10
1895
	 */
1896
	public function view() {
1897
1898
		if ( false !== $this->callback_action( 'view' ) ) {
1899
			return null;
1900
		}
1901
1902
		if ( empty( $this->row ) ) {
1903
			$this->get_row();
1904
		}
1905
1906
		if ( empty( $this->row ) ) {
1907
			return $this->error( sprintf( __( '<strong>Error:</strong> %s not found.', 'pods' ), $this->item ) );
1908
		}
1909
1910
		$pod =& $this->pod;
1911
		$obj =& $this;
1912
1913
		$fields = array();
1914
1915
		if ( isset( $this->fields[ $this->action ] ) ) {
1916
			$fields = $this->fields[ $this->action ];
1917
		}
1918
1919
		if ( is_object( $this->pod ) ) {
1920
			$object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true );
1921
1922
			$object_field_objects = array(
1923
				'post_type',
1924
				'taxonomy',
1925
				'media',
1926
				'user',
1927
				'comment',
1928
			);
1929
1930
			if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects ) ) {
1931
				$object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
1932
			}
1933
1934
			if ( empty( $fields ) ) {
1935
				// Add core object fields if $fields is empty
1936
				$fields = array_merge( $object_fields, $this->pod->fields );
1937
			}
1938
		}
1939
1940
		$view_fields = $fields;
1941
		// Temporary
1942
		$fields = array();
1943
1944
		foreach ( $view_fields as $k => $field ) {
1945
			$name = $k;
1946
1947
			$defaults = array(
1948
				'name'    => $name,
1949
				'type'    => 'text',
1950
				'options' => 'text',
1951
			);
1952
1953
			if ( ! is_array( $field ) ) {
1954
				$name = $field;
1955
1956
				$field = array(
1957
					'name' => $name,
1958
				);
1959
			}
1960
1961
			$field = array_merge( $defaults, $field );
1962
1963
			$field['name'] = trim( $field['name'] );
1964
1965
			$value = pods_var_raw( 'default', $field );
1966
1967
			if ( empty( $field['name'] ) ) {
1968
				$field['name'] = trim( $name );
1969
			}
1970
1971
			if ( isset( $object_fields[ $field['name'] ] ) ) {
1972
				$field = array_merge( $field, $object_fields[ $field['name'] ] );
1973
			} elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) {
1974
				$field = array_merge( $this->pod->fields[ $field['name'] ], $field );
1975
			}
1976
1977
			if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' === $field['type'] ) {
1978
				continue;
1979
			} elseif ( ! PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $pod->id() ) ) {
1980
				continue;
1981
			}
1982
1983
			$fields[ $field['name'] ] = $field;
1984
1985
			if ( empty( $this->id ) && null !== $value ) {
1986
				$this->pod->row_override[ $field['name'] ] = $value;
1987
			}
1988
		}//end foreach
1989
1990
		unset( $view_fields );
1991
		// Cleanup
1992
		?>
1993
		<div class="wrap pods-ui">
1994
			<div id="icon-edit-pages" class="icon32"
1995
			<?php
1996
			if ( false !== $this->icon ) {
1997
?>
1998
 style="background-position:0 0;background-size:100%;background-image:url(<?php echo esc_url( $this->icon ); ?>);"<?php } ?>>
1999
				<br /></div>
2000
			<h2>
2001
				<?php
2002
				echo wp_kses_post( $this->do_template( $this->header['view'] ) );
2003
2004
				if ( ! in_array( 'add', $this->actions_disabled ) && ! in_array( 'add', $this->actions_hidden ) && ! $this->restricted( 'add' ) ) {
2005
					$link = pods_query_arg(
2006
						array(
2007
							'action' . $this->num => 'add',
2008
							'id' . $this->num     => '',
2009
							'do' . $this->num = '',
2010
						), self::$allowed, $this->exclusion()
2011
					);
2012
2013
					if ( ! empty( $this->action_links['add'] ) ) {
2014
						$link = $this->action_links['add'];
2015
					}
2016
					?>
2017
					<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2"><?php echo wp_kses_post( $this->heading['add'] ); ?></a>
2018
					<?php
2019
				} elseif ( ! in_array( 'manage', $this->actions_disabled ) && ! in_array( 'manage', $this->actions_hidden ) && ! $this->restricted( 'manage' ) ) {
2020
					$link = pods_query_arg(
2021
						array(
2022
							'action' . $this->num => 'manage',
2023
							'id' . $this->num     => '',
2024
						), self::$allowed, $this->exclusion()
2025
					);
2026
2027
					if ( ! empty( $this->action_links['manage'] ) ) {
2028
						$link = $this->action_links['manage'];
2029
					}
2030
					?>
2031
					<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2">&laquo; <?php echo sprintf( __( 'Back to %s', 'pods' ), $this->heading['manage'] ); ?></a>
2032
					<?php
2033
				}//end if
2034
2035
				pods_view( PODS_DIR . 'ui/admin/view.php', compact( array_keys( get_defined_vars() ) ) );
2036
				?>
2037
2038
			</h2>
2039
		</div>
2040
		<?php
2041
	}
2042
2043
	/**
2044
	 * Reorder data
2045
	 */
2046
	public function reorder() {
2047
2048
		// loop through order
2049
		$order = (array) pods_var_raw( 'order', 'post', array(), null, true );
2050
2051
		$params = array(
2052
			'pod'   => $this->pod->pod,
2053
			'field' => $this->reorder['on'],
2054
			'order' => $order,
2055
		);
2056
2057
		$reorder = pods_api()->reorder_pod_item( $params );
2058
2059
		if ( $reorder ) {
2060
			$this->message( sprintf( __( '<strong>Success!</strong> %s reordered successfully.', 'pods' ), $this->items ) );
2061
		} else {
2062
			$this->error( sprintf( __( '<strong>Error:</strong> %s has not been reordered.', 'pods' ), $this->items ) );
2063
		}
2064
	}
2065
2066
	/**
2067
	 * @param bool $insert
2068
	 *
2069
	 * @return mixed
2070
	 */
2071
	public function save( $insert = false ) {
2072
2073
		$this->do_hook( 'pre_save', $insert );
2074
2075
		if ( $this->callback( 'save', $insert ) ) {
2076
			return null;
2077
		}
2078
2079
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
2080
		$action = __( 'saved', 'pods' );
2081
		if ( true === $insert ) {
2082
			$action = __( 'created', 'pods' );
2083
		}
2084
		$field_sql = array();
2085
		$values    = array();
2086
		$data      = array();
2087
		foreach ( $this->fields['form'] as $field => $attributes ) {
2088
			$vartype = '%s';
2089
			if ( 'bool' === $attributes['type'] ) {
2090
				$selected = ( 1 == pods_var( $field, 'post', 0 ) ) ? 1 : 0;
2091
			} elseif ( '' == pods_var( $field, 'post', '' ) ) {
2092
				continue;
2093
			}
2094
			if ( false === $attributes['display'] || false !== $attributes['readonly'] ) {
2095
				if ( ! in_array( $attributes['type'], array( 'date', 'time', 'datetime' ) ) ) {
2096
					continue;
2097
				}
2098
				if ( false === $attributes['date_touch'] && ( false === $attributes['date_touch_on_create'] || false === $insert || 0 < $this->id ) ) {
2099
					continue;
2100
				}
2101
			}
2102
			if ( in_array( $attributes['type'], array( 'date', 'time', 'datetime' ) ) ) {
2103
				$format = 'Y-m-d H:i:s';
2104
				if ( 'date' === $attributes['type'] ) {
2105
					$format = 'Y-m-d';
2106
				}
2107
				if ( 'time' === $attributes['type'] ) {
2108
					$format = 'H:i:s';
2109
				}
2110
				if ( false !== $attributes['date_touch'] || ( false !== $attributes['date_touch_on_create'] && true === $insert && $this->id < 1 ) ) {
2111
					$value = date_i18n( $format );
2112
				} else {
2113
					$value = date_i18n( $format, strtotime( ( 'time' === $attributes['type'] ) ? date_i18n( 'Y-m-d ' ) : pods_var( $field, 'post', '' ) ) );
2114
				}
2115
			} else {
2116
				if ( 'bool' === $attributes['type'] ) {
2117
					$vartype = '%d';
2118
					$value   = 0;
2119
					if ( '' != pods_var( $field, 'post', '' ) ) {
2120
						$value = 1;
2121
					}
2122
				} elseif ( 'number' === $attributes['type'] ) {
2123
					$vartype = '%d';
2124
					$value   = number_format( pods_var( $field, 'post', 0 ), 0, '', '' );
2125
				} elseif ( 'decimal' === $attributes['type'] ) {
2126
					$vartype = '%d';
2127
					$value   = number_format( pods_var( $field, 'post', 0 ), 2, '.', '' );
2128
				} elseif ( 'related' === $attributes['type'] ) {
2129
					if ( is_array( pods_var( $field, 'post', '' ) ) ) {
2130
						$value = implode( ',', pods_var( $field, 'post', '' ) );
2131
					} else {
2132
						$value = pods_var( $field, 'post', '' );
2133
					}
2134
				} else {
2135
					$value = pods_var( $field, 'post', '' );
2136
				}//end if
2137
			}//end if
2138
2139
			if ( isset( $attributes['custom_save'] ) && false !== $attributes['custom_save'] && is_callable( $attributes['custom_save'] ) ) {
2140
				$value = call_user_func_array(
2141
					$attributes['custom_save'], array(
2142
						$value,
2143
						$field,
2144
						$attributes,
2145
						&$this,
2146
					)
2147
				);
2148
			}
2149
2150
			$field_sql[]    = "`$field`=$vartype";
2151
			$values[]       = $value;
2152
			$data[ $field ] = $value;
2153
		}//end foreach
2154
		$field_sql = implode( ',', $field_sql );
2155
		if ( false === $insert && 0 < $this->id ) {
2156
			$this->insert_id = $this->id;
0 ignored issues
show
The property insert_id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
2157
			$values[]        = $this->id;
2158
			$check           = $wpdb->query( $wpdb->prepare( "UPDATE $this->sql['table'] SET $field_sql WHERE id=%d", $values ) );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
2159
		} else {
2160
			$check = $wpdb->query( $wpdb->prepare( "INSERT INTO $this->sql['table'] SET $field_sql", $values ) );
0 ignored issues
show
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
2161
		}
2162
		if ( $check ) {
2163
			if ( 0 == $this->insert_id ) {
2164
				$this->insert_id = $wpdb->insert_id;
2165
			}
2166
			$this->message( sprintf( __( '<strong>Success!</strong> %1\$s %2\$s successfully.', 'pods' ), $this->item, $action ) );
2167
		} else {
2168
			$this->error( sprintf( __( '<strong>Error:</strong> %1\$s has not been %2\$s.', 'pods' ), $this->item, $action ) );
2169
		}
2170
		$this->do_hook( 'post_save', $this->insert_id, $data, $insert );
2171
	}
2172
2173
	/**
2174
	 * @param null $id
2175
	 *
2176
	 * @return bool|mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
2177
	 */
2178
	public function delete( $id = null ) {
2179
2180
		$this->do_hook( 'pre_delete', $id );
2181
2182
		if ( false !== $this->callback_action( 'delete', $id ) ) {
2183
			return null;
2184
		}
2185
2186
		$id = pods_absint( $id );
2187
2188
		if ( empty( $id ) ) {
2189
			$id = pods_absint( $this->id );
2190
		}
2191
2192
		if ( $id < 1 ) {
2193
			return $this->error( __( '<strong>Error:</strong> Invalid Configuration - Missing "id" definition.', 'pods' ) );
2194
		}
2195
2196
		if ( false === $id ) {
2197
			$id = $this->id;
2198
		}
2199
2200
		if ( is_object( $this->pod ) ) {
2201
			$check = $this->pod->delete( $id );
2202
		} else {
2203
			$check = $this->pods_data->delete( $this->sql['table'], array( $this->sql['field_id'] => $id ) );
2204
		}
2205
2206
		if ( $check ) {
2207
			$this->message( sprintf( __( '<strong>Deleted:</strong> %s has been deleted.', 'pods' ), $this->item ) );
2208
		} else {
2209
			$this->error( sprintf( __( '<strong>Error:</strong> %s has not been deleted.', 'pods' ), $this->item ) );
2210
		}
2211
2212
		$this->do_hook( 'post_delete', $id );
2213
	}
2214
2215
	/**
2216
	 * Callback for deleting items in bulk
2217
	 */
2218
	public function delete_bulk() {
2219
2220
		$this->do_hook( 'pre_delete_bulk' );
2221
2222
		if ( 1 != pods_var( 'deleted_bulk', 'get', 0 ) ) {
2223
			$ids = $this->bulk;
2224
2225
			$success = false;
2226
2227
			if ( ! empty( $ids ) ) {
2228
				$ids = (array) $ids;
2229
2230
				foreach ( $ids as $id ) {
2231
					$id = pods_absint( $id );
2232
2233
					if ( empty( $id ) ) {
2234
						continue;
2235
					}
2236
2237
					if ( $callback = $this->callback( 'delete', $id ) ) {
2238
						$check = $callback;
2239
					} elseif ( is_object( $this->pod ) ) {
2240
						$check = $this->pod->delete( $id );
2241
					} else {
2242
						$check = $this->pods_data->delete( $this->sql['table'], array( $this->sql['field_id'] => $id ) );
2243
					}
2244
2245
					if ( $check ) {
2246
						$success = true;
2247
					}
2248
				}
2249
			}//end if
2250
2251
			if ( $success ) {
2252
				pods_redirect(
2253
					pods_query_arg(
2254
						array(
2255
							'action_bulk'  => 'delete',
2256
							'deleted_bulk' => 1,
2257
						), array(
2258
							'page',
2259
							'lang',
2260
							'action',
2261
							'id',
2262
						)
2263
					)
2264
				);
2265
			} else {
2266
				$this->error( sprintf( __( '<strong>Error:</strong> %s has not been deleted.', 'pods' ), $this->item ) );
2267
			}
2268
		} else {
2269
			$this->message( sprintf( __( '<strong>Deleted:</strong> %s have been deleted.', 'pods' ), $this->items ) );
2270
2271
			unset( $_GET['deleted_bulk'] );
2272
		}//end if
2273
2274
		$this->action_bulk = false;
2275
		unset( $_GET['action_bulk'] );
2276
2277
		$this->do_hook( 'post_delete_bulk' );
2278
2279
		$this->manage();
2280
	}
2281
2282
	/**
2283
	 * Callback for exporting items in bulk
2284
	 */
2285
	public function export_bulk() {
2286
2287
		if ( ! empty( $_POST['bulk_export_type'] ) ) {
2288
			if ( ! empty( $_POST['bulk_export_fields'] ) ) {
2289
				$export_fields = $_POST['bulk_export_fields'];
2290
2291
				$this->fields['export '] = array();
2292
2293
				if ( $this->pod ) {
2294
					$fields = $this->pod->fields();
2295
2296
					foreach ( $fields as $field ) {
2297
						if ( in_array( $field['name'], $export_fields ) ) {
2298
							$this->fields['export'][] = $field;
2299
						}
2300
					}
2301
				}
2302
			}
2303
2304
			// Set up where clause so that export function finds it
2305
			if ( ! empty( $_POST['action_bulk_ids'] ) ) {
2306
				$ids = (array) explode( ',', $_POST['action_bulk_ids'] );
2307
				$ids = array_map( 'absint', $ids );
2308
				$ids = array_filter( $ids );
2309
2310
				if ( ! empty( $ids ) ) {
2311
					$ids = implode( ', ', $ids );
2312
2313
					$this->where = array(
2314
						'manage' => '`' . pods_sanitize( $this->sql['field_id'] ) . '` IN ( ' . $ids . ' )',
2315
					);
2316
				}
2317
			}
2318
2319
			$this->export( $_POST['bulk_export_type'] );
2320
2321
			// Cleanup since export function calls get_data before returning
2322
			$this->action_bulk = '';
2323
			$this->where       = array();
2324
			$this->data        = false;
2325
2326
			$_GET['action_bulk_ids'] = '';
2327
2328
			$this->manage();
2329
		} else {
2330
			$this->export_fields_form();
2331
		}//end if
2332
2333
	}
2334
2335
	/**
2336
	 * Select the pods fields to be exported
2337
	 */
2338
	public function export_fields_form() {
2339
2340
		?>
2341
		<div class="wrap pods-admin pods-ui">
2342
			<h2><?php echo __( 'Choose Export Fields', 'pods' ); ?></h2>
2343
2344
			<form method="post" id="pods_admin_ui_export_form">
2345
				<?php
2346
				// Avoid a bunch of inputs if there's a lot selected
2347
				if ( ! empty( $_REQUEST['action_bulk_ids'] ) ) {
2348
					$_GET['action_bulk_ids'] = implode( ',', (array) $_REQUEST['action_bulk_ids'] );
2349
				}
2350
2351
				$this->hidden_vars();
2352
				?>
2353
2354
				<ul>
2355
					<?php foreach ( $this->pod->fields() as $field_name => $field ) { ?>
2356
						<li>
2357
							<label for="bulk_export_fields_<?php echo esc_attr( $field['name'] ); ?>">
2358
								<input type="checkbox" name="bulk_export_fields[]" id="bulk_export_fields_<?php echo esc_attr( $field['name'] ); ?>" value="<?php echo esc_attr( $field['name'] ); ?>" />
2359
								<?php echo esc_html( $field['label'] ); ?>
2360
							</label>
2361
						</li>
2362
					<?php } ?>
2363
				</ul>
2364
2365
				<p class="submit">
2366
					<?php _e( 'Export as:', 'pods' ); ?>&nbsp;&nbsp;
2367
					<?php foreach ( $this->export['formats'] as $format => $separator ) { ?>
2368
						<input type="submit" id="export_type_<?php echo esc_attr( strtoupper( $format ) ); ?>" value=" <?php echo esc_attr( strtoupper( $format ) ); ?> " name="bulk_export_type" class="button-primary" />
2369
					<?php } ?>
2370
				</p>
2371
			</form>
2372
		</div>
2373
		<?php
2374
2375
	}
2376
2377
	/**
2378
	 * @param null $export_type
2379
	 */
2380
	public function export( $export_type = null ) {
2381
2382
		if ( empty( $export_type ) ) {
2383
			$export_type = pods_var( 'export_type', 'get', 'csv' );
2384
		}
2385
2386
		$export_type = trim( strtolower( $export_type ) );
2387
2388
		$type = $export_type;
2389
2390
		$delimiter = ',';
2391
2392
		if ( ! empty( $this->export['formats'][ $export_type ] ) ) {
2393
			$delimiter = $this->export['formats'][ $export_type ];
2394
		}
2395
2396
		$columns = array(
2397
			$this->sql['field_id'] => 'ID',
2398
		);
2399
2400
		if ( empty( $this->fields['export'] ) && $this->pod && ! empty( $this->pod->fields ) ) {
2401
			$this->fields['export'] = $this->pod->fields;
2402
		}
2403
2404
		if ( ! empty( $this->fields['export'] ) ) {
2405
			foreach ( $this->fields['export'] as $field ) {
2406
				$columns[ $field['name'] ] = $field['label'];
2407
			}
2408
		}
2409
2410
		$params = array(
2411
			'full'      => true,
2412
			'flatten'   => true,
2413
			'fields'    => array_keys( $columns ),
2414
			'type'      => $type,
2415
			'delimiter' => $delimiter,
2416
			'columns'   => $columns,
2417
		);
2418
2419
		$items = $this->get_data( $params );
2420
2421
		$data = array(
2422
			'columns' => $columns,
2423
			'items'   => $items,
2424
			'fields'  => $this->fields['export'],
2425
		);
2426
2427
		$migrate = pods_migrate( $type, $delimiter, $data );
2428
2429
		$migrate->export();
2430
2431
		$save_params = array(
2432
			'attach' => true,
2433
		);
2434
2435
		$export_file = $migrate->save( $save_params );
2436
2437
		$this->message( sprintf( __( '<strong>Success:</strong> Your export is ready, you can download it <a href="%s" target="_blank">here</a>', 'pods' ), $export_file ) );
2438
2439
		// echo '<script type="text/javascript">window.open("' . esc_js( $export_file ) . '");</script>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
2440
		$this->get_data();
2441
	}
2442
2443
	/**
2444
	 * @param $field
2445
	 *
2446
	 * @return array|bool|mixed|null
2447
	 */
2448
	public function get_field( $field ) {
2449
2450
		$value = null;
2451
2452
		// use PodsData to get field
2453
		if ( $callback = $this->callback( 'get_field', $field ) ) {
2454
			return $callback;
2455
		}
2456
2457
		if ( isset( $this->row[ $field ] ) ) {
2458
			$value = $this->row[ $field ];
2459
		} elseif ( false !== $this->pod && is_object( $this->pod ) && ( 'Pods' == get_class( $this->pod ) || 'Pod' == get_class( $this->pod ) ) ) {
2460
			if ( 'Pod' == get_class( $this->pod ) ) {
2461
				$value = $this->pod->get_field( $field );
0 ignored issues
show
Documentation Bug introduced by
The method get_field does not exist on object<Pod>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
2462
			} else {
2463
				$value = $this->pod->field( $field );
2464
			}
2465
		}
2466
2467
		return $this->do_hook( 'get_field', $value, $field );
2468
	}
2469
2470
	/**
2471
	 * Get find() params based on current UI action
2472
	 *
2473
	 * @param null|array  $params
2474
	 * @param null|string $action
2475
	 *
2476
	 * @return array|mixed|void
2477
	 */
2478
	public function get_params( $params = null, $action = null ) {
2479
2480
		if ( null === $action ) {
2481
			$action = $this->action;
2482
		}
2483
2484
		$defaults = array(
2485
			'full'    => false,
2486
			'flatten' => true,
2487
			'fields'  => null,
2488
			'type'    => '',
2489
		);
2490
2491
		if ( ! empty( $params ) && is_array( $params ) ) {
2492
			$params = (object) array_merge( $defaults, $params );
2493
		} else {
2494
			$params = (object) $defaults;
2495
		}
2496
2497
		if ( ! in_array( $action, array( 'manage', 'reorder' ) ) ) {
2498
			$action = 'manage';
2499
		}
2500
2501
		$params_override = false;
2502
2503
		$orderby = array();
2504
2505
		$limit = $this->limit;
2506
2507
		$sql = null;
2508
2509
		if ( 'reorder' === $this->action ) {
2510
			if ( ! empty( $this->reorder['orderby'] ) ) {
2511
				$orderby[ $this->reorder['orderby'] ] = $this->reorder['orderby_dir'];
2512
			} else {
2513
				$orderby[ $this->reorder['on'] ] = $this->reorder['orderby_dir'];
2514
			}
2515
2516
			if ( ! empty( $this->reorder['limit'] ) ) {
2517
				$limit = $this->reorder['limit'];
2518
			}
2519
2520
			if ( ! empty( $this->reorder['sql'] ) ) {
2521
				$sql = $this->reorder['sql'];
2522
			}
2523
		}
2524
2525
		if ( ! empty( $this->orderby ) ) {
2526
			$this->orderby = (array) $this->orderby;
2527
2528
			foreach ( $this->orderby as $order ) {
2529
				if ( false !== strpos( $order, ' ' ) ) {
2530
					$orderby[] = $order;
2531
				} elseif ( ! isset( $orderby[ $order ] ) ) {
2532
					$orderby[ $order ] = $this->orderby_dir;
2533
				}
2534
			}
2535
		}
2536
2537
		if ( false !== $this->pod && is_object( $this->pod ) && ( 'Pods' == get_class( $this->pod ) || 'Pod' == get_class( $this->pod ) ) ) {
2538
			$find_params = array(
2539
				'where'               => pods_v( $action, $this->where, null, true ),
2540
				'orderby'             => $orderby,
2541
				'page'                => (int) $this->page,
2542
				'pagination'          => true,
2543
				'limit'               => (int) $limit,
2544
				'search'              => $this->searchable,
2545
				'search_query'        => $this->search,
2546
				'search_across'       => $this->search_across,
2547
				'search_across_picks' => $this->search_across_picks,
2548
				'filters'             => $this->filters,
2549
				'sql'                 => $sql,
2550
			);
2551
2552
			$params_override = true;
2553
		} else {
2554
			$find_params = array(
2555
				'table'        => $this->sql['table'],
2556
				'id'           => $this->sql['field_id'],
2557
				'index'        => $this->sql['field_index'],
2558
				'where'        => pods_v( $action, $this->where, null, true ),
2559
				'orderby'      => $orderby,
2560
				'page'         => (int) $this->page,
2561
				'pagination'   => true,
2562
				'limit'        => (int) $limit,
2563
				'search'       => $this->searchable,
2564
				'search_query' => $this->search,
2565
				'fields'       => $this->fields['search'],
2566
				'sql'          => $sql,
2567
			);
2568
2569
			if ( ! empty( $this->sql['select'] ) ) {
2570
				$find_params['select'] = $this->sql['select'];
2571
			}
2572
		}//end if
2573
2574
		if ( empty( $find_params['where'] ) && $this->restricted( $this->action ) ) {
2575
			$find_params['where'] = $this->pods_data->query_fields( $this->restrict[ $this->action ], ( is_object( $this->pod ) ? $this->pod->pod_data : null ) );
2576
		}
2577
2578
		if ( $params_override ) {
2579
			$find_params = array_merge( $find_params, (array) $this->params );
2580
		}
2581
2582
		if ( $params->full ) {
2583
			$find_params['limit'] = - 1;
2584
		}
2585
2586
		$find_params = apply_filters( 'pods_ui_get_params', $find_params, ( is_object( $this->pod ) ? $this->pod->pod : null ), $this );
2587
2588
		/**
2589
		 * Filter Pods::find() parameters to make it more easily extended by plugins and developers.
2590
		 *
2591
		 * @param array  $find_params Parameters used with Pods::find()
2592
		 * @param string $action      Current action
2593
		 * @param PodsUI $this        PodsUI instance
2594
		 *
2595
		 * @since 2.6.8
2596
		 */
2597
		$find_params = apply_filters( 'pods_ui_get_find_params', $find_params, $action, $this );
2598
2599
		// Debug purposes
2600
		if ( 1 == pods_v( 'pods_debug_params', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
2601
			pods_debug( $find_params );
2602
		}
2603
2604
		return $find_params;
2605
	}
2606
2607
	/**
2608
	 * @param null $params
2609
	 *
2610
	 * @return bool
2611
	 * @internal param bool $full Whether to get ALL data or use pagination
2612
	 */
2613
	public function get_data( $params = null ) {
2614
2615
		$action = $this->action;
2616
2617
		$defaults = array(
2618
			'full'    => false,
2619
			'flatten' => true,
2620
			'fields'  => null,
2621
			'type'    => '',
2622
		);
2623
2624
		if ( ! empty( $params ) && is_array( $params ) ) {
2625
			$params = (object) array_merge( $defaults, $params );
2626
		} else {
2627
			$params = (object) $defaults;
2628
		}
2629
2630
		if ( ! in_array( $action, array( 'manage', 'reorder' ) ) ) {
2631
			$action = 'manage';
2632
		}
2633
2634
		$find_params = $this->get_params( $params, $action );
2635
2636
		if ( false !== $this->pod && is_object( $this->pod ) && ( 'Pods' == get_class( $this->pod ) || 'Pod' == get_class( $this->pod ) ) ) {
2637
			$this->pod->find( $find_params );
0 ignored issues
show
The method find does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2638
2639
			if ( ! $params->full ) {
2640
				$data = $this->pod->data();
0 ignored issues
show
The method data does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2641
2642
				$this->data = $data;
2643
2644
				if ( ! empty( $this->data ) ) {
2645
					$this->data_keys = array_keys( $this->data );
2646
				}
2647
2648
				$this->total       = $this->pod->total();
0 ignored issues
show
The method total does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2649
				$this->total_found = $this->pod->total_found();
0 ignored issues
show
The method total_found does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2650
			} else {
2651
				$this->data_full = array();
2652
2653
				$export_params = array(
2654
					'fields'  => $params->fields,
2655
					'flatten' => true,
2656
				);
2657
2658
				if ( in_array( $params->type, array( 'json', 'xml' ) ) ) {
2659
					$export_params['flatten'] = false;
2660
				}
2661
2662
				$export_params = $this->do_hook( 'export_options', $export_params, $params );
2663
2664
				while ( $this->pod->fetch() ) {
0 ignored issues
show
The method fetch does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2665
					$this->data_full[ $this->pod->id() ] = $this->pod->export( $export_params );
0 ignored issues
show
The method id does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
The method export does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2666
				}
2667
2668
				$this->pod->reset();
0 ignored issues
show
The method reset does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2669
2670
				return $this->data_full;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->data_full; (array) is incompatible with the return type documented by PodsUI::get_data of type boolean.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
2671
			}//end if
2672
		} else {
2673
			if ( ! empty( $this->data ) ) {
2674
				return $this->data;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->data; of type boolean|array adds the type array to the return on line 2674 which is incompatible with the return type documented by PodsUI::get_data of type boolean.
Loading history...
2675
			}
2676
2677
			if ( empty( $this->sql['table'] ) ) {
2678
				return $this->data;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->data; of type boolean|array adds the type array to the return on line 2678 which is incompatible with the return type documented by PodsUI::get_data of type boolean.
Loading history...
2679
			}
2680
2681
			$this->pods_data->select( $find_params );
2682
2683
			if ( ! $params->full ) {
2684
				$this->data = $this->pods_data->data;
2685
2686
				if ( ! empty( $this->data ) ) {
2687
					$this->data_keys = array_keys( $this->data );
2688
				}
2689
2690
				$this->total       = $this->pods_data->total();
2691
				$this->total_found = $this->pods_data->total_found();
2692
			} else {
2693
				$this->data_full = $this->pods_data->data;
2694
2695
				if ( ! empty( $this->data_full ) ) {
2696
					$this->data_keys = array_keys( $this->data_full );
2697
				}
2698
2699
				return $this->data_full;
2700
			}
2701
		}//end if
2702
2703
		return $this->data;
2704
	}
2705
2706
	/**
2707
	 * Sort out data alphabetically by a key
2708
	 */
2709
	public function sort_data() {
2710
2711
		// only do this if we have a default orderby
2712
		if ( isset( $this->orderby['default'] ) ) {
2713
			$orderby = $this->orderby['default'];
2714
			foreach ( $this->data as $k => $v ) {
0 ignored issues
show
The expression $this->data of type boolean|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
2715
				$sorter[ $k ] = strtolower( $v[ $orderby ] );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$sorter was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sorter = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2716
			}
2717
			if ( $this->orderby_dir == 'ASC' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
2718
				asort( $sorter );
2719
			} else {
2720
				arsort( $sorter );
2721
			}
2722
			foreach ( $sorter as $key => $val ) {
2723
				$intermediary[] = $this->data[ $key ];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$intermediary was never initialized. Although not strictly required by PHP, it is generally a good practice to add $intermediary = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2724
			}
2725
			if ( isset( $intermediary ) ) {
2726
				$this->data      = $intermediary;
2727
				$this->data_keys = array_keys( $this->data );
2728
			}
2729
		}
2730
	}
2731
2732
	/**
2733
	 * @param int  $counter
2734
	 * @param null $method
2735
	 *
2736
	 * @return array
2737
	 */
2738
	public function get_row( &$counter = 0, $method = null ) {
2739
2740
		if ( ! empty( $this->row ) && 0 < (int) $this->id && 'table' !== $method ) {
2741
			return $this->row;
2742
		}
2743
2744
		if ( is_object( $this->pod ) && ( 'Pods' == get_class( $this->pod ) || 'Pod' == get_class( $this->pod ) ) ) {
2745
			$this->row = $this->pod->fetch();
0 ignored issues
show
The method fetch does only exist in Pods, but not in Pod.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
2746
		} else {
2747
			$this->row = false;
2748
2749
			if ( ! empty( $this->data ) ) {
2750
				if ( empty( $this->data_keys ) || count( $this->data ) != count( $this->data_keys ) ) {
2751
					$this->data_keys = array_keys( $this->data );
2752
				}
2753
2754
				if ( count( $this->data ) == $this->total && isset( $this->data_keys[ $counter ] ) && isset( $this->data[ $this->data_keys[ $counter ] ] ) ) {
2755
					$this->row = $this->data[ $this->data_keys[ $counter ] ];
2756
2757
					$counter ++;
2758
				}
2759
			}
2760
2761
			if ( false === $this->row && 0 < (int) $this->id && ! empty( $this->sql['table'] ) ) {
2762
				$this->pods_data->select(
2763
					array(
2764
						'table' => $this->sql['table'],
2765
						'where' => '`' . pods_sanitize( $this->sql['field_id'] ) . '` = ' . (int) $this->id,
2766
						'limit' => 1,
2767
					)
2768
				);
2769
2770
				$this->row = $this->pods_data->fetch();
2771
			}
2772
		}//end if
2773
2774
		return $this->row;
2775
	}
2776
2777
	/**
2778
	 * @param bool $reorder
2779
	 *
2780
	 * @return mixed|null
2781
	 */
2782
	public function manage( $reorder = false ) {
2783
		if ( false !== $this->callback_action( 'manage', $reorder ) ) {
2784
			return null;
2785
		}
2786
2787
		if ( ! empty( $this->action_bulk ) && ! empty( $this->actions_bulk ) && isset( $this->actions_bulk[ $this->action_bulk ] ) && ! in_array( $this->action_bulk, $this->actions_disabled ) && ( ! empty( $this->bulk ) || 'export' === $this->action_bulk ) ) {
2788
			if ( empty( $_REQUEST[ '_wpnonce' . $this->num ] ) || false === wp_verify_nonce( $_REQUEST[ '_wpnonce' . $this->num ], 'pods-ui-action-bulk' ) ) {
2789
				pods_message( __( 'Invalid bulk request, please try again.', 'pods' ) );
2790
			} elseif ( false !== $this->callback_bulk( $this->action_bulk, $this->bulk ) ) {
2791
				return null;
2792
			} elseif ( 'delete' === $this->action_bulk ) {
2793
				$this->delete_bulk();
2794
2795
				return;
2796
			} elseif ( 'export' === $this->action_bulk ) {
2797
				$this->export_bulk();
2798
2799
				return;
2800
			}
2801
		}
2802
2803
		$this->screen_meta();
2804
2805
		if ( true === $reorder ) {
2806
			wp_enqueue_script( 'jquery-ui-sortable' );}
2807
		?>
2808
	<div class="wrap pods-admin pods-ui">
2809
		<div id="icon-edit-pages" class="icon32"
2810
		<?php
2811
		if ( false !== $this->icon ) {
2812
?>
2813
 style="background-position:0 0;background-size:100%;background-image:url(<?php echo esc_url( $this->icon ); ?>);"<?php } ?>><br /></div>
2814
		<h2>
2815
			<?php
2816
			if ( true === $reorder ) {
2817
				echo wp_kses_post( $this->header['reorder'] );
2818
2819
				if ( ! in_array( 'manage', $this->actions_disabled ) && ! in_array( 'manage', $this->actions_hidden ) && ! $this->restricted( 'manage' ) ) {
2820
					$link = pods_query_arg(
2821
						array(
2822
							'action' . $this->num => 'manage',
2823
							'id' . $this->num     => '',
2824
						), self::$allowed, $this->exclusion()
2825
					);
2826
2827
					if ( ! empty( $this->action_links['manage'] ) ) {
2828
						$link = $this->action_links['manage'];
2829
					}
2830
				?>
2831
				<small>(<a href="<?php echo esc_url( $link ); ?>">&laquo; <?php echo sprintf( __( 'Back to %s', 'pods' ), $this->heading['manage'] ); ?></a>)</small>
2832
				<?php
2833
				}
2834
			} else {
2835
				echo wp_kses_post( $this->header['manage'] );}
2836
2837
			if ( ! in_array( 'add', $this->actions_disabled ) && ! in_array( 'add', $this->actions_hidden ) && ! $this->restricted( 'add' ) ) {
2838
				$link = pods_query_arg(
2839
					array(
2840
						'action' . $this->num => 'add',
2841
						'id' . $this->num     => '',
2842
						'do' . $this->num     => '',
2843
					), self::$allowed, $this->exclusion()
2844
				);
2845
2846
				if ( ! empty( $this->action_links['add'] ) ) {
2847
					$link = $this->action_links['add'];}
2848
				?>
2849
				<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2"><?php echo wp_kses_post( $this->label['add_new'] ); ?></a>
2850
				<?php
2851
			}
2852
			if ( ! in_array( 'reorder', $this->actions_disabled ) && ! in_array( 'reorder', $this->actions_hidden ) && false !== $this->reorder['on'] && ! $this->restricted( 'reorder' ) ) {
2853
				$link = pods_query_arg( array( 'action' . $this->num => 'reorder' ), self::$allowed, $this->exclusion() );
2854
2855
				if ( ! empty( $this->action_links['reorder'] ) ) {
2856
					$link = $this->action_links['reorder'];}
2857
				?>
2858
				<a href="<?php echo esc_url( $link ); ?>" class="add-new-h2"><?php echo wp_kses_post( $this->label['reorder'] ); ?></a>
2859
				<?php
2860
			}
2861
			?>
2862
		</h2>
2863
2864
		<form id="posts-filter" action="" method="get">
2865
			<?php
2866
				$excluded_filters = array(
2867
					'search' . $this->num,
2868
					'pg' . $this->num,
2869
					'action' . $this->num,
2870
					'action_bulk' . $this->num,
2871
					'action_bulk_ids' . $this->num,
2872
					'_wpnonce' . $this->num,
2873
				);
2874
2875
				$filters = $this->filters;
2876
2877
			foreach ( $filters as $k => $filter ) {
2878
				if ( isset( $this->pod->fields[ $filter ] ) ) {
2879
					$filter_field = $this->pod->fields[ $filter ];
2880
				} elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
2881
					$filter_field = $this->fields['manage'][ $filter ];
2882
				} else {
2883
					unset( $filters[ $k ] );
2884
					continue;
2885
				}
2886
2887
				if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
2888
					if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) {
2889
						unset( $filters[ $k ] );
2890
						continue;
2891
					}
2892
				} elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) {
2893
					unset( $filters[ $k ] );
2894
					continue;
2895
				}
2896
2897
				$excluded_filters[] = 'filter_' . $filter . '_start';
2898
				$excluded_filters[] = 'filter_' . $filter . '_end';
2899
				$excluded_filters[] = 'filter_' . $filter;
2900
			}//end foreach
2901
2902
				$get = $_GET;
2903
2904
			foreach ( $get as $k => $v ) {
2905
				if ( is_array( $v ) || in_array( $k, $excluded_filters ) || strlen( $v ) < 1 ) {
2906
					continue;}
2907
			?>
2908
			<input type="hidden" name="<?php echo esc_attr( $k ); ?>" value="<?php echo esc_attr( $v ); ?>" />
2909
			<?php
2910
			}
2911
2912
			if ( false !== $this->callback( 'header', $reorder ) ) {
2913
				return null;
2914
			}
2915
2916
			if ( false === $this->data ) {
2917
				$this->get_data();} elseif ( $this->sortable ) {
2918
				// we have the data already as an array
2919
				$this->sort_data();}
2920
2921
				if ( ! in_array( 'export', $this->actions_disabled ) && 'export' === $this->action ) {
2922
					$this->export();}
2923
2924
				if ( ( ! empty( $this->data ) || false !== $this->search || ( $this->filters_enhanced && ! empty( $this->views ) ) ) && ( ( $this->filters_enhanced && ! empty( $this->views ) ) || false !== $this->searchable ) ) {
2925
					if ( $this->filters_enhanced ) {
2926
						$this->filters();} else {
2927
										?>
2928
										<p class="search-box" align="right">
2929
										<?php
2930
										$excluded_filters = array( 'search' . $this->num, 'pg' . $this->num );
2931
2932
										foreach ( $this->filters as $filter ) {
2933
											$excluded_filters[] = 'filter_' . $filter . '_start';
2934
											$excluded_filters[] = 'filter_' . $filter . '_end';
2935
											$excluded_filters[] = 'filter_' . $filter;
2936
										}
2937
2938
										$this->hidden_vars( $excluded_filters );
2939
2940
										foreach ( $this->filters as $filter ) {
2941
											if ( isset( $this->pod->fields[ $filter ] ) ) {
2942
												$filter_field = $this->pod->fields[ $filter ];
2943
											} elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
2944
												$filter_field = $this->fields['manage'][ $filter ];
2945
											} else {
2946
												continue;
2947
											}
2948
2949
											if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
2950
												$start = pods_var_raw( 'filter_' . $filter . '_start', 'get', pods_var_raw( 'filter_default', $filter_field, '', null, true ), null, true );
2951
												$end   = pods_var_raw( 'filter_' . $filter . '_end', 'get', pods_var_raw( 'filter_ongoing_default', $filter_field, '', null, true ), null, true );
2952
2953
												// override default value
2954
												$filter_field['options']['default_value']                          = '';
2955
												$filter_field['options'][ $filter_field['type'] . '_allow_empty' ] = 1;
2956
2957
												if ( ! empty( $start ) && ! in_array( $start, array( '0000-00-00', '0000-00-00 00:00:00', '00:00:00' ) ) ) {
2958
													$start = PodsForm::field_method( $filter_field['type'], 'convert_date', $start, 'n/j/Y' );}
2959
2960
												if ( ! empty( $end ) && ! in_array( $end, array( '0000-00-00', '0000-00-00 00:00:00', '00:00:00' ) ) ) {
2961
													$end = PodsForm::field_method( $filter_field['type'], 'convert_date', $end, 'n/j/Y' );}
2962
										?>
2963
											<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>_start">
2964
							<?php echo esc_html( $filter_field['label'] ); ?>
2965
						</label>
2966
						<?php echo PodsForm::field( 'filter_' . $filter . '_start', $start, $filter_field['type'], $filter_field ); ?>
2967
2968
						<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>_end">
2969
							to
2970
						</label>
2971
					<?php
2972
							echo PodsForm::field( 'filter_' . $filter . '_end', $end, $filter_field['type'], $filter_field );
2973
											} elseif ( 'pick' === $filter_field['type'] ) {
2974
												$value = pods_var_raw( 'filter_' . $filter );
2975
2976
												if ( strlen( $value ) < 1 ) {
2977
													$value = pods_var_raw( 'filter_default', $filter_field );}
2978
2979
												// override default value
2980
												$filter_field['options']['default_value'] = '';
2981
2982
												$filter_field['options']['pick_format_type']   = 'single';
2983
												$filter_field['options']['pick_format_single'] = 'dropdown';
2984
2985
												$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
2986
												$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
2987
2988
												$options = array_merge( $filter_field, $filter_field['options'] );
2989
										?>
2990
											<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
2991
							<?php echo esc_html( $filter_field['label'] ); ?>
2992
						</label>
2993
					<?php
2994
							echo PodsForm::field( 'filter_' . $filter, $value, 'pick', $options );
2995
											} elseif ( 'boolean' === $filter_field['type'] ) {
2996
												$value = pods_var_raw( 'filter_' . $filter, 'get', '' );
2997
2998
												if ( strlen( $value ) < 1 ) {
2999
													$value = pods_var_raw( 'filter_default', $filter_field );}
3000
3001
												// override default value
3002
												$filter_field['options']['default_value'] = '';
3003
3004
												$filter_field['options']['pick_format_type']   = 'single';
3005
												$filter_field['options']['pick_format_single'] = 'dropdown';
3006
3007
												$filter_field['options']['pick_object'] = 'custom-simple';
3008
												$filter_field['options']['pick_custom'] = array(
3009
													'1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3010
													'0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
0 ignored issues
show
Detected usage of 0, possible slow query.
Loading history...
3011
												);
3012
3013
												$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3014
												$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3015
3016
												$options = array_merge( $filter_field, $filter_field['options'] );
3017
										?>
3018
											<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3019
							<?php echo esc_html( $filter_field['label'] ); ?>
3020
						</label>
3021
					<?php
3022
							echo PodsForm::field( 'filter_' . $filter, $value, 'pick', $options );
3023
											} else {
3024
												$value = pods_var_raw( 'filter_' . $filter );
3025
3026
												if ( strlen( $value ) < 1 ) {
3027
													$value = pods_var_raw( 'filter_default', $filter_field );}
3028
3029
												// override default value
3030
												$filter_field['options']['default_value'] = '';
3031
3032
												$options                 = array();
3033
												$options['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3034
												$options['input_helper'] = pods_var_raw( 'ui_input_helper', $options, $options['input_helper'], null, true );
3035
										?>
3036
											<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3037
							<?php echo esc_html( $filter_field['label'] ); ?>
3038
						</label>
3039
					<?php
3040
							echo PodsForm::field( 'filter_' . $filter, $value, 'text', $options );
3041
											}//end if
3042
										}//end foreach
3043
3044
										if ( false !== $this->do_hook( 'filters_show_search', true ) ) {
3045
										?>
3046
											&nbsp;&nbsp; <label<?php echo ( empty( $this->filters ) ) ? ' class="screen-reader-text"' : ''; ?> for="page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
3047
						<?php echo PodsForm::field( 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ) ) ); ?>
3048
					<?php
3049
										} else {
3050
											echo PodsForm::field( 'search' . $this->num, '', 'hidden' );
3051
										}
3052
										?>
3053
										<?php echo PodsForm::submit_button( $this->header['search'], 'button', false, false, array( 'id' => 'search' . $this->num . '-submit' ) ); ?>
3054
					<?php
3055
					if ( 0 < strlen( $this->search ) ) {
3056
						$clear_filters = array(
3057
							'search' . $this->num => false,
3058
						);
3059
3060
						foreach ( $this->filters as $filter ) {
3061
							$clear_filters[ 'filter_' . $filter . '_start' ] = false;
3062
							$clear_filters[ 'filter_' . $filter . '_end' ]   = false;
3063
							$clear_filters[ 'filter_' . $filter ]            = false;
3064
						}
3065
						?>
3066
						<br class="clear" />
3067
						<small>[<a href="<?php echo esc_url( pods_query_arg( $clear_filters, array( 'orderby' . $this->num, 'orderby_dir' . $this->num, 'limit' . $this->num, 'page' ), $this->exclusion() ) ); ?>"><?php _e( 'Reset Filters', 'pods' ); ?></a>]</small>
3068
						<br class="clear" />
3069
						<?php
3070
					}
3071
					?>
3072
					</p>
3073
					<?php
3074
						}//end if
3075
				} else {
3076
					?>
3077
					<br class="clear" />
3078
					<?php
3079
				}//end if
3080
3081
				if ( ! empty( $this->data ) && ( false !== $this->pagination_total || false !== $this->pagination || true === $reorder ) || ( ! in_array( 'export', $this->actions_disabled ) && ! in_array( 'export', $this->actions_hidden ) ) || ! empty( $this->actions_disabled ) ) {
3082
					?>
3083
					<div class="tablenav">
3084
					<?php
3085
					if ( ! empty( $this->data ) && ! empty( $this->actions_bulk ) ) {
3086
				?>
3087
					<div class="alignleft actions">
3088
						<?php wp_nonce_field( 'pods-ui-action-bulk', '_wpnonce' . $this->num, false ); ?>
3089
3090
						<select name="action_bulk<?php echo esc_attr( $this->num ); ?>">
3091
							<option value="-1" selected="selected"><?php _e( 'Bulk Actions', 'pods' ); ?></option>
3092
3093
							<?php
3094
							foreach ( $this->actions_bulk as $action => $action_data ) {
3095
								if ( in_array( $action, $this->actions_hidden ) || in_array( $action, $this->actions_hidden ) ) {
3096
									continue;}
3097
3098
								if ( ! isset( $action_data['label'] ) ) {
3099
									$action_data['label'] = ucwords( str_replace( '_', ' ', $action ) );}
3100
							?>
3101
							<option value="<?php echo esc_attr( $action ); ?>"><?php echo esc_html( $action_data['label'] ); ?></option>
3102
							<?php
3103
							}
3104
							?>
3105
						</select>
3106
3107
						<input type="submit" id="doaction_bulk<?php echo esc_attr( $this->num ); ?>" class="button-secondary action" value="<?php esc_attr_e( 'Apply', 'pods' ); ?>">
3108
					</div>
3109
				<?php
3110
					}//end if
3111
3112
					if ( true !== $reorder && ( false !== $this->pagination_total || false !== $this->pagination ) ) {
3113
						?>
3114
						<div class="tablenav-pages<?php echo esc_attr( ( $this->limit < $this->total_found || 1 < $this->page ) ? '' : ' one-page' ); ?>">
3115
							<?php $this->pagination( 1 ); ?>
3116
						</div>
3117
						<?php
3118
					}
3119
3120
					if ( true === $reorder ) {
3121
						$link = pods_query_arg(
3122
							array(
3123
								'action' . $this->num => 'manage',
3124
								'id' . $this->num     => '',
3125
							), self::$allowed, $this->exclusion()
3126
						);
3127
3128
						if ( ! empty( $this->action_links['manage'] ) ) {
3129
							$link = $this->action_links['manage'];
3130
						}
3131
						?>
3132
						<input type="button" value="<?php esc_attr_e( 'Update Order', 'pods' ); ?>" class="button" onclick="jQuery('form.admin_ui_reorder_form').submit();" />
3133
						<input type="button" value="<?php esc_attr_e( 'Cancel', 'pods' ); ?>" class="button" onclick="document.location='<?php echo esc_js( $link ); ?>';" />
3134
					</form>
3135
				<?php
3136
					} elseif ( ! in_array( 'export', $this->actions_disabled ) && ! in_array( 'export', $this->actions_hidden ) ) {
3137
						?>
3138
						<div class="alignleft actions">
3139
							<input type="button" value="<?php echo esc_attr( sprintf( __( 'Export all %s', 'pods' ), $this->items ) ); ?>" class="button" onclick="document.location=';
3140
																	<?php
3141
																	echo pods_slash(
3142
																		pods_query_arg(
3143
																			array(
3144
																				'action_bulk' . $this->num => 'export',
3145
																				'_wpnonce' => wp_create_nonce( 'pods-ui-action-bulk' ),
3146
																			), self::$allowed, $this->exclusion()
3147
																		)
3148
																	);
3149
							?>
3150
							';" />
3151
						</div>
3152
						<?php
3153
					}//end if
3154
					?>
3155
					<br class="clear" />
3156
					</div>
3157
					<?php
3158
				} else {
3159
					?>
3160
					<br class="clear" />
3161
					<?php
3162
				}//end if
3163
			?>
3164
			<div class="clear"></div>
3165
			<?php
3166
			if ( empty( $this->data ) && false !== $this->default_none && false === $this->search ) {
3167
				?>
3168
				<p><?php _e( 'Please use the search filter(s) above to display data', 'pods' ); ?>
3169
								<?php
3170
								if ( $this->export ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->export of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3171
				?>
3172
				, <?php _e( 'or click on an Export to download a full copy of the data', 'pods' ); ?><?php } ?>.</p>
3173
				<?php
3174
			} else {
3175
				$this->table( $reorder );}
3176
			if ( ! empty( $this->data ) ) {
3177
				if ( true !== $reorder && ( false !== $this->pagination_total || false !== $this->pagination ) ) {
3178
					?>
3179
					<div class="tablenav">
3180
						<div class="tablenav-pages<?php echo esc_attr( ( $this->limit < $this->total_found || 1 < $this->page ) ? '' : ' one-page' ); ?>">
3181
							<?php $this->pagination( 0 ); ?>
3182
							<br class="clear" />
3183
						</div>
3184
					</div>
3185
					<?php
3186
				}
3187
			}
3188
3189
			?>
3190
		</form>
3191
	</div>
3192
	<?php
3193
	if ( $this->filters_enhanced ) {
3194
		$this->filters_popup();}
3195
	}
3196
3197
	public function filters() {
3198
3199
		include_once ABSPATH . 'wp-admin/includes/template.php';
3200
3201
		wp_enqueue_script( 'thickbox' );
3202
		wp_enqueue_style( 'thickbox' );
3203
		wp_enqueue_style( 'pods-styles' );
3204
3205
		$filters = $this->filters;
3206
3207
		foreach ( $filters as $k => $filter ) {
3208
			if ( isset( $this->pod->fields[ $filter ] ) ) {
3209
				$filter_field = $this->pod->fields[ $filter ];
3210
			} elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3211
				$filter_field = $this->fields['manage'][ $filter ];
3212
			} else {
3213
				continue;
3214
			}
3215
3216
			if ( isset( $filter_field ) && in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3217
				if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) {
3218
					unset( $filters[ $k ] );
3219
				}
3220
			} elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) {
3221
				unset( $filters[ $k ] );
3222
			}
3223
		}
3224
3225
		$filtered = false;
3226
3227
		if ( ! empty( $filters ) ) {
3228
			$filtered = true;
3229
		}
3230
		?>
3231
		<div class="pods-ui-filter-bar">
3232
			<div class="pods-ui-filter-bar-primary">
3233
				<?php
3234
				if ( ! empty( $this->views ) ) {
3235
					?>
3236
					<ul class="subsubsub">
3237
						<li class="pods-ui-filter-view-label">
3238
							<strong><?php echo wp_kses_post( $this->heading['views'] ); ?></strong></li>
3239
3240
						<?php
3241
						foreach ( $this->views as $view => $label ) {
3242
							if ( false === strpos( $label, '<a' ) ) {
3243
								$link = pods_query_arg(
3244
									array(
3245
										'view' . $this->num => $view,
3246
										'pg' . $this->num => '',
3247
									), self::$allowed, $this->exclusion()
3248
								);
3249
3250
								if ( $this->view == $view ) {
3251
									$label = '<a href="' . esc_url( $link ) . '" class="current">' . esc_html( $label ) . '</a>';
3252
								} else {
3253
									$label = '<a href="' . esc_url( $link ) . '">' . esc_html( $label ) . '</a>';
3254
								}
3255
							} else {
3256
								$label = wp_kses_post( $label );
3257
							}
3258
							?>
3259
							<li class="<?php echo esc_attr( $view ); ?>">
3260
								<?php
3261
								/* Escaped above to support links */
3262
								echo $label;
3263
								?>
3264
							</li>
3265
							<?php
3266
						}//end foreach
3267
						?>
3268
					</ul>
3269
					<?php
3270
				}//end if
3271
				?>
3272
3273
				<?php
3274
				if ( false !== $this->search && false !== $this->searchable ) {
3275
					?>
3276
					<p class="search-box">
3277
						<?php
3278
						if ( $filtered || '' != pods_var_raw( 'search' . $this->num, 'get', '', null, true ) ) {
3279
							$clear_filters = array(
3280
								'search' . $this->num => false,
3281
							);
3282
3283
							foreach ( $this->filters as $filter ) {
3284
								$clear_filters[ 'filter_' . $filter . '_start' ] = false;
3285
								$clear_filters[ 'filter_' . $filter . '_end' ]   = false;
3286
								$clear_filters[ 'filter_' . $filter ]            = false;
3287
							}
3288
							?>
3289
							<a href="
3290
							<?php
3291
							echo esc_url(
3292
								pods_query_arg(
3293
									$clear_filters, array(
3294
										'orderby' . $this->num,
3295
										'orderby_dir' . $this->num,
3296
										'limit' . $this->num,
3297
										'page',
3298
									), $this->exclusion()
3299
								)
3300
							);
3301
							?>
3302
							" class="pods-ui-filter-reset">[<?php _e( 'Reset', 'pods' ); ?>]</a>
3303
							<?php
3304
						}//end if
3305
3306
						if ( false !== $this->do_hook( 'filters_show_search', true ) ) {
3307
							?>
3308
							&nbsp;&nbsp;
3309
							<label class="screen-reader-text" for="page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
3310
							<?php echo PodsForm::field( 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ) ) ); ?>
3311
							<?php
3312
						} else {
3313
							echo PodsForm::field( 'search' . $this->num, '', 'hidden' );
3314
						}
3315
						?>
3316
3317
						<?php echo PodsForm::submit_button( $this->header['search'], 'button', false, false, array( 'id' => 'search' . $this->num . '-submit' ) ); ?>
3318
					</p>
3319
					<?php
3320
				}//end if
3321
				?>
3322
			</div>
3323
3324
			<?php
3325
			if ( ! empty( $this->filters ) ) {
3326
				?>
3327
				<div class="pods-ui-filter-bar-secondary">
3328
					<ul class="subsubsub">
3329
						<?php
3330
						if ( ! $filtered ) {
3331
							?>
3332
							<li class="pods-ui-filter-bar-add-filter">
3333
								<a href="#TB_inline?width=640&inlineId=pods-ui-posts-filter-popup" class="thickbox" title="<?php esc_attr_e( 'Advanced Filters', 'pods' ); ?>">
3334
									<?php _e( 'Advanced Filters', 'pods' ); ?>
3335
								</a>
3336
							</li>
3337
							<?php
3338
						} else {
3339
							?>
3340
							<li class="pods-ui-filter-bar-add-filter">
3341
								<a href="#TB_inline?width=640&inlineId=pods-ui-posts-filter-popup" class="thickbox" title="<?php esc_attr_e( 'Advanced Filters', 'pods' ); ?>"> + <?php _e( 'Add Filter', 'pods' ); ?>
3342
								</a>
3343
							</li>
3344
							<?php
3345
						}
3346
3347
						foreach ( $filters as $filter ) {
3348
							$value = pods_var_raw( 'filter_' . $filter );
3349
3350
							if ( isset( $this->pod->fields[ $filter ] ) ) {
3351
								$filter_field = $this->pod->fields[ $filter ];
3352
							} elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3353
								$filter_field = $this->fields['manage'][ $filter ];
3354
							} else {
3355
								continue;
3356
							}
3357
3358
							$data_filter = 'filter_' . $filter;
3359
3360
							$start = $end = $value_label = '';
3361
3362
							if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3363
								$start = pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true );
3364
								$end   = pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true );
3365
3366
								if ( ! empty( $start ) && ! in_array(
3367
									$start, array(
3368
										'0000-00-00',
3369
										'0000-00-00 00:00:00',
3370
										'00:00:00',
3371
									)
3372
								) ) {
3373
									$start = PodsForm::field_method( $filter_field['type'], 'convert_date', $start, 'n/j/Y' );
3374
								}
3375
3376
								if ( ! empty( $end ) && ! in_array(
3377
									$end, array(
3378
										'0000-00-00',
3379
										'0000-00-00 00:00:00',
3380
										'00:00:00',
3381
									)
3382
								) ) {
3383
									$end = PodsForm::field_method( $filter_field['type'], 'convert_date', $end, 'n/j/Y' );
3384
								}
3385
3386
								$value = trim( $start . ' - ' . $end, ' -' );
3387
3388
								$data_filter = 'filter_' . $filter . '_start';
3389
							} elseif ( 'pick' === $filter_field['type'] ) {
3390
								$value_label = trim( PodsForm::field_method( 'pick', 'value_to_label', $filter, $value, $filter_field, $this->pod->pod_data, null ) );
3391
							} elseif ( 'boolean' === $filter_field['type'] ) {
3392
								$yesno_options = array(
3393
									'1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3394
									'0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
0 ignored issues
show
Detected usage of 0, possible slow query.
Loading history...
3395
								);
3396
3397
								if ( isset( $yesno_options[ (string) $value ] ) ) {
3398
									$value_label = $yesno_options[ (string) $value ];
3399
								}
3400
							}//end if
3401
3402
							if ( strlen( $value_label ) < 1 ) {
3403
								$value_label = $value;
3404
							}
3405
							?>
3406
							<li class="pods-ui-filter-bar-filter" data-filter="<?php echo esc_attr( $data_filter ); ?>">
3407
								<a href="#TB_inline?width=640&inlineId=pods-ui-posts-filter-popup" class="thickbox" title="<?php esc_attr_e( 'Advanced Filters', 'pods' ); ?>">
3408
									<strong><?php echo esc_html( $filter_field['label'] ); ?>:</strong>
3409
									<?php echo esc_html( $value_label ); ?>
3410
								</a>
3411
3412
								<a href="#remove-filter" class="remove-filter" title="<?php esc_attr_e( 'Remove Filter', 'pods' ); ?>">x</a>
3413
3414
								<?php
3415
								if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3416
									echo PodsForm::field( 'filter_' . $filter . '_start', $start, 'hidden' );
3417
									echo PodsForm::field( 'filter_' . $filter . '_end', $end, 'hidden' );
3418
								} else {
3419
									echo PodsForm::field( $data_filter, $value, 'hidden' );
3420
								}
3421
								?>
3422
							</li>
3423
							<?php
3424
						}//end foreach
3425
						?>
3426
					</ul>
3427
				</div>
3428
				<?php
3429
			}//end if
3430
			?>
3431
		</div>
3432
3433
		<script type="text/javascript">
3434
			jQuery( function () {
3435
				jQuery( '.pods-ui-filter-bar-secondary' ).on( 'click', '.remove-filter', function ( e ) {
3436
					jQuery( '.pods-ui-filter-popup #' + jQuery( this ).parent().data( 'filter' ) ).remove();
3437
3438
					jQuery( this ).parent().find( 'input' ).each( function () {
3439
						jQuery( this ).remove();
3440
					} );
3441
3442
					jQuery( 'form#posts-filter [name="pg<?php echo esc_attr( $this->num ); ?>"]' ).prop( 'disabled', true );
3443
					jQuery( 'form#posts-filter [name="action<?php echo esc_attr( $this->num ); ?>"]' ).prop( 'disabled', true );
3444
					jQuery( 'form#posts-filter [name="action_bulk<?php echo esc_attr( $this->num ); ?>"]' ).prop( 'disabled', true );
3445
					jQuery( 'form#posts-filter [name="_wpnonce<?php echo esc_attr( $this->num ); ?>"]' ).prop( 'disabled', true );
3446
3447
					jQuery( 'form#posts-filter' ).submit();
3448
3449
					e.preventDefault();
3450
				} );
3451
			} );
3452
		</script>
3453
		<?php
3454
	}
3455
3456
	public function filters_popup() {
3457
3458
		$filters = $this->filters;
3459
		?>
3460
		<div id="pods-ui-posts-filter-popup" class="pods-hidden">
3461
			<form action="" method="get" class="pods-ui-posts-filter-popup">
3462
				<h2><?php _e( 'Advanced Filters', 'pods' ); ?></h2>
3463
3464
				<div class="pods-ui-posts-filters">
3465
					<?php
3466
					$excluded_filters = array(
3467
						'search' . $this->num,
3468
						'pg' . $this->num,
3469
						'action' . $this->num,
3470
						'action_bulk' . $this->num,
3471
						'action_bulk_ids' . $this->num,
3472
						'_wpnonce' . $this->num,
3473
					);
3474
3475
					foreach ( $filters as $filter ) {
3476
						$excluded_filters[] = 'filters_relation';
3477
						$excluded_filters[] = 'filters_compare_' . $filter;
3478
						$excluded_filters[] = 'filter_' . $filter . '_start';
3479
						$excluded_filters[] = 'filter_' . $filter . '_end';
3480
						$excluded_filters[] = 'filter_' . $filter;
3481
					}
3482
3483
					$get = $_GET;
3484
3485
					foreach ( $get as $k => $v ) {
3486
						if ( in_array( $k, $excluded_filters ) || strlen( $v ) < 1 ) {
3487
							continue;
3488
						}
3489
						?>
3490
						<input type="hidden" name="<?php echo esc_attr( $k ); ?>" value="<?php echo esc_attr( $v ); ?>" />
3491
						<?php
3492
					}
3493
3494
					$zebra = true;
3495
3496
					foreach ( $filters as $filter ) {
3497
						if ( empty( $filter ) ) {
3498
							continue;
3499
						}
3500
3501
						if ( isset( $this->pod->fields[ $filter ] ) ) {
3502
							$filter_field = $this->pod->fields[ $filter ];
3503
						} elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3504
							$filter_field = $this->fields['manage'][ $filter ];
3505
						} else {
3506
							continue;
3507
						}
3508
						?>
3509
						<p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-<?php echo esc_attr( $filter . ( $zebra ? ' clear' : '' ) ); ?>">
3510
							<?php
3511
							if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3512
								$start = pods_var_raw( 'filter_' . $filter . '_start', 'get', pods_var_raw( 'filter_default', $filter_field, '', null, true ), null, true );
3513
								$end   = pods_var_raw( 'filter_' . $filter . '_end', 'get', pods_var_raw( 'filter_ongoing_default', $filter_field, '', null, true ), null, true );
3514
3515
								// override default value
3516
								$filter_field['options']['default_value']                          = '';
3517
								$filter_field['options'][ $filter_field['type'] . '_allow_empty' ] = 1;
3518
3519
								if ( ! empty( $start ) && ! in_array(
3520
									$start, array(
3521
										'0000-00-00',
3522
										'0000-00-00 00:00:00',
3523
										'00:00:00',
3524
									)
3525
								) ) {
3526
									$start = PodsForm::field_method( $filter_field['type'], 'convert_date', $start, 'n/j/Y' );
3527
								}
3528
3529
								if ( ! empty( $end ) && ! in_array(
3530
									$end, array(
3531
										'0000-00-00',
3532
										'0000-00-00 00:00:00',
3533
										'00:00:00',
3534
									)
3535
								) ) {
3536
									$end = PodsForm::field_method( $filter_field['type'], 'convert_date', $end, 'n/j/Y' );
3537
								}
3538
								?>
3539
								<span class="pods-ui-posts-filter-toggle toggle-on<?php echo esc_attr( ( empty( $start ) && empty( $end ) ) ? '' : ' pods-hidden' ); ?>">+</span>
3540
								<span class="pods-ui-posts-filter-toggle toggle-off<?php echo esc_attr( ( empty( $start ) && empty( $end ) ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3541
3542
								<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>_start">
3543
									<?php echo esc_html( $filter_field['label'] ); ?>
3544
								</label>
3545
3546
								<span class="pods-ui-posts-filter<?php echo esc_attr( ( empty( $start ) && empty( $end ) ) ? ' pods-hidden' : '' ); ?>">
3547
								<?php echo PodsForm::field( 'filter_' . $filter . '_start', $start, $filter_field['type'], $filter_field ); ?>
3548
3549
									<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>_end">to</label>
3550
									<?php echo PodsForm::field( 'filter_' . $filter . '_end', $end, $filter_field['type'], $filter_field ); ?>
3551
							</span>
3552
								<?php
3553
							} elseif ( 'pick' === $filter_field['type'] ) {
3554
								$value = pods_var_raw( 'filter_' . $filter, 'get', '' );
3555
3556
								if ( strlen( $value ) < 1 ) {
3557
									$value = pods_var_raw( 'filter_default', $filter_field );
3558
								}
3559
3560
								// override default value
3561
								$filter_field['options']['default_value'] = '';
3562
3563
								$filter_field['options']['pick_format_type']   = 'single';
3564
								$filter_field['options']['pick_format_single'] = 'dropdown';
3565
3566
								$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3567
								$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3568
3569
								$options = array_merge( $filter_field, $filter_field['options'] );
3570
								?>
3571
								<span class="pods-ui-posts-filter-toggle toggle-on<?php echo esc_attr( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3572
								<span class="pods-ui-posts-filter-toggle toggle-off<?php echo esc_attr( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3573
3574
								<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3575
									<?php echo esc_html( $filter_field['label'] ); ?>
3576
								</label>
3577
3578
								<span class="pods-ui-posts-filter<?php echo esc_attr( strlen( $value ) < 1 ? ' pods-hidden' : '' ); ?>">
3579
								<?php echo PodsForm::field( 'filter_' . $filter, $value, 'pick', $options ); ?>
3580
							</span>
3581
								<?php
3582
							} elseif ( 'boolean' === $filter_field['type'] ) {
3583
								$value = pods_var_raw( 'filter_' . $filter, 'get', '' );
3584
3585
								if ( strlen( $value ) < 1 ) {
3586
									$value = pods_var_raw( 'filter_default', $filter_field );
3587
								}
3588
3589
								// override default value
3590
								$filter_field['options']['default_value'] = '';
3591
3592
								$filter_field['options']['pick_format_type']   = 'single';
3593
								$filter_field['options']['pick_format_single'] = 'dropdown';
3594
3595
								$filter_field['options']['pick_object'] = 'custom-simple';
3596
								$filter_field['options']['pick_custom'] = array(
3597
									'1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3598
									'0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
0 ignored issues
show
Detected usage of 0, possible slow query.
Loading history...
3599
								);
3600
3601
								$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3602
								$filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3603
3604
								$options = array_merge( $filter_field, $filter_field['options'] );
3605
								?>
3606
								<span class="pods-ui-posts-filter-toggle toggle-on<?php echo esc_attr( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3607
								<span class="pods-ui-posts-filter-toggle toggle-off<?php echo esc_attr( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3608
3609
								<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3610
									<?php echo esc_html( $filter_field['label'] ); ?>
3611
								</label>
3612
3613
								<span class="pods-ui-posts-filter<?php echo esc_attr( strlen( $value ) < 1 ? ' pods-hidden' : '' ); ?>">
3614
								<?php echo PodsForm::field( 'filter_' . $filter, $value, 'pick', $options ); ?>
3615
							</span>
3616
								<?php
3617
							} else {
3618
								$value = pods_var_raw( 'filter_' . $filter );
3619
3620
								if ( strlen( $value ) < 1 ) {
3621
									$value = pods_var_raw( 'filter_default', $filter_field );
3622
								}
3623
3624
								$options = array(
3625
									'input_helper' => pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true ),
3626
								);
3627
3628
								if ( empty( $options['input_helper'] ) && isset( $filter_field['options'] ) && isset( $filter_field['options']['input_helper'] ) ) {
3629
									$options['input_helper'] = $filter_field['options']['input_helper'];
3630
								}
3631
								?>
3632
								<span class="pods-ui-posts-filter-toggle toggle-on<?php echo esc_attr( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3633
								<span class="pods-ui-posts-filter-toggle toggle-off<?php echo esc_attr( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3634
3635
								<label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3636
									<?php echo esc_html( $filter_field['label'] ); ?>
3637
								</label>
3638
3639
								<span class="pods-ui-posts-filter<?php echo esc_attr( empty( $value ) ? ' pods-hidden' : '' ); ?>">
3640
								<?php echo PodsForm::field( 'filter_' . $filter, $value, 'text', $options ); ?>
3641
							</span>
3642
								<?php
3643
							}//end if
3644
							?>
3645
						</p>
3646
						<?php
3647
						$zebra = empty( $zebra );
3648
					}//end foreach
3649
					?>
3650
3651
					<p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-search<?php echo esc_attr( $zebra ? ' clear' : '' ); ?>">
3652
						<label for="pods-form-ui-search<?php echo esc_attr( $this->num ); ?>"><?php _e( 'Search Text', 'pods' ); ?></label>
3653
						<?php echo PodsForm::field( 'search' . $this->num, pods_var_raw( 'search' . $this->num ), 'text' ); ?>
3654
					</p>
3655
3656
					<?php $zebra = empty( $zebra ); ?>
3657
				</div>
3658
3659
				<p class="submit<?php echo esc_attr( $zebra ? ' clear' : '' ); ?>">
3660
					<input type="submit" value="<?php echo esc_attr( $this->header['search'] ); ?>" class="button button-primary" />
3661
				</p>
3662
			</form>
3663
		</div>
3664
3665
		<script type="text/javascript">
3666
			jQuery( function () {
3667
				jQuery( document ).on( 'click', '.pods-ui-posts-filter-toggle.toggle-on', function ( e ) {
3668
					jQuery( this ).parent().find( '.pods-ui-posts-filter' ).removeClass( 'pods-hidden' );
3669
3670
					jQuery( this ).hide();
3671
					jQuery( this ).parent().find( '.toggle-off' ).show();
3672
				} );
3673
3674
				jQuery( document ).on( 'click', '.pods-ui-posts-filter-toggle.toggle-off', function ( e ) {
3675
					jQuery( this ).parent().find( '.pods-ui-posts-filter' ).addClass( 'pods-hidden' );
3676
					jQuery( this ).parent().find( 'select, input' ).val( '' );
3677
3678
					jQuery( this ).hide();
3679
					jQuery( this ).parent().find( '.toggle-on' ).show();
3680
				} );
3681
3682
				jQuery( document ).on( 'click', '.pods-ui-posts-filter-toggled label', function ( e ) {
3683
					if ( jQuery( this ).parent().find( '.pods-ui-posts-filter' ).hasClass( 'pods-hidden' ) ) {
3684
						jQuery( this ).parent().find( '.pods-ui-posts-filter' ).removeClass( 'pods-hidden' );
3685
3686
						jQuery( this ).parent().find( '.toggle-on' ).hide();
3687
						jQuery( this ).parent().find( '.toggle-off' ).show();
3688
					}
3689
					else {
3690
						jQuery( this ).parent().find( '.pods-ui-posts-filter' ).addClass( 'pods-hidden' );
3691
						jQuery( this ).parent().find( 'select, input' ).val( '' );
3692
3693
						jQuery( this ).parent().find( '.toggle-on' ).show();
3694
						jQuery( this ).parent().find( '.toggle-off' ).hide();
3695
					}
3696
				} );
3697
			} );
3698
		</script>
3699
		<?php
3700
	}
3701
3702
	/**
3703
	 * @param bool $reorder
3704
	 *
3705
	 * @return bool|mixed
0 ignored issues
show
Consider making the return type a bit more specific; maybe use null|boolean.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
3706
	 */
3707
	public function table( $reorder = false ) {
3708
3709
		if ( false !== $this->callback( 'table', $reorder ) ) {
3710
			return null;
3711
		}
3712
3713
		if ( empty( $this->data ) ) {
3714
			?>
3715
			<p><?php echo pods_v( 'label_no_items_found', $this->label, sprintf( __( 'No %s found', 'pods' ), $this->items ) ); ?></p>
3716
			<?php
3717
			return false;
3718
		}
3719
		if ( true === $reorder && ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) {
3720
3721
			?>
3722
			<style type="text/css">
3723
			table.widefat.fixed tbody.reorderable tr {
3724
				height: 50px;
3725
			}
3726
3727
			.dragme {
3728
				background:          url(<?php echo esc_url( PODS_URL ); ?>/ui/images/handle.gif) no-repeat;
3729
				background-position: 8px 8px;
3730
				cursor:              pointer;
3731
			}
3732
3733
			.dragme strong {
3734
				margin-left: 30px;
3735
			}
3736
			</style>
3737
			<form action="
3738
			<?php
3739
			echo esc_url(
3740
				pods_query_arg(
3741
					array(
3742
						'action' . $this->num => 'reorder',
3743
						'do' . $this->num     => 'save',
3744
						'page'                => pods_var_raw( 'page' ),
3745
					), self::$allowed, $this->exclusion()
3746
				)
3747
			);
3748
		?>
3749
		" method="post" class="admin_ui_reorder_form">
3750
					<?php
3751
		}//end if
3752
			$table_fields = $this->fields['manage'];
3753
		if ( true === $reorder && ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) {
3754
			$table_fields = $this->fields['reorder'];
3755
		}
3756
		if ( false === $table_fields || empty( $table_fields ) ) {
3757
			return $this->error( __( '<strong>Error:</strong> Invalid Configuration - Missing "fields" definition.', 'pods' ) );
3758
		}
3759
			?>
3760
			<table class="widefat page fixed wp-list-table" cellspacing="0"<?php echo ( 1 == $reorder && $this->reorder ) ? ' id="admin_ui_reorder"' : ''; ?>>
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->reorder of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
3761
				<thead>
3762
				<tr>
3763
					<?php
3764
					if ( ! empty( $this->actions_bulk ) ) {
3765
						?>
3766
						<th scope="col" id="cb" class="manage-column column-cb check-column"><input type="checkbox" />
3767
						</th>
3768
						<?php
3769
					}
3770
3771
					$name_field = false;
3772
					$fields     = array();
3773
					if ( ! empty( $table_fields ) ) {
3774
						foreach ( $table_fields as $field => $attributes ) {
3775
							if ( false === $attributes['display'] ) {
3776
								continue;
3777
							}
3778
							if ( false === $name_field ) {
3779
								$id = 'title';
3780
							} else {
3781
								$id = '';
3782
							}
3783
							if ( 'other' === $attributes['type'] ) {
3784
								$id = '';
3785
							}
3786
							if ( in_array( $attributes['type'], array( 'date', 'datetime', 'time' ) ) ) {
3787
								$id = 'date';
3788
							}
3789
							if ( false === $name_field && 'title' === $id ) {
3790
								$name_field = true;
3791
							}
3792
							$fields[ $field ]             = $attributes;
3793
							$fields[ $field ]['field_id'] = $id;
3794
							$dir                          = 'DESC';
3795
							$current_sort                 = ' asc';
3796
							if ( isset( $this->orderby['default'] ) && $field == $this->orderby['default'] ) {
3797
								if ( 'DESC' === $this->orderby_dir ) {
3798
									$dir          = 'ASC';
3799
									$current_sort = ' desc';
3800
								}
3801
							}
3802
3803
							$att_id = '';
3804
							if ( ! empty( $id ) ) {
3805
								$att_id = ' id="' . esc_attr( $id ) . '"';
3806
							}
3807
3808
							$width = '';
3809
3810
							$column_classes = array(
3811
								'manage-column',
3812
								'column-' . $id,
3813
							);
3814
3815
							// Merge with the classes taken from the UI call
3816
							if ( ! empty( $attributes['classes'] ) && is_array( $attributes['classes'] ) ) {
3817
								$column_classes = array_merge( $column_classes, $attributes['classes'] );
3818
							}
3819
							if ( $id == 'title' ) {
0 ignored issues
show
Found "== '". Use Yoda Condition checks, you must
Loading history...
3820
								$column_classes[] = 'column-primary';
3821
							}
3822
3823
							if ( isset( $attributes['width'] ) && ! empty( $attributes['width'] ) ) {
3824
								$width = ' style="width: ' . esc_attr( $attributes['width'] ) . '"';
3825
							}
3826
3827
							if ( $fields[ $field ]['sortable'] ) {
3828
								$column_classes[] = 'sortable' . $current_sort;
3829
								?>
3830
								<th scope="col"<?php echo $att_id; ?> class="<?php echo esc_attr( implode( ' ', $column_classes ) ); ?>"<?php echo $width; ?>>
3831
									<a href="
3832
									<?php
3833
									echo esc_url_raw(
3834
										pods_query_arg(
3835
											array(
3836
												'orderby' . $this->num => $field,
3837
												'orderby_dir' . $this->num => $dir,
3838
											), array(
3839
												'limit' . $this->num,
3840
												'search' . $this->num,
3841
												'pg' . $this->num,
3842
												'page',
3843
											), $this->exclusion()
3844
										)
3845
									);
3846
									?>
3847
									">
3848
										<span><?php echo esc_html( $attributes['label'] ); ?></span>
3849
										<span class="sorting-indicator"></span> </a>
3850
								</th>
3851
								<?php
3852
							} else {
3853
								?>
3854
								<th scope="col"<?php echo $att_id; ?> class="<?php echo esc_attr( implode( ' ', $column_classes ) ); ?>"<?php echo $width; ?>><?php echo esc_html( $attributes['label'] ); ?></th>
3855
								<?php
3856
							}//end if
3857
						}//end foreach
3858
					}//end if
3859
					?>
3860
				</tr>
3861
				</thead>
3862
				<?php
3863
				if ( 6 < $this->total_found ) {
3864
					?>
3865
					<tfoot>
3866
					<tr>
3867
						<?php
3868
						if ( ! empty( $this->actions_bulk ) ) {
3869
							?>
3870
							<th scope="col" class="manage-column column-cb check-column"><input type="checkbox" /></th>
3871
							<?php
3872
						}
3873
3874
						if ( ! empty( $fields ) ) {
3875
							foreach ( $fields as $field => $attributes ) {
3876
								$dir = 'ASC';
3877
								if ( $field == $this->orderby ) {
3878
									$current_sort = 'desc';
3879
									if ( 'ASC' === $this->orderby_dir ) {
3880
										$dir          = 'DESC';
3881
										$current_sort = 'asc';
3882
									}
3883
								}
3884
3885
								$width = '';
3886
3887
								if ( isset( $attributes['width'] ) && ! empty( $attributes['width'] ) ) {
3888
									$width = ' style="width: ' . esc_attr( $attributes['width'] ) . '"';
3889
								}
3890
3891
								if ( $fields[ $field ]['sortable'] ) {
3892
									?>
3893
									<th scope="col" class="manage-column column-<?php echo esc_attr( $id ); ?> sortable <?php echo esc_attr( $current_sort ); ?>"<?php echo $width; ?>>
0 ignored issues
show
The variable $id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
The variable $current_sort does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
3894
										<a href="
3895
										<?php
3896
										echo esc_url_raw(
3897
											pods_query_arg(
3898
												array(
3899
													'orderby' . $this->num     => $field,
3900
													'orderby_dir' . $this->num => $dir,
3901
												), array(
3902
													'limit' . $this->num,
3903
													'search' . $this->num,
3904
													'pg' . $this->num,
3905
													'page',
3906
												), $this->exclusion()
3907
											)
3908
										);
3909
										?>
3910
										"><span><?php echo esc_html( $attributes['label'] ); ?></span><span class="sorting-indicator"></span></a>
3911
									</th>
3912
									<?php
3913
								} else {
3914
									?>
3915
									<th scope="col" class="manage-column column-<?php echo esc_attr( $id ); ?>"<?php echo $width; ?>><?php echo esc_html( $attributes['label'] ); ?></th>
3916
									<?php
3917
								}//end if
3918
							}//end foreach
3919
						}//end if
3920
						?>
3921
					</tr>
3922
					</tfoot>
3923
					<?php
3924
				}//end if
3925
				?>
3926
				<tbody id="the-list"<?php echo ( true === $reorder && ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) ? ' class="reorderable"' : ''; ?>>
3927
				<?php
3928
				if ( ! empty( $this->data ) && is_array( $this->data ) ) {
3929
					$counter = 0;
3930
3931
					while ( $row = $this->get_row( $counter, 'table' ) ) {
3932
						if ( is_object( $row ) ) {
3933
							$row = get_object_vars( (object) $row );
3934
						}
3935
3936
						$toggle_class = '';
3937
3938
						if ( is_array( $this->actions_custom ) && isset( $this->actions_custom['toggle'] ) ) {
3939
							$toggle_class = ' pods-toggled-on';
3940
3941
							if ( ! isset( $row['toggle'] ) || empty( $row['toggle'] ) ) {
3942
								$toggle_class = ' pods-toggled-off';
3943
							}
3944
						}
3945
						?>
3946
						<tr id="item-<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>" class="iedit<?php echo esc_attr( $toggle_class ); ?>">
3947
							<?php
3948
							if ( ! empty( $this->actions_bulk ) ) {
3949
								?>
3950
								<th scope="row" class="check-column">
3951
									<input type="checkbox" name="action_bulk_ids<?php echo esc_attr( $this->num ); ?>[]" value="<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>">
3952
								</th>
3953
								<?php
3954
							}
3955
							// Boolean for the first field to output after the check-column
3956
							// will be set to false at the end of the first loop
3957
							$first_field = true;
3958
							foreach ( $fields as $field => $attributes ) {
3959
								if ( false === $attributes['display'] ) {
3960
									continue;
3961
								}
3962
3963
								if ( ! isset( $row[ $field ] ) ) {
3964
									$row[ $field ] = $this->get_field( $field );
3965
								}
3966
3967
								$row_value = $row[ $field ];
3968
3969
								if ( ! empty( $attributes['custom_display'] ) ) {
3970
									if ( is_callable( $attributes['custom_display'] ) ) {
3971
										$row_value = call_user_func_array(
3972
											$attributes['custom_display'], array(
3973
												$row,
3974
												&$this,
3975
												$row_value,
3976
												$field,
3977
												$attributes,
3978
											)
3979
										);
3980
									} elseif ( is_object( $this->pod ) && class_exists( 'Pods_Helpers' ) ) {
3981
										$row_value = $this->pod->helper( $attributes['custom_display'], $row_value, $field );
3982
									}
3983
								} else {
3984
									ob_start();
3985
3986
									$field_value = PodsForm::field_method( $attributes['type'], 'ui', $this->id, $row_value, $field, array_merge( $attributes, pods_var_raw( 'options', $attributes, array(), null, true ) ), $fields, $this->pod );
3987
3988
									$field_output = trim( (string) ob_get_clean() );
3989
3990
									if ( false === $field_value ) {
3991
										$row_value = '';
3992
									} elseif ( 0 < strlen( trim( (string) $field_value ) ) ) {
3993
										$row_value = trim( (string) $field_value );
3994
									} elseif ( 0 < strlen( $field_output ) ) {
3995
										$row_value = $field_output;
3996
									}
3997
								}//end if
3998
3999
								if ( false !== $attributes['custom_relate'] ) {
4000
									global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
4001
									$table = $attributes['custom_relate'];
4002
									$on    = $this->sql['field_id'];
4003
									$is    = $row[ $this->sql['field_id'] ];
4004
									$what  = array( 'name' );
4005
									if ( is_array( $table ) ) {
4006
										if ( isset( $table['on'] ) ) {
4007
											$on = pods_sanitize( $table['on'] );
4008
										}
4009
										if ( isset( $table['is'] ) && isset( $row[ $table['is'] ] ) ) {
4010
											$is = pods_sanitize( $row[ $table['is'] ] );
4011
										}
4012
										if ( isset( $table['what'] ) ) {
4013
											$what = array();
4014
											if ( is_array( $table['what'] ) ) {
4015
												foreach ( $table['what'] as $wha ) {
4016
													$what[] = pods_sanitize( $wha );
4017
												}
4018
											} else {
4019
												$what[] = pods_sanitize( $table['what'] );
4020
											}
4021
										}
4022
										if ( isset( $table['table'] ) ) {
4023
											$table = $table['table'];
4024
										}
4025
									}//end if
4026
									$table = pods_sanitize( $table );
4027
									$wha   = implode( ',', $what );
4028
									$sql   = "SELECT {$wha} FROM {$table} WHERE `{$on}`='{$is}'";
4029
									$value = @current( $wpdb->get_results( $sql, ARRAY_A ) );
0 ignored issues
show
Silencing errors is discouraged
Loading history...
Usage of a direct database call is discouraged.
Loading history...
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
4030
									if ( ! empty( $value ) ) {
4031
										$val = array();
4032
										foreach ( $what as $wha ) {
4033
											if ( isset( $value[ $wha ] ) ) {
4034
												$val[] = $value[ $wha ];
4035
											}
4036
										}
4037
										if ( ! empty( $val ) ) {
4038
											$row_value = implode( ' ', $val );
4039
										}
4040
									}
4041
								}//end if
4042
4043
								$css_classes = array(
4044
									'pods-ui-col-field-' . sanitize_title( $field ),
4045
								);
4046
4047
								// Merge with the classes taken from the UI call
4048
								if ( ! empty( $attributes['classes'] ) && is_array( $attributes['classes'] ) ) {
4049
									$css_classes = array_merge( $css_classes, $attributes['classes'] );
4050
								}
4051
4052
								if ( $attributes['css_values'] ) {
4053
									$css_field_value = $row[ $field ];
4054
4055
									if ( is_object( $css_field_value ) ) {
4056
										$css_field_value = get_object_vars( $css_field_value );
4057
									}
4058
4059
									if ( is_array( $css_field_value ) ) {
4060
										foreach ( $css_field_value as $css_field_val ) {
4061
											if ( is_object( $css_field_val ) ) {
4062
												$css_field_val = get_object_vars( $css_field_val );
4063
											}
4064
4065
											if ( is_array( $css_field_val ) ) {
4066
												foreach ( $css_field_val as $css_field_v ) {
4067
													if ( is_object( $css_field_v ) ) {
4068
														$css_field_v = get_object_vars( $css_field_v );
4069
													}
4070
4071
													$css_classes[] = 'pods-ui-css-value-' . sanitize_title(
4072
														str_replace(
4073
															array(
4074
																"\n",
4075
																"\r",
4076
															), ' ', strip_tags( (string) $css_field_v )
4077
														)
4078
													);
4079
												}
4080
											} else {
4081
												$css_classes[] = ' pods-ui-css-value-' . sanitize_title(
4082
													str_replace(
4083
														array(
4084
															"\n",
4085
															"\r",
4086
														), ' ', strip_tags( (string) $css_field_val )
4087
													)
4088
												);
4089
											}//end if
4090
										}//end foreach
4091
									} else {
4092
										$css_classes[] = ' pods-ui-css-value-' . sanitize_title(
4093
											str_replace(
4094
												array(
4095
													"\n",
4096
													"\r",
4097
												), ' ', strip_tags( (string) $css_field_value )
4098
											)
4099
										);
4100
									}//end if
4101
								}//end if
4102
4103
								if ( is_object( $this->pod ) ) {
4104
									$row_value = $this->do_hook( $this->pod->pod . '_field_value', $row_value, $field, $attributes, $row );
4105
								}
4106
4107
								$row_value = $this->do_hook( 'field_value', $row_value, $field, $attributes, $row );
4108
4109
								if ( ! empty( $attributes['custom_display_formatted'] ) && is_callable( $attributes['custom_display_formatted'] ) ) {
4110
									$row_value = call_user_func_array(
4111
										$attributes['custom_display_formatted'], array(
4112
											$row,
4113
											&$this,
4114
											$row_value,
4115
											$field,
4116
											$attributes,
4117
										)
4118
									);
4119
								}
4120
4121
								if ( 'title' === $attributes['field_id'] ) {
4122
									$default_action = $this->do_hook( 'default_action', 'edit', $row );
4123
4124
									if ( $first_field ) {
4125
										$css_classes[] = 'column-primary';
4126
									}
4127
									$css_classes[] = 'post-title';
4128
									$css_classes[] = 'page-title';
4129
									$css_classes[] = 'column-title';
4130
4131
									if ( 'raw' !== $attributes['type'] ) {
4132
										$row_value = wp_kses_post( $row_value );
4133
									}
4134
4135
									if ( ! in_array( 'edit', $this->actions_disabled ) && ! in_array( 'edit', $this->actions_hidden ) && ( false === $reorder || in_array( 'reorder', $this->actions_disabled ) || false === $this->reorder['on'] ) && 'edit' === $default_action ) {
4136
										$link = pods_query_arg(
4137
											array(
4138
												'action' . $this->num => 'edit',
4139
												'id' . $this->num     => $row[ $this->sql['field_id'] ],
4140
											), self::$allowed, $this->exclusion()
4141
										);
4142
4143
										if ( ! empty( $this->action_links['edit'] ) ) {
4144
											$link = $this->do_template( $this->action_links['edit'], $row );
4145
										}
4146
										?>
4147
										<td class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>">
4148
										<strong><a class="row-title" href="<?php echo esc_url_raw( $link ); ?>" title="<?php esc_attr_e( 'Edit this item', 'pods' ); ?>">
4149
																						<?php
4150
																						/* Escaped above for non-HTML types */
4151
																						echo $row_value;
4152
												?>
4153
												</a></strong>
4154
										<?php
4155
									} elseif ( ! in_array( 'view', $this->actions_disabled ) && ! in_array( 'view', $this->actions_hidden ) && ( false === $reorder || in_array( 'reorder', $this->actions_disabled ) || false === $this->reorder['on'] ) && 'view' === $default_action ) {
4156
										$link = pods_query_arg(
4157
											array(
4158
												'action' . $this->num => 'view',
4159
												'id' . $this->num     => $row[ $this->sql['field_id'] ],
4160
											), self::$allowed, $this->exclusion()
4161
										);
4162
4163
										if ( ! empty( $this->action_links['view'] ) ) {
4164
											$link = $this->do_template( $this->action_links['view'], $row );
4165
										}
4166
										?>
4167
										<td class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>">
4168
										<strong><a class="row-title" href="<?php echo esc_url_raw( $link ); ?>" title="<?php esc_attr_e( 'View this item', 'pods' ); ?>">
4169
																						<?php
4170
																						/* Escaped above for non-HTML types */
4171
																						echo $row_value;
4172
												?>
4173
												</a></strong>
4174
										<?php
4175
									} else {
4176
										if ( 1 == $reorder && $this->reorder ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->reorder of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
4177
											$css_classes[] = 'dragme';
4178
										}
4179
										?>
4180
										<td class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>">
4181
										<strong>
4182
										<?php
4183
										/* Escaped above for non-HTML types */
4184
											echo $row_value;
4185
											?>
4186
											</strong>
4187
										<?php
4188
									}//end if
4189
4190
									if ( true !== $reorder || in_array( 'reorder', $this->actions_disabled ) || false === $this->reorder['on'] ) {
4191
										$toggle = false;
4192
4193
										$actions = $this->get_actions( $row );
4194
										$actions = $this->do_hook( 'row_actions', $actions, $row[ $this->sql['field_id'] ] );
4195
4196
										if ( ! empty( $actions ) ) {
4197
											?>
4198
											<div class="row-actions<?php echo esc_attr( $toggle ? ' row-actions-toggle' : '' ); ?>">
4199
												<?php
4200
												$this->callback( 'actions_start', $row, $actions );
4201
4202
												echo implode( ' | ', $actions );
4203
4204
												$this->callback( 'actions_end', $row, $actions );
4205
												?>
4206
											</div>
4207
											<?php
4208
										}
4209
									} else {
4210
										?>
4211
										<input type="hidden" name="order[]" value="<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>" />
4212
										<?php
4213
									}//end if
4214
									?>
4215
									<button type="button" class="toggle-row">
4216
										<span class="screen-reader-text"><?php esc_html_e( 'Show more details', 'pods' ); ?></span>
4217
									</button>
4218
									</td>
4219
									<?php
4220
								} elseif ( 'date' === $attributes['type'] ) {
4221
									if ( $first_field ) {
4222
										$css_classes[] = 'column-primary';
4223
									}
4224
									$css_classes[] = 'date';
4225
									$css_classes[] = 'column-date';
4226
									?>
4227
									<td class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>" data-colname="<?php echo esc_attr( $attributes['label'] ); ?>">
4228
										<abbr title="<?php echo esc_attr( $row_value ); ?>"><?php echo wp_kses_post( $row_value ); ?></abbr>
4229
										<?php if ( $first_field ) { ?>
4230
											<button type="button" class="toggle-row">
4231
											<span class="screen-reader-text"><?php esc_html_e( 'Show more details', 'pods' ); ?></span>
4232
											</button><?php } ?>
4233
									</td>
4234
									<?php
4235
								} else {
4236
									if ( $first_field ) {
4237
										$css_classes[] = 'column-primary';
4238
									}
4239
4240
									$css_classes[] = 'author';
4241
4242
									if ( 'raw' !== $attributes['type'] ) {
4243
										$row_value = wp_kses_post( $row_value );
4244
									}
4245
									?>
4246
									<td class="<?php echo esc_attr( implode( ' ', $css_classes ) ); ?>" data-colname="<?php echo esc_attr( $attributes['label'] ); ?>">
4247
										<span>
4248
										<?php
4249
										/* Escaped above for non-HTML types */
4250
											echo $row_value;
4251
											?>
4252
											</span>
4253
										<?php if ( $first_field ) { ?>
4254
											<button type="button" class="toggle-row">
4255
											<span class="screen-reader-text"><?php esc_html_e( 'Show more details', 'pods' ); ?></span>
4256
											</button><?php } ?>
4257
									</td>
4258
									<?php
4259
								}//end if
4260
								$first_field = false;
4261
							}//end foreach
4262
							?>
4263
						</tr>
4264
						<?php
4265
					}//end while
4266
				}//end if
4267
				?>
4268
				</tbody>
4269
			</table>
4270
			<?php
4271
			if ( true === $reorder && ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) {
4272
4273
			?>
4274
		</form>
4275
		<?php
4276
			}
4277
		?>
4278
		<script type="text/javascript">
4279
			jQuery( 'table.widefat tbody tr:even' ).addClass( 'alternate' );
4280
			<?php
4281
			if ( true === $reorder && ! in_array( 'reorder', $this->actions_disabled ) && false !== $this->reorder['on'] ) {
4282
			?>
4283
			jQuery( document ).ready( function () {
4284
				jQuery( ".reorderable" ).sortable( {axis : "y", handle : ".dragme"} );
4285
				jQuery( ".reorderable" ).bind( 'sortupdate', function ( event, ui ) {
4286
					jQuery( 'table.widefat tbody tr' ).removeClass( 'alternate' );
4287
					jQuery( 'table.widefat tbody tr:even' ).addClass( 'alternate' );
4288
				} );
4289
			} );
4290
			<?php
4291
			}
4292
			?>
4293
		</script>
4294
		<?php
4295
	}
4296
4297
	/**
4298
	 * Get actions for row.
4299
	 *
4300
	 * @param array $row
4301
	 *
4302
	 * @return array
4303
	 */
4304
	public function get_actions( $row ) {
4305
4306
		$actions = array();
4307
4308
		if ( ! in_array( 'view', $this->actions_disabled ) && ! in_array( 'view', $this->actions_hidden ) ) {
4309
			$link = pods_query_arg(
4310
				array(
4311
					'action' . $this->num => 'view',
4312
					'id' . $this->num     => $row[ $this->sql['field_id'] ],
4313
				), self::$allowed, $this->exclusion()
4314
			);
4315
4316
			if ( ! empty( $this->action_links['view'] ) ) {
4317
				$link = $this->do_template( $this->action_links['view'], $row );
4318
			}
4319
4320
			$actions['view'] = '<span class="view"><a href="' . esc_url( $link ) . '" title="' . esc_attr__( 'View this item', 'pods' ) . '">' . __( 'View', 'pods' ) . '</a></span>';
4321
		}
4322
4323
		if ( ! in_array( 'edit', $this->actions_disabled ) && ! in_array( 'edit', $this->actions_hidden ) && ! $this->restricted( 'edit', $row ) ) {
4324
			$link = pods_query_arg(
4325
				array(
4326
					'action' . $this->num => 'edit',
4327
					'id' . $this->num     => $row[ $this->sql['field_id'] ],
4328
				), self::$allowed, $this->exclusion()
4329
			);
4330
4331
			if ( ! empty( $this->action_links['edit'] ) ) {
4332
				$link = $this->do_template( $this->action_links['edit'], $row );
4333
			}
4334
4335
			$actions['edit'] = '<span class="edit"><a href="' . esc_url( $link ) . '" title="' . esc_attr__( 'Edit this item', 'pods' ) . '">' . __( 'Edit', 'pods' ) . '</a></span>';
4336
		}
4337
4338
		if ( ! in_array( 'duplicate', $this->actions_disabled ) && ! in_array( 'duplicate', $this->actions_hidden ) && ! $this->restricted( 'edit', $row ) ) {
4339
			$link = pods_query_arg(
4340
				array(
4341
					'action' . $this->num => 'duplicate',
4342
					'id' . $this->num     => $row[ $this->sql['field_id'] ],
4343
				), self::$allowed, $this->exclusion()
4344
			);
4345
4346
			if ( ! empty( $this->action_links['duplicate'] ) ) {
4347
				$link = $this->do_template( $this->action_links['duplicate'], $row );
4348
			}
4349
4350
			$actions['duplicate'] = '<span class="edit"><a href="' . esc_url( $link ) . '" title="' . esc_attr__( 'Duplicate this item', 'pods' ) . '">' . __( 'Duplicate', 'pods' ) . '</a></span>';
4351
		}
4352
4353
		if ( ! in_array( 'delete', $this->actions_disabled ) && ! in_array( 'delete', $this->actions_hidden ) && ! $this->restricted( 'delete', $row ) ) {
4354
			$link = pods_query_arg(
4355
				array(
4356
					'action' . $this->num => 'delete',
4357
					'id' . $this->num     => $row[ $this->sql['field_id'] ],
4358
					'_wpnonce'            => wp_create_nonce( 'pods-ui-action-delete' ),
4359
				), self::$allowed, $this->exclusion()
4360
			);
4361
4362
			if ( ! empty( $this->action_links['delete'] ) ) {
4363
				$link = add_query_arg( array( '_wpnonce' => wp_create_nonce( 'pods-ui-action-delete' ) ), $this->do_template( $this->action_links['delete'], $row ) );
4364
			}
4365
4366
			$actions['delete'] = '<span class="delete"><a href="' . esc_url( $link ) . '" title="' . esc_attr__( 'Delete this item', 'pods' ) . '" class="submitdelete" onclick="if(confirm(\'' . esc_attr__( 'You are about to permanently delete this item\n Choose \\\'Cancel\\\' to stop, \\\'OK\\\' to delete.', 'pods' ) . '\')){return true;}return false;">' . __( 'Delete', 'pods' ) . '</a></span>';
4367
		}
4368
4369
		if ( is_array( $this->actions_custom ) ) {
4370
			foreach ( $this->actions_custom as $custom_action => $custom_data ) {
4371
				if ( 'add' !== $custom_action && is_array( $custom_data ) && ( isset( $custom_data['link'] ) || isset( $custom_data['callback'] ) ) && ! in_array( $custom_action, $this->actions_disabled ) && ! in_array( $custom_action, $this->actions_hidden ) ) {
4372
					if ( ! in_array(
4373
						$custom_action, array(
4374
							'add',
4375
							'view',
4376
							'edit',
4377
							'duplicate',
4378
							'delete',
4379
							'save',
4380
							'export',
4381
							'reorder',
4382
							'manage',
4383
							'table',
4384
						)
4385
					) ) {
4386
						if ( 'toggle' === $custom_action ) {
4387
							$toggle        = true;
4388
							$toggle_labels = array(
4389
								__( 'Enable', 'pods' ),
4390
								__( 'Disable', 'pods' ),
4391
							);
4392
4393
							$custom_data['label'] = ( $row['toggle'] ? $toggle_labels[1] : $toggle_labels[0] );
4394
						}
4395
4396
						if ( ! isset( $custom_data['label'] ) ) {
4397
							$custom_data['label'] = ucwords( str_replace( '_', ' ', $custom_action ) );
4398
						}
4399
4400
						if ( ! isset( $custom_data['link'] ) ) {
4401
							$vars = array(
4402
								'action'   => $custom_action,
4403
								'id'       => $row[ $this->sql['field_id'] ],
4404
								'_wpnonce' => wp_create_nonce( 'pods-ui-action-' . $custom_action ),
4405
							);
4406
4407
							if ( 'toggle' === $custom_action ) {
4408
								$vars['toggle']  = (int) ( ! $row['toggle'] );
4409
								$vars['toggled'] = 1;
4410
							}
4411
4412
							$custom_data['link'] = pods_query_arg( $vars, self::$allowed, $this->exclusion() );
4413
4414
							if ( isset( $this->action_links[ $custom_action ] ) && ! empty( $this->action_links[ $custom_action ] ) ) {
4415
								$custom_data['link'] = add_query_arg( array( '_wpnonce' => wp_create_nonce( 'pods-ui-action-' . $custom_action ) ), $this->do_template( $this->action_links[ $custom_action ], $row ) );
4416
							}
4417
						}
4418
4419
						$confirm = '';
4420
4421
						if ( isset( $custom_data['confirm'] ) ) {
4422
							$confirm = ' onclick="if(confirm(\'' . esc_js( $custom_data['confirm'] ) . '\')){return true;}return false;"';
4423
						}
4424
4425
						if ( $this->restricted( $custom_action, $row ) ) {
4426
							continue;
4427
						}
4428
4429
						$actions[ $custom_action ] = '<span class="edit action-' . esc_attr( $custom_action ) . '"><a href="' . esc_url( $this->do_template( $custom_data['link'], $row ) ) . '" title="' . esc_attr( $custom_data['label'] ) . ' this item"' . $confirm . '>' . $custom_data['label'] . '</a></span>';
4430
					}//end if
4431
				}//end if
4432
			}//end foreach
4433
		}//end if
4434
4435
		return $actions;
4436
4437
	}
4438
4439
	/**
4440
	 *
4441
	 */
4442
	public function screen_meta() {
4443
4444
		$screen_html = $help_html = '';
4445
		$screen_link = $help_link = '';
4446
		if ( ! empty( $this->screen_options ) && ! empty( $this->help ) ) {
4447
			foreach ( $this->ui_page as $page ) {
4448
				if ( isset( $this->screen_options[ $page ] ) ) {
4449
					if ( is_array( $this->screen_options[ $page ] ) ) {
4450
						if ( isset( $this->screen_options[ $page ]['link'] ) ) {
4451
							$screen_link = $this->screen_options[ $page ]['link'];
4452
							break;
4453
						}
4454
					} else {
4455
						$screen_html = $this->screen_options[ $page ];
4456
						break;
4457
					}
4458
				}
4459
			}
4460
			foreach ( $this->ui_page as $page ) {
4461
				if ( isset( $this->help[ $page ] ) ) {
4462
					if ( is_array( $this->help[ $page ] ) ) {
4463
						if ( isset( $this->help[ $page ]['link'] ) ) {
4464
							$help_link = $this->help[ $page ]['link'];
4465
							break;
4466
						}
4467
					} else {
4468
						$help_html = $this->help[ $page ];
4469
						break;
4470
					}
4471
				}
4472
			}
4473
		}//end if
4474
		$screen_html = $this->do_hook( 'screen_meta_screen_html', $screen_html );
4475
		$screen_link = $this->do_hook( 'screen_meta_screen_link', $screen_link );
4476
		$help_html   = $this->do_hook( 'screen_meta_help_html', $help_html );
4477
		$help_link   = $this->do_hook( 'screen_meta_help_link', $help_link );
4478
		if ( 0 < strlen( $screen_html ) || 0 < strlen( $screen_link ) || 0 < strlen( $help_html ) || 0 < strlen( $help_link ) ) {
4479
			?>
4480
			<div id="screen-meta">
4481
				<?php
4482
				$this->do_hook( 'screen_meta_pre' );
4483
				if ( 0 < strlen( $screen_html ) ) {
4484
					?>
4485
					<div id="screen-options-wrap" class="pods-hidden">
4486
						<form id="adv-settings" action="" method="post">
4487
							<?php
4488
							echo $screen_html;
4489
							$fields = array();
4490
							foreach ( $this->ui_page as $page ) {
4491
								if ( isset( $this->fields[ $page ] ) && ! empty( $this->fields[ $page ] ) ) {
4492
									$fields = $this->fields[ $page ];
4493
								}
4494
							}
4495
							if ( ! empty( $fields ) || true === $this->pagination ) {
4496
								?>
4497
								<h5><?php _e( 'Show on screen', 'pods' ); ?></h5>
4498
								<?php
4499
								if ( ! empty( $fields ) ) {
4500
									?>
4501
									<div class="metabox-prefs">
4502
										<?php
4503
										$this->do_hook( 'screen_meta_screen_options' );
4504
										foreach ( $fields as $field => $attributes ) {
4505
											if ( false === $attributes['display'] || true === $attributes['hidden'] ) {
4506
												continue;
4507
											}
4508
											?>
4509
											<label for="<?php echo esc_attr( $field ); ?>-hide">
4510
												<input class="hide-column-tog" name="<?php echo esc_attr( $this->unique_identifier ); ?>_<?php echo esc_attr( $field ); ?>-hide" type="checkbox" id="<?php echo esc_attr( $field ); ?>-hide" value="<?php echo esc_attr( $field ); ?>" checked="checked"><?php echo esc_html( $attributes['label'] ); ?>
4511
											</label>
4512
											<?php
4513
										}
4514
										?>
4515
										<br class="clear">
4516
									</div>
4517
									<h5><?php _e( 'Show on screen', 'pods' ); ?></h5>
4518
									<?php
4519
								}//end if
4520
								?>
4521
								<div class="screen-options">
4522
									<?php
4523
									if ( true === $this->pagination ) {
4524
										?>
4525
										<input type="text" class="screen-per-page" name="wp_screen_options[value]" id="<?php echo esc_attr( $this->unique_identifier ); ?>_per_page" maxlength="3" value="20">
4526
										<label for="<?php echo esc_attr( $this->unique_identifier ); ?>_per_page"><?php echo esc_html( sprintf( __( '%s per page', 'pods' ), $this->items ) ); ?></label>
4527
										<?php
4528
									}
4529
									$this->do_hook( 'screen_meta_screen_submit' );
4530
									?>
4531
									<input type="submit" name="screen-options-apply" id="screen-options-apply" class="button" value="<?php esc_attr_e( 'Apply', 'pods' ); ?>">
4532
									<input type="hidden" name="wp_screen_options[option]" value="<?php echo esc_attr( $this->unique_identifier ); ?>_per_page">
4533
									<?php wp_nonce_field( 'screen-options-nonce', 'screenoptionnonce', false ); ?>
4534
								</div>
4535
								<?php
4536
							}//end if
4537
							?>
4538
						</form>
4539
					</div>
4540
					<?php
4541
				}//end if
4542
				if ( 0 < strlen( $help_html ) ) {
4543
					?>
4544
					<div id="contextual-help-wrap" class="pods-hidden">
4545
						<div class="metabox-prefs">
4546
							<?php echo $help_html; ?>
4547
						</div>
4548
					</div>
4549
					<?php
4550
				}
4551
				?>
4552
				<div id="screen-meta-links">
4553
					<?php
4554
					$this->do_hook( 'screen_meta_links_pre' );
4555
					if ( 0 < strlen( $help_html ) || 0 < strlen( $help_link ) ) {
4556
						?>
4557
						<div id="contextual-help-link-wrap" class="hide-if-no-js screen-meta-toggle">
4558
							<?php
4559
							if ( 0 < strlen( $help_link ) ) {
4560
								?>
4561
								<a href="<?php echo esc_url( $help_link ); ?>" class="show-settings">Help</a>
4562
								<?php
4563
							} else {
4564
								?>
4565
								<a href="#contextual-help" id="contextual-help-link" class="show-settings">Help</a>
4566
								<?php
4567
							}
4568
							?>
4569
						</div>
4570
						<?php
4571
					}
4572
					if ( 0 < strlen( $screen_html ) || 0 < strlen( $screen_link ) ) {
4573
						?>
4574
						<div id="screen-options-link-wrap" class="hide-if-no-js screen-meta-toggle">
4575
							<?php
4576
							if ( 0 < strlen( $screen_link ) ) {
4577
								?>
4578
								<a href="<?php echo esc_url( $screen_link ); ?>" class="show-settings">Screen Options</a>
4579
								<?php
4580
							} else {
4581
								?>
4582
								<a href="#screen-options" id="show-settings-link" class="show-settings">Screen Options</a>
4583
								<?php
4584
							}
4585
							?>
4586
						</div>
4587
						<?php
4588
					}
4589
					$this->do_hook( 'screen_meta_links_post' );
4590
					?>
4591
				</div>
4592
				<?php
4593
				$this->do_hook( 'screen_meta_post' );
4594
				?>
4595
			</div>
4596
			<?php
4597
		}//end if
4598
	}
4599
4600
	/**
4601
	 * @param bool $header
4602
	 *
4603
	 * @return mixed
4604
	 */
4605
	public function pagination( $header = false ) {
4606
4607
		if ( false !== $this->callback( 'pagination', $header ) ) {
4608
			return null;
4609
		}
4610
4611
		$total_pages = ceil( $this->total_found / $this->limit );
4612
		$request_uri = pods_query_arg(
4613
			array( 'pg' . $this->num => '' ), array(
4614
				'limit' . $this->num,
4615
				'orderby' . $this->num,
4616
				'orderby_dir' . $this->num,
4617
				'search' . $this->num,
4618
				'filter_*',
4619
				'view' . $this->num,
4620
				'page' . $this->num,
4621
			), $this->exclusion()
4622
		);
4623
4624
		$append = false;
4625
4626
		if ( false !== strpos( $request_uri, '?' ) ) {
4627
			$append = true;
4628
		}
4629
4630
		if ( false !== $this->pagination_total && ( $header || 1 != $this->total_found ) ) {
4631
			$singular_label = strtolower( $this->item );
4632
			$plural_label   = strtolower( $this->items );
4633
			?>
4634
			<span class="displaying-num"><?php echo number_format_i18n( $this->total_found ) . ' ' . _n( $singular_label, $plural_label, $this->total_found, 'pods' ) . $this->extra['total']; ?></span>
4635
			<?php
4636
		}
4637
4638
		if ( false !== $this->pagination ) {
4639
			if ( 1 < $total_pages ) {
4640
				?>
4641
				<a class="first-page<?php echo esc_attr( ( 1 < $this->page ) ? '' : ' disabled' ); ?>" title="<?php esc_attr_e( 'Go to the first page', 'pods' ); ?>" href="<?php echo esc_url( $request_uri . ( $append ? '&' : '?' ) . 'pg' . $this->num . '=1' ); ?>">&laquo;</a>
4642
				<a class="prev-page<?php echo esc_attr( ( 1 < $this->page ) ? '' : ' disabled' ); ?>" title="<?php esc_attr_e( 'Go to the previous page', 'pods' ); ?>" href="<?php echo esc_url( $request_uri . ( $append ? '&' : '?' ) . 'pg' . $this->num . '=' . max( $this->page - 1, 1 ) ); ?>">&lsaquo;</a>
4643
				<?php
4644
				if ( true == $header ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
4645
					?>
4646
					<span class="paging-input"><input class="current-page" title="<?php esc_attr_e( 'Current page', 'pods' ); ?>" type="text" name="pg<?php echo esc_attr( $this->num ); ?>" value="<?php echo esc_attr( absint( $this->page ) ); ?>" size="<?php echo esc_attr( strlen( $total_pages ) ); ?>"> <?php _e( 'of', 'pods' ); ?>
4647
						<span class="total-pages"><?php echo absint( $total_pages ); ?></span></span>
4648
					<script>
4649
4650
						jQuery( document ).ready( function ( $ ) {
4651
							var pageInput = $( 'input.current-page' );
4652
							var currentPage = pageInput.val();
4653
							pageInput.closest( 'form' ).submit( function ( e ) {
4654
								if ( ( 1 > $( 'select[name="action<?php echo esc_attr( $this->num ); ?>"]' ).length || $( 'select[name="action<?php echo esc_attr( $this->num ); ?>"]' ).val() == -1 ) && ( 1 > $( 'select[name="action_bulk<?php echo esc_attr( $this->num ); ?>"]' ).length || $( 'select[name="action_bulk<?php echo esc_attr( $this->num ); ?>"]' ).val() == -1 ) && pageInput.val() == currentPage ) {
4655
									pageInput.val( '1' );
4656
								}
4657
							} );
4658
						} );
4659
					</script>
4660
					<?php
4661
				} else {
4662
					?>
4663
					<span class="paging-input"><?php echo absint( $this->page ); ?> <?php _e( 'of', 'pods' ); ?>
4664
						<span class="total-pages"><?php echo number_format_i18n( $total_pages ); ?></span></span>
4665
					<?php
4666
				}//end if
4667
				?>
4668
				<a class="next-page<?php echo esc_attr( ( $this->page < $total_pages ) ? '' : ' disabled' ); ?>" title="<?php esc_attr_e( 'Go to the next page', 'pods' ); ?>" href="<?php echo esc_url( $request_uri . ( $append ? '&' : '?' ) . 'pg' . $this->num . '=' . min( $this->page + 1, $total_pages ) ); ?>">&rsaquo;</a>
4669
				<a class="last-page<?php echo esc_attr( ( $this->page < $total_pages ) ? '' : ' disabled' ); ?>" title="<?php esc_attr_e( 'Go to the last page', 'pods' ); ?>'" href="<?php echo esc_url( $request_uri . ( $append ? '&' : '?' ) . 'pg' . $this->num . '=' . $total_pages ); ?>">&raquo;</a>
4670
				<?php
4671
			}//end if
4672
		}//end if
4673
	}
4674
4675
	/**
4676
	 * @param bool $options
4677
	 *
4678
	 * @return mixed
4679
	 */
4680
	public function limit( $options = false ) {
4681
4682
		if ( false !== $this->callback( 'limit', $options ) ) {
4683
			return null;
4684
		}
4685
4686
		if ( false === $options || ! is_array( $options ) || empty( $options ) ) {
4687
			$options = array( 10, 25, 50, 100, 200 );
4688
		}
4689
4690
		if ( ! in_array( $this->limit, $options ) && - 1 != $this->limit ) {
4691
			$this->limit = $options[1];
4692
		}
4693
4694
		foreach ( $options as $option ) {
4695
			if ( $option == $this->limit ) {
4696
				echo ' <span class="page-numbers current">' . esc_html( $option ) . '</span>';
4697
			} else {
4698
				echo ' <a href="' . esc_url(
4699
					pods_query_arg(
4700
						array( 'limit' => $option ), array(
4701
							'orderby' . $this->num,
4702
							'orderby_dir' . $this->num,
4703
							'search' . $this->num,
4704
							'filter_*',
4705
							'page' . $this->num,
4706
						), $this->exclusion()
4707
					)
4708
				) . '">' . esc_html( $option ) . '</a>';
4709
			}
4710
		}
4711
	}
4712
4713
	/**
4714
	 * @param            $code
4715
	 * @param bool|array $row
4716
	 *
4717
	 * @return mixed
4718
	 */
4719
	public function do_template( $code, $row = false ) {
4720
4721
		if ( is_object( $this->pod ) && 1 == 0 && 0 < $this->pod->id() ) {
0 ignored issues
show
Found "== 0". Use Yoda Condition checks, you must
Loading history...
4722
			return $this->pod->do_magic_tags( $code );
4723
		} else {
4724
			if ( false !== $row ) {
4725
				$this->temp_row = $this->row;
0 ignored issues
show
The property temp_row does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
4726
				$this->row      = $row;
4727
			}
4728
4729
			$code = preg_replace_callback( '/({@(.*?)})/m', array( $this, 'do_magic_tags' ), $code );
4730
4731
			if ( false !== $row ) {
4732
				$this->row = $this->temp_row;
4733
				unset( $this->temp_row );
4734
			}
4735
		}
4736
4737
		return $code;
4738
	}
4739
4740
	/**
4741
	 * @param $tag
4742
	 *
4743
	 * @return string
0 ignored issues
show
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
4744
	 */
4745
	public function do_magic_tags( $tag ) {
4746
4747
		if ( is_array( $tag ) ) {
4748
			if ( ! isset( $tag[2] ) && strlen( trim( $tag[2] ) ) < 1 ) {
4749
				return '';
4750
			}
4751
4752
			$tag = $tag[2];
4753
		}
4754
4755
		$tag = trim( $tag, ' {@}' );
4756
		$tag = explode( ',', $tag );
4757
4758
		if ( empty( $tag ) || ! isset( $tag[0] ) || strlen( trim( $tag[0] ) ) < 1 ) {
4759
			return null;
4760
		}
4761
4762
		foreach ( $tag as $k => $v ) {
4763
			$tag[ $k ] = trim( $v );
4764
		}
4765
4766
		$field_name = $tag[0];
4767
4768
		$value = $this->get_field( $field_name );
4769
4770
		if ( isset( $tag[1] ) && ! empty( $tag[1] ) && is_callable( $tag[1] ) ) {
4771
			$value = call_user_func_array( $tag[1], array( $value, $field_name, $this->row, &$this ) );
4772
		}
4773
4774
		$before = $after = '';
4775
4776
		if ( isset( $tag[2] ) && ! empty( $tag[2] ) ) {
4777
			$before = $tag[2];
4778
		}
4779
4780
		if ( isset( $tag[3] ) && ! empty( $tag[3] ) ) {
4781
			$after = $tag[3];
4782
		}
4783
4784
		if ( 0 < strlen( $value ) ) {
4785
			return $before . $value . $after;
4786
		}
4787
4788
		return null;
4789
	}
4790
4791
	/**
4792
	 * @param bool|array $exclude
4793
	 * @param bool|array $array
4794
	 */
4795
	public function hidden_vars( $exclude = false, $array = false ) {
4796
4797
		$exclude = $this->do_hook( 'hidden_vars', $exclude, $array );
4798
		if ( false === $exclude ) {
4799
			$exclude = array();
4800
		}
4801
		if ( ! is_array( $exclude ) ) {
4802
			$exclude = explode( ',', $exclude );
4803
		}
4804
		$get = $_GET;
4805
		if ( is_array( $array ) ) {
4806
			foreach ( $array as $key => $val ) {
4807
				if ( 0 < strlen( $val ) ) {
4808
					$get[ $key ] = $val;
4809
				} else {
4810
					unset( $get[ $key ] );
4811
				}
4812
			}
4813
		}
4814
		foreach ( $get as $k => $v ) {
4815
			if ( in_array( $k, $exclude ) ) {
4816
				continue;
4817
			}
4818
4819
			if ( is_array( $v ) ) {
4820
				foreach ( $v as $vk => $vv ) {
4821
					?>
4822
					<input type="hidden" name="<?php echo esc_attr( $k ); ?>[<?php echo esc_attr( $vk ); ?>]" value="<?php echo esc_attr( $vv ); ?>" />
4823
					<?php
4824
				}
4825
			} else {
4826
				?>
4827
				<input type="hidden" name="<?php echo esc_attr( $k ); ?>" value="<?php echo esc_attr( $v ); ?>" />
4828
				<?php
4829
			}
4830
		}
4831
	}
4832
4833
	/**
4834
	 * @return array
4835
	 */
4836
	public function exclusion() {
4837
4838
		$exclusion = self::$excluded;
4839
4840
		foreach ( $exclusion as $k => $exclude ) {
4841
			$exclusion[ $k ] = $exclude . $this->num;
4842
		}
4843
4844
		return $exclusion;
4845
	}
4846
4847
	/**
4848
	 * @param string $action
4849
	 * @param null   $row
4850
	 *
4851
	 * @return bool
4852
	 */
4853
	public function restricted( $action = 'edit', $row = null ) {
4854
4855
		$restricted = false;
4856
4857
		$restrict = array();
4858
4859
		if ( isset( $this->restrict[ $action ] ) ) {
4860
			$restrict = (array) $this->restrict[ $action ];
4861
		}
4862
4863
		// @todo Build 'edit', 'duplicate', 'delete' action support for 'where' which runs another find() query
4864
		/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
4865
		if ( !in_array( $action, array( 'manage', 'reorder' ) ) ) {
4866
            $where = pods_var_raw( $action, $this->where, null, null, true );
4867
4868
            if ( !empty( $where ) ) {
4869
                $restricted = true;
4870
4871
                $old_where = $this->where[ $action ];
4872
4873
                $id = $this->row[ $this->sql[ 'field_id' ] ];
4874
4875
                if ( is_array( $where ) ) {
4876
                    if ( 'OR' == pods_var( 'relation', $where ) )
4877
                        $where = array( $where );
4878
4879
                    $where[] = "`t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id;
4880
                }
4881
                else
4882
                    $where = "( {$where} ) AND `t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id;
4883
4884
                $this->where[ $action ] = $where;
4885
4886
                $data = false;
4887
4888
                //$data = $this->get_data();
4889
4890
                $this->where[ $action ] = $old_where;
4891
4892
                if ( empty( $data ) )
4893
                    $restricted = true;
4894
            }
4895
        }*/
4896
4897
		$author_restrict = false;
4898
4899
		if ( ! empty( $this->restrict['author_restrict'] ) && $restrict === $this->restrict['author_restrict'] ) {
4900
			$restricted = false;
4901
4902
			$author_restrict = true;
4903
4904
			if ( is_object( $this->pod ) ) {
4905
				$restricted = true;
4906
4907
				if ( 'settings' === $this->pod->pod_data['type'] && 'add' === $action ) {
4908
					$action = 'edit';
4909
				}
4910
4911
				if ( pods_is_admin( array( 'pods', 'pods_content' ) ) ) {
4912
					$restricted = false;
4913
				} elseif ( 'manage' === $action ) {
4914
					if ( ! in_array( 'edit', $this->actions_disabled ) && current_user_can( 'pods_edit_' . $this->pod->pod ) && current_user_can( 'pods_edit_others_' . $this->pod->pod ) ) {
4915
						$restricted = false;
4916
					} elseif ( ! in_array( 'delete', $this->actions_disabled ) && current_user_can( 'pods_delete_' . $this->pod->pod ) && current_user_can( 'pods_delete_others_' . $this->pod->pod ) ) {
4917
						$restricted = false;
4918
					} elseif ( current_user_can( 'pods_' . $action . '_' . $this->pod->pod ) && current_user_can( 'pods_' . $action . '_others_' . $this->pod->pod ) ) {
4919
						$restricted = false;
4920
					}
4921
				} elseif ( current_user_can( 'pods_' . $action . '_' . $this->pod->pod ) && current_user_can( 'pods_' . $action . '_others_' . $this->pod->pod ) ) {
4922
					$restricted = false;
4923
				}
4924
			}//end if
4925
			/*
4926
			 @todo determine proper logic for non-pods capabilities
4927
			 * else {
4928
			 * $restricted = true;
4929
			 *
4930
			 * if ( pods_is_admin( array( 'pods', 'pods_content' ) ) )
4931
			 * $restricted = false;
4932
			 * elseif ( current_user_can( 'pods_' . $action . '_others_' . $_tbd ) )
4933
			 * $restricted = false;
4934
			 * }*/
4935
		}//end if
4936
4937
		if ( $restricted && ! empty( $restrict ) ) {
4938
			$relation = strtoupper( trim( pods_var( 'relation', $restrict, 'AND', null, true ) ) );
4939
4940
			if ( 'AND' !== $relation ) {
4941
				$relation = 'OR';
4942
			}
4943
4944
			$okay = true;
4945
4946
			foreach ( $restrict as $field => $match ) {
4947
				if ( 'relation' === $field ) {
4948
					continue;
4949
				}
4950
4951
				if ( is_array( $match ) ) {
4952
					$match_okay = true;
4953
4954
					$match_relation = strtoupper( trim( pods_var( 'relation', $match, 'OR', null, true ) ) );
4955
4956
					if ( 'AND' !== $match_relation ) {
4957
						$match_relation = 'OR';
4958
					}
4959
4960
					foreach ( $match as $the_field => $the_match ) {
4961
						if ( 'relation' === $the_field ) {
4962
							continue;
4963
						}
4964
4965
						$value = null;
4966
4967
						if ( is_object( $this->pod ) ) {
4968
							$value = $this->pod->field( $the_match, true );
4969
						} else {
4970
							if ( empty( $row ) ) {
4971
								$row = $this->row;
4972
							}
4973
4974
							if ( isset( $row[ $the_match ] ) ) {
4975
								if ( is_array( $row[ $the_match ] ) ) {
4976
									if ( false !== strpos( $the_match, '.' ) ) {
4977
										$the_matches = explode( '.', $the_match );
4978
4979
										$value = $row[ $the_match ];
4980
4981
										foreach ( $the_matches as $m ) {
4982
											if ( is_array( $value ) && isset( $value[ $m ] ) ) {
4983
												$value = $value[ $m ];
4984
											} else {
4985
												$value = null;
4986
4987
												break;
4988
											}
4989
										}
4990
									}
4991
								} else {
4992
									$value = $row[ $the_match ];
4993
								}
4994
							}//end if
4995
						}//end if
4996
4997
						if ( is_array( $value ) ) {
4998
							if ( ! in_array( $the_match, $value ) ) {
4999
								$match_okay = false;
5000
							} elseif ( 'OR' === $match_relation ) {
5001
								$match_okay = true;
5002
5003
								break;
5004
							}
5005
						} elseif ( $value == $the_match ) {
5006
							$match_okay = false;
5007
						} elseif ( 'OR' === $match_relation ) {
5008
							$match_okay = true;
5009
5010
							break;
5011
						}
5012
					}//end foreach
5013
5014
					if ( ! $match_okay ) {
5015
						$okay = false;
5016
					}
5017
					if ( 'OR' === $relation ) {
5018
						$okay = true;
5019
5020
						break;
5021
					}
5022
				} else {
5023
					$value = null;
5024
5025
					if ( is_object( $this->pod ) ) {
5026
						$value = $this->pod->field( $match, true );
5027
					} else {
5028
						if ( empty( $row ) ) {
5029
							$row = $this->row;
5030
						}
5031
5032
						if ( isset( $row[ $match ] ) ) {
5033
							if ( is_array( $row[ $match ] ) ) {
5034
								if ( false !== strpos( $match, '.' ) ) {
5035
									$matches = explode( '.', $match );
5036
5037
									$value = $row[ $match ];
5038
5039
									foreach ( $matches as $m ) {
5040
										if ( is_array( $value ) && isset( $value[ $m ] ) ) {
5041
											$value = $value[ $m ];
5042
										} else {
5043
											$value = null;
5044
5045
											break;
5046
										}
5047
									}
5048
								}
5049
							} else {
5050
								$value = $row[ $match ];
5051
							}
5052
						}//end if
5053
					}//end if
5054
5055
					if ( is_array( $value ) ) {
5056
						if ( ! in_array( $match, $value ) ) {
5057
							$okay = false;
5058
						} elseif ( 'OR' === $relation ) {
5059
							$okay = true;
5060
5061
							break;
5062
						}
5063
					} elseif ( $value != $match ) {
5064
						$okay = false;
5065
					} elseif ( 'OR' === $relation ) {
5066
						$okay = true;
5067
5068
						break;
5069
					}
5070
				}//end if
5071
			}//end foreach
5072
5073
			if ( ! empty( $author_restrict ) ) {
5074
				if ( is_object( $this->pod ) && 'manage' === $action ) {
5075
					if ( ! in_array( 'edit', $this->actions_disabled ) && ! current_user_can( 'pods_edit_' . $this->pod->pod ) && ! in_array( 'delete', $this->actions_disabled ) && ! current_user_can( 'pods_delete_' . $this->pod->pod ) ) {
5076
						$okay = false;
5077
					}
5078
				}
5079
				if ( is_object( $this->pod ) && ! current_user_can( 'pods_' . $action . '_' . $this->pod->pod ) ) {
5080
					$okay = false;
5081
				}
5082
				/*
5083
				 @todo determine proper logic for non-pods capabilities
5084
				 * elseif ( !current_user_can( 'pods_' . $action . '_' . $_tbd ) )
5085
				 * $okay = false;*/
5086
5087
				if ( ! $okay && ! empty( $row ) ) {
5088
					foreach ( $this->restrict['author_restrict'] as $key => $val ) {
5089
						$author_restricted = $this->get_field( $key );
5090
5091
						if ( ! empty( $author_restricted ) ) {
5092
							if ( ! is_array( $author_restricted ) ) {
5093
								$author_restricted = (array) $author_restricted;
5094
							}
5095
5096
							if ( is_array( $val ) ) {
5097
								foreach ( $val as $v ) {
5098
									if ( in_array( $v, $author_restricted ) ) {
5099
										$okay = true;
5100
									}
5101
								}
5102
							} elseif ( in_array( $val, $author_restricted ) ) {
5103
								$okay = true;
5104
							}
5105
						}
5106
					}
5107
				}//end if
5108
			}//end if
5109
5110
			if ( $okay ) {
5111
				$restricted = false;
5112
			}
5113
		}//end if
5114
5115
		if ( isset( $this->actions_custom[ $action ] ) && is_array( $this->actions_custom[ $action ] ) && isset( $this->actions_custom[ $action ]['restrict_callback'] ) && is_callable( $this->actions_custom[ $action ]['restrict_callback'] ) ) {
5116
			$restricted = call_user_func( $this->actions_custom[ $action ]['restrict_callback'], $restricted, $restrict, $action, $row, $this );
5117
		}
5118
5119
		$restricted = $this->do_hook( 'restricted_' . $action, $restricted, $restrict, $action, $row );
5120
5121
		return $restricted;
5122
	}
5123
5124
	/**
5125
	 * Check for a custom action callback and run it
5126
	 *
5127
	 * @return bool|mixed
5128
	 */
5129
	public function callback() {
5130
5131
		$args = func_get_args();
5132
5133
		if ( empty( $args ) ) {
5134
			return false;
5135
		}
5136
5137
		$action = array_shift( $args );
5138
5139
		// Do hook
5140
		$callback_args = $args;
5141
		array_unshift( $callback_args, null );
5142
		array_unshift( $callback_args, $action );
5143
5144
		$callback = call_user_func_array( array( $this, 'do_hook' ), $callback_args );
5145
5146
		if ( null === $callback ) {
5147
			$callback = false;
5148
		}
5149
5150
		$args[] = $this;
5151
5152
		if ( isset( $this->actions_custom[ $action ] ) ) {
5153
			if ( is_array( $this->actions_custom[ $action ] ) && isset( $this->actions_custom[ $action ]['callback'] ) && is_callable( $this->actions_custom[ $action ]['callback'] ) ) {
5154
				$callback = call_user_func_array( $this->actions_custom[ $action ]['callback'], $args );
5155
			} elseif ( is_callable( $this->actions_custom[ $action ] ) ) {
5156
				$callback = call_user_func_array( $this->actions_custom[ $action ], $args );
5157
			}
5158
		}
5159
5160
		return $callback;
5161
5162
	}
5163
5164
	/**
5165
	 * Check for a custom action callback and run it (deprecated reverse arg order)
5166
	 *
5167
	 * @return bool|mixed
5168
	 */
5169
	public function callback_action() {
5170
5171
		$args = func_get_args();
5172
5173
		if ( empty( $args ) ) {
5174
			return false;
5175
		}
5176
5177
		$action = array_shift( $args );
5178
5179
		$deprecated = false;
5180
5181
		if ( is_bool( $action ) ) {
5182
			$deprecated = $action;
5183
5184
			$action = array_shift( $args );
5185
		}
5186
5187
		// Do hook
5188
		$callback_args = $args;
5189
		array_unshift( $callback_args, null );
5190
		array_unshift( $callback_args, 'action_' . $action );
5191
5192
		$callback = call_user_func_array( array( $this, 'do_hook' ), $callback_args );
5193
5194
		if ( null === $callback ) {
5195
			$callback = false;
5196
		}
5197
5198
		$args[] = $this;
5199
5200
		// Deprecated reverse arg order
5201
		if ( $deprecated ) {
5202
			$args = array_reverse( $args );
5203
		}
5204
5205
		if ( isset( $this->actions_custom[ $action ] ) ) {
5206
			if ( is_array( $this->actions_custom[ $action ] ) && isset( $this->actions_custom[ $action ]['callback'] ) && is_callable( $this->actions_custom[ $action ]['callback'] ) ) {
5207
				$callback = call_user_func_array( $this->actions_custom[ $action ]['callback'], $args );
5208
			} elseif ( is_callable( $this->actions_custom[ $action ] ) ) {
5209
				$callback = call_user_func_array( $this->actions_custom[ $action ], $args );
5210
			}
5211
		}
5212
5213
		return $callback;
5214
5215
	}
5216
5217
	/**
5218
	 * Check for a bulk action callback and run it
5219
	 *
5220
	 * @return bool|mixed Callback result
5221
	 */
5222
	public function callback_bulk() {
5223
5224
		$args = func_get_args();
5225
5226
		if ( empty( $args ) ) {
5227
			return false;
5228
		}
5229
5230
		$action = array_shift( $args );
5231
5232
		$deprecated = false;
5233
5234
		if ( is_bool( $action ) ) {
5235
			$deprecated = $action;
5236
5237
			$action = array_shift( $args );
5238
		}
5239
5240
		// Do hook
5241
		$callback_args = $args;
5242
		array_unshift( $callback_args, null );
5243
		array_unshift( $callback_args, 'bulk_action_' . $action );
5244
5245
		$callback = call_user_func_array( array( $this, 'do_hook' ), $callback_args );
5246
5247
		if ( null === $callback ) {
5248
			$callback = false;
5249
		}
5250
5251
		$args[] = $this;
5252
5253
		// Deprecated reverse arg order
5254
		if ( $deprecated ) {
5255
			$args = array_reverse( $args );
5256
		}
5257
5258
		if ( isset( $this->actions_bulk[ $action ] ) ) {
5259
			if ( is_array( $this->actions_bulk[ $action ] ) && isset( $this->actions_bulk[ $action ]['callback'] ) && is_callable( $this->actions_bulk[ $action ]['callback'] ) ) {
5260
				$callback = call_user_func_array( $this->actions_bulk[ $action ]['callback'], $args );
5261
			} elseif ( is_callable( $this->actions_bulk[ $action ] ) ) {
5262
				$callback = call_user_func_array( $this->actions_bulk[ $action ], $args );
5263
			}
5264
		}
5265
5266
		return $callback;
5267
5268
	}
5269
5270
	/*
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
5271
        // Example code for use with $this->do_hook
5272
        public function my_filter_function ($args, $obj) {
5273
            $obj[0]->item = 'Post';
5274
            $obj[0]->add = true;
5275
            // args are an array (0 => $arg1, 1 => $arg2)
5276
            // may have more than one arg, dependant on filter
5277
            return $args;
5278
        }
5279
        add_filter('pods_ui_post_init', 'my_filter_function', 10, 2);
5280
    */
5281
	/**
5282
	 * @return array|bool|mixed|null
5283
	 */
5284
	private function do_hook() {
5285
5286
		$args = func_get_args();
5287
5288
		if ( empty( $args ) ) {
5289
			return false;
5290
		}
5291
5292
		$name = array_shift( $args );
5293
5294
		return pods_do_hook( 'ui', $name, $args, $this );
5295
5296
	}
5297
}
5298